Solve this question on instance: ssh ckad7326
The Tech Lead of Mercury2D decided it's time for more logging, to finally fight all these missing data incidents. There is an existing container named cleaner-con in Deployment cleaner in Namespace mercury. This container mounts a volume and writes logs into a file called cleaner.log.
The yaml for the existing Deployment is available at /opt/course/16/cleaner.yaml. Persist your changes at /opt/course/16/cleaner-new.yaml on ckad7326 but also make sure the Deployment is running.
Create a sidecar container named logger-con, image busybox:1.31.0, which mounts the same volume and writes the content of cleaner.log to stdout, you can use the tail -f command for this. This way it can be picked up by kubectl logs.
Check if the logs of the new container reveal something about the missing data incidents.
Answer
Step 1: Copy and modify the existing Deployment
cp /opt/course/16/cleaner.yaml /opt/course/16/cleaner-new.yaml
vim /opt/course/16/cleaner-new.yamlStep 2: Add sidecar container as initContainer
Modern Kubernetes supports sidecar containers as initContainers with restartPolicy: Always:
# /opt/course/16/cleaner-new.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
name: cleaner
namespace: mercury
spec:
replicas: 2
selector:
matchLabels:
id: cleaner
template:
metadata:
labels:
id: cleaner
spec:
volumes:
- name: logs
emptyDir: {}
initContainers:
- name: init
image: bash:5.0.11
command: ['bash', '-c', 'echo init > /var/log/cleaner/cleaner.log']
volumeMounts:
- name: logs
mountPath: /var/log/cleaner
- name: logger-con # add
image: busybox:1.31.0 # add
restartPolicy: Always # add
command: ["sh", "-c", "tail -f /var/log/cleaner/cleaner.log"] # add
volumeMounts: # add
- name: logs # add
mountPath: /var/log/cleaner # add
containers:
- name: cleaner-con
image: bash:5.0.11
args: ['bash', '-c', 'while true; do echo `date`: "remove random file" >> /var/log/cleaner/cleaner.log; sleep 1; done']
volumeMounts:
- name: logs
mountPath: /var/log/cleanerStep 3: Legacy approach (for older Kubernetes versions)
In earlier K8s versions, sidecar containers were defined as additional application containers:
# LEGACY example of defining sidecar containers in earlier K8s versions
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
name: cleaner
namespace: mercury
spec:
# ...
template:
# ...
spec:
# ...
initContainers:
- name: init
image: bash:5.0.11
# ...
containers:
- name: cleaner-con
image: bash:5.0.11
# ...
- name: logger-con # LEGACY example
image: busybox:1.31.0 # LEGACY example
command: ["sh", "-c", "tail -f /var/log/cleaner/cleaner.log"] # LEGACY example
volumeMounts: # LEGACY example
- name: logs # LEGACY example
mountPath: /var/log/cleaner # LEGACY exampleStep 4: Apply the changes
k -f /opt/course/16/cleaner-new.yaml applyStep 5: Monitor the deployment rollout
k -n mercury rollout history deploy cleaner
k -n mercury rollout history deploy cleaner --revision 1
k -n mercury rollout history deploy cleaner --revision 2Step 6: Check Pod statuses
k -n mercury get podInitial output (during rollout):
NAME READY STATUS RESTARTS AGE
cleaner-86b7758668-9pw6t 2/2 Running 0 6s
cleaner-86b7758668-qgh4v 0/2 Init:0/1 0 1s
Final output (after rollout):
NAME READY STATUS RESTARTS AGE
cleaner-86b7758668-9pw6t 2/2 Running 0 14s
cleaner-86b7758668-qgh4v 2/2 Running 0 9s
Step 7: Check the sidecar logs
k -n mercury logs cleaner-576967576c-cqtgx -c logger-conExpected output:
init
Wed Sep 11 10:45:44 UTC 2099: remove random file
Wed Sep 11 10:45:45 UTC 2099: remove random file
Wed Sep 11 10:45:46 UTC 2099: remove random file
...
The logs reveal that something is "removing random files" - this explains the missing data incidents! The sidecar pattern allows us to capture and monitor application logs effectively.
Solve this question on instance: ssh ckad5601
Last lunch you told your coworker from department Mars Inc how amazing InitContainers are. Now he would like to see one in action. There is a Deployment yaml at /opt/course/17/test-init-container.yaml. This Deployment spins up a single Pod of image nginx:1.17.3-alpine and serves files from a mounted volume, which is empty right now.
Create an InitContainer named init-con which also mounts that volume and creates a file index.html with content check this out! in the root of the mounted volume. For this test we ignore that it doesn't contain valid html.
The InitContainer should be using image busybox:1.31.0. Test your implementation for example using curl from a temporary nginx:alpine Pod.
Answer
Step 1: Copy and modify the existing Deployment
cp /opt/course/17/test-init-container.yaml ~/17_test-init-container.yaml
vim 17_test-init-container.yamlStep 2: Add the InitContainer
# 17_test-init-container.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-init-container
namespace: mars
spec:
replicas: 1
selector:
matchLabels:
id: test-init-container
template:
metadata:
labels:
id: test-init-container
spec:
volumes:
- name: web-content
emptyDir: {}
initContainers: # initContainer start
- name: init-con
image: busybox:1.31.0
command: ['sh', '-c', 'echo "check this out!" > /tmp/web-content/index.html']
volumeMounts:
- name: web-content
mountPath: /tmp/web-content # initContainer end
containers:
- image: nginx:1.17.3-alpine
name: nginx
volumeMounts:
- name: web-content
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80Step 3: Create the Deployment
k -f 17_test-init-container.yaml createStep 4: Verify the Pod is running
k -n mars get podExpected output:
NAME READY STATUS RESTARTS AGE
test-init-container-7d5c7b9f8d-xyz12 1/1 Running 0 30s
Step 5: Test the configuration
Get the Pod IP:
k -n mars get pod -o wideTest with curl:
k run tmp --restart=Never --rm -i --image=nginx:alpine -- curl 10.0.0.67Expected output:
check this out!
This pattern is perfect for ensuring that the nginx server has the required content before it starts serving requests.