CKA 1.22 模拟题
Question 1
Task weight: 1%
You have access to multiple clusters from your main terminal through
kubectlcontexts. Write all those context names into/opt/course/1/contexts.Next write a command to display the current context into
/opt/course/1/context_default_kubectl.sh, the command should usekubectl.Finally write a second command doing the same thing into
/opt/course/1/context_default_no_kubectl.sh, but without the use ofkubectl.
题目解析:
考点
- kubectl, contexts kubectl 概述 | Kubernetes, kubectl-commands
解题
根据题意:Write all those context names into
/opt/course/1/contexts➜ kubectl config get-contexts -o name > /opt/course/1/contexts根据题意:Next write a command to display the current context into
/opt/course/1/context_default_kubectl.sh, the command should usekubectl➜ vim /opt/course/1/context_default_kubectl.sh kubectl config current-context根据题意:Finally write a second command doing the same thing into
/opt/course/1/context_default_no_kubectl.sh, but without the use ofkubectl➜ vim /opt/course/1/context_default_no_kubectl.sh grep "current-context: " ~/.kube/config | awk '{print $2}'
Question 2
Task weight: 3%
Use context:
kubectl config use-context k8s-c1-HCreate a single Pod of image
httpd:2.4.41-alpinein Namespacedefault. The Pod should be namedpod1and the container should be namedpod1-container. This Pod should only be scheduled on a master node, do not add new labels any nodes.Shortly write the reason on why Pods are by default not scheduled on master nodes into
/opt/course/2/master_schedule_reason.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c1-H Switched to context "k8s-c1-H".快速生成创建 Pod 的 yaml 模板
➜ kubectl run pod1 --image=httpd:2.4.41-alpine --dry-run=client -o yaml > 2.yaml根据题意,修改模板
➜ vim 2.yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: pod1 name: pod1 spec: containers: - image: httpd:2.4.41-alpine name: pod1-container # 修改, the container should be named `pod1-container` resources: {} dnsPolicy: ClusterFirst restartPolicy: Always tolerations: # 新增, This Pod should only be scheduled on a master node,所以要容忍master的污点 - effect: NoSchedule # 新增 key: node-role.kubernetes.io/master # 新增 nodeSelector: # 新增,指定nodeSelector,标签通过kubectl get node --show-labels查看 node-role.kubernetes.io/master: "" # 新增 status: {}创建资源
kubectl apply -f 2.yaml根据题意:Shortly write the reason on why Pods are by default not scheduled on master nodes into
/opt/course/2/master_schedule_reason➜ vim /opt/course/2/master_schedule_reason master nodes usually have a taint defined
Question 3
Task weight: 1%
Use context:
kubectl config use-context k8s-c1-HThere are two Pods named
o3db-*in Namespaceproject-c13. C13 management asked you to scale the Pods down to one replica to save resources. Record the action.
题目解析:
考点
- Pod伸缩
解题
切换上下文
kubectl config use-context k8s-c1-H根据题意,注意两点
- 将副本数设为 1
- 记录操作
➜ kubectl -n project-c13 scale sts o3db --replicas 1 --record
Question 4
Task weight: 4%
Use context:
kubectl config use-context k8s-c1-HDo the following in Namespace
default. Create a single Pod namedready-if-service-readyof imagenginx:1.16.1-alpine. Configure a LivenessProbe which simply runstrue. Also configure a ReadinessProbe which does check if the urlhttp://service-am-i-ready:80is reachable, you can usewget -T2 -O- http://service-am-i-ready:80for this. Start the Pod and confirm it isn't ready because of the ReadinessProbe.Create a second Pod named
am-i-readyof imagenginx:1.16.1-alpinewith labelid: cross-server-ready. The already existing Serviceservice-am-i-readyshould now have that second Pod as endpoint.Now the first Pod should be in ready state, confirm that.
题目解析:
考点
- LivenessProbe, ReadinessProbe, Service 配置存活、就绪和启动探测器 | Kubernetes, 服务 | Kubernetes
解题
切换上下文
➜ kubectl config use-context k8s-c1-H快速生成创建 Pod 的 yaml 模版
➜ kubectl run ready-if-service-ready --image=nginx:1.16.1-alpine --dry-run=client -o yaml > 4.yaml根据题意:Create a single Pod named
ready-if-service-ready...,修改模板➜ vim 4.yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: ready-if-service-ready name: ready-if-service-ready spec: containers: - image: nginx:1.16.1-alpine name: ready-if-service-ready resources: {} livenessProbe: # 新增 httpGet: # 新增 path: / # 新增 port: 80 # 新增 readinessProbe: # 新增 exec: # 新增 command: # 新增 - sh # 新增 - -c # 新增 - wget -T2 -O- http://service-am-i-ready:80 # 新增 dnsPolicy: ClusterFirst restartPolicy: Always status: {}根据题意:Create a second Pod named
am-i-readyof imagenginx:1.16.1-alpinewith labelid: cross-server-ready...# 快速生成创建 Pod 的 yaml 模板 ➜ kubectl run am-i-ready --image=nginx:1.16.1-alpine --dry-run=client -o yaml > 4-2.yaml # 修改模板 ➜ vim 4-2.yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: id: cross-server-ready # 修改,with label id: cross-server-ready name: am-i-ready spec: containers: - image: nginx:1.16.1-alpine name: am-i-ready resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {}创建资源
➜ kubectl apply -f 4.yaml -f 4-2.yaml
Question 5
Task weight: 1%
Use context:
kubectl config use-context k8s-c1-HThere are various Pods in all namespaces. Write a command into
/opt/course/5/find_pods.shwhich lists all Pods sorted by their AGE (metadata.creationTimestamp).Write a second command into
/opt/course/5/find_pods_uid.shwhich lists all Pods sorted by fieldmetadata.uid. Usekubectlsorting for both commands.
题目解析:
考点
- kubectl kubectl 概述 | Kubernetes, kubectl-commands
解题
列出所有 Pod 并以创建时间排序
➜ vim /opt/course/5/find_pods.sh kubectl get pod --all-namespaces --sort-by=metadata.creationTimestamp列出所有 Pod 并以创建 uid 排序
➜ vim /opt/course/5/find_pods_uid.sh kubectl get pod --all-namespaces --sort-by=metadata.uid
Question 6
Task weight: 8%
Use context:
kubectl config use-context k8s-c1-HCreate a new PersistentVolume named
safari-pv. It should have a capacity of 2Gi, accessMode ReadWriteOnce, hostPath/Volumes/Dataand no storageClassName defined.Next create a new PersistentVolumeClaim in Namespace
project-tigernamedsafari-pvc. It should request 2Gi storage, accessMode ReadWriteOnce and should not define a storageClassName. The PVC should bound to the PV correctly.Finally create a new Deployment
safariin Namespaceproject-tigerwhich mounts that volume at/tmp/safari-data. The Pods of that Deployment should be of imagehttpd:2.4.41-alpine.
题目解析:
考点
- pv, pvc, deployment 持久卷 | Kubernetes, Deployments | Kubernetes
解题
切换上下文
➜ kubectl config use-context k8s-c1-Hpv, pvc 的 yaml 要自己写,可以从官网拷贝示例来修改
➜ vim 6.yaml apiVersion: v1 kind: PersistentVolume metadata: name: safari-pv spec: capacity: storage: 2Gi accessModes: - ReadWriteOnce hostPath: path: "/Volumes/Data" --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: safari-pvc namespace: project-tiger spec: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi volumeName: safari-pv ---快速生成创建 deployment 的 yaml 模板
➜ kubectl -n project-tiger create deployment safari --image=httpd:2.4.41-alpine --dry-run -o yaml >> 6.yaml根据题意,修改模板
➜ vim 6.yaml ... --- apiVersion: apps/v1 kind: Deployment metadata: name: safari namespace: project-tiger labels: app: safari spec: replicas: 1 selector: matchLabels: app: safari template: metadata: labels: app: safari spec: containers: - name: httpd image: httpd:2.4.41-alpine volumeMounts: # 新增 - name: data # 新增 mountPath: /tmp/safari-data # 新增 volumes: # 新增 - name: data # 新增 persistentVolumeClaim: # 新增 claimName: safari-pvc # 新增创建资源
➜ kubectl apply -f 6.yaml
Question 7
Task weight: 1%
Use context:
kubectl config use-context k8s-c1-HThe metrics-server hasn't been installed yet in the cluster, but it's something that should be done soon. Your college would already like to know the kubectl commands to:
- show node resource usage
- show Pod and their containers resource usage
Please write the commands into
/opt/course/7/node.shand/opt/course/7/pod.sh.
题目解析:
考点
- metric-server
解题
➜ vim /opt/course/7/node.sh kubectl top node ➜ vim /opt/course/7/pod.sh kubectl top pod --containers=true
Question 8
Task weight: 2%
Use context:
kubectl config use-context k8s-c1-HSsh into the master node with
ssh cluster1-master1. Check how the master components kubelet, kube-apiserver, kube-scheduler, kube-controller-manager and etcd are started/installed on the master node. Also find out the name of the DNS application and how it's started/installed on the master node.Write your findings into file
/opt/course/8/master-components.txt. The file should be structured like:# /opt/course/8/master-components.txt kubelet: [TYPE] kube-apiserver: [TYPE] kube-scheduler: [TYPE] kube-controller-manager: [TYPE] etcd: [TYPE] dns: [TYPE] [NAME]Choices of
[TYPE]are:not-installed,process,static-pod,pod
题目解析:
考点
- 系统组件, 部署
解题
切换上下文
➜ kubectl config use-context k8s-c1-H通过
kubectl -n kube-system get pod可以看出 kube-apiserver, kube-scheduler, kube-controller-manager, etcd 是静态 pod. dns 是 coredns, 由 deployment 管理的,因此是 pod 类型➜ vim /opt/course/8/master-components.txt kubelet: process kube-apiserver: static-pod kube-scheduler: static-pod kube-controller-manager: static-pod etcd: static-pod dns: pod coredns
Question 9
Use context:
kubectl config use-context k8s-c2-ACSsh into the master node with
ssh cluster2-master1. Temporarily stop the kube-scheduler, this means in a way that you can start it again afterwards.Create a single Pod named
manual-scheduleof imagehttpd:2.4-alpine, confirm its started but not scheduled on any node.Now you're the scheduler and have all its power, manually schedule that Pod on node cluster2-master1. Make sure it's running.
Start the kube-scheduler again and confirm its running correctly by creating a second Pod named
manual-schedule2of imagehttpd:2.4-alpineand check if it's running on cluster2-worker1.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c2-AC停止 kube-scheduler
➜ ssh cluster2-master1 ➜ root@cluster2-master1:~# cd /etc/kubernetes/manifests/ ➜ root@cluster2-master1:~# mv kube-scheduler.yaml ..创建 Pod:Create a single Pod named
manual-scheduleof imagehttpd:2.4-alpine➜ kubectl run manual-schedule --image=httpd:2.4-alpine查看状态
➜ kubectl get pod manual-schedule -o wide NAME READY STATUS ... NODE NOMINATED NODE manual-schedule 0/1 Pending ... <none> <none>手动调度
➜ kubectl edit pod manual-schedule apiVersion: v1 kind: Pod metadata: ... spec: nodeName: cluster2-master1 # 新增 containers: - image: httpd:2.4-alpine imagePullPolicy: IfNotPresent name: manual-schedule ...再次查看状态
➜ kubectl get pod manual-schedule -o wide NAME READY STATUS ... NODE manual-schedule 1/1 Running ... cluster2-master1启动 kube-scheduler
➜ ssh cluster2-master1 ➜ root@cluster2-master1:~# cd /etc/kubernetes/ ➜ root@cluster2-master1:~# mv kube-scheduler.yaml manifests/创建 Pod:
➜ kubectl run manual-schedule2 --image=httpd:2.4-alpine查看状态
➜ kubectl get pod -o wide | grep schedule manual-schedule 1/1 Running ... cluster2-master1 manual-schedule2 1/1 Running ... cluster2-worker1
Question 10
Task weight: 6%
Use context:
kubectl config use-context k8s-c1-HCreate a new ServiceAccount
processorin Namespaceproject-hamster. Create a Role and RoleBinding, both namedprocessoras well. These should allow the new SA to only create Secrets and ConfigMaps in that Namespace.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c1-H创建 ServiceAccount
➜ kubectl -n project-hamster create sa processor创建 Role
➜ kubectl -n project-hamster create role processor --verb=create --resource=secrets,configmap创建 RoleBanding
➜ kubectl -n project-hamster create rolebinding processor --role=processor --serviceaccount=project-hamster:processor验证
➜ kubectl -n project-hamster auth can-i create secret --as system:serviceaccount:project-hamster:processor yes ➜ kubectl -n project-hamster auth can-i create configmap --as system:serviceaccount:project-hamster:processor yes ➜ kubectl -n project-hamster auth can-i create pod --as system:serviceaccount:project-hamster:processor no ➜ kubectl -n project-hamster auth can-i delete secret --as system:serviceaccount:project-hamster:processor no ➜ kubectl -n project-hamster auth can-i get configmap --as system:serviceaccount:project-hamster:processor no
Question 11
Task weight: 4%
Use context:
kubectl config use-context k8s-c1-HUse Namespace
project-tigerfor the following. Create a DaemonSet namedds-importantwith imagehttpd:2.4-alpineand labelsid=ds-importantanduuid=18426a0b-5f59-4e10-923f-c0e078e82462. The Pods it creates should request 10 millicore cpu and 10 megabytes memory. The Pods of that DaemonSet should run on all nodes, master and worker.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c1-H在官网找一份 DaemonSet 示例修改
➜ vim 11.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: ds-important namespace: project-tiger labels: k8s-app: ds-important spec: selector: matchLabels: id: ds-important uuid: 18426a0b-5f59-4e10-923f-c0e078e82462 template: metadata: labels: id: ds-important uuid: 18426a0b-5f59-4e10-923f-c0e078e82462 spec: tolerations: # this toleration is to have the daemonset runnable on master nodes # remove it if your masters can't run pods - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule containers: - name: httpd image: httpd:2.4-alpine resources: requests: cpu: 10m memory: 10Mi创建资源
➜ kubectl apply -f 11.yaml
Question 12
Task weight: 6%
Use context:
kubectl config use-context k8s-c1-HUse Namespace
project-tigerfor the following. Create a Deployment nameddeploy-importantwith labelid=very-important(thePodsshould also have this label) and 3 replicas. It should contain two containers, the first named container1 with imagenginx:1.17.6-alpineand the second one named container2 with imagekubernetes/pause.There should be only ever one Pod of that Deployment running on one worker node. We have two worker nodes: cluster1-worker1 and cluster1-worker2. Because the Deployment has three replicas the result should be that on both nodes one Pod is running. The third Pod won't be scheduled, unless a new worker node will be added.
In a way we kind of simulate the behaviour of a DaemonSet here, but using a Deployment and a fixed number of replicas.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c1-H快速生成部署 deployment 的 yaml 文件
➜ kubectl -n project-tiger create deployment --image=nginx:1.17.6-alpine deploy-important --dry-run=client -o yaml > 12.yaml根据题意修改模板
➜ vim 12.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deploy-important namespace: project-tiger labels: id: very-important # 修改 spec: replicas: 3 # 修改 selector: matchLabels: id: very-important # 修改 template: metadata: labels: id: very-important # 修改 spec: containers: - name: container1 # 修改 image: nginx:1.17.6-alpine - name: container2 # 新增 image: kubernetes/pause # 新增 affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: # 新增 - topologyKey: kubernetes.io/hostname # 新增 labelSelector: # 新增 #matchExpressions: # 新增 #- key: id # 新增 # operator: In # 新增 # values: # 新增 # - very-important # 新增 matchLabels: # 新增 id: very-important # 新增
Question 13
Task weight: 4%
Use context:
kubectl config use-context k8s-c1-HCreate a Pod named
multi-container-playgroundin Namespacedefaultwith three containers, namedc1,c2andc3. There should be a volume attached to that Pod and mounted into every container, but the volume shouldn't be persisted or shared with other Pods.Container
c1should be of imagenginx:1.17.6-alpineand have the name of the node where its Pod is running on value available as environment variable MY_NODE_NAME.Container
c2should be of imagebusybox:1.31.1and write the output of thedatecommand every second in the shared volume into filedate.log. You can usewhile true; do date >> /your/vol/path/date.log; sleep 1; donefor this.Container
c3should be of imagebusybox:1.31.1and constantly write the content of filedate.logfrom the shared volume to stdout. You can usetail -f /your/vol/path/date.logfor this.Check the logs of container
c3to confirm correct setup.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c1-H快速生成部署 pod 的 yaml 模板
➜ kubectl run multi-container-playground --image=nginx:1.17.6-alpine > 13.yaml根据题意,修改模板
➜ vim 13.yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: multi-container-playground name: multi-container-playground spec: containers: - image: nginx:1.17.6-alpine name: c1 # 修改 volumeMounts: # 新增 - name: data # 新增 mountPath: /data # 新增 env: # 新增 - name: MY_NODE_NAME # 新增 valueFrom: # 新增 fieldRef: # 新增 fieldPath: spec.nodeName # 新增 - image: busybox:1.31.1 # 新增 name: c2 # 新增 command: # 新增 - sh # 新增 - -c # 新增 - while true; do date >> /data/date.log; sleep 1; done # 新增 volumeMounts: # 新增 - name: data # 新增 mountPath: /data # 新增 - image: busybox:1.31.1 # 新增 name: c3 # 新增 command: # 新增 - sh # 新增 - -c # 新增 - tail -f /data/date.log # 新增 volumeMounts: # 新增 - name: data # 新增 mountPath: /data # 新增 volumes: # 新增 - name: data # 新增 emptyDir: {} # 新增
Question 14
Task weight: 2%
Use context:
kubectl config use-context k8s-c1-HYou're ask to find out following information about the cluster
k8s-c1-H:
- How many master nodes are available?
- How many worker nodes are available?
- What is the Service CIDR?
- Which Networking (or CNI Plugin) is configured and where is its config file?
- Which suffix will static pods have that run on cluster1-worker1?
Write your answers into file
/opt/course/14/cluster-info, structured like this:# /opt/course/14/cluster-info 1: [ANSWER] 2: [ANSWER] 3: [ANSWER] 4: [ANSWER] 5: [ANSWER]
题目解析:
考点
- 集群信息
解题
切换上下文
➜ kubectl config use-context k8s-c1-H通过查看节点,1,2 可解
➜ kubectl get node查看配置文件,3,4 可解
➜ ssh cluster1-master1 ➜ root@cluster1-master1:~# cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep range - --service-cluster-ip-range=10.96.0.0/12 ➜ root@cluster1-master1:~# ls /etc/cni/net.d/ 10-weave.conflist可得答案
1: 1 2: 2 3: 10.96.0.0/12 4: Weave, /etc/cni/net.d/10-weave.conflist 5: -cluster1-worker1
Question 15
Task weight: 3%
Use context:
kubectl config use-context k8s-c2-ACWrite a command into
/opt/course/15/cluster_events.shwhich shows the latest events in the whole cluster, ordered by time. Usekubectlfor it.Now kill the kube-proxy Pod running on node cluster2-worker1 and write the events this caused into
/opt/course/15/pod_kill.log.Finally kill the containerd container of the kube-proxy Pod on node cluster2-worker1 and write the events into
/opt/course/15/container_kill.log.Do you notice differences in the events both actions caused?
题目解析:
考点
- event
解题
切换上下文
➜ kubectl config use-context k8s-c2-AC获取集群events,以时间排序
kubectl get events -A --sort-by=.metadata.creationTimestamp删除 cluster2-worker1 上的 kube-proxy pod
➜ kubectl -n kube-system get pod ➜ kubectl -n kube-system delete pod kube-proxy-xxxx获取 events
➜ sh /opt/course/15/cluster_events.sh # 将最新的 events 写入 /opt/course/15/pod_kill.log删除 cluster2-worker1 上的 kube-proxy 容器
➜ ssh cluster2-worker1 ➜ root@cluster2-worker1:~# crictl ps ➜ root@cluster2-worker1:~# crictl rm CONTAINER_ID获取 events
➜ sh /opt/course/15/cluster_events.sh # 将最新的 events 写入 /opt/course/15/container_kill.log
Question 16
Task weight: 2%
Use context:
kubectl config use-context k8s-c1-HCreate a new Namespace called
cka-master.Write the names of all namespaced Kubernetes resources (like Pod, Secret, ConfigMap...) into
/opt/course/16/resources.txt.Find the
project-*Namespace with the highest number ofRolesdefined in it and write its name and amount of Roles into/opt/course/16/crowded-namespace.txt.
题目解析:
考点
- kubectl
解题
切换上下文
➜ kubectl config use-context k8s-c1-HCreate a new Namespace called
cka-master➜ kubectl create ns cka-masterWrite the names of all namespaced Kubernetes resources (like Pod, Secret, ConfigMap...) into
/opt/course/16/resources.txt➜ kubectl api-resources --namespaced=true -o name > /opt/course/16/resources.txtFind the
project-*Namespace with the highest number ofRolesdefined in it...➜ kubectl get role -A | grep ^project- | awk '{print $1}' | sort | uniq -c # 将结果写入/opt/course/16/crowded-namespace.txt
Question 17
Task weight: 3%
Use context:
kubectl config use-context k8s-c1-HIn Namespace
project-tigercreate a Pod namedtigers-reuniteof imagehttpd:2.4.41-alpinewith labelspod=containerandcontainer=pod. Find out on which node the Pod is scheduled. Ssh into that node and find the containerd container belonging to that Pod.Using command
crictl:
- Write the ID of the container and the
info.runtimeTypeinto/opt/course/17/pod-container.txt- Write the logs of the container into
/opt/course/17/pod-container.log
题目解析:
考点
- containerd, crictl
解题
切换上下文
➜ kubectl config use-context k8s-c1-H部署 Pod
➜ kubectl -n project-tiger run tigers-reunite --image=httpd:2.4.41-alpine --labels=pod=container,container=pod查看 info.runtimeType
# 先查看 Pod 调度到了哪个节点 ➜ kubectl -n project-tiger get pod -o wide ➜ ssh cluster1-worker2 crictl ps | grep tigers-reunite b01edbe6f89ed 54b0995a63052 5 seconds ago Running tigers-reunite ... ➜ ssh cluster1-worker2 crictl inspect b01edbe6f89ed | grep runtimeType "runtimeType": "io.containerd.runc.v2", # 将container id 和 runtimeType 写入 /opt/course/17/pod-container.txt b01edbe6f89ed io.containerd.runc.v2获取容器日志
➜ kubectl -n project-tiger logs tigers-reunite > /opt/course/17/pod-container.log
Question 18
Task weight: 8%
Use context:
kubectl config use-context k8s-c3-CCCThere seems to be an issue with the kubelet not running on cluster3-worker1. Fix it and confirm that cluster3 has node cluster3-worker1 available in Ready state afterwards. You should be able to schedule a Pod on cluster3-worker1 afterwards.
Write the reason of the issue into
/opt/course/18/reason.txt.
题目解析:
考点
- 故障排查
解题
切换上下文
➜ kubectl config use-context k8s-c3-CCC检查 cluster3-worker1 节点 kubelet
➜ ssh cluster3-worker1 ➜ root@cluster3-worker1:~# ps aux | grep kubelet root 29294 0.0 0.2 14856 1016 pts/0 S+ 11:30 0:00 grep --color=auto kubelet ➜ root@cluster3-worker1:~# systemctl status kubelet ● kubelet.service - kubelet: The Kubernetes Node Agent Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled) Drop-In: /etc/systemd/system/kubelet.service.d └─10-kubeadm.conf Active: inactive (dead) since Sun 2019-12-08 11:30:06 UTC; 50min 52s ago ➜ root@cluster3-worker1:~# systemctl start kubelet ➜ root@cluster3-worker1:~# systemctl status kubelet ➜ root@cluster3-worker1:~# journalctl -xe # 通过查看 `systemctl status kubelet` 和 journalctl -xe,发现报错信息:/usr/local/bin/kubelet: No such file or directory # 查看配置文件:/etc/systemd/system/kubelet.service.d/10-kubeadm.conf # 修改 /usr/local/bin/kubelet 为 /usr/bin/kubelet ➜ root@cluster3-worker1:~# systemctl start kubelet故障原因
➜ vim /opt/course/18/reason.txt wrong path to kubelet binary specified in service config
Question 19
Task weight: 3%
this task can only be solved if questions 18 or 20 have been successfully implemented and the k8s-c3-CCC cluster has a functioning worker node
Use context:
kubectl config use-context k8s-c3-CCCDo the following in a new Namespace
secret. Create a Pod namedsecret-podof imagebusybox:1.31.1which should keep running for some time, it should be able to run on master nodes as well.There is an existing Secret located at
/opt/course/19/secret1.yaml, create it in thesecretNamespace and mount it readonly into the Pod at/tmp/secret1.Create a new Secret in Namespace
secretcalledsecret2which should containuser=user1andpass=1234. These entries should be available inside the Pod's container as environment variables APP_USER and APP_PASS.Confirm everything is working.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c3-CCC创建命名空间 secret
➜ kubectl create ns secret快速生成部署 Pod 的 yaml 模板
➜ kubectl -n secret run secret-pod --image=busybox:1.31.1 --dry-run=client -o yaml > 19.yaml修改模板
➜ vim 19.yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: secret-pod name: secret-pod namespace: secret spec: containers: - image: busybox:1.31.1 name: secret-pod resources: {} command: # 新增 - sh # 新增 - -c # 新增 - sleep 1d # 新增 volumeMounts: # 新增,mount it readonly into the *Pod* at `/tmp/secret1` - name: secret1 # 新增 mountPath: /tmp/secret1 # 新增 readOnly: true # 新增 env: # 新增,environment variables APP_USER and APP_PASS. - name: APP_USER # 新增 valueFrom: # 新增 secretKeyRef: # 新增 name: secret2 # 新增 key: pass # 新增 - name: APP_PASS # 新增 valueFrom: # 新增 secretKeyRef: # 新增 name: secret2 # 新增 key: pass # 新增 dnsPolicy: ClusterFirst restartPolicy: Always tolerations: # 新增,it should be able to run on master nodes as well. - key: "node-role.kubernetes.io/master" # 新增 operator: "Exists" # 新增 effect: "NoSchedule" # 新增 volumes: # 新增 - name: secret1 # 新增 secret: # 新增 secretName: secret1 # 新增 status: {}创建 secret1
➜ cp /opt/course/19/secret1.yaml 19_secret1.yaml ➜ vim 19_secret1.yaml apiVersion: v1 data: halt: IyEgL2Jpbi9zaAo... kind: Secret metadata: creationTimestamp: null name: secret1 namespace: secret # 修改 ➜ kubectl apply -f 19_secret1.yaml创建secret2
➜ kubectl -n secret create secret generic secret2 --from-literal=user=user1 --from-literal=pass=1234创建 Pod
kubectl apply -f 19.yaml
Question 20
Task weight: 10%
Use context:
kubectl config use-context k8s-c3-CCCYour coworker said node cluster3-worker2 is running an older Kubernetes version and is not even part of the cluster. Update kubectl and kubeadm to the version that's running on cluster3-master1. Then add this node to the cluster, you can use kubeadm for this.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c3-CCC查看版本
➜ kubectl get node NAME STATUS ROLES AGE VERSION cluster3-master1 Ready control-plane,master 116m v1.22.1 cluster3-worker1 NotReady <none> 112m v1.22.1查看 cluster3-worker2 节点 kubelet, kubectl, kubeadm 版本
➜ ssh cluster3-worker2 ➜ root@cluster3-worker2:~# kubeadm version ubeadm version: &version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.1", GitCommit:"632ed300f2c34f6d6d15ca4cef3d3c7073412212", GitTreeState:"clean", BuildDate:"2021-08-19T15:44:22Z", GoVersion:"go1.16.7", Compiler:"gc", Platform:"linux/amd64"} ➜ root@cluster3-worker2:~# kubectl version Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.4", GitCommit:"3cce4a82b44f032d0cd1a1790e6d2f5a55d20aae", GitTreeState:"clean", BuildDate:"2021-08-11T18:16:05Z", GoVersion:"go1.16.7", Compiler:"gc", Platform:"linux/amd64"} The connection to the server localhost:8080 was refused - did you specify the right host or port? ➜ root@cluster3-worker2:~# kubelet --version Kubernetes v1.21.4尝试一下 kubeadm 升级
➜ root@cluster3-worker2:~# kubeadm upgrade node couldn't create a Kubernetes client from file "/etc/kubernetes/kubelet.conf": failed to load admin kubeconfig: open /etc/kubernetes/kubelet.conf: no such file or directory To see the stack trace of this error execute with --v=5 or higher # 看到这个报错,说明这个节点没有做过初始化,即从没有加入过集群 # 这种情况,就升级 kubectl, kubeadm, kubelet 到指定版本,然后 kubeadm join 加入集群升级 kubectl, kubeadm, kubelet
➜ root@cluster3-worker2:~# apt-get update ➜ root@cluster3-worker2:~# apt-cache show kubelet | grep 1.22 Version: 1.22.1-00 Filename: pool/kubectl_1.22.1-00_amd64_2a00cd912bfa610fe4932bc0a557b2dd7b95b2c8bff9d001dc6b3d34323edf7d.deb Version: 1.22.0-00 Filename: pool/kubectl_1.22.0-00_amd64_052395d9ddf0364665cf7533aa66f96b310ec8a2b796d21c42f386684ad1fc56.deb Filename: pool/kubectl_1.17.1-00_amd64_0dc19318c9114db2931552bb8bf650a14227a9603cb73fe0917ac7868ec7fcf0.deb SHA256: 0dc19318c9114db2931552bb8bf650a14227a9603cb73fe0917ac7868ec7fcf0 ... ➜ root@cluster3-worker2:~# apt install kubectl=1.22.1-00 kubeadm=1.22.1-00 kubelet=1.22.1-00获取 kubeadm join 命令
➜ ssh cluster3-master1 ➜ root@cluster3-master1:~# kubeadm token create --print-join-command kubeadm join 192.168.100.31:6443 --token leqq1l.1hlg4rw8mu7brv73 --discovery-token-ca-cert-hash sha256:2e2c3407a256fc768f0d8e70974a8e24d7b9976149a79bd08858c4d7aa2ff79acluster3-worker2 节点加入集群
➜ ssh cluster3-worker2 ➜ root@cluster3-worker2:~# kubeadm join 192.168.100.31:6443 --token leqq1l.1hlg4rw8mu7brv73 --discovery-token-ca-cert-hash sha256:2e2c3407a256fc768f0d8e70974a8e24d7b9976149a79bd08858c4d7aa2ff79a
Question 21
Task weight: 2%
Use context:
kubectl config use-context k8s-c3-CCCCreate a
Static Podnamedmy-static-podin Namespacedefaulton cluster3-master1. It should be of imagenginx:1.16-alpineand have resource requests for 10m CPU and 20Mi memory.Then create a NodePort Service named
static-pod-servicewhich exposes that static Pod on port 80 and check if it has Endpoints and if its reachable through the cluster3-master1 internal IP address. You can connect to the internal node IPs from your main terminal.
题目解析:
考点
- 静态 Pod
解题
切换上下文
➜ kubectl config use-context k8s-c3-CCC创建静态Pod
➜ ssh cluster3-master1 ➜ root@cluster1-master1:~# cd /etc/kubernetes/manifests/ ➜ root@cluster1-master1:~# kubectl run my-static-pod --image=nginx:1.16-alpine --requests "cpu=10m,memory=20Mi" --dry-run=client -o yaml > my-static-pod.yaml创建Service
➜ kubectl expose pod my-static-pod-cluster3-master1 --name static-pod-service --type=NodePort --port 80
Questin 22
Task weight: 2%
Use context:
kubectl config use-context k8s-c2-ACCheck how long the kube-apiserver server certificate is valid on
cluster2-master1. Do this with openssl or cfssl. Write the exipiration date into/opt/course/22/expiration.Also run the correct
kubeadmcommand to list the expiration dates and confirm both methods show the same date.Write the correct
kubeadmcommand that would renew the apiserver server certificate into/opt/course/22/kubeadm-renew-certs.sh.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c2-AC查看证书有效期
➜ ssh cluster2-master1 ➜ root@cluster2-master1:~# openssl x509 -noout -text -in /etc/kubernetes/pki/apiserver.crt ... Validity Not Before: Jan 14 18:18:15 2021 GMT Not After : Jan 14 18:49:40 2022 GMT ... # 将结果写入 /opt/course/22/expiration Jan 14 18:49:40 2022 GMT证书续期命令
➜ vim /opt/course/22/kubeadm-renew-certs.sh kubeadm certs renew apiserver
Question 23
Task weight: 2%
Use context:
kubectl config use-context k8s-c2-ACNode cluster2-worker1 has been added to the cluster using
kubeadmand TLS bootstrapping.Find the "Issuer" and "Extended Key Usage" values of the cluster2-worker1:
- kubelet client certificate, the one used for outgoing connections to the kube-apiserver.
- kubelet server certificate, the one used for incoming connections from the kube-apiserver.
Write the information into file
/opt/course/23/certificate-info.txt.Compare the "Issuer" and "Extended Key Usage" fields of both certificates and make sense of these.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c2-AC查看证书信息
➜ ssh cluster2-worker1 ➜ root@cluster2-worker1:~# openssl x509 -noout -text -in /var/lib/kubelet/pki/kubelet-client-current.pem | grep Issuer Issuer: CN = kubernetes ➜ root@cluster2-worker1:~# openssl x509 -noout -text -in /var/lib/kubelet/pki/kubelet-client-current.pem | grep "Extended Key Usage" -A1 X509v3 Extended Key Usage: TLS Web Client Authentication ➜ root@cluster2-worker1:~# openssl x509 -noout -text -in /var/lib/kubelet/pki/kubelet.crt | grep Issuer Issuer: CN = cluster2-worker1-ca@1588186506 ➜ root@cluster2-worker1:~# openssl x509 -noout -text -in /var/lib/kubelet/pki/kubelet.crt | grep "Extended Key Usage" -A1 X509v3 Extended Key Usage: TLS Web Server Authentication # 将证书信息写入 /opt/course/23/certificate-info.txt
Question 24
Task weight: 9%
Use context:
kubectl config use-context k8s-c1-HThere was a security incident where an intruder was able to access the whole cluster from a single hacked backend Pod.
To prevent this create a NetworkPolicy called
np-backendin Namespaceproject-snake. It should allow thebackend-*Pods only to:
- connect to
db1-*Pods on port 1111- connect to
db2-*Pods on port 2222Use the
applabel of Pods in your policy.After implementation, connections from
backend-*Pods tovault-*Pods on port 3333 should for example no longer work.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c1-H从官网找一份示例 yaml 来修改
➜ vim 24.yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: np-backend namespace: project-snake spec: podSelector: matchLabels: app: backend policyTypes: - Egress egress: - to: - podSelector: matchLabels: app: db1 ports: - protocol: TCP port: 1111 - to: - podSelector: matchLabels: app: db2 ports: - protocol: TCP port: 2222
Question 25
Task weight: 8%
Use context:
kubectl config use-context k8s-c3-CCCMake a backup of etcd running on cluster3-master1 and save it on the master node at
/tmp/etcd-backup.db.Then create a Pod of your kind in the cluster.
Finally restore the backup, confirm the cluster is still working and that the created Pod is no longer with us.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c3-CCC备份 etcd
➜ cluster3-master1 ➜ root@cluster3-master1:~# ETCDCTL_API=3 etcdctl snapshot save /tmp/etcd-backup.db \ --cacert /etc/kubernetes/pki/etcd/ca.crt \ --cert /etc/kubernetes/pki/etcd/server.crt \ --key /etc/kubernetes/pki/etcd/server.key创建 Pod
➜ kubectl run test --image=nginx恢复etcd
root@cluster3-master1:~# cd /etc/kubernetes/manifests/ root@cluster3-master1:/etc/kubernetes/manifests# mv * .. # 等系统组件静态 Pod 停止运行 ➜ root@cluster3-master1:~# ETCDCTL_API=3 etcdctl snapshot restore /tmp/etcd-backup.db \ --data-dir /var/lib/etcd-backup \ --cacert /etc/kubernetes/pki/etcd/ca.crt \ --cert /etc/kubernetes/pki/etcd/server.crt \ --key /etc/kubernetes/pki/etcd/server.key ➜ root@cluster3-master1:~# vim /etc/kubernetes/etcd.yaml ... - hostPath: path: /var/lib/etcd-backup # 修改 type: DirectoryOrCreate ... ➜ root@cluster3-master1:/etc/kubernetes/manifests# mv ../*.yaml . # 等系统组件静态 Pod 启动
Extra Question 1
Use context:
kubectl config use-context k8s-c1-HCheck all available Pods in the Namespace
project-c13and find the names of those that would probably be terminated first if the Nodes run out of resources (cpu or memory) to schedule all Pods. Write the Pod names into/opt/course/e1/pods-not-stable.txt.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c1-H查看 Pod 的 QoS 级别
➜ kubectl get pods -n project-c13 -o jsonpath="{range .items[*]}{.metadata.name} {.status.qosClass}{'\n'}" c13-2x3-api-86784557bd-cgs8g Burstable c13-2x3-api-86784557bd-lnxvj Burstable c13-2x3-api-86784557bd-mnp77 Burstable c13-2x3-web-769c989898-6hbgt Burstable c13-2x3-web-769c989898-g57nq Burstable c13-2x3-web-769c989898-hfd5v Burstable c13-2x3-web-769c989898-jfx64 Burstable c13-2x3-web-769c989898-r89mg Burstable c13-2x3-web-769c989898-wtgxl Burstable c13-3cc-runner-98c8b5469-dzqhr Burstable c13-3cc-runner-98c8b5469-hbtdv Burstable c13-3cc-runner-98c8b5469-n9lsw Burstable c13-3cc-runner-heavy-65588d7d6-djtv9 BestEffort c13-3cc-runner-heavy-65588d7d6-v8kf5 BestEffort c13-3cc-runner-heavy-65588d7d6-wwpb4 BestEffort c13-3cc-web-675456bcd-glpq6 Burstable c13-3cc-web-675456bcd-knlpx Burstable c13-3cc-web-675456bcd-nfhp9 Burstable c13-3cc-web-675456bcd-twn7m Burstable o3db-0 BestEffort o3db-1 BestEffort # BestEffort 为最低级别,会优先被 kill写入答案
➜ vim /opt/course/e1/pods-not-stable.txt c13-3cc-runner-heavy-65588d7d6-djtv9 c13-3cc-runner-heavy-65588d7d6-v8kf5 c13-3cc-runner-heavy-65588d7d6-wwpb4 o3db-0 o3db-1
Extra Question 2
Use context:
kubectl config use-context k8s-c1-HThere is an existing ServiceAccount
secret-readerin Namespaceproject-hamster. Create a Pod of imagecurlimages/curl:7.65.3namedtmp-api-contactwhich uses this ServiceAccount. Make sure the container keeps running.Exec into the Pod and use
curlto access the Kubernetes Api of that cluster manually, listing all available secrets. You can ignore insecure https connection. Write the command(s) for this into file/opt/course/e4/list-secrets.sh.
题目解析:
考点
解题
切换上下文
➜ kubectl config use-context k8s-c1-H创建 Pod
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: tmp-api-contact name: tmp-api-contact namespace: project-hamster spec: serviceAccountName: secret-reader containers: - command: - sh - -c - sleep 1d image: curlimages/curl:7.65.3 name: tmp-api-contact resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {}命令
➜ vim /opt/course/e4/list-secrets.sh TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) curl -k https://kubernetes.default/api/v1/secrets -H "Authorization: Bearer ${TOKEN}" # 或者 ➜ vim /opt/course/e4/list-secrets.sh TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt curl --cacert ${CACERT} https://kubernetes.default/api/v1/secrets -H "Authorization: Bearer ${TOKEN}"
Preview Question 1
Use context:
kubectl config use-context k8s-c2-ACThe cluster admin asked you to find out the following information about etcd running on cluster2-master1:
- Server private key location
- Server certificate expiration date
- Is client certificate authentication enabled
Write these information into
/opt/course/p1/etcd-info.txtFinally you're asked to save an etcd snapshot at
/etc/etcd-snapshot.dbon cluster2-master1 and display its status.
题目解析:
考点
- 证书, etcd备份 证书 | Kubernetes, 为 Kubernetes 运行 etcd 集群 | Kubernetes
解题
切换上下文
➜ kubectl config use-context k8s-c2-AC证书信息
# 查看 /etc/kubernetes/manifests/etcd.yaml 可得证书路径和鉴权是否开启 # openssl x509 -noout -text -in /etc/kubernetes/pki/etcd/server.crt 可得证书有效期 ➜ vim /opt/course/p1/etcd-info.txt Server private key location: /etc/kubernetes/pki/etcd/server.key Server certificate expiration date: Sep 13 13:01:31 2022 GMT Is client certificate authentication enabled: yes备份etcd
➜ root@cluster2-master1:~# ETCDCTL_API=3 etcdctl snapshot save /etc/etcd-snapshot.db \ --cacert /etc/kubernetes/pki/etcd/ca.crt \ --cert /etc/kubernetes/pki/etcd/server.crt \ --key /etc/kubernetes/pki/etcd/server.key # 查看备份状态 ➜ root@cluster2-master1:~# ETCDCTL_API=3 etcdctl snapshot status /etc/etcd-snapshot.db 4d4e953, 7213, 1291, 2.7 MB
Preview Question 2
Use context:
kubectl config use-context k8s-c1-HYou're asked to confirm that kube-proxy is running correctly on all nodes. For this perform the following in Namespace
project-hamster:Create a new Pod named
p2-podwith two containers, one of imagenginx:1.21.3-alpineand one of imagebusybox:1.31. Make sure the busybox container keeps running for some time.Create a new Service named
p2-servicewhich exposes that Pod internally in the cluster on port 3000->80.Find the kube-proxy container on all nodes
cluster1-master1,cluster1-worker1andcluster1-worker2and make sure that it's using iptables. Use commandcrictlfor this.Write the iptables rules of all nodes belonging the created Service
p2-serviceinto file/opt/course/p2/iptables.txt.Finally delete the Service and confirm that the iptables rules are gone from all nodes.
题目解析:
考点
- iptables
解题
切换上下文
➜ kubectl config use-context k8s-c1-H部署清单
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: p2-pod name: p2-pod namespace: project-hamster spec: containers: - image: nginx:1.21.3-alpine name: c1 resources: {} - image: busybox:1.31 name: c2 resources: {} command: ["sh", "-c", "sleep 1d"] dnsPolicy: ClusterFirst restartPolicy: Always status: {} --- apiVersion: v1 kind: Service metadata: creationTimestamp: null labels: app: p2-service name: p2-service namespace: project-hamster spec: ports: - name: 3000-80 port: 3000 protocol: TCP targetPort: 80 selector: run: p2-pod type: ClusterIP status: loadBalancer: {}iptables规则
➜ ssh cluster1-master1 iptables-save | grep p2-service >> /opt/course/p2/iptables.txt ➜ ssh cluster1-worker1 iptables-save | grep p2-service >> /opt/course/p2/iptables.txt ➜ ssh cluster1-worker2 iptables-save | grep p2-service >> /opt/course/p2/iptables.txt
Preview Question 3
Use context:
kubectl config use-context k8s-c2-ACCreate a Pod named
check-ipin Namespace default using imagehttpd:2.4.41-alpine. Expose it on port 80 as a ClusterIP Service namedcheck-ip-service. Remember/output the IP of that Service.Change the Service CIDR to
11.96.0.0/12for the cluster.Then create a second Service named
check-ip-service2pointing to the same Pod to check if your settings did take effect. Finally check if the IP of the first Service has changed.
题目解析:
考点
- iptables
解题
切换上下文
➜ kubectl config use-context k8s-c2-AC部署清单
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: check-ip name: check-ip spec: containers: - image: httpd:2.4.41-alpine name: check-ip resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {} --- apiVersion: v1 kind: Service metadata: creationTimestamp: null labels: app: check-ip-service name: check-ip-service spec: ports: - name: 80-80 port: 80 protocol: TCP targetPort: 80 selector: run: check-ip type: ClusterIP status: loadBalancer: {}修改网段
➜ root@cluster2-master1:~# vim /etc/kubernetes/manifests/kube-controller-manager.yaml - --service-cluster-ip-range=11.96.0.0/12 # 修改创建另一个 service
➜ kubectl expose pod check-ip --name check-ip-service2 --port 80