How to wait until Kubernetes list of pods are successful using shell script - shell

I am trying to find a command or a sample shell snippet where I can wait until the list of Kubernetes pods is successful. I have checked the answer but it was not giving any output. Can someone guide me or suggest an approach, I am completely new to kubernetes.
kubectl -n test-ns get jobs -w
NAME DESIRED SUCCESSFUL AGE
test-1 1 1 2d
test-2 1 1 2d
test-3 1 1 2d
test-4 1 1 2d
until kubectl get jobs -n test-ns -o jsonpath='{.status.conditions[?(#.type=="Complete")].status}' | grep True ; do sleep 1 ; done
This is not giving any output

To wait until your pods are running, check for "condition=ready" and filter by app label, for example:
$ kubectl wait --for=condition=ready pod -l app=netshoot
pod/netshoot-58785d5fc7-xt6fg condition met

you need to use this command
kubectl rollout status

If you want to use kubectl as described here where it gets all the jobs, you need to use .items[*]... in your JSONpath (That answer is for just one specific job). For example:
kubectl -n test-ns get jobs \
-o jsonpath='{.items[*].status.conditions[?(#.type=="Complete")].status}' \
| grep True

Related

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

Shell script should wait until kubernetes pod is running [duplicate]

This question already has an answer here:
kubectl wait for a pod to complete
(1 answer)
Closed 1 year ago.
In a simple bash script I want to run multiple kubectl and helm commands, like:
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.5.4 \
--set installCRDs=true
kubectl apply -f deploy/cert-manager/cluster-issuers.yaml
My problem here is, that after the helm install command I have to wait until the cert-manager pod is running, then the kubectl apply command can be used. Right now the script is calling it too early, so it will fail.
As stated in the comments kubectl wait is the way to go.
Example from the kubectl wait --help
Examples:
# Wait for the pod "busybox1" to contain the status condition of type "Ready"
kubectl wait --for=condition=Ready pod/busybox1
This way your script will pause until specified pod is Running, and kubectl will output
<pod-name> condition met
to STDOUT.
kubectl wait is still in experimental phase. If you want to avoid experimental features, you can achieve similar result with bash while loop.
By pod name:
while [[ $(kubectl get pods <pod-name> -o 'jsonpath={..status.conditions[?(#.type=="Ready")].status}') != "True" ]]; do
sleep 1
done
or by label:
while [[ $(kubectl get pods -l <label>=<label-value> -o 'jsonpath={..status.conditions[?(#.type=="Ready")].status}') != "True" ]]; do
sleep 1
done

Get timestamp of the last successful cronjob completion via kubectl

I have a cronjob running every couple of minutes in kubernetes and would like to set up an alert that notifies me when the cronjob stops working.
I'm expecting it to fail sometimes, it's calling two REST endpoints and they won't always be available.
I want to know if the last successful run happened more than x minutes ago. For this I need the last successful completion timestamp.
I'd like to use the kubectl command line tool. How do I do this?
It was easier than I thought, this is my solution using kubectl and jq:
kubectl get job -l component=<cronjob> -n <namespace> -o json | \
jq -r '.items[] | select(.status.succeeded) | .status.completionTime' | \
sort -r | head -n 1
kubectl fetches all job executions of the cronjob and prints them to json.
jq then selects all successful jobs and prints their completion-time.
sort and head then select the latest timestamp.

View kubectl logs page by page on bash terminal

Team,
On bash I run below to view logs but when they are huge the terminal all is all occupied dumping them out and i can't stop it for minutes.
Is there a way i can execute kubectl on bash in a a way that it shows logs only till shell screen size and then i use return key or spacebar to see more ? just like journalctl? but i want to achieve this when using kubectl.
kubectl logs test-pod -n namespace-test
Above displans 10K lines at a time which i don't want. Neither I want to exec on to the pod and see log file physically. any hints? or is there something like which displays last 100lines? or first with xargs?
There are a few ways to obtain that.
1) less
kubectl logs test-pod -n namespace-test | less
This command will allow you to read logs page by page from top to the bottom. You can use arrows to go up or down.
2) --tail=
kubectl logs test-pod -n namespace-test --tail=500
Will display last 500 rows of logs
3) pipeline with grep
kubectl logs test-pod -n namespace-test | grep <some_phrase>
It will allow you to find logs with given phrases. Please note that you can join commands via pipeline i.e
kubectl logs test-pod -n namespace-test --tail=500 | grep <some_phrase>
4) --since=
kubectl logs test-pod -n namespace-test --since=60
It display logs from last 60 seconds
5) --since-time=''
Similar to previous one. It will display logs from provided time. Format in this command is
'YYYY-MM-DDTHH:MM:ssZ'
kubectl logs test-pod -n namespace-test --since-time='2019-04-23T12:00:00Z'
You could hear about more option like but it is old format. You can scroll only from top to the bottom, you cannot go up.
kubectl logs test-pod -n namespace-test | more
You can do:
kubectl logs --tail=100 test-pod -n namespace-test

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