CKA考試相關(guān)說明及經(jīng)驗總結(jié)
什么是CKA考試?
CKA全稱是Certified Kubernetes Administrator,即Kubernetes認(rèn)證管理員,由CNCF官方組織考試并頒發(fā)證書,應(yīng)該來說還是比較權(quán)威的。還有一個是CKAD考試,旨在檢測參加者是否可以在Kubernetes上設(shè)計,構(gòu)建,配置和公開云原生應(yīng)用程序。這邊我們主要說說CKA考試。
CKA證書的含金量如何?
前兩年K8沒現(xiàn)在這么火,加上考試費不便宜,考試又很麻煩(需要連國外服務(wù)器),這個證書拿的人不多,這兩年K8大火,有越來越多的各種xx云和培訓(xùn)機(jī)構(gòu)都在做這個培訓(xùn),應(yīng)該說拿證書的難度是大大降低了(培訓(xùn)費很貴)。當(dāng)然一張證書無法體現(xiàn)一個人的全部能力(其實所有的各種認(rèn)證證書都是一樣的問題),但是有CKA至少說明了你對kubernetes的各種組件、原理、常規(guī)操作、簡單排障是沒有問題了,我覺得是相當(dāng)于一個入門磚吧,對于工作不久并且有志于從事云原生相關(guān)工作的人,還是有積極意義的。而對于企業(yè)來說,如果想招聘K8集群管理員,那看這個證書無疑是最方便的,省去了很多能力考察的精力。
考試難度
考試整體難度不算很高,全部是實操類題目,共24題,沒有選擇題、判斷題,考察的是你對于k8的實際應(yīng)用和操作能力,并不會涉及非常深的底層原理、架構(gòu)設(shè)計思想等。但是題目涉及的范圍比較廣,相對時間會比較緊張,所以要通過這個考試需要你對于k8的整體功能有一個非常全面的認(rèn)識。
考試報名
有個好消息是,今年linux基金會的開源軟件大學(xué)終于落地中國,這樣中國的考生就可以方便的在線下考點考試了,從而避免啃爹的網(wǎng)絡(luò)問題和各種報名、考試環(huán)境、攝像頭的準(zhǔn)備,考官也是中國人,交流非常方便。個人建議如果不是住特別偏遠(yuǎn)的交通不便,參加線下考試是最佳選擇。考試費用是2165元。
線下考點列表:https://training.linuxfoundation.cn/faq#13
報名網(wǎng)址:https://training.linuxfoundation.cn/certificate/details/1
考綱及考試小貼士:https://training.linuxfoundation.cn/faq#15
注意考綱是全英文的,一般以最新的release的k8版本為基礎(chǔ),不過核心的組件和功能最近的版本中變化不大。
考前復(fù)習(xí)
現(xiàn)在有各種培訓(xùn)機(jī)構(gòu)和云計算公司會針對CKA有專門的培訓(xùn)課程,價格很貴(考試+培訓(xùn)一般都要1萬出頭),時間其實也就2到3天左右。個人認(rèn)為除非是你對于k8毫無概念,或者是公司報銷費用,否則沒有必要去參加這些培訓(xùn),根據(jù)官方考綱復(fù)習(xí)+看官方文檔足夠你通過考試了,復(fù)習(xí)的時候搭建一個簡單的k8集群供進(jìn)行實操,minikube,docker自帶的k8,或者像katacoda這樣的線上kubernetes playground都是很好的選擇。考試的時候是可以查看kubernetes的官方文檔網(wǎng)站的,所以對于很多命令、操作不需要死記硬背,只需要知道大致的位置就可以。
目前的考試政策,如果你報名考試沒通過(考到75分通過),還會有一次retake的機(jī)會,還是比較人性化的,所以我相信只要認(rèn)真復(fù)習(xí)通過的問題不會很大。證書有效期為2年,續(xù)不續(xù)看你們公司的實際需求(CNCF也要賺錢啊),我覺得除非K8架構(gòu)發(fā)生了非常大的改動,或者公司對于資格認(rèn)定這塊有要求,否則也沒必要特意去續(xù),能考出來已經(jīng)證明了你的能力了。
真題解析
這里要感謝簡書作者桶裝醬油王,下面的題目主要出自他考試過后的整理,原文在這里http://www.lxweimin.com/p/135c1d618a79
1.列出環(huán)境內(nèi)所有的pv 并以 name字段排序(使用kubectl自帶排序功能)
kubectl get pv --sort-by=.metadata.name
考點:kubectl命令熟悉程度
2.列出指定pod的日志中狀態(tài)為Error的行,并記錄在指定的文件上
kubectl logs <podname> | grep bash > /opt/KUCC000xxx/KUCC000xxx.txt
考點:Monitor, Log, and Debug
3.列出k8s可用的節(jié)點,不包含不可調(diào)度的 和 NoReachable的節(jié)點,并把數(shù)字寫入到文件里
#笨方法,人工數(shù)
kubectl get nodes
#CheatSheet方法,應(yīng)該還能優(yōu)化JSONPATH
JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \
&& kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"
考點:kubectl命令熟悉程度(cheatsheet非常重要,最好能熟練掌握)
4.創(chuàng)建一個pod名稱為nginx,并將其調(diào)度到節(jié)點為 disk=stat上
#我的操作,實際上從文檔復(fù)制更快
kubectl run nginx --image=nginx --restart=Never --dry-run > 4.yaml
#增加對應(yīng)參數(shù)
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的調(diào)度。
5.提供一個pod的yaml,要求添加Init Container,Init Container的作用是創(chuàng)建一個空文件,pod的Containers判斷文件是否存在,不存在則退出
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: apline
image: nginx
command: ['sh', '-c', 'if [ ! -e "/opt/myfile" ];then exit; fi;']
###增加init Container####
initContainers:
- name: init
image: busybox
command: ['sh', '-c', 'touch /目錄/work;']
考點:init Container。一開始審題不仔細(xì),以為要用到livenessProbes
6.指定在命名空間內(nèi)創(chuàng)建一個pod名稱為test,內(nèi)含四個指定的鏡像nginx、redis、memcached、busybox
kubectl run test --image=nginx --image=redis --image=memcached --image=buxybox --restart=Never -n <namespace>
考點:kubectl命令熟悉程度、多個容器的pod的創(chuàng)建
7.創(chuàng)建一個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
8.列出Service名為test下的pod 并找出使用CPU使用率最高的一個,將pod名稱寫入文件中
#使用-o wide 獲取service test的SELECTOR
kubectl get svc test -o wide
##獲取結(jié)果我就隨便造了
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
test ClusterIP None <none> 3306/TCP 50d app=wordpress,tier=mysql
#獲取對應(yīng)SELECTOR的pod使用率,找到最大那個寫入文件中
kubectl top pod -l 'app=wordpress,tier=mysql'
考點:獲取service selector,kubectl top監(jiān)控pod資源
參考:Tools for Monitoring Resources
9.創(chuàng)建一個Pod名稱為nginx-app,鏡像為nginx,并根據(jù)pod創(chuàng)建名為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對應(yīng)
name: nginx-app
type: NodePort
考點:Service
參考:publishing-services-service-types
10.創(chuàng)建一個nginx的Workload,保證其在每個節(jié)點上運行,注意不要覆蓋節(jié)點原有的Tolerations
這道題直接復(fù)制文檔的yaml太長了,由于damonSet的格式和Deployment格式差不多,我用旁門左道的方法 先創(chuàng)建Deploy,再修改,這樣速度會快一點
#先創(chuàng)建一個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
11.將deployment為nginx-app的副本數(shù)從1變成4。
#方法1
kubectl scale --replicas=4 deployment nginx-app
#方法2,使用edit命令將replicas改成4
kubectl edit deploy nginx-app
考點:deployment的Scaling,搜索Scaling
參考:Scaling the application by increasing the replica count
12.創(chuàng)建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
考點:資源的更新
參考:Kubectl Cheat Sheet:Updating Resources
13.根據(jù)已有的一個nginx的pod、創(chuàng)建名為nginx的svc、并使用nslookup查找出service dns記錄,pod的dns記錄并分別寫入到指定的文件中
#創(chuàng)建一個服務(wù)
kubectl create svc nodeport nginx --tcp=80:80
#創(chuàng)建一個指定版本的busybox,用于執(zhí)行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>
考點:網(wǎng)絡(luò)相關(guān),DNS解析
14.創(chuàng)建Secret 名為mysecret,內(nèi)含有password字段,值為bob,然后 在pod1里 使用ENV進(jìn)行調(diào)用,Pod2里使用Volume掛載在/data 下
#將密碼值使用base64加密,記錄在Notepad里
echo -n 'bob' | base64
secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
password: Ym9i
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
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
15.使node1節(jié)點不可調(diào)度,并重新分配該節(jié)點上的pod
#直接drain會出錯,需要添加--ignore-daemonsets --delete-local-data參數(shù)
kubectl drain node node1 --ignore-daemonsets --delete-local-data
考點:節(jié)點調(diào)度、維護(hù)
參考:Safely Drain a Node while Respecting Application SLOs
16.使用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的集群的備份與恢復(fù)
17.給出一個失聯(lián)節(jié)點的集群,排查節(jié)點故障,要保證改動是永久的。
#查看集群狀態(tài)
kubectl get nodes
#查看故障節(jié)點信息
kubectl describe node node1
#Message顯示kubelet無法訪問(記不清了)
#進(jìn)入故障節(jié)點
ssh node1
#查看節(jié)點中的kubelet進(jìn)程
ps -aux | grep kubelete
#沒找到kubelet進(jìn)程,查看kubelet服務(wù)狀態(tài)
systemctl status kubelet.service
#kubelet服務(wù)沒啟動,啟動服務(wù)并觀察
systemctl start kubelet.service
#啟動正常,enable服務(wù)
systemctl enable kubelet.service
#回到考試節(jié)點并查看狀態(tài)
exit
kubectl get nodes #正常
考點:故障排查
18.給出一個集群,排查出集群的故障
這道題沒空做完。kubectl get node顯示connection refuse,估計是apiserver的故障。
考點:故障排查
19.給出一個節(jié)點,完善kubelet配置文件,要求使用systemd配置kubelet
這道題沒空做完,
考點我知道,doc沒找到··在哪 逃~ε=ε=ε=┏(゜ロ゜;)┛
20.給出一個集群,將節(jié)點node1添加到集群中,并使用TLS bootstrapping
這道題沒空做完,花費時間比較長,可惜了。
考點:TLS Bootstrapping
21.創(chuàng)建一個pv,類型是hostPath,位于/data中,大小1G,模式ReadOnlyMany
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadOnlyMany
hostPath:
path: /data
考點:創(chuàng)建PV