# 不熟 ## 输出pod status kubectl -n default describe pod pod1 | grep -i status: kubectl -n default get pod pod1 -o jsonpath="{.status.phase}" ## Check the pod for error kubectl describe pod podname | grep -i error ... Error: ImagePullBackOff ## a fast way to get an overview of the ReplicaSets of a Deployment and their images could be done with: kubectl -n neptune get rs -o wide | grep deployname NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR deployname 3 3 3 9m6s httpd httpd:alpine app=wonderful
## 创建job kubectl -n neptune create job neb-new-job --image=busybox:1.31.0 $do > /opt/course/3/job.yaml -- sh -c "sleep 2 && echo done" ## If a Secret bolongs to a serviceaccount, it'll have the annotation kubernetes.io/service-account.name kubectl get secrets -oyaml | grep annotations -A 1 # shows secrets with first annotation ## log kubectl logs podname > /opt/test.log ➜ k -n mercury logs cleaner-576967576c-cqtgx --container logger-con
## check service connection using a temporary Pod ## k run tmp --restart=Never --rm --image=nginx:alpine -i -- curl http://svcname.namespace:svcport kubectl run tmp --restart=Never --rm --image=nginx:alpine -i -- curl http://svcname.namespace:80 ## check that both PV and PVC have the status Bound: k -n earth get pv,pvc NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/earth-project-earthflower-pv 2Gi RWO Retain Bound earth/earth-project-earthflower-pvc 8m4s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/earth-project-earthflower-pvc Bound earth-project-earthflower-pv 2Gi RWO 7m38s
## We can confirm the pod of deployment with PVC mounting correctly: k describe pod project-earthflower-586758cc49-hb87f -n earth | grep -A2 Mount: Mounts: /tmp/project-data from task-pv-storage (rw) /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-jj2t2 (ro)
In the namespace ckad-prep create a new Pod named mypod with the image nginx:2.3.5. Expose the port 80.
Identify the issue with creating the container. Write down the root cause of issue in a file named pod-error.txt.
Change the image of the Pod to nginx:1.15.12.
List the Pod and ensure that the container is running.
Log into the container and run the ls command. Write down the output. Log out of the container.
Retrieve the IP address of the Pod mypod.
Run a temporary Pod using the image busybox, shell into it and run a wget command against the nginx Pod using port 80.
Render the logs of Pod mypod.
Delete the Pod and the namespace.
1 2 3 4 5 6 7 8
# 1. create the namespace. $ kubectl create ns ckad-prep
# 2. create a new Pod $ kubectl run mypod -n ckad-prep --image=nginx:2.3.5 --port=80 # 或者: # $ kubectl run mypod --namespace=ckad-prep --image=nginx:2.3.5 --port=80 pod/mypod created
# 5. List the Pod and ensure that the container is running. $ kubectl get pod -n ckad-prep NAME READY STATUS RESTARTS AGE mypod 1/1 Running 0 19m
# 6. Log into the container and run the ls command. Write down the output. Log out of the container. $ kubectl exec mypod -n ckad-prep -- ls # 或者 $ kubectl exec mypod -it -n ckad-prep -- /bin/sh / # ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var / # exit
# 7. Retrieve the IP address of the Pod mypod. $ kubectl get pod -n ckad-prep -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mypod 1/1 Running 0 29m 192.168.0.6 controlplane <none> <none>
# 8. Run a temporary Pod using the image busybox, shell into it and run a wget command against the nginx Pod using port 80. # 用#7 里面得到的IP $ kubectl run busybox --image=busybox --rm -it --restart=Never -n ckad-prep -- /bin/sh / # wget -O- 192.168.0.6:80 Connecting to 192.168.0.6:80 (192.168.0.6:80) writing to stdout <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p>
<p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p> </body> </html> - 100% |***************************************************************************************************| 612 0:00:00 ETA written to stdout / # exit
1 2 3 4 5 6 7 8 9 10
# 9. Render the logs of Pod mypod. $ kubectl logs pods/mypod -n ckad-prep 192.168.0.7 - - [25/Dec/2022:10:47:23 +0000] "GET / HTTP/1.1" 200 612 "-""Wget""-"
# 10. Delete the Pod and the namespace. $ kubectl delete pods/mypod -n ckad-prep pod "mypod" deleted
Create a new file named config.txt with the following environment variables as key/value pairs on each line.
DB_URL equates to localhost:3306
DB_USERNAME equates to postgres
Create a new ConfigMap named db-config from that file.
Create a Pod named backend that uses the environment variables from the ConfigMap and runs the container with the image nginx.
Shell into the Pod and print out the created environment variables. You should find DB_URL and DB_USERNAME with their appropriate values.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 1. Create a new file named `config.txt` $ echo -e "DB_URL=localhost:3306\nDB_USERNAME=postgres" > config.txt 或者 $ vim config.txt DB_URL=localhost:3306 DB_USERNAME=postgres
# 2. Create a new ConfigMap `db-config` $ kubectl create configmap db-config --from-file config.txt configmap/db-config created
# 3. Create a Pod `backend` $ kubectl run backend --image nginx --dry-run=client -o yaml > 1.yaml $ vim 1.yaml
# 4. Shell into the Pod and print out the created environment variables. You should find `DB_URL` and `DB_USERNAME` with their appropriate values. $ kubectl exec backend -it -- /bin/sh / # env config.txt=DB_URL=localhost:3306 DB_USERNAME=postgres ... / # exit
Create a new Secret named db-credentials with the key/value pair db-password=passwd.
Create a Pod named backend that defines uses the Secret as environment variable named DB_PASSWORD and runs the container with the image nginx.
Shell into the Pod and print out the created environment variables. You should find DB_PASSWORD variable.
1 2 3 4 5 6 7 8 9
# 1. $ kubectl create secret generic db-credentials --from-literal=db-password=passwd secret/db-credentials created $ kubectl get secrets NAME TYPE DATA AGE db-credentials Opaque 1 26s
Create a Pod named secured that uses the image nginx for a single container. Mount an emptyDir volume to the directory /data/app.
Files created on the volume should use the filesystem group ID 3000.
Get a shell to the running container and create a new file named logs.txt in the directory /data/app. List the contents of the directory and write them down.
Create a new Pod that exceeds the limits of the resource quota requirements. Write down the error message.
Change the request limits to fulfill the requirements to ensure that the Pod could be created successfully. Write down the output of the command that renders the used amount of resources for the namespace.
# 尝试get resourcequota, 但没得到东西 # k get resourcequota -n namespace1
# 尝试get resourcequota, 但没得到东西 k get limitranges -n namespace1 NAMESPACE NAME CREATED AT default mem-limit-range
k k describe limitrange -n namespace1 Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Container memory - 898Mi 256Mi 512Mi -
# 3.2 $ k apply -f 6.yaml pod/backend created $ k get pod/backend -o wide
# 4. print out the token from the volume source at /var/run/secrets/kubernetes.io/serviceaccount $ kubectl exec -it backend -- /bin/sh / # cat /var/run/secrets/kubernetes.io/serviceaccount/token eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImJhY2tlbmQtdGVhbS10b2tlbi1kbTJmZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJiYWNrZW5kLXRlYW0iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIxNzM0MzVjMS00NDJmLTExZTktOGRjMy0wMjUwMDAwMDAwMDEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpiYWNrZW5kLXRlYW0ifQ.DjWUxEMNUmQVoXd4b-eIjxboj3w3k7hS5hfV8mm8eoEPz3HJJMgjIpAaurcvo1pp2Ggpd1kIhQvfRqI6-u57f80N5UqXt_qATJfonat2NNXX8pXmFNoPig9LB-pbo8TN_pYGWNworXsxmK9w6V9eaRosIinRp0u-cvijQbsBw3lxWgGo9S4G-7f19mMKN1Pg2xS2J6fKX9IKvhHrUkM91nwcwmsO0use5B4TGbuRa9METiGsfEpegvzMPBbPl0B_T1ANH_pck0LFNtvKe0g1v5zpKx2lRF9WdFAqPsG7BJ1dEH88JtBHzD59OhxIPqtyT4sXKjACBN_ka5ZADMzPJg
考题7 - Implementing the Adapter Pattern
The adapter pattern helps with providing a simplified, homogenized view of an application running within a container. For example, we could stand up another container that unifies the log output of the application container. As a result, other monitoring tools can rely on a standardized view of the log output without having to transform it into an expected format.
Create a new Pod in a YAML file named adapter.yaml. The Pod declares two containers.
The container app uses the image busybox and runs the command while true; do echo "$(date) | $(du -sh ~)" >> /var/logs/diskspace.txt; sleep 5; done;.
The adapter container transformer uses the image busybox and runs the command sleep 20; while true; do while read LINE; do echo "$LINE" | cut -f2 -d"|" >> $(date +%Y-%m-%d-%H-%M-%S)-transformed.txt; done < /var/logs/diskspace.txt; sleep 20; done; to strip the log output off the date for later consumption my a monitoring tool. Be aware that the logic does not handle corner cases (e.g. automatically deleting old entries) and would look different in production systems
Before creating the Pod, define an emptyDir volume. Mount the volume in both containers with the path /var/logs.
Create the Pod, log into the container transformer. The current directory should continuously write a new file every 20 seconds.
考题8 - Defining a Pod’s Readiness and Liveness Probe
Create a new Pod named hello with the image bonomat/nodejs-hello-world that exposes the port 3000. Provide the name nodejs-port for the container port.
Add a Readiness Probe that checks the URL path / on the port referenced with the name nodejs-port after a 2 seconds delay. You do not have to define the period interval.
Add a Liveness Probe that verifies that the app is up and running every 8 seconds by checking the URL path / on the port referenced with the name nodejs-port. The probe should start with a 5 seconds delay.
Shell into container and curl localhost:3000. Write down the output. Exit the container. Retrieve the logs from the container. Write down the output.
1 2 3
# 1. Create a new Pod named `hello` $ kubectl run hello --image=bonomat/nodejs-hello-world --port=3000 -o yaml --dry-run > pod.yaml $ vim pod.yaml
# 4. $ kubectl exec failing-pod -it -- /bin/sh / # mkdir -p /root/tmp / # cd /root ~ # ls -l total 4 drwxr-xr-x 2 root root 4096 Dec 26 04:47 tmp ~ # chmod 777 /root/tmp ~ # cd /root/tmp ~/tmp # ls -l total 4 -rw-r--r-- 1 root root 112 May 9 23:52 curr-date.txt / # cat ~/tmp/curr-date.txt Thu May 9 23:59:01 UTC 2019 Thu May 9 23:59:06 UTC 2019 Thu May 9 23:59:11 UTC 2019 / # exit
考题10 - 2022 Rollout Canary
Application “wonderful” is running in default Namespace.
You can call the app using curl wonderful:30080 .
The application YAML is available at /wonderful/init.yaml .
The app has a Deployment with image httpd:alpine , but should be switched over to nginx:alpine .
The switch should not happen fast or automatically, but using the Canary approach:
20% of requests should hit the new image
80% of requests should hit the old image
For this create a new Deployment wonderful-v2 which uses image nginx:alpine .
The total amount of Pods of both Deployments combined should be 10.
$ k get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE wonderful-v1 8/8 8 8 5m38s wonderful-v2 2/2 2 2 65s
考题11 - 2022 Helm Nanagement
考题12 - 2022 NetworkPolicy
记不太清了。。。
修改pod pod1,使得only to and from pod frondend and db
networkpolicy已经建好,不要增加,新建或者修改
这样的话,应该只需要根据已有networkpolicy,修改pod1的labels就可以了。
有个类似的题:
Restricting Access to and from a Pod
Let’s assume we are working on an application stack that defines three different layers: a frontend, a backend and a database. Each of the layers runs in a Pod. You can find the definition in the YAML file app-stack.yaml. The application needs to run in the namespace app-stack.
Task:
Create the required namespace.
Copy the Pod definition to the file app-stack.yaml and create all three Pods. Notice that the namespace has already been defined in the YAML definition.
Create a network policy in the YAML file app-stack-network-policy.yaml.
The network policy should allow incoming traffic from the backend to the database but disallow incoming traffic from the frontend.
Incoming traffic to the database should only be allowed on TCP port 3306 and no other port.
Application “wonderful” is running in default Namespace.
You can call the app using curl wonderful:30080 .
The app has a Deployment with image httpd:alpine , but should be switched over to nginx:alpine .
Set the maxSurge to 50% and the maxUnavailable to 0% . Then perform a rolling update.
Wait till the rolling update has succeeded.
Explanation
Why can you call `curl wonderful:30080` and it works?
There is a NodePort Service `wonderful` which listens on port `30080` . It has the Pods of Deployment of app "wonderful" as selector.
We can reach the NodePort Service via the K8s Node IP:
1
curl 172.30.1.2:30080
And because of an entry in `/etc/hosts `we can call:
$ k apply -f v2.yaml # Wait till all Pods are running, then switch the Service selector: $ k get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE wonderful-v1 4/4 4 4 13m wonderful-v2 4/4 4 4 4s
# 1.2 $ k get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE wonderful NodePort 10.98.188.152 <none> 80:30080/TCP 9m21s