Part1 17個題目

eryoung2發表於2024-04-02

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

相關文章