CKA證書模擬24道題-題解
快捷別名
alias k=kubectl # will already be pre-configured
export do="--dry-run=client -o yaml" # k create deploy nginx --image=nginx $do
export now="--force --grace-period 0" # k delete pod x $now
vim設(shè)置
set tabstop=2
set expandtab
set shiftwidth=2
題庫1
任務(wù)權(quán)重:1%
您可以通過上下文從主終端訪問多個集群。將所有這些上下文名稱寫入 。kubectl/opt/course/1/contexts
接下來編寫一個命令以將當(dāng)前上下文顯示到 ,該命令應(yīng)使用 。/opt/course/1/context_default_kubectl.shkubectl
最后在 中編寫執(zhí)行相同操作的第二個命令,但不使用 ./opt/course/1/context_default_no_kubectl.shkubectl
You have access to multiple clusters from your main terminal through kubectl contexts. 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 use kubectl.
Finally write a second command doing the same thing into /opt/course/1/context_default_no_kubectl.sh, but without the use of kubectl.
題解
k config get-contexts
k config get-contexts -o name > /opt/course/1/contexts
或者
Or using jsonpath:
k config view -o yaml # overview
k config view -o jsonpath="{.contexts[*].name}"
k config view -o jsonpath="{.contexts[*].name}" | tr " " "\n" # new lines
k config view -o jsonpath="{.contexts[*].name}" | tr " " "\n" > /opt/course/1/contexts
#/opt/course/1/contexts
k8s-c1-H
k8s-c2-AC
k8s-c3-CCC
接下來創(chuàng)建第一個命令
# /opt/course/1/context_default_kubectl.sh
kubectl config current-context
? sh /opt/course/1/context_default_kubectl.sh
k8s-c1-H
第二個
# /opt/course/1/context_default_no_kubectl.sh
cat ~/.kube/config | grep current
? sh /opt/course/1/context_default_no_kubectl.sh
current-context: k8s-c1-H
第二個命令也可以改進(jìn)為
# /opt/course/1/context_default_no_kubectl.sh
cat ~/.kube/config | grep current | sed -e "s/current-context: //"
題庫2
任務(wù)權(quán)重:3%
使用上下文:kubectl config use-context k8s-c1-H
在命名空間中創(chuàng)建單個映像 Pod。應(yīng)該命名 Pod,容器應(yīng)該命名。此 Pod 應(yīng)該只調(diào)度在控制平面節(jié)點(diǎn)上,不要在任何節(jié)點(diǎn)上添加新標(biāo)簽。httpd:2.4.41-alpinedefaultpod1pod1-container
Use context: kubectl config use-context k8s-c1-H
Create a single Pod of image httpd:2.4.41-alpine in Namespace default. The Pod should be named pod1 and the container should be named pod1-container. This Pod should only be scheduled on a controlplane node, do not add new labels any nodes.
題解
答:
首先,我們找到控制平面節(jié)點(diǎn)及其污點(diǎn):
k get node # find controlplane node
k describe node cluster1-controlplane1 | grep Taint -A1 # get controlplane node taints
k get node cluster1-controlplane1 --show-labels # get controlplane node labels
接下來我們創(chuàng)建 Pod 模板:
# check the export on the very top of this document so we can use $do
k run pod1 --image=httpd:2.4.41-alpine $do > 2.yaml #追加為yaml文件
vim 2.yaml
手動執(zhí)行必要的更改。使用 Kubernetes 文檔并搜索例如容忍和 nodeSelector 來查找示例:
# 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 # change
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
tolerations: # add
- effect: NoSchedule # add
key: node-role.kubernetes.io/control-plane # add
nodeSelector: # add
node-role.kubernetes.io/control-plane: "" # add
status: {}
這里重要的是添加在控制平面節(jié)點(diǎn)上運(yùn)行的容差,以及 nodeSelector,以確保它只在控制平面節(jié)點(diǎn)上運(yùn)行。如果我們只指定容忍度,則可以 在控制平面或工作節(jié)點(diǎn)上調(diào)度 Pod。
現(xiàn)在我們創(chuàng)建它:
k -f 2.yaml create
讓我們檢查一下 Pod 是否已調(diào)度:
? k get pod pod1 -o wide
NAME READY STATUS RESTARTS ... NODE NOMINATED NODE
pod1 1/1 Running 0 ... cluster1-controlplane1 <none>
題庫3
任務(wù)權(quán)重:1%
使用上下文:kubectl config use-context k8s-c1-H
命名空間中有兩個命名的 Pod。C13 管理層要求您將 Pod 縮減到一個副本以節(jié)省資源。o3db-*project-c13
Use context: kubectl config use-context k8s-c1-H
There are two Pods named in Namespace . C13 management asked you to scale the Pods down to one replica to save resources.o3db-*project-c13
題解
答:
如果我們檢查 Pod,我們會看到兩個副本:
? k -n project-c13 get pod | grep o3db
o3db-0 1/1 Running 0 52s
o3db-1 1/1 Running 0 42s
從它們的名字來看,這些似乎由StatefulSet管理。但是,如果我們不確定,我們還可以檢查管理 Pod 的最常見資源:
? k -n project-c13 get deploy,ds,sts | grep o3db
statefulset.apps/o3db 2/2 2m56s
確認(rèn),我們必須使用StatefulSet。要找出這一點(diǎn),我們還可以查看 Pod 標(biāo)簽:
? k -n project-c13 get pod --show-labels | grep o3db
o3db-0 1/1 Running 0 3m29s app=nginx,controller-revision-hash=o3db-5fbd4bb9cc,statefulset.kubernetes.io/pod-name=o3db-0
o3db-1 1/1 Running 0 3m19s app=nginx,controller-revision-hash=o3db-5fbd4bb9cc,statefulset.kubernetes.io/pod-name=o3db-1
為了完成任務(wù),我們只需運(yùn)行:
? k -n project-c13 scale sts o3db --replicas 1
statefulset.apps/o3db scaled
? k -n project-c13 get sts o3db
NAME READY AGE
o3db 1/1 4m39s
題庫4
任務(wù)權(quán)重:4%
使用上下文:kubectl config use-context k8s-c1-H
在命名空間中執(zhí)行以下操作。創(chuàng)建一個以 image 命名的 Pod 。配置一個只執(zhí)行命令的活體探針。還要配置一個 準(zhǔn)備探測 檢查 url 是否可訪問,您可以為此使用。啟動 Pod 并確認(rèn)由于準(zhǔn)備情況探測而未準(zhǔn)備就緒。defaultready-if-service-readynginx:1.16.1-alpinetruehttp://service-am-i-ready:80wget -T2 -O- http://service-am-i-ready:80
創(chuàng)建第二個以帶有標(biāo)簽的映像命名的 Pod?,F(xiàn)有的服務(wù)現(xiàn)在應(yīng)該將第二個 Pod 作為端點(diǎn)。am-i-readynginx:1.16.1-alpineid: cross-server-readyservice-am-i-ready
現(xiàn)在第一個 Pod 應(yīng)該處于就緒狀態(tài),確認(rèn)這一點(diǎn)。
Use context: kubectl config use-context k8s-c1-H
Do the following in Namespace . Create a single Pod named of image . Configure a LivenessProbe which simply executes command . Also configure a ReadinessProbe which does check if the url is reachable, you can use for this. Start the Pod and confirm it isn't ready because of the ReadinessProbe.defaultready-if-service-readynginx:1.16.1-alpinetruehttp://service-am-i-ready:80wget -T2 -O- http://service-am-i-ready:80
Create a second Pod named of image with label . The already existing Service should now have that second Pod as endpoint.am-i-readynginx:1.16.1-alpineid: cross-server-readyservice-am-i-ready
Now the first Pod should be in ready state, confirm that.
題解
答:
對于一個 Pod 使用探針檢查另一個 Pod 是否準(zhǔn)備就緒有點(diǎn)反模式,因此通常可用的對 絕對遠(yuǎn)程 url 不起作用。盡管如此,此任務(wù)中請求的解決方法仍應(yīng)顯示探測器和 Pod<-> 服務(wù)通信的工作原理。readinessProbe.httpGet
首先,我們創(chuàng)建第一個 Pod:
k run ready-if-service-ready --image=nginx:1.16.1-alpine $do > 4_pod1.yaml
vim 4_pod1.yaml
# 4_pod1.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: # add from here
exec:
command:
- 'true'
readinessProbe:
exec:
command:
- sh
- -c
- 'wget -T2 -O- http://service-am-i-ready:80' # to here
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
然后創(chuàng)建 Pod
k -f 4_pod1.yaml create
并確認(rèn)它處于未就緒狀態(tài):
? k get pod ready-if-service-ready
NAME READY STATUS RESTARTS AGE
ready-if-service-ready 0/1 Running 0 7s
我們還可以使用描述來檢查其原因:
? k describe pod ready-if-service-ready
...
Warning Unhealthy 18s kubelet, cluster1-node1 Readiness probe failed: Connecting to service-am-i-ready:80 (10.109.194.234:80)
wget: download timed out
現(xiàn)在我們創(chuàng)建第二個 Pod:
k run am-i-ready --image=nginx:1.16.1-alpine --labels="id=cross-server-ready"
現(xiàn)有的服務(wù) 現(xiàn)在應(yīng)該有一個終結(jié)點(diǎn):service-am-i-ready
k describe svc service-am-i-ready
k get ep # also possible
這將導(dǎo)致我們的第一個 Pod 準(zhǔn)備就緒,只需給它一分鐘時間讓就緒探測再次檢查:
? k get pod ready-if-service-ready
NAME READY STATUS RESTARTS AGE
ready-if-service-ready 1/1 Running 0 53s
看看這些 Pod 一起工作!
題庫5
任務(wù)權(quán)重:1%
使用上下文:kubectl config use-context k8s-c1-H
所有命名空間中都有各種 Pod。編寫一個命令,其中列出了按 AGE () 排序的所有 Pod。/opt/course/5/find_pods.shmetadata.creationTimestamp
編寫第二個命令,其中列出了按字段排序的所有 Pod。對這兩個命令都使用排序。/opt/course/5/find_pods_uid.shmetadata.uidkubectl
Use context: kubectl config use-context k8s-c1-H
There are various Pods in all namespaces. Write a command into which lists all Pods sorted by their AGE ()./opt/course/5/find_pods.shmetadata.creationTimestamp
Write a second command into which lists all Pods sorted by field . Use sorting for both commands./opt/course/5/find_pods_uid.shmetadata.uidkubectl
題解
答:
這里的一個很好的資源(以及許多其他事情)是kubectl-cheat-sheet。在 Kubernetes 文檔中搜索“備忘單”時,您可以快速訪問它。
# /opt/course/5/find_pods.sh
kubectl get pod -A --sort-by=.metadata.creationTimestamp
并執(zhí)行:
? sh /opt/course/5/find_pods.sh
NAMESPACE NAME ... AGE
kube-system kube-scheduler-cluster1-controlplane1 ... 63m
kube-system etcd-cluster1-controlplane1 ... 63m
kube-system kube-apiserver-cluster1-controlplane1 ... 63m
kube-system kube-controller-manager-cluster1-controlplane1 ... 63m
...
對于第二個命令:
# /opt/course/5/find_pods_uid.sh
kubectl get pod -A --sort-by=.metadata.uid
并執(zhí)行:
? sh /opt/course/5/find_pods_uid.sh
NAMESPACE NAME ... AGE
kube-system coredns-5644d7b6d9-vwm7g ... 68m
project-c13 c13-3cc-runner-heavy-5486d76dd4-ddvlt ... 63m
project-hamster web-hamster-shop-849966f479-278vp ... 63m
project-c13 c13-3cc-web-646b6c8756-qsg4b ... 63m
題庫6
任務(wù)權(quán)重:8%
使用上下文:kubectl config use-context k8s-c1-H
創(chuàng)建一個名為 的新持久卷。它應(yīng)該具有2Gi的容量,訪問模式讀寫一次,hostPath和未定義存儲類名。safari-pv/Volumes/Data
接下來,在命名空間中創(chuàng)建一個名為 的新 PersistentVolumeClaim。它應(yīng)該請求 2Gi 存儲,訪問模式 ReadWriteOnce,并且不應(yīng)該定義 storageClassName。PVC 應(yīng)正確綁定到 PV。project-tigersafari-pvc
最后,在命名空間中創(chuàng)建一個新的部署,該部署將該卷裝載在 。該部署的 Pod 應(yīng)為映像 。safariproject-tiger/tmp/safari-datahttpd:2.4.41-alpine
Use context: kubectl config use-context k8s-c1-H
Create a new PersistentVolume named . It should have a capacity of 2Gi, accessMode ReadWriteOnce, hostPath and no storageClassName defined.safari-pv/Volumes/Data
Next create a new PersistentVolumeClaim in Namespace named . It should request 2Gi storage, accessMode ReadWriteOnce and should not define a storageClassName. The PVC should bound to the PV correctly.project-tigersafari-pvc
Finally create a new Deployment in Namespace which mounts that volume at . The Pods of that Deployment should be of image .safariproject-tiger/tmp/safari-datahttpd:2.4.41-alpine
題解
答
vim 6_pv.yaml
從 https://kubernetes.io/docs 中找到一個例子 并對其進(jìn)行更改:
# 6_pv.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: safari-pv
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/Volumes/Data"
然后創(chuàng)建它:
k -f 6_pv.yaml create
接下來是 PersistentVolumeClaim:
vim 6_pvc.yaml
從 https://kubernetes.io/docs 中找到一個例子 并對其進(jìn)行更改:
# 6_pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: safari-pvc
namespace: project-tiger
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
然后創(chuàng)建:
k -f 6_pvc.yaml create
并檢查兩者的狀態(tài)是否為“綁定”:
? k -n project-tiger get pv,pvc
NAME CAPACITY ... STATUS CLAIM ...
persistentvolume/safari-pv 2Gi ... Bound project-tiger/safari-pvc ...
NAME STATUS VOLUME CAPACITY ...
persistentvolumeclaim/safari-pvc Bound safari-pv 2Gi ...
接下來,我們創(chuàng)建一個部署并掛載該卷:
k -n project-tiger create deploy safari \
--image=httpd:2.4.41-alpine $do > 6_dep.yaml
vim 6_dep.yaml
更改 yaml 以裝載卷:
# 6_dep.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: safari
name: safari
namespace: project-tiger
spec:
replicas: 1
selector:
matchLabels:
app: safari
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: safari
spec:
volumes: # add
- name: data # add
persistentVolumeClaim: # add
claimName: safari-pvc # add
containers:
- image: httpd:2.4.41-alpine
name: container
volumeMounts: # add
- name: data # add
mountPath: /tmp/safari-data # add
k -f 6_dep.yaml create
我們可以確認(rèn)它是否正確安裝:
? k -n project-tiger describe pod safari-5cbf46d6d-mjhsb | grep -A2 Mounts:
Mounts:
/tmp/safari-data from data (rw) # there it is
/var/run/secrets/kubernetes.io/serviceaccount from default-token-n2sjj (ro)
題庫7
Use context: kubectl config use-context k8s-c1-H
The metrics-server has been installed in the cluster. Your college would like to know the kubectl commands to:
show Nodes resource usage
show Pods and their containers resource usage
Please write the commands into and ./opt/course/7/node.sh/opt/course/7/pod.sh
任務(wù)權(quán)重:1%
使用上下文:kubectl config use-context k8s-c1-H
指標(biāo)服務(wù)器已安裝在群集中。您的大學(xué)想知道 kubectl 命令:
顯示節(jié)點(diǎn)資源使用情況
顯示 Pod 及其容器的資源使用情況
請將命令寫入 和 。/opt/course/7/node.sh/opt/course/7/pod.sh
題解
答:
我們在這里需要使用的命令是 top:
? k top -h
Display Resource (CPU/Memory/Storage) usage.
The top command allows you to see the resource consumption for nodes or pods.
This command requires Metrics Server to be correctly configured and working on the server.
Available Commands:
node Display Resource (CPU/Memory/Storage) usage of nodes
pod Display Resource (CPU/Memory/Storage) usage of pods
我們看到指標(biāo)服務(wù)器提供有關(guān)資源使用情況的信息:
? k top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
cluster1-controlplane1 178m 8% 1091Mi 57%
cluster1-node1 66m 6% 834Mi 44%
cluster1-node2 91m 9% 791Mi 41%
我們創(chuàng)建第一個文件:
# /opt/course/7/node.sh
kubectl top node
對于第二個文件,我們可能需要再次檢查文檔:
? k top pod -h
Display Resource (CPU/Memory/Storage) usage of pods.
...
Namespace in current context is ignored even if specified with --namespace.
--containers=false: If present, print usage of containers within a pod.
--no-headers=false: If present, print output without headers.
...
有了這個,我們可以完成這個任務(wù):
# /opt/course/7/pod.sh
kubectl top pod --containers=true
題庫8
Use context: kubectl config use-context k8s-c1-H
Ssh into the controlplane node with . Check how the controlplane components kubelet, kube-apiserver, kube-scheduler, kube-controller-manager and etcd are started/installed on the controlplane node. Also find out the name of the DNS application and how it's started/installed on the controlplane node.ssh cluster1-controlplane1
Write your findings into file . The file should be structured like:/opt/course/8/controlplane-components.txt
任務(wù)權(quán)重:2%
使用上下文:kubectl config use-context k8s-c1-H
使用 Ssh 進(jìn)入控制平面節(jié)點(diǎn)。檢查控制平面組件 kubelet、kube-apiserver、kube-scheduler、kube-controller-manager 和 etcd 是如何在控制平面節(jié)點(diǎn)上啟動/安裝的。還要了解 DNS 應(yīng)用程序的名稱以及它在控制平面節(jié)點(diǎn)上的啟動/安裝方式。ssh cluster1-controlplane1
將您的發(fā)現(xiàn)寫入文件 。該文件的結(jié)構(gòu)應(yīng)如下所示:/opt/course/8/controlplane-components.txt
# /opt/course/8/controlplane-components.txt
kubelet: [TYPE]
kube-apiserver: [TYPE]
kube-scheduler: [TYPE]
kube-controller-manager: [TYPE]
etcd: [TYPE]
dns: [TYPE] [NAME]
選項(xiàng)包括:、、、[TYPE]not-installedprocessstatic-podpod
題解
答:
我們可以從查找所請求組件的進(jìn)程開始,尤其是一開始的 kubelet:
? ssh cluster1-controlplane1
root@cluster1-controlplane1:~# ps aux | grep kubelet # shows kubelet process
我們可以看到哪些組件是通過 systemd 控制的,查看 目錄:/etc/systemd/system
? root@cluster1-controlplane1:~# find /etc/systemd/system/ | grep kube
/etc/systemd/system/kubelet.service.d
/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
/etc/systemd/system/multi-user.target.wants/kubelet.service
? root@cluster1-controlplane1:~# find /etc/systemd/system/ | grep etcd
這表明 kubelet 是通過 systemd 控制的,但沒有其他名為 kube 和 etcd 的服務(wù)。似乎這個集群是使用 kubeadm 設(shè)置的,所以我們檢查默認(rèn)的清單目錄:
? root@cluster1-controlplane1:~# find /etc/kubernetes/manifests/
/etc/kubernetes/manifests/
/etc/kubernetes/manifests/kube-controller-manager.yaml
/etc/kubernetes/manifests/etcd.yaml
/etc/kubernetes/manifests/kube-apiserver.yaml
/etc/kubernetes/manifests/kube-scheduler.yaml
(kubelet 也可以有一個不同的清單目錄,通過 它的 systemd 啟動配置中的參數(shù)指定)--pod-manifest-path
這意味著主要的 4 個控制平面服務(wù)被設(shè)置為靜態(tài) Pod。實(shí)際上,讓我們檢查在 控制平面節(jié)點(diǎn)上的命名空間中 運(yùn)行的所有 Pod:kube-system
? root@cluster1-controlplane1:~# kubectl -n kube-system get pod -o wide | grep controlplane1
coredns-5644d7b6d9-c4f68 1/1 Running ... cluster1-controlplane1
coredns-5644d7b6d9-t84sc 1/1 Running ... cluster1-controlplane1
etcd-cluster1-controlplane1 1/1 Running ... cluster1-controlplane1
kube-apiserver-cluster1-controlplane1 1/1 Running ... cluster1-controlplane1
kube-controller-manager-cluster1-controlplane1 1/1 Running ... cluster1-controlplane1
kube-proxy-q955p 1/1 Running ... cluster1-controlplane1
kube-scheduler-cluster1-controlplane1 1/1 Running ... cluster1-controlplane1
weave-net-mwj47 2/2 Running ... cluster1-controlplane1
在那里,我們看到 5 個靜態(tài) pod,帶有 as 后綴。-cluster1-controlplane1
我們還看到 dns 應(yīng)用程序似乎是 coredns,但它是如何控制的?
? root@cluster1-controlplane1$ kubectl -n kube-system get ds
NAME DESIRED CURRENT ... NODE SELECTOR AGE
kube-proxy 3 3 ... kubernetes.io/os=linux 155m
weave-net 3 3 ... <none> 155m
? root@cluster1-controlplane1$ kubectl -n kube-system get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
coredns 2/2 2 2 155m
似乎 coredns 是通過部署控制的。我們將我們的發(fā)現(xiàn)合并到請求的文件中:
# /opt/course/8/controlplane-components.txt
kubelet: process
kube-apiserver: static-pod
kube-scheduler: static-pod
kube-controller-manager: static-pod
etcd: static-pod
dns: pod coredns
您應(yīng)該能夠輕松調(diào)查正在運(yùn)行的集群,了解如何設(shè)置集群及其服務(wù)的不同方法,并能夠進(jìn)行故障排除和查找錯誤源。
題庫9
Use context: kubectl config use-context k8s-c2-AC
Ssh into the controlplane node with ssh cluster2-controlplane1. Temporarily stop the kube-scheduler, this means in a way that you can start it again afterwards.
Create a single Pod named manual-schedule of image httpd:2.4-alpine, confirm it's created but not scheduled on any node.
Now you're the scheduler and have all its power, manually schedule that Pod on node cluster2-controlplane1. Make sure it's running.
Start the kube-scheduler again and confirm it's running correctly by creating a second Pod named manual-schedule2 of image httpd:2.4-alpine and check if it's running on cluster2-node1.
任務(wù)權(quán)重:5%
使用上下文:kubectl config use-context k8s-c2-AC
使用 Ssh 進(jìn)入控制平面節(jié)點(diǎn)。暫時停止 kube-scheduler,這意味著您可以在之后再次啟動它。ssh cluster2-controlplane1
創(chuàng)建一個以 image 命名的 Pod,確認(rèn)它已創(chuàng)建但未在任何節(jié)點(diǎn)上調(diào)度。manual-schedulehttpd:2.4-alpine
現(xiàn)在你是調(diào)度程序并擁有它的所有功能,在節(jié)點(diǎn)集群 2-controlplane1 上手動調(diào)度該 Pod。確保它正在運(yùn)行。
再次啟動 kube-scheduler,并通過創(chuàng)建第二個名為 image 的 Pod 來確認(rèn)它是否正常運(yùn)行,并檢查它是否在 cluster2-node1 上運(yùn)行。manual-schedule2httpd:2.4-alpine
題解
答:
停止調(diào)度程序
首先,我們找到控制平面節(jié)點(diǎn):
? k get node
NAME STATUS ROLES AGE VERSION
cluster2-controlplane1 Ready control-plane 26h v1.26.0
cluster2-node1 Ready <none> 26h v1.26.0
然后我們連接并檢查調(diào)度程序是否正在運(yùn)行:
? ssh cluster2-controlplane1
? root@cluster2-controlplane1:~# kubectl -n kube-system get pod | grep schedule
kube-scheduler-cluster2-controlplane1 1/1 Running 0 6s
終止調(diào)度程序(暫時):
? root@cluster2-controlplane1:~# cd /etc/kubernetes/manifests/
? root@cluster2-controlplane1:~# mv kube-scheduler.yaml ..
并且應(yīng)該停止:
? root@cluster2-controlplane1:~# kubectl -n kube-system get pod | grep schedule
? root@cluster2-controlplane1:~#
創(chuàng)建容器
現(xiàn)在我們創(chuàng)建 Pod:
k run manual-schedule --image=httpd:2.4-alpine
并確認(rèn)它沒有分配節(jié)點(diǎn):
? k get pod manual-schedule -o wide
NAME READY STATUS ... NODE NOMINATED NODE
manual-schedule 0/1 Pending ... <none> <none>
手動調(diào)度 Pod
現(xiàn)在讓我們玩調(diào)度程序:
k get pod manual-schedule -o yaml > 9.yaml
# 9.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2020-09-04T15:51:02Z"
labels:
run: manual-schedule
managedFields:
...
manager: kubectl-run
operation: Update
time: "2020-09-04T15:51:02Z"
name: manual-schedule
namespace: default
resourceVersion: "3515"
selfLink: /api/v1/namespaces/default/pods/manual-schedule
uid: 8e9d2532-4779-4e63-b5af-feb82c74a935
spec:
nodeName: cluster2-controlplane1 # add the controlplane node name
containers:
- image: httpd:2.4-alpine
imagePullPolicy: IfNotPresent
name: manual-schedule
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-nxnc7
readOnly: true
dnsPolicy: ClusterFirst
...
調(diào)度器唯一要做的就是為 Pod 聲明設(shè)置 nodeName 。它如何找到正確的節(jié)點(diǎn)進(jìn)行調(diào)度,這是一個非常復(fù)雜的問題,需要考慮許多變量。
由于我們不能 或 ,在這種情況下,我們需要刪除并創(chuàng)建或替換:kubectl apply``kubectl edit
k -f 9.yaml replace --force
它看起來如何?
? k get pod manual-schedule -o wide
NAME READY STATUS ... NODE
manual-schedule 1/1 Running ... cluster2-controlplane1
看起來我們的 Pod 現(xiàn)在正在按照要求在控制平面上運(yùn)行,盡管沒有指定容忍度。只有調(diào)度程序在查找正確的節(jié)點(diǎn)名稱時會考慮 tains/toleranceations/affinity。這就是為什么仍然可以手動將 Pod 直接分配給控制平面節(jié)點(diǎn)并跳過調(diào)度程序的原因。
再次啟動調(diào)度程序
? ssh cluster2-controlplane1
? root@cluster2-controlplane1:~# cd /etc/kubernetes/manifests/
? root@cluster2-controlplane1:~# mv ../kube-scheduler.yaml .
檢查它是否正在運(yùn)行:
? root@cluster2-controlplane1:~# kubectl -n kube-system get pod | grep schedule
kube-scheduler-cluster2-controlplane1 1/1 Running 0 16s
安排第二個測試 Pod:
k run manual-schedule2 --image=httpd:2.4-alpine
? k get pod -o wide | grep schedule
manual-schedule 1/1 Running ... cluster2-controlplane1
manual-schedule2 1/1 Running ... cluster2-node1
恢復(fù)正常。
題庫10
Use context: kubectl config use-context k8s-c1-H
Create a new ServiceAccount processor in Namespace project-hamster. Create a Role and RoleBinding, both named processor as well. These should allow the new SA to only create Secrets and ConfigMaps in that Namespace.
任務(wù)權(quán)重:6%
使用上下文:kubectl config use-context k8s-c1-H
在命名空間中創(chuàng)建新的服務(wù)帳戶。創(chuàng)建角色和角色綁定,兩者都已命名。這些應(yīng)該允許新的 SA 僅在該命名空間中創(chuàng)建機(jī)密和配置映射。processorproject-hamsterprocessor
題解
答:
讓我們談?wù)?RBAC 資源
集群角色|角色定義一組權(quán)限,以及該權(quán)限可用的地方,在整個群集中或僅單個命名空間中。
集群角色綁定|RoleBinding 將一組權(quán)限與帳戶連接起來,并定義在整個群集或單個命名空間中的應(yīng)用位置。
因此,有 4 種不同的 RBAC 組合和 3 種有效的組合:
- 角色 + 角色綁定(在單個命名空間中可用,在單個命名空間中應(yīng)用))
- ClusterRole + ClusterRoleBinding(在群集范圍內(nèi)可用,在群集范圍內(nèi)應(yīng)用)
- 群集角色 + 角色綁定(在群集范圍內(nèi)可用,在單個命名空間中應(yīng)用))
- 角色 + 群集角色綁定(**不可能:**在單個命名空間中可用,在群集范圍內(nèi)應(yīng)用)
跳轉(zhuǎn)至解決方案
我們首先創(chuàng)建服務(wù)帳戶:
? k -n project-hamster create sa processor
serviceaccount/processor created
然后對于角色:
k -n project-hamster create role -h # examples
所以我們執(zhí)行:
k -n project-hamster create role processor \
--verb=create \
--resource=secret \
--resource=configmap
這將創(chuàng)建一個角色,例如:
# kubectl -n project-hamster create role processor --verb=create --resource=secret --resource=configmap
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: processor
namespace: project-hamster
rules:
- apiGroups:
- ""
resources:
- secrets
- configmaps
verbs:
- create
現(xiàn)在,我們將角色綁定到服務(wù)帳戶:
k -n project-hamster create rolebinding -h # examples
所以我們創(chuàng)建它:
k -n project-hamster create rolebinding processor \
--role processor \
--serviceaccount project-hamster:processor
這將創(chuàng)建一個角色綁定,如下所示:
# kubectl -n project-hamster create rolebinding processor --role processor --serviceaccount project-hamster:processor
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: processor
namespace: project-hamster
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: processor
subjects:
- kind: ServiceAccount
name: processor
namespace: project-hamster
要測試我們的 RBAC 設(shè)置,我們可以使用:kubectl auth can-i
k auth can-i -h # examples
喜歡這個:
? k -n project-hamster auth can-i create secret \
--as system:serviceaccount:project-hamster:processor
yes
? k -n project-hamster auth can-i create configmap \
--as system:serviceaccount:project-hamster:processor
yes
? k -n project-hamster auth can-i create pod \
--as system:serviceaccount:project-hamster:processor
no
? k -n project-hamster auth can-i delete secret \
--as system:serviceaccount:project-hamster:processor
no
? k -n project-hamster auth can-i get configmap \
--as system:serviceaccount:project-hamster:processor
no
做。
題庫11
Use context: kubectl config use-context k8s-c1-H
Use Namespace project-tiger for the following. Create a DaemonSet named ds-important with image httpd:2.4-alpine and labels id=ds-important and uuid=18426a0b-5f59-4e10-923f-c0e078e82462. The Pods it creates should request 10 millicore cpu and 10 mebibyte memory. The Pods of that DaemonSet should run on all nodes, also controlplanes.
任務(wù)權(quán)重:4%
使用上下文:kubectl config use-context k8s-c1-H
將命名空間用于以下內(nèi)容。創(chuàng)建一個以圖像和標(biāo)簽命名的守護(hù)程序集,以及 .它創(chuàng)建的 Pod 應(yīng)該請求 10 毫核 CPU 和 10 兆字節(jié)內(nèi)存。該守護(hù)程序集的 Pod 應(yīng)該在所有節(jié)點(diǎn)上運(yùn)行,也應(yīng)該在控制平面上運(yùn)行。project-tigerds-importanthttpd:2.4-alpineid=ds-importantuuid=18426a0b-5f59-4e10-923f-c0e078e82462
題解
答:
到目前為止,我們無法 直接使用 創(chuàng)建守護(hù)程序集,因此我們創(chuàng)建一個部署并對其進(jìn)行更改:kubectl
k -n project-tiger create deployment --image=httpd:2.4-alpine ds-important $do > 11.yaml
vim 11.yaml
(當(dāng)然,你也可以在 Kubernetes 文檔中搜索 DaemonSet 示例 yaml 并對其進(jìn)行更改。
然后我們將 yaml 調(diào)整為:
# 11.yaml
apiVersion: apps/v1
kind: DaemonSet # change from Deployment to Daemonset
metadata:
creationTimestamp: null
labels: # add
id: ds-important # add
uuid: 18426a0b-5f59-4e10-923f-c0e078e82462 # add
name: ds-important
namespace: project-tiger # important
spec:
#replicas: 1 # remove
selector:
matchLabels:
id: ds-important # add
uuid: 18426a0b-5f59-4e10-923f-c0e078e82462 # add
#strategy: {} # remove
template:
metadata:
creationTimestamp: null
labels:
id: ds-important # add
uuid: 18426a0b-5f59-4e10-923f-c0e078e82462 # add
spec:
containers:
- image: httpd:2.4-alpine
name: ds-important
resources:
requests: # add
cpu: 10m # add
memory: 10Mi # add
tolerations: # add
- effect: NoSchedule # add
key: node-role.kubernetes.io/control-plane # add
#status: {} # remove
請求守護(hù)程序集在所有節(jié)點(diǎn)上運(yùn)行,因此我們需要為此指定容忍度。
讓我們確認(rèn)一下:
k -f 11.yaml create
? k -n project-tiger get ds
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
ds-important 3 3 3 3 3 <none> 8s
? k -n project-tiger get pod -l id=ds-important -o wide
NAME READY STATUS NODE
ds-important-6pvgm 1/1 Running ... cluster1-node1
ds-important-lh5ts 1/1 Running ... cluster1-controlplane1
ds-important-qhjcq 1/1 Running ... cluster1-node2
題庫12
Use context: kubectl config use-context k8s-c1-H
Use Namespace project-tiger for the following. Create a Deployment named deploy-important with label id=very-important (the Pods should also have this label) and 3 replicas. It should contain two containers, the first named container1 with image nginx:1.17.6-alpine and the second one named container2 with image kubernetes/pause.
There should be only ever one Pod of that Deployment running on one worker node. We have two worker nodes: cluster1-node1 and cluster1-node2. 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.
任務(wù)權(quán)重:6%
使用上下文:kubectl config use-context k8s-c1-H
將命名空間用于以下內(nèi)容。創(chuàng)建一個以標(biāo)簽命名的部署(也應(yīng)具有此標(biāo)簽)和 3 個副本。它應(yīng)該包含兩個容器,第一個名為 container1 帶有圖像,第二個名為 container2 帶有圖像。project-tigerdeploy-importantid=very-importantPodsnginx:1.17.6-alpinekubernetes/pause
在一個工作節(jié)點(diǎn)上應(yīng)該只有一個該部署的 Pod 運(yùn)行。我們有兩個工作節(jié)點(diǎn):cluster1-node1 和cluster1-node2。因?yàn)椴渴鹩腥齻€副本,所以結(jié)果應(yīng)該是在兩個節(jié)點(diǎn)上都有一個 Pod 正在運(yùn)行。第三個 Pod 不會被調(diào)度,除非添加新的工作節(jié)點(diǎn)。
在某種程度上,我們在這里模擬了守護(hù)程序集的行為,但使用部署和固定數(shù)量的副本。
題解
答:
有兩種可能的方法,一種使用,一種 使用 .podAntiAffinity``topologySpreadConstraint
豆莢反親和力
這里的想法是,我們創(chuàng)建了一個“Pod 間反親和力”,它允許我們說一個 Pod 應(yīng)該只調(diào)度在一個節(jié)點(diǎn)上,其中另一個特定標(biāo)簽的 Pod (這里是相同的標(biāo)簽)尚未運(yùn)行。
讓我們從創(chuàng)建部署模板開始:
k -n project-tiger create deployment \
--image=nginx:1.17.6-alpine deploy-important $do > 12.yaml
vim 12.yaml
然后將 yaml 更改為:
# 12.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
id: very-important # change
name: deploy-important
namespace: project-tiger # important
spec:
replicas: 3 # change
selector:
matchLabels:
id: very-important # change
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
id: very-important # change
spec:
containers:
- image: nginx:1.17.6-alpine
name: container1 # change
resources: {}
- image: kubernetes/pause # add
name: container2 # add
affinity: # add
podAntiAffinity: # add
requiredDuringSchedulingIgnoredDuringExecution: # add
- labelSelector: # add
matchExpressions: # add
- key: id # add
operator: In # add
values: # add
- very-important # add
topologyKey: kubernetes.io/hostname # add
status: {}
指定一個拓?fù)滏I,這是一個預(yù)填充的 Kubernetes 標(biāo)簽,你可以通過描述一個節(jié)點(diǎn)來找到它。
拓?fù)鋽U(kuò)展約束
我們可以用. 最好嘗試并同時玩兩者。topologySpreadConstraints
# 12.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
id: very-important # change
name: deploy-important
namespace: project-tiger # important
spec:
replicas: 3 # change
selector:
matchLabels:
id: very-important # change
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
id: very-important # change
spec:
containers:
- image: nginx:1.17.6-alpine
name: container1 # change
resources: {}
- image: kubernetes/pause # add
name: container2 # add
topologySpreadConstraints: # add
- maxSkew: 1 # add
topologyKey: kubernetes.io/hostname # add
whenUnsatisfiable: DoNotSchedule # add
labelSelector: # add
matchLabels: # add
id: very-important # add
status: {}
應(yīng)用并運(yùn)行
讓我們運(yùn)行它:
k -f 12.yaml create
然后我們檢查部署狀態(tài),其中顯示 2/3 就緒計(jì)數(shù):
? k -n project-tiger get deploy -l id=very-important
NAME READY UP-TO-DATE AVAILABLE AGE
deploy-important 2/3 3 2 2m35s
運(yùn)行以下命令,我們看到每個工作節(jié)點(diǎn)上都有一個 Pod,一個未調(diào)度。
? k -n project-tiger get pod -o wide -l id=very-important
NAME READY STATUS ... NODE
deploy-important-58db9db6fc-9ljpw 2/2 Running ... cluster1-node1
deploy-important-58db9db6fc-lnxdb 0/2 Pending ... <none>
deploy-important-58db9db6fc-p2rz8 2/2 Running ... cluster1-node2
如果我們 kubectl 描述 Pod,它將向我們展示不調(diào)度的原因是我們實(shí)現(xiàn)的 podAntiAffinity 規(guī)則:deploy-important-58db9db6fc-lnxdb
Warning FailedScheduling 63s (x3 over 65s) default-scheduler 0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/control-plane: }, that the pod didn't tolerate, 2 node(s) didn't match pod affinity/anti-affinity, 2 node(s) didn't satisfy existing pods anti-affinity rules.
或者我們的拓?fù)鋽U(kuò)展約束:
Warning FailedScheduling 16s default-scheduler 0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/control-plane: }, that the pod didn't tolerate, 2 node(s) didn't match pod topology spread constraints.
題庫13
Use context: kubectl config use-context k8s-c1-H
Create a Pod named multi-container-playground in Namespace default with three containers, named c1, c2 and c3. 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 c1 should be of image nginx:1.17.6-alpine and have the name of the node where its Pod is running available as environment variable MY_NODE_NAME.
Container c2 should be of image busybox:1.31.1 and write the output of the date command every second in the shared volume into file date.log. You can use while true; do date >> /your/vol/path/date.log; sleep 1; done for this.
Container c3 should be of image busybox:1.31.1 and constantly send the content of file date.log from the shared volume to stdout. You can use tail -f /your/vol/path/date.log for this.
Check the logs of container c3 to confirm correct setup.
任務(wù)權(quán)重:4%
使用上下文:kubectl config use-context k8s-c1-H
創(chuàng)建一個在命名空間中命名的 Pod,其中包含三個容器,分別名為 和 。應(yīng)該有一個卷附加到該 Pod 并掛載到每個容器中,但該卷不應(yīng)持久化或與其他 Pod 共享。multi-container-playgrounddefaultc1c2c3
容器應(yīng)該是鏡像的,并且具有運(yùn)行其 Pod 的節(jié)點(diǎn)的名稱,可用作環(huán)境變量MY_NODE_NAME。c1nginx:1.17.6-alpine
容器應(yīng)該是映像的,并且每秒將共享卷中命令的輸出寫入文件。你可以為此使用。c2busybox:1.31.1datedate.logwhile true; do date >> /your/vol/path/date.log; sleep 1; done
容器應(yīng)該是圖像的,并不斷將文件的內(nèi)容從共享卷發(fā)送到標(biāo)準(zhǔn)輸出。你可以為此使用。c3busybox:1.31.1date.logtail -f /your/vol/path/date.log
檢查容器的日志以確認(rèn)設(shè)置正確。c3
題解
答:
首先,我們創(chuàng)建 Pod 模板:
k run multi-container-playground --image=nginx:1.17.6-alpine $do > 13.yaml
vim 13.yaml
并添加其他容器和它們應(yīng)執(zhí)行的命令:
# 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 # change
resources: {}
env: # add
- name: MY_NODE_NAME # add
valueFrom: # add
fieldRef: # add
fieldPath: spec.nodeName # add
volumeMounts: # add
- name: vol # add
mountPath: /vol # add
- image: busybox:1.31.1 # add
name: c2 # add
command: ["sh", "-c", "while true; do date >> /vol/date.log; sleep 1; done"] # add
volumeMounts: # add
- name: vol # add
mountPath: /vol # add
- image: busybox:1.31.1 # add
name: c3 # add
command: ["sh", "-c", "tail -f /vol/date.log"] # add
volumeMounts: # add
- name: vol # add
mountPath: /vol # add
dnsPolicy: ClusterFirst
restartPolicy: Always
volumes: # add
- name: vol # add
emptyDir: {} # add
status: {}
k -f 13.yaml create
哦,天哪,很多要求的東西。我們檢查 Pod 是否一切正常:
? k get pod multi-container-playground
NAME READY STATUS RESTARTS AGE
multi-container-playground 3/3 Running 0 95s
很好,然后我們檢查容器 c1 是否將請求的節(jié)點(diǎn)名稱作為 env 變量:
? k exec multi-container-playground -c c1 -- env | grep MY
MY_NODE_NAME=cluster1-node2
最后我們檢查日志記錄:
? k logs multi-container-playground -c c3
Sat Dec 7 16:05:10 UTC 2077
Sat Dec 7 16:05:11 UTC 2077
Sat Dec 7 16:05:12 UTC 2077
Sat Dec 7 16:05:13 UTC 2077
Sat Dec 7 16:05:14 UTC 2077
Sat Dec 7 16:05:15 UTC 2077
Sat Dec 7 16:05:16 UTC 2077
題庫14
Use context: kubectl config use-context k8s-c1-H
You're ask to find out following information about the cluster k8s-c1-H:
How many controlplane 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-node1?
Write your answers into file /opt/course/14/cluster-info, structured like this:
任務(wù)權(quán)重:2%
使用上下文:kubectl config use-context k8s-c1-H
系統(tǒng)會要求您了解有關(guān)群集的以下信息:k8s-c1-H
有多少個控制平面節(jié)點(diǎn)可用?
有多少個工作器節(jié)點(diǎn)可用?
什么是服務(wù)網(wǎng)段?
配置了哪個網(wǎng)絡(luò)(或CNI插件),其配置文件在哪里?
靜態(tài) Pod 將具有哪個后綴在 cluster1-node1 上運(yùn)行?
將您的答案寫入文件,結(jié)構(gòu)如下:/opt/course/14/cluster-info
# /opt/course/14/cluster-info
1: [ANSWER]
2: [ANSWER]
3: [ANSWER]
4: [ANSWER]
5: [ANSWER]
題解
答:
有多少個控制平面和工作器節(jié)點(diǎn)可用?
? k get node
NAME STATUS ROLES AGE VERSION
cluster1-controlplane1 Ready control-plane 27h v1.26.0
cluster1-node1 Ready <none> 27h v1.26.0
cluster1-node2 Ready <none> 27h v1.26.0
我們看到一個控制平面和兩個工作線程。
什么是服務(wù)網(wǎng)段?
? ssh cluster1-controlplane1
? root@cluster1-controlplane1:~# cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep range
- --service-cluster-ip-range=10.96.0.0/12
配置了哪個網(wǎng)絡(luò)(或CNI插件),其配置文件在哪里?
? root@cluster1-controlplane1:~# find /etc/cni/net.d/
/etc/cni/net.d/
/etc/cni/net.d/10-weave.conflist
? root@cluster1-controlplane1:~# cat /etc/cni/net.d/10-weave.conflist
{
"cniVersion": "0.3.0",
"name": "weave",
...
默認(rèn)情況下,kubelet 會查看 以發(fā)現(xiàn) CNI 插件。這在每個控制平面和工作器節(jié)點(diǎn)上都是相同的。/etc/cni/net.d
靜態(tài) Pod 將具有哪個后綴在 cluster1-node1 上運(yùn)行?
后綴是帶有前導(dǎo)連字符的節(jié)點(diǎn)主機(jī)名。它曾經(jīng)在 早期的 Kubernetes 版本中。-static
結(jié)果
結(jié)果 可能如下所示:/opt/course/14/cluster-info
# /opt/course/14/cluster-info
# How many controlplane nodes are available?
1: 1
# How many worker nodes are available?
2: 2
# What is the Service CIDR?
3: 10.96.0.0/12
# Which Networking (or CNI Plugin) is configured and where is its config file?
4: Weave, /etc/cni/net.d/10-weave.conflist
# Which suffix will static pods have that run on cluster1-node1?
5: -cluster1-node1
題庫15
Use context: kubectl config use-context k8s-c2-AC
Write a command into /opt/course/15/cluster_events.sh which shows the latest events in the whole cluster, ordered by time (metadata.creationTimestamp). Use kubectl for it.
Now kill the kube-proxy Pod running on node cluster2-node1 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-node1 and write the events into /opt/course/15/container_kill.log.
Do you notice differences in the events both actions caused?
任務(wù)權(quán)重:3%
使用上下文:kubectl config use-context k8s-c2-AC
編寫一個命令,在其中顯示整個群集中的最新事件,按時間排序 ()。用于它。/opt/course/15/cluster_events.shmetadata.creationTimestampkubectl
現(xiàn)在殺死在節(jié)點(diǎn)集群 2-node1 上運(yùn)行的 kube-proxy Pod,并將由此引起的事件寫入 ./opt/course/15/pod_kill.log
最后在節(jié)點(diǎn)集群 2-node1 上殺死 kube-proxy Pod 的容器,并將事件寫入 ./opt/course/15/container_kill.log
您是否注意到兩種行為引起的事件存在差異?
題解
答:
# /opt/course/15/cluster_events.sh
kubectl get events -A --sort-by=.metadata.creationTimestamp
現(xiàn)在我們殺死 kube-proxy Pod:
k -n kube-system get pod -o wide | grep proxy # find pod running on cluster2-node1
k -n kube-system delete pod kube-proxy-z64cg
現(xiàn)在檢查事件:
sh /opt/course/15/cluster_events.sh
將殺戮造成的事件寫成:/opt/course/15/pod_kill.log
# /opt/course/15/pod_kill.log
kube-system 9s Normal Killing pod/kube-proxy-jsv7t ...
kube-system 3s Normal SuccessfulCreate daemonset/kube-proxy ...
kube-system <unknown> Normal Scheduled pod/kube-proxy-m52sx ...
default 2s Normal Starting node/cluster2-node1 ...
kube-system 2s Normal Created pod/kube-proxy-m52sx ...
kube-system 2s Normal Pulled pod/kube-proxy-m52sx ...
kube-system 2s Normal Started pod/kube-proxy-m52sx ...
最后,我們將嘗試通過殺死屬于 kube-proxy Pod 容器的容器來引發(fā)事件:
? ssh cluster2-node1
? root@cluster2-node1:~# crictl ps | grep kube-proxy
1e020b43c4423 36c4ebbc9d979 About an hour ago Running kube-proxy ...
? root@cluster2-node1:~# crictl rm 1e020b43c4423
1e020b43c4423
? root@cluster2-node1:~# crictl ps | grep kube-proxy
0ae4245707910 36c4ebbc9d979 17 seconds ago Running kube-proxy ...
我們殺死了主容器(1e020b43c4423),但也注意到直接創(chuàng)建了一個新容器(0ae4245707910)。謝謝 Kubernetes!
現(xiàn)在我們看看這是否再次導(dǎo)致事件,并將其寫入第二個文件:
sh /opt/course/15/cluster_events.sh
# /opt/course/15/container_kill.log
kube-system 13s Normal Created pod/kube-proxy-m52sx ...
kube-system 13s Normal Pulled pod/kube-proxy-m52sx ...
kube-system 13s Normal Started pod/kube-proxy-m52sx ...
比較事件,我們看到當(dāng)我們刪除整個 Pod 時,有更多的事情要做,因此有更多的事件。例如,游戲中的守護(hù)程序集用于重新創(chuàng)建丟失的 Pod。當(dāng)我們手動殺死 Pod 的主容器時,Pod 仍然存在,但只需要重新創(chuàng)建它的容器,因此事件更少。
題庫16
Use context: kubectl config use-context k8s-c1-H
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 of Roles defined in it and write its name and amount of Roles into /opt/course/16/crowded-namespace.txt.
任務(wù)權(quán)重:2%
使用上下文:kubectl config use-context k8s-c1-H
將所有命名空間的 Kubernetes 資源(如 Pod、Secret、ConfigMap...)的名稱寫入 ./opt/course/16/resources.txt
找到其中定義的命名空間數(shù)量最多,并將其名稱和角色數(shù)量寫入 。project-*Roles/opt/course/16/crowded-namespace.txt
題解
答:
命名空間和命名空間資源
現(xiàn)在我們可以得到所有資源的列表,例如:
k api-resources # shows all
k api-resources -h # help always good
k api-resources --namespaced -o name > /opt/course/16/resources.txt
這將導(dǎo)致文件:
# /opt/course/16/resources.txt
bindings
configmaps
endpoints
events
limitranges
persistentvolumeclaims
pods
podtemplates
replicationcontrollers
resourcequotas
secrets
serviceaccounts
services
controllerrevisions.apps
daemonsets.apps
deployments.apps
replicasets.apps
statefulsets.apps
localsubjectaccessreviews.authorization.k8s.io
horizontalpodautoscalers.autoscaling
cronjobs.batch
jobs.batch
leases.coordination.k8s.io
events.events.k8s.io
ingresses.extensions
ingresses.networking.k8s.io
networkpolicies.networking.k8s.io
poddisruptionbudgets.policy
rolebindings.rbac.authorization.k8s.io
roles.rbac.authorization.k8s.io
具有大多數(shù)角色的命名空間
? k -n project-c13 get role --no-headers | wc -l
No resources found in project-c13 namespace.
0
? k -n project-c14 get role --no-headers | wc -l
300
? k -n project-hamster get role --no-headers | wc -l
No resources found in project-hamster namespace.
0
? k -n project-snake get role --no-headers | wc -l
No resources found in project-snake namespace.
0
? k -n project-tiger get role --no-headers | wc -l
No resources found in project-tiger namespace.
0
最后,我們將名稱和金額寫入文件:
# /opt/course/16/crowded-namespace.txt
project-c14 with 300 resources
題庫17
Use context: kubectl config use-context k8s-c1-H
In Namespace project-tiger create a Pod named tigers-reunite of image httpd:2.4.41-alpine with labels pod=container and container=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.runtimeType into /opt/course/17/pod-container.txt
Write the logs of the container into /opt/course/17/pod-container.log
任務(wù)權(quán)重:3%
使用上下文:kubectl config use-context k8s-c1-H
在命名空間中,創(chuàng)建一個以圖像命名的 Pod,并帶有標(biāo)簽和 .找出 Pod 調(diào)度在哪個節(jié)點(diǎn)上。Ssh 進(jìn)入該節(jié)點(diǎn)并找到屬于該 Pod 的容器。project-tigertigers-reunitehttpd:2.4.41-alpinepod=containercontainer=pod
使用命令 :crictl
將容器的 ID 寫入info.runtimeType/opt/course/17/pod-container.txt
將容器的日志寫入/opt/course/17/pod-container.log
題解
答:
首先,我們創(chuàng)建 Pod:
k -n project-tiger run tigers-reunite \
--image=httpd:2.4.41-alpine \
--labels "pod=container,container=pod"
接下來,我們找出它被調(diào)度的節(jié)點(diǎn):
k -n project-tiger get pod -o wide
# or fancy:
k -n project-tiger get pod tigers-reunite -o jsonpath="{.spec.nodeName}"
然后我們 ssh 到該節(jié)點(diǎn)并檢查容器信息:
? ssh cluster1-node2
? root@cluster1-node2:~# crictl ps | grep tigers-reunite
b01edbe6f89ed 54b0995a63052 5 seconds ago Running tigers-reunite ...
? root@cluster1-node2:~# crictl inspect b01edbe6f89ed | grep runtimeType
"runtimeType": "io.containerd.runc.v2",
然后我們填寫請求的文件(在主終端上):
# /opt/course/17/pod-container.txt
b01edbe6f89ed io.containerd.runc.v2
最后,我們將容器日志寫入第二個文件中:
ssh cluster1-node2 'crictl logs b01edbe6f89ed' &> /opt/course/17/pod-container.log
上面的 in 命令重定向標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤。&>
您也可以簡單地在 節(jié)點(diǎn)上運(yùn)行并手動復(fù)制內(nèi)容,如果不是很多。該文件應(yīng)如下所示:crictl logs
# /opt/course/17/pod-container.log
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.44.0.37. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.44.0.37. Set the 'ServerName' directive globally to suppress this message
[Mon Sep 13 13:32:18.555280 2021] [mpm_event:notice] [pid 1:tid 139929534545224] AH00489: Apache/2.4.41 (Unix) configured -- resuming normal operations
[Mon Sep 13 13:32:18.555610 2021] [core:notice] [pid 1:tid 139929534545224] AH00094: Command line: 'httpd -D FOREGROUND'
題庫18
Use context: kubectl config use-context k8s-c3-CCC
There seems to be an issue with the kubelet not running on cluster3-node1. Fix it and confirm that cluster has node cluster3-node1 available in Ready state afterwards. You should be able to schedule a Pod on cluster3-node1 afterwards.
Write the reason of the issue into /opt/course/18/reason.txt.
任務(wù)權(quán)重:8%
使用上下文:kubectl config use-context k8s-c3-CCC
似乎有一個問題 kubelet 無法運(yùn)行.修復(fù)此問題,并在之后確認(rèn)群集的節(jié)點(diǎn)處于“就緒”狀態(tài)。之后你應(yīng)該能夠安排一個 Pod。cluster3-node1cluster3-node1cluster3-node1
將問題的原因?qū)懙?中。/opt/course/18/reason.txt
題解
答:
此類任務(wù)的過程應(yīng)該是檢查 kubelet 是否正在運(yùn)行,如果沒有啟動它,則檢查其日志并糾正錯誤(如果有)。
檢查其他集群是否已經(jīng)定義并運(yùn)行了一些組件總是有幫助的,因此您可以復(fù)制和使用現(xiàn)有的配置文件。盡管在這種情況下可能不需要。
檢查節(jié)點(diǎn)狀態(tài):
? k get node
NAME STATUS ROLES AGE VERSION
cluster3-controlplane1 Ready control-plane 14d v1.26.0
cluster3-node1 NotReady <none> 14d v1.26.0
首先,我們檢查 kubelet 是否正在運(yùn)行:
? ssh cluster3-node1
? root@cluster3-node1:~# ps aux | grep kubelet
root 29294 0.0 0.2 14856 1016 pts/0 S+ 11:30 0:00 grep --color=auto kubelet
不,所以我們檢查它是否使用 systemd 作為服務(wù)進(jìn)行配置:
? root@cluster3-node1:~# service kubelet status
● 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
...
是的,它配置為 config at 的服務(wù),但我們看到它處于非活動狀態(tài)。讓我們嘗試啟動它:/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
? root@cluster3-node1:~# service kubelet start
? root@cluster3-node1:~# service kubelet status
● 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: activating (auto-restart) (Result: exit-code) since Thu 2020-04-30 22:03:10 UTC; 3s ago
Docs: https://kubernetes.io/docs/home/
Process: 5989 ExecStart=/usr/local/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS (code=exited, status=203/EXEC)
Main PID: 5989 (code=exited, status=203/EXEC)
Apr 30 22:03:10 cluster3-node1 systemd[5989]: kubelet.service: Failed at step EXEC spawning /usr/local/bin/kubelet: No such file or directory
Apr 30 22:03:10 cluster3-node1 systemd[1]: kubelet.service: Main process exited, code=exited, status=203/EXEC
Apr 30 22:03:10 cluster3-node1 systemd[1]: kubelet.service: Failed with result 'exit-code'.
我們看到它正在嘗試 使用其服務(wù)配置文件中定義的一些參數(shù)來執(zhí)行。查找錯誤并獲取更多日志的一個好方法是手動運(yùn)行命令(通常也使用其參數(shù))。/usr/local/bin/kubelet
? root@cluster3-node1:~# /usr/local/bin/kubelet
-bash: /usr/local/bin/kubelet: No such file or directory
? root@cluster3-node1:~# whereis kubelet
kubelet: /usr/bin/kubelet
另一種方法是查看服務(wù)的擴(kuò)展日志記錄,例如使用 .journalctl -u kubelet
好吧,我們有它,指定了錯誤的路徑。更正文件中的路徑并運(yùn)行:/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
vim /etc/systemd/system/kubelet.service.d/10-kubeadm.conf # fix
systemctl daemon-reload && systemctl restart kubelet
systemctl status kubelet # should now show running
此外,該節(jié)點(diǎn)應(yīng)該可用于 api 服務(wù)器,不過要給它一點(diǎn)時間:
? k get node
NAME STATUS ROLES AGE VERSION
cluster3-controlplane1 Ready control-plane 14d v1.26.0
cluster3-node1 Ready <none> 14d v1.26.0
最后,我們將原因?qū)懭胛募?/p>
# /opt/course/18/reason.txt
wrong path to kubelet binary specified in service config
題庫19
NOTE: 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-CCC
Do the following in a new Namespace secret. Create a Pod named secret-pod of image busybox:1.31.1 which should keep running for some time.
There is an existing Secret located at /opt/course/19/secret1.yaml, create it in the Namespace secret and mount it readonly into the Pod at /tmp/secret1.
Create a new Secret in Namespace secret called secret2 which should contain user=user1 and pass=1234. These entries should be available inside the Pod's container as environment variables APP_USER and APP_PASS.
Confirm everything is working.
任務(wù)權(quán)重:3%
注意:僅當(dāng)問題 18 或 20 已成功實(shí)現(xiàn)并且 k8s-c3-CCC 集群具有正常運(yùn)行的工作節(jié)點(diǎn)時,才能解決此任務(wù)
使用上下文:kubectl config use-context k8s-c3-CCC
在新的命名空間中執(zhí)行以下操作。創(chuàng)建一個以 image 命名的 Pod,它應(yīng)該會持續(xù)運(yùn)行一段時間。secretsecret-podbusybox:1.31.1
有一個現(xiàn)有的密鑰位于 ,在命名空間中創(chuàng)建它并將其只讀地掛載到 Pod 中。/opt/course/19/secret1.yamlsecret/tmp/secret1
在名為 的命名空間中創(chuàng)建一個新的密鑰,該密鑰應(yīng)包含 和 。這些條目應(yīng)該在 Pod 的容器中作為環(huán)境變量APP_USER和APP_PASS提供。secretsecret2user=user1pass=1234
確認(rèn)一切正常。
題解
答
首先,我們在其中創(chuàng)建命名空間和請求的機(jī)密:
k create ns secret
cp /opt/course/19/secret1.yaml 19_secret1.yaml
vim 19_secret1.yaml
我們需要調(diào)整 該密鑰的命名空間:
# 19_secret1.yaml
apiVersion: v1
data:
halt: IyEgL2Jpbi9zaAo...
kind: Secret
metadata:
creationTimestamp: null
name: secret1
namespace: secret # change
k -f 19_secret1.yaml create
接下來,我們創(chuàng)建第二個密鑰:
k -n secret create secret generic secret2 --from-literal=user=user1 --from-literal=pass=1234
現(xiàn)在我們創(chuàng)建 Pod 模板:
k -n secret run secret-pod --image=busybox:1.31.1 $do -- sh -c "sleep 5d" > 19.yaml
vim 19.yaml
然后進(jìn)行必要的更改:
# 19.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: secret-pod
name: secret-pod
namespace: secret # add
spec:
containers:
- args:
- sh
- -c
- sleep 1d
image: busybox:1.31.1
name: secret-pod
resources: {}
env: # add
- name: APP_USER # add
valueFrom: # add
secretKeyRef: # add
name: secret2 # add
key: user # add
- name: APP_PASS # add
valueFrom: # add
secretKeyRef: # add
name: secret2 # add
key: pass # add
volumeMounts: # add
- name: secret1 # add
mountPath: /tmp/secret1 # add
readOnly: true # add
dnsPolicy: ClusterFirst
restartPolicy: Always
volumes: # add
- name: secret1 # add
secret: # add
secretName: secret1 # add
status: {}
在當(dāng)前的 K8s 版本中可能不需要指定 , 因?yàn)樗鼰o論如何都是默認(rèn)設(shè)置。readOnly: true
并執(zhí)行:
k -f 19.yaml create
最后,我們檢查一切是否正確:
? k -n secret exec secret-pod -- env | grep APP
APP_PASS=1234
APP_USER=user1
? k -n secret exec secret-pod -- find /tmp/secret1
/tmp/secret1
/tmp/secret1/..data
/tmp/secret1/halt
/tmp/secret1/..2019_12_08_12_15_39.463036797
/tmp/secret1/..2019_12_08_12_15_39.463036797/halt
? k -n secret exec secret-pod -- cat /tmp/secret1/halt
#! /bin/sh
### BEGIN INIT INFO
# Provides: halt
# Required-Start:
# Required-Stop:
# Default-Start:
# Default-Stop: 0
# Short-Description: Execute the halt command.
# Description:
...
題庫20
Use context: kubectl config use-context k8s-c3-CCC
Your coworker said node cluster3-node2 is running an older Kubernetes version and is not even part of the cluster. Update Kubernetes on that node to the exact version that's running on cluster3-controlplane1. Then add this node to the cluster. Use kubeadm for this.
任務(wù)權(quán)重:10%
使用上下文:kubectl config use-context k8s-c3-CCC
你的同事說節(jié)點(diǎn)運(yùn)行的是較舊的 Kubernetes 版本,甚至不是集群的一部分。將該節(jié)點(diǎn)上的 Kubernetes 更新為在 上運(yùn)行的確切版本。然后將此節(jié)點(diǎn)添加到群集。為此使用 kubeadm。cluster3-node2cluster3-controlplane1
題解
答:
將 Kubernetes 升級到 cluster3-controlplane1 版本
在文檔中搜索 kubeadm 升級: https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade
? k get node
NAME STATUS ROLES AGE VERSION
cluster3-controlplane1 Ready control-plane 22h v1.26.0
cluster3-node1 Ready <none> 22h v1.26.0
控制平面節(jié)點(diǎn)似乎正在運(yùn)行 Kubernetes 1.26.0,并且還不是集群的一部分。cluster3-node2
? ssh cluster3-node2
? root@cluster3-node2:~# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.0", GitCommit:"b46a3f887ca979b1a5d14fd39cb1af43e7e5d12d", GitTreeState:"clean", BuildDate:"2022-12-08T19:57:06Z", GoVersion:"go1.19.4", Compiler:"gc", Platform:"linux/amd64"}
? root@cluster3-node2:~# kubectl version --short
Client Version: v1.25.5
Kustomize Version: v4.5.7
? root@cluster3-node2:~# kubelet --version
Kubernetes v1.25.5
這里 kubeadm 已經(jīng)安裝在想要的版本中,所以我們不需要安裝它。因此,我們可以運(yùn)行:
? root@cluster3-node2:~# 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
這通常是升級節(jié)點(diǎn)的正確命令。但是這個錯誤意味著這個節(jié)點(diǎn)甚至從未初始化過,所以這里沒有什么可更新的。稍后將使用 完成此操作。現(xiàn)在我們可以繼續(xù)使用 kubelet 和 kubectl:kubeadm join
? root@cluster3-node2:~# apt update
...
Fetched 5,775 kB in 2s (2,313 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
90 packages can be upgraded. Run 'apt list --upgradable' to see them.
? root@cluster3-node2:~# apt show kubectl -a | grep 1.26
Version: 1.26.0-00
? root@cluster3-node2:~# apt install kubectl=1.26.0-00 kubelet=1.26.0-00
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be upgraded:
kubectl kubelet
2 upgraded, 0 newly installed, 0 to remove and 135 not upgraded.
Need to get 30.5 MB of archives.
After this operation, 9,996 kB of additional disk space will be used.
Get:1 https://packages.cloud.google.com/apt kubernetes-xenial/main amd64 kubectl amd64 1.26.0-00 [10.1 MB]
Get:2 https://packages.cloud.google.com/apt kubernetes-xenial/main amd64 kubelet amd64 1.26.0-00 [20.5 MB]
Fetched 30.5 MB in 1s (29.7 MB/s)
(Reading database ... 112508 files and directories currently installed.)
Preparing to unpack .../kubectl_1.26.0-00_amd64.deb ...
Unpacking kubectl (1.26.0-00) over (1.25.5-00) ...
Preparing to unpack .../kubelet_1.26.0-00_amd64.deb ...
Unpacking kubelet (1.26.0-00) over (1.25.5-00) ...
Setting up kubectl (1.26.0-00) ...
Setting up kubelet (1.26.0-00) ...
? root@cluster3-node2:~# kubelet --version
Kubernetes v1.26.0
現(xiàn)在我們了解了 kubeadm、kubectl 和 kubelet。重新啟動 kubelet:
? root@cluster3-node2:~# service kubelet restart
? root@cluster3-node2:~# service kubelet status
● 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: activating (auto-restart) (Result: exit-code) since Wed 2022-12-21 16:29:26 UTC; 5s ago
Docs: https://kubernetes.io/docs/home/
Process: 32111 ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS (code=exited, status=1/FAILURE)
Main PID: 32111 (code=exited, status=1/FAILURE)
Dec 21 16:29:26 cluster3-node2 systemd[1]: kubelet.service: Main process exited, code=exited, status=1/FAILURE
Dec 21 16:29:26 cluster3-node2 systemd[1]: kubelet.service: Failed with result 'exit-code'.
發(fā)生這些錯誤是因?yàn)槲覀內(nèi)匀恍枰\(yùn)行 才能將節(jié)點(diǎn)加入群集。讓我們在下一步中執(zhí)行此操作。kubeadm join
將群集 3-節(jié)點(diǎn) 2 添加到群集
首先,我們登錄到控制平面 1 并生成一個新的 TLS 引導(dǎo)令牌,同時打印出 join 命令:
? ssh cluster3-controlplane1
? root@cluster3-controlplane1:~# kubeadm token create --print-join-command
kubeadm join 192.168.100.31:6443 --token rbhrjh.4o93r31o18an6dll --discovery-token-ca-cert-hash sha256:d94524f9ab1eed84417414c7def5c1608f84dbf04437d9f5f73eb6255dafdb18
? root@cluster3-controlplane1:~# kubeadm token list
TOKEN TTL EXPIRES ...
44dz0t.2lgmone0i1o5z9fe <forever> <never>
4u477f.nmpq48xmpjt6weje 1h 2022-12-21T18:14:30Z
rbhrjh.4o93r31o18an6dll 23h 2022-12-22T16:29:58Z
我們看到我們的令牌到期了 23 小時,我們可以通過傳遞 ttl 參數(shù)來調(diào)整它。
接下來,我們再次連接到 并簡單地執(zhí)行 join 命令:cluster3-node2
? ssh cluster3-node2
? root@cluster3-node2:~# kubeadm join 192.168.100.31:6443 --token rbhrjh.4o93r31o18an6dll --discovery-token-ca-cert-hash sha256:d94524f9ab1eed84417414c7def5c1608f84dbf04437d9f5f73eb6255dafdb18
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
? root@cluster3-node2:~# service kubelet status
● 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: active (running) since Wed 2022-12-21 16:32:19 UTC; 1min 4s ago
Docs: https://kubernetes.io/docs/home/
Main PID: 32510 (kubelet)
Tasks: 11 (limit: 462)
Memory: 55.2M
CGroup: /system.slice/kubelet.service
└─32510 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --container-runti>
如果您有問題,您可能需要 運(yùn)行 .kubeadm join``kubeadm reset
這對我們來說看起來很棒。最后我們回到主終端并檢查節(jié)點(diǎn)狀態(tài):
? k get node
NAME STATUS ROLES AGE VERSION
cluster3-controlplane1 Ready control-plane 22h v1.26.0
cluster3-node1 Ready <none> 22h v1.26.0
cluster3-node2 NotReady <none> 22h v1.26.0
給它一點(diǎn)時間,直到節(jié)點(diǎn)準(zhǔn)備就緒。
? k get node
NAME STATUS ROLES AGE VERSION
cluster3-controlplane1 Ready control-plane 22h v1.26.0
cluster3-node1 Ready <none> 22h v1.26.0
cluster3-node2 Ready <none> 22h v1.26.0
我們看到 現(xiàn)在可用且是最新的。cluster3-node2
題庫21
Use context: kubectl config use-context k8s-c3-CCC
Create a Static Pod named my-static-pod in Namespace default on cluster3-controlplane1. It should be of image nginx:1.16-alpine and have resource requests for 10m CPU and 20Mi memory.
Then create a NodePort Service named static-pod-service which exposes that static Pod on port 80 and check if it has Endpoints and if it's reachable through the cluster3-controlplane1 internal IP address. You can connect to the internal node IPs from your main terminal.
任務(wù)權(quán)重:2%
使用上下文:kubectl config use-context k8s-c3-CCC
在群集 3-控制平面 1 上的命名空間中創(chuàng)建一個命名。它應(yīng)該是映像的,并且具有對 CPU 和內(nèi)存的資源請求。Static Podmy-static-poddefaultnginx:1.16-alpine10m20Mi
然后創(chuàng)建一個名為的 NodePort 服務(wù),該服務(wù)在端口 80 上公開該靜態(tài) Pod,并檢查它是否有端點(diǎn)以及是否可以通過內(nèi)部 IP 地址訪問它。您可以從主終端連接到內(nèi)部節(jié)點(diǎn) IP。static-pod-servicecluster3-controlplane1
題解
答:
? ssh cluster3-controlplane1
? root@cluster1-controlplane1:~# cd /etc/kubernetes/manifests/
? root@cluster1-controlplane1:~# kubectl run my-static-pod \
--image=nginx:1.16-alpine \
-o yaml --dry-run=client > my-static-pod.yaml
然后編輯 以 添加請求的資源請求:my-static-pod.yaml
# /etc/kubernetes/manifests/my-static-pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: my-static-pod
name: my-static-pod
spec:
containers:
- image: nginx:1.16-alpine
name: my-static-pod
resources:
requests:
cpu: 10m
memory: 20Mi
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
并確保它正在運(yùn)行:
? k get pod -A | grep my-static
NAMESPACE NAME READY STATUS ... AGE
default my-static-pod-cluster3-controlplane1 1/1 Running ... 22s
現(xiàn)在我們公開靜態(tài) Pod:
k expose pod my-static-pod-cluster3-controlplane1 \
--name static-pod-service \
--type=NodePort \
--port 80
這將生成如下服務(wù):
# kubectl expose pod my-static-pod-cluster3-controlplane1 --name static-pod-service --type=NodePort --port 80
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
run: my-static-pod
name: static-pod-service
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: my-static-pod
type: NodePort
status:
loadBalancer: {}
然后運(yùn)行并測試:
? k get svc,ep -l run=my-static-pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/static-pod-service NodePort 10.99.168.252 <none> 80:30352/TCP 30s
NAME ENDPOINTS AGE
endpoints/static-pod-service 10.32.0.4:80 30s
看起來不錯。
題庫22
Use context: kubectl config use-context k8s-c2-AC
Check how long the kube-apiserver server certificate is valid on cluster2-controlplane1. Do this with openssl or cfssl. Write the exipiration date into /opt/course/22/expiration.
Also run the correct kubeadm command to list the expiration dates and confirm both methods show the same date.
Write the correct kubeadm command that would renew the apiserver server certificate into /opt/course/22/kubeadm-renew-certs.sh.
任務(wù)權(quán)重:2%
使用上下文:kubectl config use-context k8s-c2-AC
檢查 kube-apiserver 服務(wù)器證書在 上的有效期。使用 openssl 或 cfssl。將過期日期寫入 。cluster2-controlplane1/opt/course/22/expiration
還要運(yùn)行正確的命令以列出到期日期,并確認(rèn)兩種方法顯示相同的日期。kubeadm
將續(xù)訂 apiserver 服務(wù)器證書的正確命令寫入 。kubeadm/opt/course/22/kubeadm-renew-certs.sh
題解
答:
首先,讓我們找到該證書:
? ssh cluster2-controlplane1
? root@cluster2-controlplane1:~# find /etc/kubernetes/pki | grep apiserver
/etc/kubernetes/pki/apiserver.crt
/etc/kubernetes/pki/apiserver-etcd-client.crt
/etc/kubernetes/pki/apiserver-etcd-client.key
/etc/kubernetes/pki/apiserver-kubelet-client.crt
/etc/kubernetes/pki/apiserver.key
/etc/kubernetes/pki/apiserver-kubelet-client.key
接下來我們使用openssl找出到期日期:
? root@cluster2-controlplane1:~# openssl x509 -noout -text -in /etc/kubernetes/pki/apiserver.crt | grep Validity -A2
Validity
Not Before: Dec 20 18:05:20 2022 GMT
Not After : Dec 20 18:05:20 2023 GMT
我們有它,所以我們把它寫在主終端上的所需位置:
# /opt/course/22/expiration
Dec 20 18:05:20 2023 GMT
我們也使用 kubeadm 的功能來獲取到期時間:
? root@cluster2-controlplane1:~# kubeadm certs check-expiration | grep apiserver
apiserver Jan 14, 2022 18:49 UTC 363d ca no
apiserver-etcd-client Jan 14, 2022 18:49 UTC 363d etcd-ca no
apiserver-kubelet-client Jan 14, 2022 18:49 UTC 363d ca no
看起來不錯。最后,我們編寫命令,將所有證書續(xù)訂到請求的位置:
# /opt/course/22/kubeadm-renew-certs.sh
kubeadm certs renew apiserver
題庫23
Use context: kubectl config use-context k8s-c2-AC
Node cluster2-node1 has been added to the cluster using kubeadm and TLS bootstrapping.
Find the "Issuer" and "Extended Key Usage" values of the cluster2-node1:
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.
任務(wù)權(quán)重:2%
使用上下文:kubectl config use-context k8s-c2-AC
節(jié)點(diǎn)群集 2-節(jié)點(diǎn) 1 已使用 和 TLS 引導(dǎo)添加到群集中。kubeadm
查找 cluster2-node1 的“頒發(fā)者”和“擴(kuò)展密鑰用法”值:
kubelet 客戶端證書,用于與 kube-apiserver 的傳出連接。
kubelet 服務(wù)器證書,用于從 kube-apiserver 傳入連接的證書。
將信息寫入文件 。/opt/course/23/certificate-info.txt
比較兩個證書的“頒發(fā)者”和“擴(kuò)展密鑰用法”字段并理解這些字段。
題解
答:
要找到正確的 kubelet 證書目錄,我們可以查找 kubelet 參數(shù)的默認(rèn)值 。對于在 Kubernetes 文檔中搜索“kubelet”,這將導(dǎo)致:https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet。我們可以檢查是否已使用 或 在 中配置了另一個證書目錄。--cert-dir``ps aux``/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
首先我們檢查 kubelet 客戶端證書:
? ssh cluster2-node1
? root@cluster2-node1:~# openssl x509 -noout -text -in /var/lib/kubelet/pki/kubelet-client-current.pem | grep Issuer
Issuer: CN = kubernetes
? root@cluster2-node1:~# 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
接下來我們檢查 kubelet 服務(wù)器證書:
? root@cluster2-node1:~# openssl x509 -noout -text -in /var/lib/kubelet/pki/kubelet.crt | grep Issuer
Issuer: CN = cluster2-node1-ca@1588186506
? root@cluster2-node1:~# openssl x509 -noout -text -in /var/lib/kubelet/pki/kubelet.crt | grep "Extended Key Usage" -A1
X509v3 Extended Key Usage:
TLS Web Server Authentication
我們看到服務(wù)器證書是在工作節(jié)點(diǎn)本身上生成的,客戶端證書是由 Kubernetes API 頒發(fā)的?!皵U(kuò)展密鑰用法”還顯示它是用于客戶端還是服務(wù)器身份驗(yàn)證。
更多關(guān)于這個: https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping
題庫24
Use context: kubectl config use-context k8s-c1-H
There 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-backend in Namespace project-snake. It should allow the backend-* Pods only to:
connect to db1-* Pods on port 1111
connect to db2-* Pods on port 2222
Use the app label of Pods in your policy.
After implementation, connections from backend-* Pods to vault-* Pods on port 3333 should for example no longer work.
任務(wù)權(quán)重:9%
使用上下文:kubectl config use-context k8s-c1-H
發(fā)生了一起安全事件,入侵者能夠從單個被黑客入侵的后端 Pod 訪問整個集群。
為了防止這種情況,請創(chuàng)建一個在命名空間中調(diào)用的網(wǎng)絡(luò)策略。它應(yīng)該只允許 Pod 執(zhí)行以下操作:np-backendproject-snakebackend-*
連接到端口 1111 上的 Podsdb1-*
連接到端口 2222 上的 Podsdb2-*
在策略中使用 Pod 標(biāo)簽。app
例如,實(shí)現(xiàn)后,端口 3333 上從 Pod 到 Pod 的連接應(yīng)該不再有效。backend-*vault-*
題解
答:
首先,我們看一下現(xiàn)有的 Pod 及其標(biāo)簽:
? k -n project-snake get pod
NAME READY STATUS RESTARTS AGE
backend-0 1/1 Running 0 8s
db1-0 1/1 Running 0 8s
db2-0 1/1 Running 0 10s
vault-0 1/1 Running 0 10s
? k -n project-snake get pod -L app
NAME READY STATUS RESTARTS AGE APP
backend-0 1/1 Running 0 3m15s backend
db1-0 1/1 Running 0 3m15s db1
db2-0 1/1 Running 0 3m17s db2
vault-0 1/1 Running 0 3m17s vault
我們測試了當(dāng)前的連接情況,發(fā)現(xiàn)沒有任何限制:
? k -n project-snake get pod -o wide
NAME READY STATUS RESTARTS AGE IP ...
backend-0 1/1 Running 0 4m14s 10.44.0.24 ...
db1-0 1/1 Running 0 4m14s 10.44.0.25 ...
db2-0 1/1 Running 0 4m16s 10.44.0.23 ...
vault-0 1/1 Running 0 4m16s 10.44.0.22 ...
? k -n project-snake exec backend-0 -- curl -s 10.44.0.25:1111
database one
? k -n project-snake exec backend-0 -- curl -s 10.44.0.23:2222
database two
? k -n project-snake exec backend-0 -- curl -s 10.44.0.22:3333
vault secret storage
現(xiàn)在我們通過 從 k8s 文檔中復(fù)制和追蹤一個示例來創(chuàng)建 NP:
vim 24_np.yaml
# 24_np.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: np-backend
namespace: project-snake
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Egress # policy is only about Egress
egress:
- # first rule
to: # first condition "to"
- podSelector:
matchLabels:
app: db1
ports: # second condition "port"
- protocol: TCP
port: 1111
- # second rule
to: # first condition "to"
- podSelector:
matchLabels:
app: db2
ports: # second condition "port"
- protocol: TCP
port: 2222
上面的NP有兩個規(guī)則,每個規(guī)則有兩個條件,可以理解為:
allow outgoing traffic if:
(destination pod has label app=db1 AND port is 1111)
OR
(destination pod has label app=db2 AND port is 2222)
錯誤的例子
現(xiàn)在讓我們看一個錯誤的例子:
# WRONG
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: np-backend
namespace: project-snake
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Egress
egress:
- # first rule
to: # first condition "to"
- podSelector: # first "to" possibility
matchLabels:
app: db1
- podSelector: # second "to" possibility
matchLabels:
app: db2
ports: # second condition "ports"
- protocol: TCP # first "ports" possibility
port: 1111
- protocol: TCP # second "ports" possibility
port: 2222
上面的NP有一個規(guī)則,有兩個條件,每個規(guī)則有兩個條件條目,可以讀作:
allow outgoing traffic if:
(destination pod has label app=db1 OR destination pod has label app=db2)
AND
(destination port is 1111 OR destination port is 2222)
使用此 NP,Pod 仍然可以 連接到 端口 1111 上的 Pod,例如應(yīng)該禁止的端口。backend-*``db2-*
創(chuàng)建網(wǎng)絡(luò)策略
我們創(chuàng)建正確的NP:
k -f 24_np.yaml create
并再次測試:
? k -n project-snake exec backend-0 -- curl -s 10.44.0.25:1111
database one
? k -n project-snake exec backend-0 -- curl -s 10.44.0.23:2222
database two
? k -n project-snake exec backend-0 -- curl -s 10.44.0.22:3333
^C
在NP上使用 也有助于了解k8s如何解釋政策。kubectl describe
太好了,看起來更安全。任務(wù)完成。
題庫25
Use context: kubectl config use-context k8s-c3-CCC
Make a backup of etcd running on cluster3-controlplane1 and save it on the controlplane 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.
任務(wù)權(quán)重:8%
使用上下文:kubectl config use-context k8s-c3-CCC
備份在集群 3-控制平面 1 上運(yùn)行的 etcd,并將其保存在控制平面節(jié)點(diǎn)上。/tmp/etcd-backup.db
然后在集群中創(chuàng)建同類 Pod。
最后恢復(fù)備份,確認(rèn)集群仍在工作,并且創(chuàng)建的 Pod 不再與我們在一起。
題解
答:
蝕刻備份
首先,我們登錄控制平面并嘗試創(chuàng)建 etcd 的快照:
? ssh cluster3-controlplane1
? root@cluster3-controlplane1:~# ETCDCTL_API=3 etcdctl snapshot save /tmp/etcd-backup.db
Error: rpc error: code = Unavailable desc = transport is closing
但它失敗了,因?yàn)槲覀冃枰?yàn)證自己。有關(guān)必要的信息,我們可以檢查 etc 清單:
? root@cluster3-controlplane1:~# vim /etc/kubernetes/manifests/etcd.yaml
我們只檢查 必要的信息,我們不會更改它。etcd.yaml
# /etc/kubernetes/manifests/etcd.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component: etcd
tier: control-plane
name: etcd
namespace: kube-system
spec:
containers:
- command:
- etcd
- --advertise-client-urls=https://192.168.100.31:2379
- --cert-file=/etc/kubernetes/pki/etcd/server.crt # use
- --client-cert-auth=true
- --data-dir=/var/lib/etcd
- --initial-advertise-peer-urls=https://192.168.100.31:2380
- --initial-cluster=cluster3-controlplane1=https://192.168.100.31:2380
- --key-file=/etc/kubernetes/pki/etcd/server.key # use
- --listen-client-urls=https://127.0.0.1:2379,https://192.168.100.31:2379 # use
- --listen-metrics-urls=http://127.0.0.1:2381
- --listen-peer-urls=https://192.168.100.31:2380
- --name=cluster3-controlplane1
- --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt
- --peer-client-cert-auth=true
- --peer-key-file=/etc/kubernetes/pki/etcd/peer.key
- --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt # use
- --snapshot-count=10000
- --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
image: k8s.gcr.io/etcd:3.3.15-0
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 8
httpGet:
host: 127.0.0.1
path: /health
port: 2381
scheme: HTTP
initialDelaySeconds: 15
timeoutSeconds: 15
name: etcd
resources: {}
volumeMounts:
- mountPath: /var/lib/etcd
name: etcd-data
- mountPath: /etc/kubernetes/pki/etcd
name: etcd-certs
hostNetwork: true
priorityClassName: system-cluster-critical
volumes:
- hostPath:
path: /etc/kubernetes/pki/etcd
type: DirectoryOrCreate
name: etcd-certs
- hostPath:
path: /var/lib/etcd # important
type: DirectoryOrCreate
name: etcd-data
status: {}
但我們也知道 API 服務(wù)器正在連接到 etcd,因此我們可以檢查其清單是如何配置的:
? root@cluster3-controlplane1:~# cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep etcd
- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
- --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
- --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
- --etcd-servers=https://127.0.0.1:2379
我們使用身份驗(yàn)證信息并將其傳遞給 etcdctl:
? root@cluster3-controlplane1:~# 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
Snapshot saved at /tmp/etcd-backup.db
**注意:**請勿使用 ,因?yàn)樗赡軙目煺瘴募⑹蛊錈o效
snapshot status
蝕刻恢復(fù)
現(xiàn)在在集群中創(chuàng)建一個 Pod 并等待它運(yùn)行:
? root@cluster3-controlplane1:~# kubectl run test --image=nginx
pod/test created
? root@cluster3-controlplane1:~# kubectl get pod -l run=test -w
NAME READY STATUS RESTARTS AGE
test 1/1 Running 0 60s
**注意:**如果您沒有解決問題 18 或 20,并且 cluster3 沒有就緒的工作節(jié)點(diǎn),則創(chuàng)建的 Pod 可能會保持“掛起”狀態(tài)。對于此任務(wù),這仍然可以。
接下來,我們停止所有控制平面組件:
root@cluster3-controlplane1:~# cd /etc/kubernetes/manifests/
root@cluster3-controlplane1:/etc/kubernetes/manifests# mv * ..
root@cluster3-controlplane1:/etc/kubernetes/manifests# watch crictl ps
現(xiàn)在我們將快照還原到特定目錄中:
? root@cluster3-controlplane1:~# 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
2020-09-04 16:50:19.650804 I | mvcc: restore compact to 9935
2020-09-04 16:50:19.659095 I | etcdserver/membership: added member 8e9e05c52164694d [http://localhost:2380] to cluster cdf818194e3a8c32
我們可以指定另一個主機(jī)來使用 進(jìn)行備份,但這里我們只使用默認(rèn)值:。 etcdctl --endpoints http://IP``http://127.0.0.1:2379,http://127.0.0.1:4001
恢復(fù)的文件位于 新文件夾 ,現(xiàn)在我們必須告訴 etcd 使用該目錄:/var/lib/etcd-backup
? root@cluster3-controlplane1:~# vim /etc/kubernetes/etcd.yaml
# /etc/kubernetes/etcd.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component: etcd
tier: control-plane
name: etcd
namespace: kube-system
spec:
...
- mountPath: /etc/kubernetes/pki/etcd
name: etcd-certs
hostNetwork: true
priorityClassName: system-cluster-critical
volumes:
- hostPath:
path: /etc/kubernetes/pki/etcd
type: DirectoryOrCreate
name: etcd-certs
- hostPath:
path: /var/lib/etcd-backup # change
type: DirectoryOrCreate
name: etcd-data
status: {}
現(xiàn)在,我們將所有控制平面 yaml 再次移動到清單目錄中。給它一些時間(最多幾分鐘)讓 etcd 重新啟動并再次訪問 API 服務(wù)器:
root@cluster3-controlplane1:/etc/kubernetes/manifests# mv ../*.yaml .
root@cluster3-controlplane1:/etc/kubernetes/manifests# watch crictl ps
然后我們再次檢查 Pod :
? root@cluster3-controlplane1:~# kubectl get pod -l run=test
No resources found in default namespace.
太棒了,備份和還原在我們的 pod 消失時工作。
@cluster3-controlplane1:~# cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep etcd
- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
- --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
- --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
- --etcd-servers=https://127.0.0.1:2379
我們使用身份驗(yàn)證信息并將其傳遞給 etcdctl:
? root@cluster3-controlplane1:~# 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
Snapshot saved at /tmp/etcd-backup.db
> **注意:**請勿使用 ,因?yàn)樗赡軙目煺瘴募⑹蛊錈o效`snapshot status`
###### 蝕刻恢復(fù)
現(xiàn)在在集群中創(chuàng)建一個 *Pod* 并等待它運(yùn)行:
? root@cluster3-controlplane1:~# kubectl run test --image=nginx
pod/test created
? root@cluster3-controlplane1:~# kubectl get pod -l run=test -w
NAME READY STATUS RESTARTS AGE
test 1/1 Running 0 60s
> **注意:**如果您沒有解決問題 18 或 20,并且 cluster3 沒有就緒的工作節(jié)點(diǎn),則創(chuàng)建的 Pod 可能會保持“掛起”狀態(tài)。對于此任務(wù),這仍然可以。
接下來,我們停止所有控制平面組件:
root@cluster3-controlplane1:~# cd /etc/kubernetes/manifests/
root@cluster3-controlplane1:/etc/kubernetes/manifests# mv * …
root@cluster3-controlplane1:/etc/kubernetes/manifests# watch crictl ps文章來源:http://www.zghlxwxcb.cn/news/detail-426110.html
現(xiàn)在我們將快照還原到特定目錄中:
? root@cluster3-controlplane1:~# 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
2020-09-04 16:50:19.650804 I | mvcc: restore compact to 9935
2020-09-04 16:50:19.659095 I | etcdserver/membership: added member 8e9e05c52164694d [http://localhost:2380] to cluster cdf818194e3a8c32
我們可以指定另一個主機(jī)來使用 進(jìn)行備份,但這里我們只使用默認(rèn)值:。 `etcdctl --endpoints http://IP``http://127.0.0.1:2379,http://127.0.0.1:4001`
恢復(fù)的文件位于 新文件夾 ,現(xiàn)在我們必須告訴 etcd 使用該目錄:`/var/lib/etcd-backup`
? root@cluster3-controlplane1:~# vim /etc/kubernetes/etcd.yaml
/etc/kubernetes/etcd.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
component: etcd
tier: control-plane
name: etcd
namespace: kube-system
spec:
…
- mountPath: /etc/kubernetes/pki/etcd
name: etcd-certs
hostNetwork: true
priorityClassName: system-cluster-critical
volumes:
- hostPath:
path: /etc/kubernetes/pki/etcd
type: DirectoryOrCreate
name: etcd-certs - hostPath:
path: /var/lib/etcd-backup # change
type: DirectoryOrCreate
name: etcd-data
status: {}
現(xiàn)在,我們將所有控制平面 yaml 再次移動到清單目錄中。給它一些時間(最多幾分鐘)讓 etcd 重新啟動并再次訪問 API 服務(wù)器:
root@cluster3-controlplane1:/etc/kubernetes/manifests# mv …/*.yaml .
root@cluster3-controlplane1:/etc/kubernetes/manifests# watch crictl ps
然后我們再次檢查 *Pod* :
? root@cluster3-controlplane1:~# kubectl get pod -l run=test
No resources found in default namespace.文章來源地址http://www.zghlxwxcb.cn/news/detail-426110.html
太棒了,備份和還原在我們的 pod 消失時工作。
到了這里,關(guān)于CKA證書模擬考試24道題的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!