Part1 17個題目
第1題.基於角色的訪問控制-RBAC
第2題.節點維護—指定node節點不可用
第3題.K8s版本升級
第4題.Etcd資料庫備份恢復
第5題.網路策略NetworkPolicy
第6題.四層負載均衡service
第7題.七層負載均衡Ingress
第8題.Deployment管理pod擴縮容
第9題.pod指定節點部署
第10題.檢查Node節點的健康狀態
第11題.一個Pod封裝多個容器
第12題.持久化儲存卷PersistentVolume
第13題.PersistentVolumeClaim
第14題.監控Pod日誌
第15題.Sidecar代理
第16題.監控Pod度量指標
第17題.叢集故障排查——kubelet故障
Part2 準備
vim ~/.bashrc
alias k="kubectl"
export drc="--dry-run=client -oyaml"
export now="--force --grace-period 0"
source ~/.bashrc
Part3 解題
1. RBAC(4分)
中文解釋:
建立一個名為deployment-clusterrole的clusterrole,該clusterrole只允許建立Deployment、Daemonset、Statefulset的create操作
在名字為app-team1的namespace下建立一個名為cicd-token的serviceAccount,並且將上一步建立clusterrole的許可權繫結到該serviceAccount
解法
k create clusterrole deployment-clusterrole --verb=create --resource=deployments,daemonsets,statefulsets
k create serviceaccount cicd-token -n app-team1
k create rolebinding role-account-binding --clusterrole=deployment-clusterrole --serviceaccount=app-tema1:cicd-token -n app-team1
驗證
kubectl auth can-i create deployment --as system:serviceaccount:app-team1:cicd-token -n app-team1 -- yes
kubectl auth can-i create daemonset --as system:serviceaccount:app-team1:cicd-token -n app-team1 -- yes
kubectl auth can-i create statefulset --as system:serviceaccount:app-team1:cicd-token -n app-team1 -- yes
kubectl auth can-i create pod --as system:serviceaccount:app-team1:cicd-token -n app-team1 -- no
參考:
https://kubernetes.io/docs/reference/access-authn-authz/rbac/
https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-service-account/
2. 節點維護(4分)
將ek8s-node-1節點設定為不可用,然後重新排程該節點上的所有Pod
解法
kubectl config use-context ek8s
k cordon ek8s-node-1
k drain ek8s-node-1 --ignore-daesonsets --delete-emptydir-data --force
參考:
https://kubernetes.io/zh/docs/tasks/configure-pod-container/
https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/
https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#drain
3. K8s升級版本(7分)
將master節點升級到v1.29.00,不升級相關元件
kubectl cordon k8s-master01
kubectl drain k8s-master01 --ignore-daemonsets --delete-emptydir-data --force
ssh k8s-master01
sudo -i
apt update -y && apt-cache madison kubeadm
apt-mark unhold kubeadm && \
apt-get update && sudo apt-get install -y kubeadm='1.29.x-*' && \
apt-mark hold kubeadm
kubeadm version
kubeadm upgrade plan --etcd-upgrade=false
kubeadm upgrade apply v1.29.x
apt-mark unhold kubelet kubectl && \
apt-get update && sudo apt-get install -y kubelet='1.29.x-*' kubectl='1.29.x-*' && \
apt-mark hold kubelet kubectl
systemctl daemon-reload
systemctl restart kubelet
exit
exit
kubectl uncordon k8s-master01
4. etcd備份與恢復(7分)
針對etcd例項https://127.0.0.1:2379建立一個快照,儲存到 /srv/data/etcd-snapshot.db。在建立快照的過程中,如果卡住了,就鍵入ctrl+c終止,然後重試。
然後恢復一個已經存在的快照:/var/lib/backup/etcd-snapshot-previous.db
執行etcdctl命令的證書存放在:
ca證書:/opt/KUIN00601/ca.crt
客戶端證書:/opt/KUIN00601/etcd-client.crt
客戶端金鑰:/opt/KUIN00601/etcd-client.key
解法
#備份
ETCDCTL_API=3 etcdctl --endpoints="https://127.0.0.1:2379" --cacert=/opt/KUIN00601/ca.crt --cert=/opt/KUIN00601/etcd-client.crt --key=/opt/KUIN00601/etcd-client.key snapshot save /srv/data/etcd-snapshot.db
#恢復(如果恢復後叢集崩掉,可以跳過)
systemctl stop etcd
mkdir -p /opt/etcd-backup
mv /etc/kubernetes/manifests/kube-* /opt/etcd-backup/
ETCDCTL_API=3 etcdctl --endpoints="https://127.0.0.1:2379" --cacert=/opt/KUIN00601/ca.crt --cert=/opt/KUIN00601/etcd-client.crt --key=/opt/KUIN00601/etcd-client.key snapshot restore /var/lib/backup/etcd-snapshot-previous.db --data-dir=/var/lib/backup/
vim /etc/kubernetes/manifests/etcd.yaml, change volume from /var/lib/etcd/ to /var/lib/backup
chown -R etcd:etcd /var/lib/backup
mv /opt/etcd-backup/ /etc/kubernetes/manifests/
systemctl restart etcd
5. NetworkPolicy(7分)
建立一個名字為allow-port-from-namespace的NetworkPolicy,這個NetworkPolicy允許internal名稱空間下的Pod訪問該名稱空間下的9000埠。
並且不允許不是internal命令空間的下的Pod訪問
不允許訪問沒有監聽9000埠的Pod。
解法:
vim 5.yaml
-----------------
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-port-from-namespace
namespace: internal
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
ports:
- port: 9000
protocol: TCP
-----------------
k apply -f 5.yaml
6. service(7分)
重新配置一個已經存在的deployment front-end,在名字為nginx的容器裡面新增一個埠配置,名字為http,暴露埠號為80/TCP,然後建立一個service,名字為front-end-svc,暴露該deployment的http埠,並且service的型別為NodePort。
解法:
Add config into existing deployment front-end
k edit deployment front-end
spec:
containers:
- name: nginx
image: nginx
# 需要加這四行
ports:
- name: http
containerPort: 80
protocol: TCP
k expose deploy front-end --name=front-end-svc --port=80 --type=NodePort --target-port=http
7. Ingress(7分)
在ing-internal 名稱空間下建立一個ingress,名字為pong,代理的service hi,埠為5678,配置路徑/hi。
驗證:訪問curl -kL <INTERNAL_IP>/hi會返回hi。
解法:
vim 7-ing-class.yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/component: controller
name: nginx-example
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: k8s.io/ingress-nginx
vim 7-ing.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pong
namespace: ing-internal
annotations:
nginx.ingress.kubernetes.io #如果ing沒有internal ip,就新增這一行
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /hi
pathType: Prefix
backend:
service:
name: hi
port:
number: 5678
k apply -f 7-ing.yaml
curl -kL <internal-ip>/hi
8. Deployment縮擴容(4分)
擴容名字為loadbalancer的deployment的副本數為6
解法:
kubectl config use-context k8s
k scale --replicas=6 deployment loadbalancer
9. 指定節點部署(4分)
建立一個Pod,名字為nginx-kusc00401,映象地址是nginx,排程到具有disk=spinning標籤的節點上
解法:
k run nginx-kusc00401 --image=nginx $drc > 9.yaml
vim 9.yaml
vim pod-ns.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-kusc00401
labels:
role: nginx-kusc00401
spec:
nodeSelector: #新增nodeSelector標籤,在spec下面,沒有就打標籤
disk: spinning
containers:
- name: nginx
image: nginx
k apply -f 9.yaml
10. 檢查node節點健康狀態(4分)
檢查叢集中有多少節點為Ready狀態,並且去除包含NoSchedule汙點的節點。之後將數字寫到/opt/KUSC00402/kusc00402.txt
解法:
kubectl config use-context k8s
k get nodes|grep -v "Taint"|grep -v "Noschedule"|wc -l > /opt/KUSC00402/kusc00402.txt
11. 一個pod多個容器(4分)
建立一個Pod,名字為kucc1,這個Pod可能包含1-4容器,該題為四個:nginx+redis+memcached+consul
解法:
k run kucc1 --image=nginx $drc > 11.yaml
然後補全所有容器資訊,最後apply
k apply -f 11.yaml
12. Persistent Volume(4分)
建立一個pv,名字為app-config,大小為2Gi,訪問許可權為ReadWriteMany。Volume的型別為hostPath,路徑為/srv/app-config
解法:
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-config
labels:
type: local
spec:
storageClassName: manual # 需要有這一項嗎?題目沒有要求,(可以不寫)
volumeMode: Filesystem
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/srv/app-config"
k apply -f 12.yaml
參考:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/
https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/
可以ctrl+F 搜003,會直接跳轉到建立pv
https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolume
13. 監控Pod度量指標(5分)
找出具有name=cpu-user的Pod,並過濾出使用CPU最高的Pod,然後把它的名字寫在已經存在的 /opt/KUTR00401/KUTR00401.txt檔案裡(注意他沒有說指定namespace。所以需要使用-A指定所以namespace)
k config use-context k8s
k top pod -A -l name=cpu-user
NAMESPACE NAME CPU(cores) MEMORY(bytes)
kube-system coredns-54d67798b7-hl8xc 7m 8Mi
kube-system coredns-54d67798b7-m4m2q 6m 8Mi
k "coredns-54d67798b7-hl8xc" > /opt/KUTR00401/KUTR00401.txt
14. 監控pod日誌(5分)
監控名為foobar的Pod的日誌,並過濾出具有unable-access-website資訊的行,然後將寫入到 /opt/KUTR00101/foobar
解法
k logs foobar|grep unable-access-website > /opt/KUTR00101/foobar
15. CSI和PVC
建立一個名字為pv-volume的pvc,指定storageClass為csi-hostpath-sc,大小為10Mi
然後建立一個Pod,名字為web-server,映象為nginx,並且掛載該PVC至/usr/share/nginx/html,掛載的許可權為ReadWriteOnce。之後透過 kubectl edit或者 kubectl path將pvc改成70Mi,並且記錄修改記錄。
解法:
vim 15-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv-volume
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 10Mi
storageClassName: csi-hostpath-sc
k apply -f 15-pvc.yaml
vim 15-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pv-volume
spec:
volumes:
- name: pv-volume
persistentVolumeClaim:
claimName: pv-volume
containers:
- name: web-server
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: pv-volume
k apply -f 15-pod.yaml
kubectl edit pvc pv-volume
kubectl edit pvc pv-volume --record
kubectl edit pvc pv-volume --save-config
16. sidecar(7分)
新增一個名為busybox且映象為busybox的sidecar到一個已經存在的名為legacy-app的Pod上,這個sidecar的啟動命令為 /bin/sh, -c, 'tail -n+1 -f /var/log/legacy-app.log'。
並且這個sidecar和原有的映象掛載一個名為logs的volume,掛載的目錄為/var/log/。
k get pod legacy-app -o yaml > c-sidecar.yaml
apiVersion: v1
kind: Pod
metadata:
name: legacy-app
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$(date) INFO $i" >> /var/log/legacy-ap.log;
i=$((i+1));
sleep 1;
done
# 以下為新增部分
volumeMounts:
- name: logs
mountPath: /var/log
- name: busybox
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/legacy-ap.log']
volumeMounts:
- name: logs
mountPath: /var/log
volumes:
- name: logs
emptyDir: {}
k delete -f c-sidecar.yaml
k create -f c-sidecar.yaml
17. kubelet故障(13分)
一個名為wk8s-node-0的節點狀態為NotReady,讓其他恢復至正常狀態,並確認所有的更改開機自動完成
ssh wk8s-node-0
k get nodes
systemctl status kubelet # 然後fix