Kubernetes Liveness probe & environment variables - kubernetes

I'm trying to figure this problem out where i need to Attach liveness probe to the container and restart after checking if environment USER is null or undefined.
Any advice on how to set this condition on a busybox container please?
Thanks for helping out a beginner.
Sincerely.
V

[[ ! -z "$YOURVAR" ]] will return false if $YOURVAR is not defined.
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- /bin/bash
- [[ ! -z "$var" ]]
initialDelaySeconds: 5
periodSeconds: 5

Related

When should I use commands or args in readinessProbes

I am working my way through killer.sh.for the CKAD. I encountered a pod definition file that has a command field under the readiness probe and the container executes another command but uses args.
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod6
name: pod6
spec:
containers:
- args:
- sh
- -c
- touch /tmp/ready && sleep 1d
image: busybox:1.31.0
name: pod6
resources: {}
readinessProbe: # add
exec: # add
command: # add
- sh # add
- -c # add
- cat /tmp/ready # add
initialDelaySeconds: 5 # add
periodSeconds: 10 # add
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
If the readiness probe weren't used and this pod were created implicitly, args wouldn't be utilized.
kubectl run pod6 --image=busybox:1.31.0 --dry-run=client --command -- sh -c "touch /tmp/ready && sleep 1d" > 6.yaml
The output YAML would look like this:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod69
name: pod69
spec:
containers:
- command:
- sh
- -c
- touch /tmp/ready && sleep 1d
image: busybox:1.31.9
name: pod69
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
Why is command not used on both the readinessProbe and the container?
When do commands become args?
Is there a way to tell?
I've read through this document: https://kubernetes.io/docs/tasks/inject-data-application/_print/
but I still haven't had much luck understanding this situation and when to switch to args.
The reason why you have both cmd + args in Kubernetes is because it gives you options to override the default Commands + Args from the image that you are trying to run.
In your specific case, the busybox image does not have any default Commands with the image so specifying the starting command in either cmd or args in the Pod.yaml file is essentially the same.
To your question of when do commands become args - they dont, when a container is spun up using your image, it simply executes cmd + args. And if the cmd is empty in (both the image & the yaml file) then only the args are executed.
The thread here may give you some more explanation

livenessProbe seems not to be executed

A container defined inside a deployment has a livenessProbe set up: by definition, it calls a remote endpoint and checks, whether response contains useful information or an empty response (which should trigger the pod's restart).
The whole definition is as follows (I removed the further checks for better clarity of the markup):
apiVersion: apps/v1
kind: Deployment
metadata:
name: fc-backend-deployment
labels:
name: fc-backend-deployment
app: fc-test
spec:
replicas: 1
selector:
matchLabels:
name: fc-backend-pod
app: fc-test
template:
metadata:
name: fc-backend-pod
labels:
name: fc-backend-pod
app: fc-test
spec:
containers:
- name: fc-backend
image: localhost:5000/backend:1.3
ports:
- containerPort: 4044
env:
- name: NODE_ENV
value: "dev"
- name: REDIS_HOST
value: "redis"
livenessProbe:
exec:
command:
- curl -X GET $BACKEND_SERVICE_HOST:$BACKEND_SERVICE_PORT/api/v3/stats | head -c 30 > /app/out.log
initialDelaySeconds: 20
failureThreshold: 12
periodSeconds: 10
I also tried putting the command into an array:
command: ["sh", "-c", "curl -X GET $BACKEND_SERVICE_HOST:$BACKEND_SERVICE_PORT/api/v3/stats", "|", "head", "-c", "30", ">", "/app/out.log"]
and splitting into separate lines:
- /bin/bash
- -c
- curl
- -X
- GET
- $BACKEND_SERVICE_HOST:$BACKEND_SERVICE_PORT/api/v3/stats
- |
- head
- -c
- "30"
- >
- /app/out.log
and even like this:
command:
- |
curl -X GET $BACKEND_SERVICE_HOST:$BACKEND_SERVICE_PORT/api/v3/stats | head -c 30 > /app/out.log
All attempts were made with and without (/bin/ba)sh -c - with the same result.
But, as you're reading this, you already know that none of these worked.
I know it by exec'ing into running container and trying to find the /app/out.log file - it wasn't present any time I watched the directory contents. It looks like the probe gets never executed.
The command run inside running container works just fine: data gets fetched and written to the specified file.
What might be causing the probe not to get executed?
When using the exec type of probes, Kubernetes will not run a shell to process the command, it will just run the command directly. This means that you can only use a single command and that the | character is considered just another parameter of your curl.
To solve the problem, you need to use sh -c to exec shell code, something like the following:
livenessProbe:
exec:
command:
- sh
- -c
- >-
curl -X GET $BACKEND_SERVICE_HOST:$BACKEND_SERVICE_PORT/api/v3/stats |
head -c 30 > /app/out.log

Kubectl wait command for init containers

I am looking for a Kubectl wait command for init containers. Basically I need to wait until pod initialization of init container before proceeding for next step in my script.
I can see a wait option for pods but not specific to init containers.
Any clue how to achieve this
Please suggest any alternative ways to wait in script
You can run multiple commands in the init container or multiple init containers to do the trick.
Multiple commands
command: ["/bin/sh","-c"]
args: ["command one; command two && command three"]
Refer: https://stackoverflow.com/a/33888424/3514300
* Multiple init containers
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
Refer: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#init-containers-in-use

How to make a k8s pod exits itself when the main container exits?

I am using a sidecard pattern for a k8s pod within which there're two containers: the main container and the sidecar container. I'd like to have the pod status depends on the main container only (say if the main container failed/completed, the pod should be in the same status) and discard the sidecard container.
Is there an elegant way to doing this?
Unfortunately the restartPolicy flag applies to all containers in the pod so the simple solution isn’t really going to work. Are you sure your logic shouldn’t be in an initContainer rather than a sidecar? If it does need to be a sidecar, have it sleep forever at the end of your logic.
As per documentation:
Pod is running and has two Containers. Container 1 exits with failure.
Log failure event.
If restartPolicy is:
Always: Restart Container; Pod phase stays Running.
OnFailure: Restart Container; Pod phase stays Running.
Never: Do not restart Container; Pod phase stays Running.
If Container 1 is not running, and Container 2 exits:
Log failure event.
If restartPolicy is:
Always: Restart Container; Pod phase stays Running.
OnFailure: Restart Container; Pod phase stays Running.
Never : Pod phase becomes Failed.
As workaround (partial solution for this problem) with restartPolicy: Never - you can apply the result of livenees probe from the main container to the sidecar container (using using exec, http or tcp probe).
It's not the good solution while working with microservices.
example:
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness1
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /test-pd/healthy; sleep 30; rm -rf /test-pd/healthy; sleep 30
livenessProbe:
exec:
command:
- cat
- /test-pd/healthy
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts:
- mountPath: /test-pd
name: test-volume
- name: liveness2
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- sleep 120
livenessProbe:
exec:
command:
- cat
- /test-pd2/healthy
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts:
- mountPath: /test-pd2
name: test-volume
restartPolicy: Never
volumes:
- name: test-volume
hostPath:
# directory location on host
path: /data
type: Directory
Please let me know if that helped.

How to define a liveness command

A livenessProbe (extracted from an example) below is working well.
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
But, my livenessProbe is not working.(pod is continually restarted).
YAML is below
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness-test
name: liveness
spec:
containers:
- name: liveness
args:
- /bin/bash
- -c
- /home/my_home/run_myprogram.sh; sleep 20
image: liveness:v0.6
securityContext:
privileged: true
livenessProbe:
exec:
command:
- /home/my_home/check.sh
initialDelaySeconds: 10
periodSeconds: 5
/home/my_home/check.sh (to restart the pod when the number of running processes is 1 or 0) is below, which is pre-tested.
#!/bin/sh
if [ $(ps -ef | grep -v grep | grep my-program | wc -l) -lt 2 ]; then
exit 1
else
exit 0
fi
This problem is related to Golang Command API.
I changed the livenessProbe as below
livenessProbe:
exec:
command:
- /bin/sh
- -c
- /home/test/check.sh