Bash grep IP from command output - bash

I'm working with fleetctl and kubectl and would like to extract an IP from kubectl get pod app-etcd:
POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS CREATED MESSAGE
app-etcd 10.10.0.1 k8s-socius-node-1/100.100.100.100 name=app-etcd Running 3 days
app-etcd xyz/etcd-discovery Running 3 days
The closest I got to get the IP address is:
kubectl get pod app-etcd | grep -Eo '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
But this gives me both IP addresses (10.10.0.1 and 100.100.100.100); I only want/need the first one to run sed over a config file afterwards.
How do I get only the first address to store it in a variable for further processing?

What if you use awk to get the second column output like
kubectl get pod app-etcd | awk '{print $2}'

kubectl offers json output with --output / -o:
kubectl get -o json pod app-etcd | jsawk 'return this.status.podIP'

Related

Get logs from all pods in namespace using xargs

Is there anyway to get all logs from pods in a specific namespace running a dynamic command like a combination of awk and xargs?
kubectl get pods | grep Running | awk '{print $1}' | xargs kubectl logs | grep value
I have tried the command above but it's failing like kubectl logs is missing pod name:
error: expected 'logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]'.
POD or TYPE/NAME is a required argument for the logs command
See 'kubectl logs -h' for help and examples
Do you have any suggestion about how get all logs from Running pods?
Think about what your pipeline is doing:
The kubectl logs command takes as an argument a single pod name, but through your use of xargs you're passing it multiple pod names. Make liberal use of the echo command to debug your pipelines; if I have these pods in my current namespace:
$ kubectl get pods -o custom-columns=name:.metadata.name
name
c069609c6193930cd1182e1936d8f0aebf72bc22265099c6a4af791cd2zkt8r
catalog-operator-6b8c45596c-262w9
olm-operator-56cf65dbf9-qwkjh
operatorhubio-catalog-48kgv
packageserver-54878d5cbb-flv2z
packageserver-54878d5cbb-t9tgr
Then running this command:
kubectl get pods | grep Running | awk '{print $1}' | xargs echo kubectl logs
Produces:
kubectl logs catalog-operator-6b8c45596c-262w9 olm-operator-56cf65dbf9-qwkjh operatorhubio-catalog-48kgv packageserver-54878d5cbb-flv2z packageserver-54878d5cbb-t9tgr
To do what you want, you need to arrange to call kubectl logs multiple times with a single argument. You can do that by adding -n1 to your xargs command line. Keeping the echo command, running this:
kubectl get pods | grep Running | awk '{print $1}' | xargs -n1 echo kubectl logs
Gets us:
kubectl logs catalog-operator-6b8c45596c-262w9
kubectl logs olm-operator-56cf65dbf9-qwkjh
kubectl logs operatorhubio-catalog-48kgv
kubectl logs packageserver-54878d5cbb-flv2z
kubectl logs packageserver-54878d5cbb-t9tgr
That looks more reasonable. If we drop the echo and run:
kubectl get pods | grep Running | awk '{print $1}' | xargs -n1 kubectl logs | grep value
Then you will get the result you want. You may want to add the --prefix argument to kubectl logs so that you know which pod generated the match:
kubectl get pods | grep Running | awk '{print $1}' | xargs -n1 kubectl logs --prefix | grep value
Not directly related to your question, but you can lose that grep:
kubectl get pods | awk '/Running/ {print $1}' | xargs -n1 kubectl logs --prefix | grep value
And even lose the awk:
kubectl get pods --field-selector=status.phase==Running -o name | xargs -n1 kubectl logs --prefix | grep value

Extracting kubernetes pod name using shell script [duplicate]

This question already has an answer here:
Kubernetes (kubectl) get running pods
(1 answer)
Closed 4 months ago.
I want to extract a pod name from a list of pods available on kubernetes.
For example, for the following command
kubectl get pods -n namespace
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 2 46d
pod2 1/1 Running 0 46d
test-pod3-yy 0/1 ImagePullBackOff 0 338d
test-pod3-xx 1/1 Running 0 255d
I want to extract pod test-pod3-xx using shell script. Currently this is the command that I'm using
POD_NAME=$(kubectl get pods -n namespace | grep testpod-3 | cut -d' ' -f1)
With this I get both the pods test-pod3-yy and test-pod3-xx but I want to extract the pod that is in running state. How can I do that?
You can use the field-selector and check for running only:
--field-selector=status.phase=Running
You could also use the -o name flag, to get only the names. With that you'll get:
$ kubectl get pods -n namespace -o name --field-selector=status.phase=Running
pod/pod1
pod/pod2
pod/test-pod3-xx
#!/bin/sh -x
kubectl get pods -n namespace > stack
while read line
do
[[ -n $(sed -n '/Running/p' "${line}" ]] && echo "${line}"
done < stack

grep for pods and select each result and pass a command in loop

I have few pods running in my kubernetes cluster. I am developing a shell script and I want to grep for few pods and want to select each pod from the grep result to execute a command.
Lets say I grep few pods by command :
kubectl get pods | grep test
the results are:
Test-0
Test-1
Test-2
From the result, I want to select each pod and execute a command for it in a loop.
for example:
for first pod:
kubectl exec -it Test-0 -- mysqldump.......
after finishing the first pod, it has to process the second pod and so on
for pod in $(kubectl get pod -oname |grep -i Test ); do
kubectl exec "$pod" -- ls -ltr ;
done
Replace ls -ltr with mysqldump .....
Get pods name and then use "for" to execute command in each pod
#!/bin/bash
pods=$(kubectl get pods | awk '{print $2}' | grep -i test)
for i in $pods
do
kubectl exec -it $i -- echo "test"
done
Select your target pods using labels is less error prone and can do multiple matching:
kubectl get pods --selector <key>=<value>,<key>=<value> --namespace <name> -oname | xargs -I{} kubectl exec -it {} --namespace <name> -- mysqldump ...

Error from server (NotFound): pods "\nmongo-client-79667cc85d-tsg72" not found

I'm trying to make a backup from Mongo / K8S with this script
export POD=$(kubectl get pods -l app=mongo-client -o custom-columns=:metadata.name -n espace-client)
kubectl exec "$POD" sh -c 'mongodump --archive' > ~/backup/mongo/$(date +%F).db.dump
I get this error:
Error from server (NotFound): pods "\nmongo-client-79667cc85d-tsg72" not found
When I check the pods, I can see mongo-client-79667cc85d-tsg72
When I put the name without variable, it works well, so it might be because of initial \n. How can I avoid it ?
How can I remove it from name ?
Your kubectl get pods command is constrained with a namespace selector -n espace-client. Your kubectl exec command also needs the namespace flag.
The output of your kubectl get pods command has a newline before the pod name because the first line of the output is the column header (which is empty in your case).
To prevent this and get only the name as output, you can suppress the column headers with the --no-headers flag:
kubectl get pods -l app=mongo-client -o custom-columns=:metadata.name -n espace-client --no-headers

How to edit a kubernetes resource from a shell script

I went through the documentation to edit kubernetes resource using kubectl edit command. Once I execute the command, the file in YAML-format is opened in the editor where I can change the values as per requirement and save it. I am trying to execute these steps by means of sed. How can the following steps be achieved?
Execute kubectl edit for a deployment resource
Set a value from true to false (using sed)
Save the changes
I tried to achieve this in the following way :
$ kubectl edit deployment tiller-deploy -n kube-system | \
sed -i "s/\(automountServiceAccountToken:.*$\)/automountServiceAccountToken: true/g"`
Your command is missing a backtick. But even though you put it there, it won't work. The reason is because when you do kubectl edit ..., it edits the file on vim. I am not sure sed would work on vim though. Even though if it does, the output goes to a file, so you get the Vim: Warning: Output is not to a terminal error, which I don't know how to solve.
I would recommend you to get the file and save it. Replace the desired parameters and run it again:
kubectl get deploy tiller-deploy -n kube-system -o yaml > tiller.yaml && sed -i "s/automountServiceAccountToken:.*$/automountServiceAccountToken: true/g" tiller.yaml && kubectl replace -f tiller.yaml
I tried the command above and it worked.
Note: no need to add -n kube-system as the yaml file already contains the namespace.
I just found a less convoluted way of doing this:
KUBE_EDITOR="sed -i s/SOMETHING TO CHANGE/CHANGED/g" kubectl edit resource -n your-ns
I automate through piping the commands through sed command without creating a temporary file. Take the below example, where I am replacing nameserver 8.8.8.8 with 1.1.1.1
$ kubectl -n kube-system get configmap/kube-dns -o yaml | sed "s/8.8.8.8/1.1.1.1/" | kubectl replace -f -
Thanks, #suren for giving what I really looking for, but you don't need to save it in a file. you can directly do kubectl replace using pipe operations
kubectl get deploy test-deploy -o yaml | sed "s/find/replace/g" | kubectl replace -f -
An easy way to do this, just use kubectl-patch instead of sed.
$ kubectl patch deployment tiller-deploy -n kube-system --patch '{"map": {"to": {"the": {"key": {"automountServiceAccountToken": "true"}}}}}'
I don't know kubectl but doc seems to explain that it extract data, edit from an editor than send back, not sure sed pipe work in this case
if piping wokrs
Don't use -i, you don't change a file in a pipe
kubectl edit deployment tiller-deploy -n kube-system | \
sed 's/automountServiceAccountToken:.*$/automountServiceAccountToken: true/g'
if editing a file (and using group in sed)
kubectl edit deployment tiller-deploy -n kube-system > YourCOnfigFile && \
sed -i 's/\(automountServiceAccountToken:\).*$/\1 true/g' YourConfigFile \
&& Some kubectl to send back YourConfigFile

Resources