K8sMeetup 中国社区在此提供了 50 道练习题,帮助开发者测试自己的技术熟练程度。

核心概念

请根据以下概念进行练习:了解 Kubernetes API 原语,创建和配置基本 Pod。
1.列出集群中的所有命名空间

  1. kubectl get namespaces
  2. kubectl get ns

2.列出所有命名空间中的所有 Pod

  1. kubectl get po --all-namespaces

3.列出特定命名空间中的所有 Pod

  1. kubectl get po -n <namespace name>

4.列出特定命名空间中的所有 Service

  1. kubectl get svc -n <namespace name>

5.用 json 路径表达式列出所有显示名称和命名空间的 Pod

  1. kubectl get pods -o=jsonpath="{.items[*]['metadata.name', 'metadata.namespace']}"

6.在默认命名空间中创建一个 Nginx Pod,并验证 Pod 是否正在运行

  1. // creating a pod
  2. kubectl run nginx --image=nginx --restart=Never
  3. // List the pod
  4. kubectl get po

7.使用 yaml 文件创建相同的 Nginx Pod

  1. // get the yaml file with --dry-run flag
  2. kubectl run nginx --image=nginx --restart=Never --dry-run -o yaml > nginx-pod.yaml
  3. // cat nginx-pod.yaml
  4. apiVersion: v1
  5. kind: Pod
  6. metadata:
  7. creationTimestamp: null
  8. labels:
  9. run: nginx
  10. name: nginx
  11. spec:
  12. containers:
  13. - image: nginx
  14. name: nginx
  15. resources: {}
  16. dnsPolicy: ClusterFirst
  17. restartPolicy: Never
  18. status: {}
  19. // create a pod
  20. kubectl create -f nginx-pod.yaml

8.输出刚创建的 Pod 的 yaml 文件

  1. kubectl get po nginx -o yaml

9.输出刚创建的 Pod 的 yaml 文件,并且其中不包含特定于集群的信息

  1. kubectl get po nginx -o yaml --export

10.获取刚刚创建的 Pod 的完整详细信息

  1. kubectl describe pod nginx

11.删除刚创建的 Pod

  1. kubectl delete po nginx
  2. kubectl delete -f nginx-pod.yaml

12.强制删除刚创建的 Pod

  1. kubectl delete po nginx --grace-period=0 --force

13.创建版本为 1.17.4 的 Nginx Pod,并将其暴露在端口 80 上

  1. kubectl run nginx --image=nginx:1.17.4 --restart=Never --port=80

14.将刚创建的容器的镜像更改为 1.15-alpine,并验证该镜像是否已更新

  1. kubectl set image pod/nginx nginx=nginx:1.15-alpine
  2. kubectl describe po nginx
  3. // another way it will open vi editor and change the version
  4. kubeclt edit po nginx
  5. kubectl describe po nginx

15.对于刚刚更新的 Pod,将镜像版本改回 1.17.1,并观察变化

  1. kubectl set image pod/nginx nginx=nginx:1.17.1
  2. kubectl describe po nginx
  3. kubectl get po nginx -w # watch it

16.在不使用 describe 命令的情况下检查镜像版本

  1. kubectl get po nginx -o jsonpath='{.spec.containers[].image}{"\n"}'

17.创建 Nginx Pod 并在 Pod 上执行简单的 shell

  1. // creating a pod
  2. kubectl run nginx --image=nginx --restart=Never
  3. // exec into the pod
  4. kubectl exec -it nginx /bin/sh

18.获取刚刚创建的 Pod 的 IP 地址

  1. kubectl get po nginx -o wide

19.创建一个 busybox Pod,在创建它时运行命令 ls 并检查日志

  1. kubectl run busybox --image=busybox --restart=Never -- ls
  2. kubectl logs busybox

20.如果 Pod 崩溃了,请检查 Pod 的先前日志

  1. kubectl logs busybox -p

21.使用命令 sleep 3600 创建一个 busybox Pod

  1. kubectl run busybox --image=busybox --restart=Never -- /bin/sh -c "sleep 3600"

22.检查 busybox Pod 中 Nginx Pod 的连接

  1. kubectl get po nginx -o wide
  2. // check the connection
  3. kubectl exec -it busybox -- wget -o- <IP Address>

23.创建一个能回显消息“How are you”的 busybox Pod,并手动将其删除

  1. kubectl run busybox --image=nginx --restart=Never -it -- echo "How are you"
  2. kubectl delete po busybox

24.创建一个能回显消息“How are you”的 busybox Pod,并手动将其删除

  1. // notice the --rm flag
  2. kubectl run busybox --image=nginx --restart=Never -it --rm -- echo "How are you"

25.创建一个 Nginx Pod 并列出具有不同复杂度(verbosity)的 Pod

  1. // create a pod
  2. kubectl run nginx --image=nginx --restart=Never --port=80
  3. // List the pod with different verbosity
  4. kubectl get po nginx --v=7
  5. kubectl get po nginx --v=8
  6. kubectl get po nginx --v=9

26.使用自定义列 PODNAME 和 PODSTATUS 列出 Nginx Pod

  1. kubectl get po -o=custom-columns="POD_NAME:.metadata.name, POD_STATUS:.status.containerStatuses[].state"

27.列出所有按名称排序的 Pod

  1. kubectl get pods --sort-by=.metadata.name

28.列出所有按创建时间排序的 Pod

  1. kubectl get pods--sort-by=.metadata.creationTimestamp

多容器 Pod

请根据以下概念进行练习:了解多容器 Pod 的设计模式(例:ambassador、adaptor、sidecar)。
29.用“ls; sleep 3600;”“echo Hello World; sleep 3600;”及“echo this is the third container; sleep 3600”三个命令创建一个包含三个 busybox 容器的 Pod,并观察其状态

  1. // first create single container pod with dry run flag
  2. kubectl run busybox --image=busybox --restart=Never --dry-run -o yaml -- bin/sh -c "sleep 3600; ls" > multi-container.yaml
  3. // edit the pod to following yaml and create it
  4. kubectl create -f multi-container.yaml
  5. kubectl get po busybox

30.检查刚创建的每个容器的日志

  1. kubectl logs busybox -c busybox1
  2. kubectl logs busybox -c busybox2
  3. kubectl logs busybox -c busybox3

31.检查第二个容器 busybox2 的先前日志(如果有)

  1. kubectl logs busybox -c busybox2 --previous

32.在上述容器的第三个容器 busybox3 中运行命令 ls

  1. kubectl exec busybox -c busybox3 -- ls

33.显示以上容器的 metrics,将其放入 file.log 中并进行验证

  1. kubectl top pod busybox --containers
  2. // putting them into file
  3. kubectl top pod busybox --containers > file.log
  4. cat file.log

34.用主容器 busybox 创建一个 Pod,并执行“while true; do echo ‘Hi I am from Main container’ >> /var/log/index.html; sleep 5; done”,并带有暴露在端口 80 上的 Nginx 镜像的 sidecar 容器。用 emptyDir Volume 将该卷安装在 /var/log 路径(用于 busybox)和 /usr/share/nginx/html 路径(用于nginx容器)。验证两个容器都在运行

  1. // create an initial yaml file with this
  2. kubectl run multi-cont-pod --image=busbox --restart=Never --dry-run -o yaml > multi-container.yaml
  3. // edit the yml as below and create it
  4. kubectl create -f multi-container.yaml
  5. kubectl get po multi-cont-pod

35.进入两个容器并验证 main.txt 是否存在,并用 curl localhost 从 sidecar 容器中查询 main.txt

  1. // exec into main container
  2. kubectl exec -it multi-cont-pod -c main-container -- sh
  3. cat /var/log/main.txt
  4. // exec into sidecar container
  5. kubectl exec -it multi-cont-pod -c sidecar-container -- sh
  6. cat /usr/share/nginx/html/index.html
  7. // install curl and get default page
  8. kubectl exec -it multi-cont-pod -c sidecar-container -- sh
  9. # apt-get update && apt-get install -y curl
  10. # curl localhost

Pod 设计

请根据以下概念进行练习:了解如何使用 Labels、Selectors 和 Annotations,了解部署以及如何执行滚动更新,了解部署以及如何执行回滚,了解 Jobs 和 CronJobs.
36.获取带有标签信息的 Pod

  1. kubectl get pods --show-labels

37.创建 5 个 Nginx Pod,其中两个标签为 env = prod,另外三个标签为 env = dev

  1. kubectl run nginx-dev1 --image=nginx --restart=Never --labels=env=dev
  2. kubectl run nginx-dev2 --image=nginx --restart=Never --labels=env=dev
  3. kubectl run nginx-dev3 --image=nginx --restart=Never --labels=env=dev
  4. kubectl run nginx-prod1 --image=nginx --restart=Never --labels=env=prod
  5. kubectl run nginx-prod2 --image=nginx --restart=Never --labels=env=prod

38.确认所有 Pod 都使用正确的标签创建

  1. kubeclt get pods --show-labels

39.获得带有标签 env = dev 的 Pod

  1. kubectl get pods -l env=dev

40.获得带有标签 env = dev 的 Pod,并输出标签

  1. kubectl get pods -l env=dev --show-labels

41.获得带有标签 env = prod 的 Pod

  1. kubectl get pods -l env=prod

42.获得带有标签 env = prod 的 Pod,并输出标签

  1. kubectl get pods -l env=prod --show-labels

43.获取带有标签 env 的 Pod

  1. kubectl get pods -L env

44.获得带有标签 env = dev 和 env = prod 的 Pod

  1. kubectl get pods -l 'env in (dev,prod)'

45.获取带有标签 env = dev 和 env = prod 的 Pod 并输出标签

  1. kubectl get pods -l 'env in (dev,prod)' --show-labels

46.将其中一个容器的标签更改为 env = uat 并列出所有要验证的容器

  1. kubectl label pod/nginx-dev3 env=uat --overwrite
  2. kubectl get pods --show-labels

47.删除刚才创建的 Pod 标签,并确认所有标签均已删除

  1. kubectl label pod nginx-dev{1..3} env-
  2. kubectl label pod nginx-prod{1..2} env-
  3. kubectl get po --show-labels

48.为所有 Pod 添加标签 app = nginx 并验证

  1. kubectl label pod nginx-dev{1..3} app=nginx
  2. kubectl label pod nginx-prod{1..2} app=nginx
  3. kubectl get po --show-labels

49.获取所有带有标签的节点(如果使用 minikube,则只会获得主节点)

  1. kubectl get nodes --show-labels

50.标记节点(如果正在使用,则为 minikube)nodeName = nginxnode

  1. kubectl label node minikube nodeName=nginxnode

51.建一个标签为 nodeName = nginxnode 的 Pod 并将其部署在此节点上

  1. kubectl run nginx --image=nginx --restart=Never --dry-run -o yaml > pod.yaml
  2. // add the nodeSelector like below and create the pod
  3. kubectl create -f pod.yaml

上周,K8sMeetup 中国社区发布了 CKAD 模拟训练的前 50 道考题,社区反响热烈。
众所周知,CKAD 考试内容分为:

  • 核心概念(13%)
  • 多容器 Pod(10%)
  • Pod 设计(20%)
  • 状态持久性(8%)
  • 配置(18%)
  • 可观察性(18%)
  • 服务和网络(13%)

Pod 设计(二)

请根据以下概念进行练习:了解如何使用 Labels、Selectors 和 Annotations,了解部署以及如何执行滚动更新,了解部署以及如何执行回滚,了解 Jobs 和 CronJobs。注:此部分考题需结合上周题目一起做。
52.使用节点选择器验证已调度的 Pod

  1. kubectl describe po nginx | grep Node-Selectors

53.验证我们刚刚创建的 Pod Nginx 是否具有 nodeName=nginxnode 这个标签

  1. kubectl describe po nginx | grep Labels

54.用 name=webapp 注释 Pod

  1. kubectl annotate pod nginx-dev{1..3} name=webapp
  2. kubectl annotate pod nginx-prod{1..2} name=webapp

55.验证已正确注释的 Pod

  1. kubectl describe po nginx-dev{1..3} | grep -i annotations
  2. kubectl describe po nginx-prod{1..2} | grep -i annotations

56.删除 Pod 上的注释并验证

  1. kubectl annotate pod nginx-dev{1..3} name-
  2. kubectl annotate pod nginx-prod{1..2} name-
  3. kubectl describe po nginx-dev{1..3} | grep -i annotations
  4. kubectl describe po nginx-prod{1..2} | grep -i annotations

57.删除到目前为止我们创建的所有 Pod

  1. kubectl delete po --all

58.创建一个名为 webapp 的 Deployment,它带有 5 个副本的镜像 Nginx

  1. kubectl create deploy webapp --image=nginx --dry-run -o yaml > webapp.yaml
  2. // change the replicas to 5 in the yaml and create it
  3. kubectl create -f webapp.yaml

59.用标签获取我们刚刚创建的 Deployment

  1. kubectl get deploy webapp --show-labels

60.导出该 Deployment 的 yaml 文件

  1. kubectl get deploy webapp -o yaml

61.获取该 Deployment 的 Pod

  1. // get the label of the deployment
  2. kubectl get deploy --show-labels
  3. // get the pods with that label
  4. kubectl get pods -l app=webapp

62.将该 Deployment 从 5 个副本扩展到 20 个副本并验证

  1. kubectl scale deploy webapp --replicas=20
  2. kubectl get po -l app=webapp

63.获取该 Deployment 的 rollout 状态

  1. kubectl rollout status deploy webapp

64.获取使用该 Deployment 创建的副本集

  1. kubectl get rs -l app=webapp

65.获取该 Deployment 的副本集和 Pod 的 yaml

  1. kubectl get rs -l app=webapp -o yaml
  2. kubectl get po -l app=webapp -o yaml

66.删除刚创建的 Deployment,并查看所有 Pod 是否已被删除

  1. kubectl delete deploy webapp
  2. kubectl get po -l app=webapp -w

67.使用镜像 nginx:1.17.1 和容器端口 80 创建 webapp Deployment,并验证镜像版本

  1. kubectl create deploy webapp --image=nginx:1.17.1 --dry-run -o yaml > webapp.yaml
  2. // add the port section and create the deployment
  3. kubectl create -f webapp.yaml
  4. // verify
  5. kubectl describe deploy webapp | grep Image

68.使用镜像版本 1.17.4 更新 Deployment 并验证

  1. kubectl set image deploy/webapp nginx=nginx:1.17.4
  2. kubectl describe deploy webapp | grep Image

69.检查 rollout 历史记录,并确保更新后一切正常

  1. kubectl rollout history deploy webapp
  2. kubectl get deploy webapp --show-labels
  3. kubectl get rs -l app=webapp
  4. kubectl get po -l app=webapp

70.撤消之前使用版本 1.17.1 的 Deployment,并验证镜像是否还有老版本

  1. kubectl rollout undo deploy webapp
  2. kubectl describe deploy webapp | grep Image

71.使用镜像版本 1.16.1 更新 Deployment,并验证镜像、检查 rollout 历史记录

  1. kubectl set image deploy/webapp nginx=nginx:1.16.1
  2. kubectl describe deploy webapp | grep Image
  3. kubectl rollout history deploy webapp

72.将 Deployment 更新到镜像 1.17.1 并确认一切正常

  1. kubectl rollout undo deploy webapp --to-revision=3
  2. kubectl describe deploy webapp | grep Image
  3. kubectl rollout status deploy webapp

73.使用错误的镜像版本 1.100 更新 Deployment,并验证有问题

  1. kubectl set image deploy/webapp nginx=nginx:1.100
  2. kubectl rollout status deploy webapp (still pending state)
  3. kubectl get pods (ImagePullErr)

74.撤消使用先前版本的 Deployment,并确认一切正常

  1. kubectl rollout undo deploy webapp
  2. kubectl rollout status deploy webapp
  3. kubectl get pods

75.检查该 Deployment 的特定修订版本的历史记录

  1. kubectl rollout history deploy webapp --revision=7

76.暂停 Deployment rollout

  1. kubectl rollout pause deploy webapp

77.用最新版本的镜像更新 Deployment,并检查历史记录

  1. kubectl set image deploy/webapp nginx=nginx:latest
  2. kubectl rollout history deploy webapp (No new revision)

78.恢复 Deployment rollout

  1. kubectl rollout resume deploy webapp

79.检查 rollout 历史记录,确保是最新版本

  1. kubectl rollout history deploy webapp
  2. kubectl rollout history deploy webapp --revision=9

80.将自动伸缩应用到该 Deployment 中,最少副本数为 10,最大副本数为 20,目标 CPU 利用率 85%,并验证 hpa 已创建,将副本数从 1 个增加到 10 个

  1. kubectl autoscale deploy webapp --min=10 --max=20 --cpu-percent=85
  2. kubectl get hpa
  3. kubectl get pod -l app=webapp

81.通过删除刚刚创建的 Deployment 和 hpa 来清理集群

  1. kubectl delete deploy webapp
  2. kubectl delete hpa webapp

82.用镜像 node 创建一个 Job,并验证是否有对应的 Pod 创建

  1. kubectl create job nodeversion --image=node -- node -v
  2. kubectl get job -w
  3. kubectl get pod

83.获取刚刚创建的 Job 的日志

  1. kubectl logs <pod name> // created from the job

84.用镜像 busybox 输出 Job 的 yaml 文件,并回显“Hello I am from job”

  1. kubectl create job hello-job --image=busybox --dry-run -o yaml -- echo "Hello I am from job"

85.将上面的 yaml 文件复制到 hello-job.yaml 文件并创建 Job

  1. kubectl create job hello-job --image=busybox --dry-run -o yaml -- echo "Hello I am from job" > hello-job.yaml
  2. kubectl create -f hello-job.yaml

86.验证 Job 并创建关联的容器,检查日志

  1. kubectl get job
  2. kubectl get po
  3. kubectl logs hello-job-*

87.删除我们刚刚创建的 Job

  1. kubectl delete job hello-job

88.创建一个相同的 Job,并使它一个接一个地运行 10 次

  1. kubectl create job hello-job --image=busybox --dry-run -o yaml -- echo "Hello I am from job" > hello-job.yaml
  2. // edit the yaml file to add completions: 10
  3. kubectl create -f hello-job.yaml

89.运行 10 次,确认已创建 10 个 Pod,并在完成后删除它们

  1. kubectl get job -w
  2. kubectl get po
  3. kubectl delete job hello-job

90.创建相同的 Job 并使它并行运行 10 次

  1. kubectl create job hello-job --image=busybox --dry-run -o yaml -- echo "Hello I am from job" > hello-job.yaml
  2. // edit the yaml file to add parallelism: 10
  3. kubectl create -f hello-job.yaml

91.并行运行 10 次,确认已创建 10 个 Pod,并在完成后将其删除

  1. kubectl get job -w
  2. kubectl get po
  3. kubectl delete job hello-job

92.创建一个带有 busybox 镜像的 Cronjob,每分钟打印一次来自 Kubernetes 集群消息的日期和 hello

  1. kubectl create cronjob date-job --image=busybox --schedule="*/1 * * * *" -- bin/sh -c "date; echo Hello from kubernetes cluster"

93.输出上述 cronjob 的 yaml 文件

  1. kubectl get cj date-job -o yaml

94.验证 cronJob 为每分钟运行创建一个单独的 Job 和 Pod,并验证 Pod 的日志

  1. kubectl get job
  2. kubectl get po
  3. kubectl logs date-job-<jobid>-<pod>

95.删除 cronJob,并验证所有关联的 Job 和 Pod 也都被删除

  1. kubectl delete cj date-job
  2. // verify pods and jobs
  3. kubectl get po
  4. kubectl get job

状态持久性

根据概念练习问题:了解存储的持久卷声明
96.列出集群中的持久卷

  1. kubectl get pv

97.创建一个名为 task-pv-volume 的 PersistentVolume,其 storgeClassName 为 manual,storage 为 10Gi,accessModes 为 ReadWriteOnce,hostPath 为 /mnt/data

  1. kubectl create -f task-pv-volume.yaml
  2. kubectl get pv

98.创建一个存储至少 3Gi、访问模式为 ReadWriteOnce 的 PersistentVolumeClaim,并确认它的状态是否是绑定的

  1. kubectl create -f task-pv-claim.yaml
  2. kubectl get pvc

99.删除我们刚刚创建的持久卷和 PersistentVolumeClaim

  1. kubectl delete pvc task-pv-claim
  2. kubectl delete pv task-pv-volume

100.使用镜像 Redis 创建 Pod,并配置一个在 Pod 生命周期内可持续使用的卷

  1. // emptyDir is the volume that lasts for the life of the pod
  2. kubectl create -f redis-storage.yaml

101.在上面的 Pod 中执行操作,并在 /data/redis 路径中创建一个名为 file.txt 的文件,其文本为“This is the file”,然后打开另一个选项卡,再次使用同一 Pod 执行,并验证文件是否在同一路径中

  1. // first terminal
  2. kubectl exec -it redis-storage /bin/sh
  3. cd /data/redis
  4. echo 'This is called the file' > file.txt
  5. //open another tab
  6. kubectl exec -it redis-storage /bin/sh
  7. cat /data/redis/file.txt

102.删除上面的 Pod,然后从相同的 yaml 文件再次创建,并验证路径 /data/redis 中是否没有 file.txt

  1. kubectl delete pod redis
  2. kubectl create -f redis-storage.yaml
  3. kubectl exec -it redis-storage /bin/sh
  4. cat /data/redis/file.txt // file doesn't exist

103.创建一个名为 task-pv-volume 的 PersistentVolume,其 storgeClassName 为 manual,storage 为 10Gi,accessModes 为 ReadWriteOnce,hostPath 为 /mnt/data;并创建一个存储至少 3Gi、访问模式为 ReadWriteOnce 的 PersistentVolumeClaim,并确认它的状态是否是绑定的

  1. kubectl create -f task-pv-volume.yaml
  2. kubectl create -f task-pv-claim.yaml
  3. kubectl get pv
  4. kubectl get pvc

104.用容器端口 80 和 PersistentVolumeClaim task-pv-claim 创建一个 Nginx 容器,且具有路径“/usr/share/nginx/html”

  1. kubectl create -f task-pv-pod.yaml