CKA考試經驗總結
1.考前準備
1.1 報考相關
報考地址。https://www.cncf.io/certification/cka
購買了CKA考試,完成后CNFC會給出Exam Preparation Checklist
1、有效期一年。在一年內需要定好考試的時間。
2、提前15分鐘進入考試系統, 提前進入考試系統后并不是立馬開始考試,而是預留給考官時間考察你的考試環境
3、考試時間 ,注意報考的TimeZone。默認是UTC時間,請改成China Time。
4、修改考試時間,考試前24小時且工作日內可更改。
1.1 CKA/CKAD考綱
考綱隔幾個月會更新,考前請留意GitHub上Latest commit 時間,一般變動不大,留意考點分值比重,以及考點中的細項
1.2 考生手冊
這部分基本變動不大,除了分值,考綱同步更新。文檔中幾點需要留意
Candidate Requirements(考試環境要求) :
1、谷歌瀏覽器、穩定的網絡、攝像頭、麥克風;
避坑提示:
重點提一下攝像頭。考試前請充分測試攝像頭,考官會要求你在攝像頭前出示護照,攝像頭要能夠對焦并清晰地拍攝到上面的文字。
實踐證明羅技 C270i不能自動對焦。
2、干凈整潔的桌面。桌面、桌底、鍵盤下上不得放任何東西。
3、攝像頭的線要夠長,允許移動。(筆記本就不用擔心了)
Retake Policy
重考策略,有一次免費重考的機會。一年后過期
Exam Rules and Policies
考試規則,這個熟讀一下,環境要求必須安靜、考生背后不能有玻璃或者強光,考試期間不能大聲朗讀,不能吃、喝。除非要求暫??荚嚕〞和?荚嚥煌V箷r間)、考試期間臉不能離開攝像頭、不允許任何電子設備,不允許在考試系統外記錄任何筆記。等等
Policy on Warnings and Exam Terminations
Exam Misconduct
這兩塊也大致瀏覽一下。避坑,否則考官會無條件終止你的考試。
注意,只允許打開多一個Chrome的 Tab,Tab只允許https://kubernetes.io/docs/和https://kubernetes.io/blog/。使用官方文檔內的搜索功能可能會搜出除上述兩個地址之外的鏈接,要注意甄別!
考生有義務甄別不是上述兩個地址的網址,千萬不要點開!
1.3 考試Tip手冊
主要看兩部分:Technical Instructions 、CKA & CKAD Environment ;這份文檔中,Technical Instructions與考生手冊重復了。主要留意一下Ctrl+W 和 Ctrl+C 、Ctrl+V的替代鍵。以及考試中的k8s環境,要用到
kubectl config use-context <環境名稱>進行替換,題目中會有提醒。
1.4 官方文檔
除了HOME CONTRIBUTE之外,其余欄目都要仔細看過一遍。SETUP CONCEPTS TASKS TUTORIALS REFERENCE里面的與考綱相關的均不能放過,我就因為大意漏了kubectl Cheat Sheet,超簡單的第一題加上考試系統故障,浪費了快10min(涉及GCE等云服務的、集群聯邦除外,不在考點內,可不看),英文文檔難啃,難免有遺漏,建議結合JimmySong的Kubernetes-handbook加深印象。最好使用二進制部署一遍,尤其是kubelet等組件的配置,再回到英文doc定位考點。
2、考中避坑經驗
2.1 與考官交流
? 考試全程與考官在Live Chat上英文交流(文字),考前考官會跟你提示注意事項??简炂綍r英語作文詞匯量的時候到了。國外的考官都很人性化的,考試中有意外狀況,詢問考官,并向考官爭取你應有的權益。舉例一下我遇到的 場景(基本上是大意,英文我就不寫了,渣渣):
1、考試正式開始前,羅技攝像頭無法清晰看到護照,向考官申請使用筆記本電腦攝像頭驗證。驗證完成后請求考官使用回臺式機重新考試(屏幕大有好處)
2、考試過程中,考試系統崩潰,提示,lost connection,詢問考官什么情況,是我電腦的問題還是系統問題。考試的中斷是否會影響我的計時。我能延長多少時間等等。
3、考試中如果有半邊臉不小心離開攝像頭,考官會在Live Chat會彈出窗口提示你,這時候請注意。并向考官表達歉意。
2.2 考試中的技巧
1、審題:
審題一定要仔細再仔細。題目有中文翻譯的版本,但標點符號特別少,斷句可能會出現問題,建議切換成英文版本再看一遍。
2、答題策略
整場考試總計24道題,分值高的題目花費的時間較多,我遇見的是集群故障排查、和TLS Bootstraping,以及節點失聯、一般較為靠后。但不是所有分值高的題目都在最后,(我的最后一題是創建PV,2%)。合理規劃答題策略。
3、網絡問題
根據同行交流經驗所得,CKA考試普遍網絡較慢,表現為考試系統Lost Connection,終端反應較慢、無法進入終端的情況:
Lost Connection:在考試計時器停止后,考官會給你相應的額外時間。
無法進入終端:這種情況使用考試系統上的reflash exam window按鈕。刷新后重新進入終端,此時會退出特權模式,需要重新使用sudo -i 進入。且bash環境需要重新配置。(bash這塊不確定,反正kubectl的自動補全我是執行了好幾次)
終端反應慢:這塊無解,只能重其他技巧節省時間。
不要刷新瀏覽器!不要刷新瀏覽器!不要刷新瀏覽器!刷新瀏覽器會導致考試被終止。
4、節省時間的技巧
考試題目刷出來較慢,建議開考時,將考題列記錄考試系統notepad里面,過一遍(后悔沒這么做)。
-
kubectl bash自動補全的命令一定要用,最好記錄在notepad上。切換環境,關鍵時刻可以復制粘貼到終端內。
source <(kubectl completion bash)
-
考試中的終端是可以復制黏貼的、但是鼠標姿勢要對,多嘗試幾次(我一開始以為復制不了,白敲了很久),無論如何請多使用終端內復制粘貼的功能(Windows下是Ctrl+Insect復制,Shift+Insect)。終端內復制粘貼一個yaml是毫無壓力的,不要被Important Tip和考生手冊給誤導了。
Important Tip和考生手冊里面的Technical Instructions有這么一句話,容易被誤導
- Ctrl+C & and Ctrl+V are not supported in your exam terminal, nor is copy and pasting large amounts of text. To copy and paste limited amounts of text (1?2 lines) please use;
kubectl explain 查定義,太慢了,查個pod.spce.containers.livenessProbe.initialDelaySeconds只能一層層的查,可能是我不熟悉grep + 正則(腦子轉的不夠快)乖乖在doc上找案例Shift+Insert(粘貼)更快
-
善用官方文檔的搜索功能,記住一些考點的關鍵字。有些知識點在CONCEPTS、TASKS、TUTORIALS、REFERENCE 連番出現,不好查找,搜索關鍵字較長時,搜索效率會低下。
比如,查找Pod和Service的解析記錄,搜索組合關鍵字Service DNS效率太低,不如直接搜索nslookup
與考點相關的文檔可以提前加入收藏夾,利用地址欄自動補全功能跳轉到對應的文檔 @Kevin Wang
避免手敲yaml,能不手敲yaml的,就別手敲,盡量從文檔上復制,手敲的效率太低了,碰上終端響應慢,那是時間的殺手?。?/p>
-
盡量使用命令創建Pod、deployment、service
#創建Pod kubectl run <podname> --image=<imagename> --restart=Never -n <namespace> #創建Deployment kubectl run <deploymentname> --image=<imagename> -n <namespace> #暴露Service kubectl expose <deploymentname> --port=<portNo.> --name=<svcname>
-
養成使用--dry-run、kubectl apply -f、kubectl delete -f的習慣,同時將答案和yaml寫入到文件里,方便根據命令模板修改yaml,以及后面檢查答案時重做題目。舉個例子,使用run命令忘記增加namespace了
#初次生成 kubectl run <podname> --image=<imagename> --restart=Never --dry-run -o yaml > <題目名稱>.yaml #應用yaml kubectl apply -f <題目名稱>.yaml #審題錯了,刪除之前做的結果 kubectl delete -f <題目名稱>.yaml #修改命令或修改yaml重新執行kubectl apply -f
見到不懂或忘記的命令參數,甭管什么kubectl,etcdctl的命令,
盤他-h,-h是萬能的。里面有示例最后,考試環境中一定要留意k8s環境和尤其是主機名和用戶名,默認可以使用ssh 進入 node, 進入node做完題目后記得退出,不然節點內是無法ssh到下一個題目的node當中去的,節點內終端一般顯示student@<worknodename>
3、題目與解答
重點來了。由于考試不允許將考題記錄在考試系統外,憑著自己的記憶,加上瀏覽器歷史紀錄,記錄下22題(總共24題),內容有部分差異,考題中的pod之類的鏡像、命名肯定都記不清了,憑空造的,請見諒。
-
列出環境內所有的pv 并以 name字段排序(使用kubectl自帶排序功能)
kubectl get pv --sort-by=.metadata.name
考點:kubectl命令熟悉程度
-
列出指定pod的日志中狀態為Error的行,并記錄在指定的文件上
kubectl logs <podname> | grep ERROR > /opt/KUCC000xxx/KUCC000xxx.txt
考點:Monitor, Log, and Debug
-
列出k8s可用的節點,不包含不可調度的 和 NoReachable的節點,并把數字寫入到文件里
kubectl get nodes | grep Ready | wc -l #CheatSheet方法,應該還能優化JSONPATH JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \ && kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"
考點:kubectl命令熟悉程度
-
創建一個pod名稱為nginx,并將其調度到節點為 disk=stat上
#我的操作,實際上從文檔復制更快 kubectl run nginx --image=nginx --restart=Never --dry-run > 4.yaml #增加對應參數 vi 4.yaml kubectl apply -f 4.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd
考點:pod的調度。
-
提供一個pod的yaml,要求添加Init Container,Init Container的作用是創建一個空文件,pod的Containers判斷文件是否存在,不存在則退出
apiVersion: v1 kind: Pod metadata: name: nginx2 spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent command: ['sh', '-c', ' cat /cache/test.txt && sleep 3600000'] volumeMounts: - mountPath: /cache name: cache-volume initContainers: - name: init-nginx image: busybox:1.28 imagePullPolicy: IfNotPresent command: ['touch', '/cache/test.txt'] volumeMounts: - mountPath: /cache name: cache-volume volumes: - name: cache-volume emptyDir: {}
考點:init Container。一開始審題不仔細,以為要用到livenessProbes
-
指定在命名空間內創建一個pod名稱為test,內含四個指定的鏡像nginx、redis、memcached、busybox
kubectl run test --image=nginx --image=redis --image=memcached --image=buxybox --restart=Never -n <namespace>
考點:kubectl命令熟悉程度、多個容器的pod的創建
-
創建一個pod名稱為test,鏡像為nginx,Volume名稱cache-volume為掛在在/data目錄下,且Volume是non-Persistent的
apiVersion: v1 kind: Pod metadata: name: test spec: containers: - image: nginx name: test-container volumeMounts: - mountPath: /cache name: cache-volume volumes: - name: cache-volume emptyDir: {}
考點:Volume、emptdir
參考:Volumes
-
列出Service名為test下的pod 并找出使用CPU使用率最高的一個,將pod名稱寫入文件中
#使用-o wide 獲取service test的SELECTOR kubectl get svc test -o wide ##獲取結果我就隨便造了 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR test ClusterIP None <none> 3306/TCP 50d app=wordpress,tier=mysql #獲取對應SELECTOR的pod使用率,找到最大那個寫入文件中 kubectl top pod -l 'app=wordpress,tier=mysql' --sort-by='cpu' | awk 'NR==2{print $1}'
考點:獲取service selector,kubectl top監控pod資源
-
創建一個Pod名稱為nginx-app,鏡像為nginx,并根據pod創建名為nginx-app的Service,type為NodePort
kubectl run nginx-app --image=nginx --restart=Never --port=80 kubectl create svc nodeport nginx-app --tcp=80:80 --dry-run -o yaml > 9.yaml #修改yaml,保證selector name=nginx-app vi 9.yaml
apiVersion: v1 kind: Service metadata: creationTimestamp: null labels: app: nginx-app name: nginx-app spec: ports: - name: 80-80 port: 80 protocol: TCP targetPort: 80 selector: #注意要和pod對應 name: nginx-app type: NodePort
考點:Service
-
創建一個nginx的Workload,保證其在每個節點上運行,注意不要覆蓋節點原有的Tolerations
這道題直接復制文檔的yaml太長了,由于damonSet的格式和Deployment格式差不多,我用旁門左道的方法 先創建Deploy,再修改,這樣速度會快一點
#先創建一個deployment的yaml模板 kubectl run nginx --image=nginx --dry-run -o yaml > 10.yaml #將yaml改成DaemonSet vi 10.yaml
#修改apiVersion和kind #apiVersion: extensions/v1beta1 #kind: Deployment apiVersion:apps/v1 kind: DaemonSet metadata: creationTimestamp: null labels: run: nginx name: nginx spec: #去掉replicas # replicas: 1 selector: matchLabels: run: nginx strategy: {} template: metadata: creationTimestamp: null labels: run: nginx spec: containers: - image: nginx name: nginx resources: {} status: {}
考點:DaemonSet
參考:DaemonSet
-
將deployment為nginx-app的副本數從1變成4。
#方法1 kubectl scale --replicas=4 deployment nginx-app #方法2,使用edit命令將replicas改成4 kubectl edit deploy nginx-app
考點:deployment的Scaling,搜索Scaling
-
創建nginx-app的deployment ,使用鏡像為nginx:1.11.0-alpine ,修改鏡像為1.11.3-alpine,并記錄升級,再使用回滾,將鏡像回滾至nginx:1.11.0-alpine
kubectl run nginx-app --image=nginx:1.11.0-alpine kubectl set image deployment nginx-app --image=nginx:1.11.3-alpine kubectl rollout undo deployment nginx-app kubectl rollout status -w deployment nginx-app
考點:資源的更新
-
根據已有的一個nginx的pod、創建名為nginx的svc、并使用nslookup查找出service dns記錄,pod的dns記錄并分別寫入到指定的文件中
#創建一個服務 kubectl create svc nodeport nginx --tcp=80:80 #創建一個指定版本的busybox,用于執行nslookup kubectl create -f https://k8s.io/examples/admin/dns/busybox.yaml #將svc的dns記錄寫入文件中 kubectl exec -ti busybox -- nslookup nginx > 指定文件 #獲取pod的ip地址 kubectl get pod nginx -o yaml #將獲取的pod ip地址使用nslookup查找dns記錄 kubectl exec -ti busybox -- nslookup <Pod ip>
考點:網絡相關,DNS解析
-
創建Secret 名為mysecret,內含有password字段,值為bob,然后 在pod1里 使用ENV進行調用,Pod2里使用Volume掛載在/data 下
#將密碼值使用base64加密,記錄在Notepad里 echo -n 'bob' | base64
14.secret.yaml
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: password: Ym9i
14.pod1.yaml
apiVersion: v1 kind: Pod metadata: name: pod1 spec: containers: - name: mypod image: nginx volumeMounts: - name: mysecret mountPath: "/data" readOnly: true volumes: - name: mysecret secret: secretName: mysecret
14.pod2.yaml
apiVersion: v1 kind: Pod metadata: name: pod2 spec: containers: - name: mycontainer image: redis env: - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password
考點 Secret
參考:Secret
-
使node1節點不可調度,并重新分配該節點上的pod
#直接drain會出錯,需要添加--ignore-daemonsets --delete-local-data參數 kubectl drain node node1 --ignore-daemonsets --delete-local-data
考點:節點調度、維護
參考:[Safely Drain a Node while Respecting Application SLOs]: (https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/)
-
使用etcd 備份功能備份etcd(提供enpoints,ca、cert、key)
ETCDCTL_API=3 etcdctl --endpoints https://127.0.0.1:2379 \ --cacert=ca.pem --cert=cert.pem --key=key.pem \ snapshot save snapshotdb
考點:etcd的集群的備份與恢復
-
給出一個失聯節點的集群,排查節點故障,要保證改動是永久的。
#查看集群狀態 kubectl get nodes #查看故障節點信息 kubectl describe node node1 #Message顯示kubelet無法訪問(記不清了) #進入故障節點 ssh node1 #查看節點中的kubelet進程 ps -aux | grep kubelete #沒找到kubelet進程,查看kubelet服務狀態 systemctl status kubelet.service #kubelet服務沒啟動,啟動服務并觀察 systemctl start kubelet.service #啟動正常,enable服務 systemctl enable kubelet.service #回到考試節點并查看狀態 exit kubectl get nodes #正常
考點:故障排查
-
給出一個集群,排查出集群的故障
這道題沒空做完。kubectl get node顯示connection refuse,估計是apiserver的故障。
考點:故障排查
-
給出一個節點,完善kubelet配置文件,要求使用systemd配置kubelet
這道題沒空做完,
參考: The kubelet drop-in file for systemd
-
給出一個集群,將節點node1添加到集群中,并使用TLS bootstrapping
這道題沒空做完,花費時間比較長,可惜了。
考點:TLS Bootstrapping
- 創建一個pv,類型是hostPath,位于/data中,大小1G,模式ReadOnlyMany
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadOnlyMany
hostPath:
path: /data
考點:創建PV
參考:persistent volumes
最后再次感謝一下華為7天kubernetes管理員實訓課程、對于完全沒有接觸過k8s的同學,難度是高了。但是作為有k8s基礎,備考CKA的同學是非常非常有用的?;旧现v的考點都有了。