CKAD练习
Kubernetes CKAD 练习
核心概念(13%)
多容器 Pod(10%)
Pod 设计(20%)
状态持久性(8%)
配置(18%)
可观察性(18%)
服务和网络(13%)
了解 Kubernetes API 原语,创建和配置基本 Pod
列出集群中的所有命名空间
1
2kubectl get namespaces
kubectl get ns列出所有命名空间中的所有 Pod
1
kubectl get po --all-namespaces
列出特定命名空间中的所有 Pod
1
2kubectl get pod -n kube-system
kubectl get pod -n 命名空间名称列出特定命名空间中的所有 Service
1
2
3kubectl get svc --all-namespaces
kubectl get svc -n 命名空间名称
kubectl get svc -n default用 json 路径表达式列出所有显示名称和命名空间的 Pod
1
2
3kubectl get pods -o=jsonpath="{. items[*]['metadata. name','metadata. namespace']}" --all-namespaces --sort-by=metadata. name
kubectl get pods -o=jsonpath="{. items[*]['metadata. name','metadata. namespace']}" --all-namespaces在默认命名空间中创建一个 Nginx Pod,并验证 Pod 是否正在运行
1
2
3
4
5
6kubectl run nginx --image=nginx
以上命令
kubectl run --generator=deployment/apps. v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead
kubectl run nginx --image=nginx --restart=Never
会直接产生 nginx 后面不会产生随机数使用 yaml 文件创建相同的 Nginx Pod
1
2
3kubectl run nginx --image=nginx --restart=Never --dry-run -o yaml > nginx. yaml
nginx. yaml 为
1 |
|
- 输出刚创建的 Pod 的 yaml 文件
1
kubectl get po nginx -o yaml
- 输出刚创建的 Pod 的 yaml 文件,并且其中不包含特定于集群的信息
kubectl get po nginx -o yaml –export
1 |
|
- 获取刚刚创建的 Pod 的完整详细信息
kubectl describe pod nginx
1 |
|
- 删除刚创建的 Pod
1 |
|
- 强制删除刚创建的 Pod
1 |
|
- 创建版本为 1. 17. 4 的 Nginx Pod,并将其暴露在端口 80 上
kubectl run nginx –image=nginx:1. 17. 4 –restart=Never –port=80
kubectl run nginx –image=nginx:1. 17. 4 –restart=Never –port=80 –dry-run -o yaml
1 |
|
将刚创建的容器的镜像更改为 1. 15-alpine,并验证该镜像是否已更新
1
2
3
4
5
6
kubectl set image pod/nginx nginx=nginx:1. 15-alpine
kubectl edit po nginx
kubectl get po nginx -w对于刚刚更新的 Pod,将镜像版本改回 1. 17. 1,并观察变化
1
2
3
4
5
6
kubectl set image pod/nginx nginx=nginx:1. 17. 1
kubectl edit po nginx
kubectl get po nginx -w在不用 describe 命令的情况下检查镜像版本
1
2
kubectl get po nginx -o=jsonpath='{. spec. containers[]. image}{"\n"}'创建 Nginx Pod 并在 Pod 上执行简单的 shell
1
2kubectl run nginx --image=nginx --restart=Never
kubectl exec -it nginx /bin/bash获取刚刚创建的 Pod 的 IP 地址
1
kubectl get po nginx -o wide
创建一个 busybox Pod,在创建它时运行命令 ls 并检查日志
kubectl run busybox –image=busybox –restart=Never – ls
kubectl logs busybox
1 |
|
- 如果 Pod 崩溃了,请检查 Pod 的先前日志
1
kubectl logs busybox -p
用命令 sleep 3600 创建一个 busybox Pod
1
kubectl run busybox --image=busybox --restart=Never -- /bin/sh -c "sleep 3600"
检查 busybox Pod 中 Nginx Pod 的连接
1
2
3kubectl get pod nginx -o wide
kubectl exec -it busybox -- wget -o- 上述命令列出的 ip 地址
- 创建一个能回显消息“How are you”的 busybox Pod,并手动将其删除
1
2kubectl run busybox --image=busybox --restart=Never -it -- echo "How are you"
kubectl delete po busybox
- 创建一个 Nginx Pod 并列出具有不同复杂度(verbosity)的 Pod
kubectl run nginx –image=nginx –restart=Never –port=80
kubectl get po nginx –v=7
1 |
|
- 使用自定义列 PODNAME 和 PODSTATUS 列出 Nginx Pod
kubectl get po nginx -o=custom-columns=”POD_NAME:.metadata.name,POD_STATUS:.status.containerStatuses”
1 |
|
列出所有按名称排序的 Pod
1
kubectl get po --sort-by=.metadata.name
列出所有按创建时间排序的 Pod
1
kubectl get po --sort-by=.metadata.creationTimestamp
- 用“ls; sleep 3600;”“echo Hello World; sleep 3600;”及“echo this is the third container; sleep 3600”三个命令创建一个包含三个 busybox 容器的 Pod,并观察其状态
sudo vim multi-containers.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: busybox
name: busybox
spec:
containers:
- args:
- bin/sh
- -c
- ls; sleep 3600
image: busybox
name: busybox1
resources: {}
- args:
- bin/sh
- -c
- echo Hello World;sleep 3600
image: busybox
name: busybox2
resources: {}
- args:
- bin/sh
- -c
- echo this is third containers;sleep 3600
image: busybox
name: busybox3
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
- 检查刚创建的每个容器的日志
1
2
3
4
5kubectl get po
kubectl logs busybox -c busybox1
kubectl logs busybox -c busybox2
kubectl logs busybox -c busybox3
检查第二个容器 busybox2 的先前日志(如果有)
1
kubectl logs busybox -c busybox2 --previous
在上述容器的第三个容器 busybox3 中运行命令 ls
1
kubectl exec busybox -c busybox3 -- ls
显示以上容器的 metrics,将其放入 file.log 中并进行验证
1
kubectl top pod busybox --containers > file.log && cat file.log
用主容器 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容器)。验证两个容器都在运行。
kubectl run muilti-containers-pod –image=busybox –restart=Never –dry-run -o yaml > nulti-containers-pod.yaml
1 |
|
kubectl create -f multi-containers-pod.yaml
进入两个容器并验证 main.txt 是否存在,并用 curl localhost 从 sidecar 容器中查询 main. txt
1
2
3
4kubectl exec -it muilti-containers-pod -c main-container -- sh
cat var/log/index.html
kubectl exec -it muilti-containers-pod -c sidercar-container -- sh
cat /usr/share/nginx/html/index.html获取带有标签信息的 Pod
1
kubectl get po --show-labels
- 创建 5 个 Nginx Pod,其中两个标签为 env = prod,另外三个标签为 env = dev
1
2
3
4
5kubectl run nginx-dev1 --image=nginx --restart=Never --labels=env=dev
kubectl run nginx-dev2 --image=nginx --restart=Never --labels=env=dev
kubectl run nginx-dev3 --image=nginx --restart=Never --labels=env=dev
kubectl run nginx-pro1 --image=nginx --restart=Never --labels=env=pro
kubectl run nginx-pro2 --image=nginx --restart=Never --labels=env=pro - 确认所有 Pod 都使用正确的标签创建
kubectl get po –show-labels
1 |
|
- 获得带有标签 env=dev 的 Pod
kubectl get pods -l env=dev
1 |
|
- 获得带标签 env=dev 的 Pod 并输出标签
1
kubectl get pods -l env=dev --show-labels
- 获得带有标签 env=pro 的 Pod
kubectl get pods -l env=pro
1 |
|
获得带标签 env=prod 的 Pod 并输出标签
1
kubectl get pods -l env=pro --show-labels
获取带有标签 env 的 Pod
1
kubectl get po -L env
获得带标签 env=dev、env=pro 的 Pod
1
kubectl get po -l 'env in (dev,pro)'
获取带有标签 env=dev 和 env=pro 的 Pod 并输出标签
1
kubectl get po -l 'env in (dev,pro)' --show-labels
将其中一个容器的标签更改为 env=uat 并列出所有要验证的容器
1
2kubectl label pod/nginx-pro1 env=aa --overwrite
kubectl get pods --show-labels删除刚才创建的 Pod 标签,并确认所有标签均已删除
1
2
3kubectl label pod nginx-dev{1..3} env-
kubectl label pod nginx-pro{1..2} env-
kubectl get pods --show-labels为所有 Pod 添加标签 app = nginx 并验证
1
2
3kubectl label pod nginx-dev{1..3} app=nginx
kubectl label pod nginx-pro{1..2} app=nginx
kubectl get pods --show-labels获取所有带有标签的节点(如果使用 minikube,则只会获得主节点)
kubectl get nodes –show-labels
1 |
|
- 标记节点(如果正在使用,则为 minikube)nodeName = nginxnode
1
kubectl label node minikube nodeName=nginxnode
- 建一个标签为 nginx=dev 的 Pod 并将其部署在此节点上
1
2kubectl label node k8s-node01 nginx=dev
kubectl label node k8s-node02 nginx=pro
参考文献
medium.com/bb-tutorials-and-thoughts/practice-enough-with-these-questions-for-the-ckad-exam
Pod 设计、状态持久性
- 使用节点选择器验证已调度的 Pod
pod.yaml
1 |
|
在 50 基础上
kubectl describe po nginx | grep Node-Selectors
1 |
|
验证我们刚刚创建的 Pod Nginx 是否具有 nginx=dev 这个标签
1
2
3
4kubectl describe po nginx | grep Labels
Labels: run=nginx用 name=webapp 注释 Pod nginx-dev.、nginx-pro.
1
2kubectl annotate po nginx-dev{1..3} name=webapp
kubectl annotate po nginx-pro{1..2} name=webapp
- 验证已正确注释的 Pod
1
2kubectl describe po nginx-dev{1..3} | grep -i annotations
kubectl describe po nginx-pro{1..2} | grep -i annotations
删除 Pod 上的注释并验证
1
2
3
4kubectl annotate po nginx-dev{1..3} name-
kubectl annotate po nginx-pro{1..2} name-
kubectl describe po nginx-dev{1..3} | grep -i annotations
kubectl describe po nginx-pro{1..2} | grep -i annotations删除到目前为止我们创建的所有 Pod
1
kubectl delete pod --all
创建一个名为 webapp 的 Deployment,它带有 5 个副本的镜像 Nginx
kubectl create deployment webapp –image=nginx –dry-run -o yaml > webapp-deployment.yaml
更改 webapp-deployment 的 replicas 为 5
1 |
|
- 用标签获取我们刚刚创建的 Deployment
kubectl get deploy webapp –show-labels
1 |
|
- 导出该 Deployment 的 yaml 文件
kubectl get deploy webapp -o yaml
1 |
|
- 获取该 Deployment 的 Pod
kubectl get deploy –show-labels
1 |
|
kubectl get po -l app=webapp
1 |
|
将该 Deployment 从 5 个副本扩展到 20 个副本并验证
1
2
3
4
5kubectl scale deploy webapp --replicas=20
尝试 --replicas=1000 机器配置过低 会发生问题
kubectl get po -l app=webapp获取该 Deployment 的 rollout 状态
1
kubectl rollout status deploy webapp
获取使用该 Deployment 创建的副本集
1
kubectl get rs -l app=webapp
获取该 Deployment 的副本集和 Pod 的 yaml
1
2kubectl get rs -l app=webapp -o yaml
kubectl get po -l app=webapp -o yaml删除刚创建的 Deployment,并查看所有 Pod 是否已被删除
1
2kubectl delete deploy webapp
kubectl get po -l app=webapp -w使用镜像 nginx:1.17.1 和容器端口 80 创建 webapp Deployment,并验证镜像版本
1
kubectl create deploy webapp --image=nginx:1.17.1 --dry-run -o yaml > webapp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: webapp
name: webapp
spec:
replicas: 1
selector:
matchLabels:
app: webapp
strategy: {}
template:
metadata:
creationTimestamp: null
labels:app: webapp
spec:
containers:- image: nginx:1.17.1
name: nginx
ports:- containerPort: 80
resources: {}
status: {}NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR1
2
3
4
5
68. 使用镜像版本 1.17.4 更新 Deployment 并验证
kubectl set image deploy/webapp nginx=nginx:1.17.4
kubectl get deploy -o wide
nginx-deployment 3/3 3 3 20h nginx nginx:1.7.9 app=nginx
webapp 1/1 1 1 5m7s nginx nginx:1.17.4 app=webappImage: nginx:1.17.41
2
kubectl describe deploy webapp | grep Imagedeployment.apps/webapp1
2
3
4
69. 检查 rollout 历史记录,并确保更新后一切正常
kubectl rollout history deploy webapp
REVISION CHANGE-CAUSE
1
2deployment.apps/webapp1
2
3
4
5
6
7
8kubectl get deploy webapp --show-labels
kubectl get rs -l app=webapp
kubectl get po -l app=webapp
70. 撤消之前使用版本 1.17.1 的 Deployment,并验证镜像是否还有老版本
kubectl rollout undo deploy webapp
kubectl rollout history deploy webapp
REVISION CHANGE-CAUSE
2
3Waiting for deployment “webapp” rollout to finish: 1 old replicas are pending termination…1
2
3
4
5
6kubectl describe deploy webapp | grep Image
71. 使用镜像版本 1.16.1 更新 Deployment,并验证镜像、检查 rollout 历史记录
kubectl set image deploy/webapp nginx=nginx:1.16.1
kubectl rollout status deploy webapp
Waiting for deployment “webapp” rollout to finish: 1 old replicas are pending termination…
deployment “webapp” successfully rolled outdeployment.apps/webapp1
kubectl rollout history deploy webapp
REVISION CHANGE-CAUSE
2
3
4
- containerPort: 80
- image: nginx:1.17.1
1 |
|
- 将 Deployment 更新到镜像 1.17.1 并确认一切正常
1
2
3kubectl rollout undo deploy webapp --to-revision=3
kubectl rollout history deploy webapp
kubectl describe deploy webapp | grep Image
使用错误的镜像版本 1.100 更新 Deployment,并验证有问题
1
2
3
4
5kubectl set image deploy/webapp nginx=nginx:1.10000
kubectl rollout history deploy webapp
kubectl get pods
kubectl describe po pod名称
Warning Failed 2s (x2 over 52s) kubelet, k8s-node01 Error: ImagePullBackOff撤消使用先前版本的 Deployment,并确认一切正常
1
2
3kubectl rollout undo deploy webapp
kubectl rollout status deploy webapp
kubectl get pods检查该 Deployment 的特定修订版本的历史记录
1
kubectl rollout history deploy webapp --revision=特定版本记录号
暂停 Deployment rollout
1
kubectl rollout pause deploy webapp
用最新版本的镜像更新 Deployment,并检查历史记录
1
2kubectl set image deploy/webapp nginx=nginx:lastest
kubectl rollout history deploy webapp恢复 Deployment rollout
1
kubectl rollout resume deploy webapp
检查 rollout 历史记录,确保是最新版本
1
2kubectl rollout history deploy webapp
kubectl rollout history deploy webapp --revision=9将自动伸缩应用到该 Deployment 中,最少副本数为 10,最大副本数为 20,
目标 CPU 利用率 85%,并验证 hpa 已创建,将副本数从 1 个增加到 10 个
kubectl autoscale deploy webapp –min=10 –max=20 –cpu-percent=85
1 |
|
kubectl get po -l app=webapp
1 |
|
通过删除刚刚创建的 Deployment 和 hpa 来清理集群
1
2kubectl delete deploy webapp
kubectl delete hpa webapp用镜像 node 创建一个 Job,并验证是否有对应的 Pod 创建
1
2
3kubectl create job nodeversion --image=node -- node v
kubectl get job -w
kubectl get pod获取刚刚创建的 Job 的日志
1
kubectl logs pod 名称
用镜像 busybox 输出 Job 的 yaml 文件,并回显“Hello I am from job”
kubectl create job hello-job –image=busybox –dry-run -o yaml – echo “Hello I am from job”
1 |
|
将上面的 yaml 文件复制到 hello-job.yaml 文件并创建 Job
1
2
3kubectl create job hello-job --image=busybox --dry-run -o yaml -- echo "Hello I am from job" > hello-job.yaml
kubectl apply -f hello-job.yaml验证 Job 并创建关联的容器,检查日志
1
2
3kubectl get pod
kubectl get po
kubectl logs po 名称删除我们刚刚创建的 Job
1
kubectl delete job hello-job
创建一个相同的 Job,并使它一个接一个地运行 10 次
kubectl create job hello-job –image=busybox –dry-run -o yaml – echo “Hello I am from job” > 10-job.yaml
在 10-job.yaml 添加 completions: 10
1 |
|
kubectl get job -w
kubectl get po
1 |
|
运行 10 次,确认已创建 10 个 Pod,并在完成后删除它们
1
kubectl delete job hello-job
创建相同的 Job 并使它并行运行 10 次
kubectl create job hello-job –image=busybox –dry-run -o yaml – echo “Hello I am from job” > 10-parallelism-job.yaml
1 |
|
- 并行运行 10 次,确认已创建 10 个 Pod,并在完成后将其删除
kubectl get job -w
kubectl get po
- 创建一个带有 busybox 镜像的 Cronjob,每分钟打印一次来自 Kubernetes 集群消息的日期和 hello
kubectl create cronjob date-job –image=busybox –schedule=”*/1 * * * *” – bin/sh -c “date; echo Hello from kubernetes cluster”
kubectl get cronjob
kubectl get po
kubectl logs pod 名称
- 输出上述 cronjob 的 yaml 文件
kubectl get cj date-job -o yaml
1 |
|
验证 cronJob 为每分钟运行创建一个单独的 Job 和 Pod,并验证 Pod 的日志
1
2
3kubectl get job
kubectl get po
kubectl logs date-job-<jobid>-<pod>删除 cronJob,并验证所有关联的 Job 和 Pod 也都被删除
1
2
3
4kubectl delete cj date-job
// verify pods and jobs
kubectl get po
kubectl get job列出集群中的持久卷
1
kubectl get pv
创建一个名为 task-pv-volume 的 PersistentVolume,其 storgeClassName 为 manual,storage 为 10Gi,accessModes 为 ReadWriteOnce,hostPath 为 /mnt/data
task-pv-volume.yaml
1 |
|
kubectl get pv
1 |
|
- 创建一个存储至少 3Gi、访问模式为 ReadWriteOnce 的 PersistentVolumeClaim,并确认它的状态是否是绑定的
kubectl create -f task-pv-claim.yaml
kubectl get pvc
1 |
|
删除我们刚刚创建的持久卷和 PersistentVolumeClaim
1
2kubectl delete pvc task-pv-claim
kubectl delete pv task-pv-volume使用镜像 Redis 创建 Pod,并配置一个在 Pod 生命周期内可持续使用的卷
redis-storage.yaml
1 |
|
- 在上面的 Pod 中执行操作,并在 /data/redis 路径中创建一个名为 file.txt 的文件,其文本为“This is the file”,然后打开另一个选项卡,再次使用同一 Pod 执行,并验证文件是否在同一路径中
1
2
3
4
5kubectl exec -it redis /bin/sh
cd /data/redis
echo "This is the file" > file.txt
- 删除上面的 Pod,然后从相同的 yaml 文件再次创建,并验证路径 /data/redis 中是否没有 file.txt
1
2
3
4
5
6
7
8kubectl delete po redis
kubectl apply -f redis-storage.yaml
kubectl exec -it redis /bin/sh
cat /data/redis/file.txt
cat: /data/redis/file.txt: No such file or directory
- 创建一个名为 task-pv-volume 的 PersistentVolume,其 storgeClassName 为 manual,storage 为 10Gi,accessModes 为 ReadWriteOnce,hostPath 为 /mnt/data;并创建一个存储至少 3Gi、访问模式为 ReadWriteOnce 的 PersistentVolumeClaim,并确认它的状态是否是绑定的
kubectl create -f task-pv-volume.yaml
kubectl create -f task-pv-claim.yaml
kubectl get pv
kubectl get pvc
配置如下所述:
task-pv-volume.yaml
1 |
|
task-pv-claim.yaml
1 |
|
- 用容器端口 80 和 PersistentVolumeClaim task-pv-claim 创建一个 Nginx 容器,且具有路径“/usr/share/nginx/html”
task-pv-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: “http-server”
volumeMounts:
- mountPath: “/usr/share/nginx/html”
name: task-pv-storage
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 10Gi RWO Retain Bound default/task-pv-claim manual 85m
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
task-pv-claim Bound task-pv-volume 10Gi RWO manual 10m
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!