Kubernetes 150 個操作練習 (上)

原文鏈接:Practice Enough With These 150 Questions for the CKAD Exam

看了 Medium 上的一篇文章記錄了 150 個 Kubernetes 的練習,自己練習了一遍,在原文基礎上根據自己的練習過程加了一些補充提示,希望對需要熟悉 K8S 操作的同學有所幫助。

練習之前需要自行搭建好一個 K8S 集羣,可以參考我之前的一篇文章 利用 Kubeadm 搭建 Kubenetes 集羣

一. 核心概念篇

這部分主要的練習目的是:

  • 瞭解 Kubernetes API 的基本操作
  • 創建、查看配置 Pod 的基本操作

1. 查看集羣中的所有命名空間

kubectl get namespaces
kubectl get ns

2. 查看所有命名空間的 Pod

kubectl get po --all-namespaces

3. 查看指定命名空間裏的所有 pod

  • 使用 -n 參數指定命名空間
kubectl get po -n <namespace name>
  • 示例
$ kubectl get po -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-585f5478d8-wq2v2   1/1     Running   0          10d

4. 查看指定命名空間的 Service

$ kubectl get svc -n ingress-nginx
NAME            TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.104.62.77   <none>        80:30372/TCP,443:31465/TCP   19d

5.列出所有的 Pod,基於 json path 表達式只展示 name 和 namseapce

kubectl get pods -o=jsonpath="{.items[*]['metadata.name', 'metadata.namespace']}"

補充

我自己練習時展示內容如下,可讀性不是特別好

# ubuntu @ VM-0-4-ubuntu in ~ [13:37:55]
$ kubectl get pods -o=jsonpath="{.items[*]['metadata.name', 'metadata.namespace']}\n"
example-pv-pod kubia-59d857b444-6z596 kubia-59d857b444-pmm5z kubia-59d857b444-w2r27 kubia-manual my-app-v1-c9b7f9985-xnwkt my-app-v2-77fc8c9499-9nxv2 default default default default default default default\n%

比起用 json-path 的輸出格式,另外一種格式 custom-columns 的輸出效果更好,如下:

NAME                         NAMESPACE
example-pv-pod               default
kubia-59d857b444-6z596       default
kubia-59d857b444-pmm5z       default
kubia-59d857b444-w2r27       default
kubia-manual                 default
my-app-v1-c9b7f9985-xnwkt    default
my-app-v2-77fc8c9499-9nxv2   default

關於 -o 參數輸出選項的設置,可以參考官方文檔 Output options

6. 在 default 命名空間創建並查看運行 Nginx 的 Pod

// 創建 Pod
kubectl run nginx --image=nginx --restart=Never
// 列出 Pod
kubectl get po

7. 使用 yaml 文件創建運行 Nginx 的 Pod


// run 運行一個 Nginx Pod,然後通過 --dry-run=client 參數指定參數 -o 將 Pod 的定義描述寫入文件
kubectl run nginx --image=nginx --restart=Never --dry-run=client -o yaml > nginx-pod.yaml   
  • 注:原文中的參數是 --dry-run,在新的 K8S 版本中已經過時,被 --dry-run=client 替換了。

  • yaml 文件

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}

// 通過 yaml 文件創建 Pod
kubectl create -f nginx-pod.yaml

8. 輸出 Pod 的 yaml 文件描述

kubectl get po nginx -o yaml

補充

和第 5 題有所重複,-o 的輸出選項有下面這些
在這裏插入圖片描述

具體查看官方文檔 Output options

9. 輸出 Pod 的 yaml 文件描述,但不包含 集羣特定信息

kubectl get po nginx -o yaml --export

補充

--export 選項已經被廢棄了,截至 v1.18.0 版本雖然還能用,但未來可能會移除。實際運行會有下面提示:

$ kubectl get po nginx  -o yaml --export
Flag --export has been deprecated, This flag is deprecated and will be removed in future.

10. 獲取 Pod 的詳細信息

kubectl describe pod nginx

11. 刪除剛創建的 Nginx Pod

kubectl delete po nginx

kubectl delete -f nginx-pod.yaml

12. 強制刪除 Pod

$ kubectl delete po nginx --grace-period=0 --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "nginx" force deleted

備註

  • --grace-period 表示刪除 Pod 前可以有幾秒的處理時間,設置爲負數時會被忽略,設置爲 1 說明要立即刪除。只有加上 --force 參數時纔可以設置爲 0,表示立刻強制刪除。

13. 創建 Nginx Pod,並指定 Nginx 的版本和開放端口

kubectl run nginx --image=nginx:1.17.4 --restart=Never --port=80

14. 修改 Pod 的鏡像版本並驗證

# 通過命令的方式修改
$ kubectl set image pod/nginx nginx=nginx:1.15-alpine
pod/nginx image updated

# 
# 通過 edit 方式,會使用 vim 打開 Pod 的yaml 文件,修改後保存,K8S 會基於修改後的文件修改 Pod。

$ kubectl edit po nginx
# 修改保存後提示 edited
pod/nginx edited


# 修改後查看 Pod
$ kubectl describe pod nginx

15. 將 Nginx 的鏡像版本改回 1.17.1

kubectl set image pod/nginx nginx=nginx:1.17.1
kubectl describe po nginx
kubectl get po nginx -w # watch it

16. 不使用 describe 查看 Pod 的容器鏡像版本

$ kubectl get po nginx -o jsonpath='{.spec.containers[].image}{"\n"}'
nginx:1.17.1

17. 創建 Nginx Pod 並執行 shell 命令

// 創建 Pod
$ kubectl run nginx --image=nginx --restart=Never
pod/nginx created


// exec 執行 命令進入 Pod 容器
$ kubectl exec -it nginx /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
# ls # 進入 Pod 容器後查看文件列表
bin  boot  dev	etc  home  lib	lib64  media  mnt  opt	proc  root  run  sbin  srv  sys  tmp  usr  var
#

補充

上面是我實際執行的命令和輸出,可以看到 K8S 提示 kubectl exec [POD] [COMMAND] 已經過時不推薦使用了,現在推薦的使用是下面格式:

kubectl exec [POD] – [COMMAND]

加了 -- 間隔符,表示在 -- 間隔符後執行的都是在容器中執行命令,這樣命令區分起來更清晰一些,示例如下:

$ kubectl exec -it nginx -- /bin/sh
# ls
bin   dev  home  lib64	mnt  proc  run	 srv  tmp  var
boot  etc  lib	 media	opt  root  sbin  sys  usr

18. 查看 Pod 列表,並展示 IP 地址

$ kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE     IP                NODE            NOMINATED NODE   READINESS GATES
example-pv-pod               1/1     Running   0          28h     192.168.171.172   vm-0-2-ubuntu   <none>           <none>
nginx                        1/1     Running   0          8m15s   192.168.171.175   vm-0-2-ubuntu   <none>           <none>

  • 依然是 -o 命令輸出選項的使用

19. 創建運行 busybox 容器的 Pod 並執行 ls 命令,查看其日誌

# 創建 Pod 並執行命令
$ kubectl run busybox --image=busybox --restart=Never -- ls
pod/busybox created


# 查看日誌
$ kubectl logs busybox
bin
dev
etc
home
proc
root
sys
tmp
usr
var

20. 查看 Pod 中上一個容器實例的日誌

kubectl logs busybox -p

21. 創建運行 busybox 容器的 Pod 並執行 命令 sleep 3600

kubectl run busybox --image=busybox --restart=Never -- /bin/sh -c "sleep 3600"

22. 從 busybox 容器的 Pod 訪問 Nginx Pod


# 查看 Nginx Pod 的 IP 地址
$ kubectl get po nginx -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP                NODE            NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          19m   192.168.171.175   vm-0-2-ubuntu   <none>           <none>


# 在 busybox 中執行命令,請求 Nginx Pod
$ kubectl exec -it busybox -- wget -o-  192.168.171.175
Connecting to 192.168.171.175 (192.168.171.175:80)
saving to 'index.html'
index.html           100% |********************************|   612  0:00:00 ETA
'index.html' saved

23. 創建運行 busybox 容器的 Pod 並打印信息 ,然後手動刪除

# 創建 Pod,打印詳細
$ kubectl run busybox --image=busybox --restart=Never -it -- echo "How are you"
How are you

# 手動刪除
$ kubectl delete po busybox
pod "busybox" deleted

24. 創建運行 busybox 容器的 Pod 並打印信息後自動刪除

  • 執行的命令中添加了 --rm 參數
$ kubectl run busybox --image=busybox  --restart=Never -it --rm -- echo "How are you"
How are you
pod "busybox" deleted

25. 基於不同的等級查看 Pod

# 創建容器
kubectl run nginx --image=nginx --restart=Never --port=80

# 通過 --v 指定查看的等級
kubectl get po nginx --v=7
kubectl get po nginx --v=8
kubectl get po nginx --v=9

不同的等級有不同的展示內容,下面是 --v=7 時命令展示的內容。

$ kubectl get po nginx --v=7
I0425 14:48:51.332674    7424 loader.go:375] Config loaded from file:  /home/ubuntu/.kube/config
I0425 14:48:51.353559    7424 round_trippers.go:420] GET https://172.19.0.4:6443/api/v1/namespaces/default/pods/nginx
I0425 14:48:51.353586    7424 round_trippers.go:427] Request Headers:
I0425 14:48:51.354807    7424 round_trippers.go:431]     Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
I0425 14:48:51.354835    7424 round_trippers.go:431]     User-Agent: kubectl/v1.18.0 (linux/amd64) kubernetes/9e99141
I0425 14:48:51.363918    7424 round_trippers.go:446] Response Status: 200 OK in 9 milliseconds
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          2m8s

26.查看 Pod 列表,使用自定義的 POA_NAME 和 POD_STATUS 展示名稱和狀態

kubectl get po -o=custom-columns="POD_NAME:.metadata.name, POD_STATUS:.status.containerStatuses[].state"
  • 還是 -o 輸出選項的使用

27. 查看所有的 Pod,根據名稱排序

kubectl get pods --sort-by=.metadata.name

28. 查看所有的 Pod,根據創建時間排序

kubectl get pods --sort-by=.metadata.creationTimestamp

二. 多容器 Pod 篇

這部分練習的主要目的是:

  • 理解 Pod 的多容器設計模式

29. 創建運行三個 busybox 容器的 Pod 並執行命令

  • yaml 文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: busybox
  name: busybox
spec:
  containers:
  - args:
    - bin/sh
    - -c
    - ls; sleep 3600
    image: busybox
    name: busybox1
    resources: {}
  - args:
    - bin/sh
    - -c
    - echo Hello world; sleep 3600
    image: busybox
    name: busybox2
    resources: {}
  - args:
    - bin/sh
    - -c
    - echo this is third container; sleep 3600
    image: busybox
    name: busybox3
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}

  • 創建 Pod 並查看日誌
# 創建 Pod
kubectl create -f multi-container.yaml

30. 查看上面 Pod 中三個容器的日誌

  • -c 參數指定容器
$ kubectl logs busybox -c busybox1
bin
dev
etc
home
proc
root
sys
tmp
usr
var

$ kubectl logs busybox -c busybox2
Hello world

$ kubectl logs busybox -c busybox3
this is third container

31. 查看 Pod 中 busybox2 先前的容器日誌

kubectl logs busybox -c busybox2 --previous
  • --previous 參數展示的上一個容器實例的日誌,如果我們的 busybox2 容器沒有重建過,那就是第一個實例,這時候是沒法查看日誌的,運行命令會報錯:
$ kubectl logs busybox -c busybox2 --previous
Error from server (BadRequest): previous terminated container "busybox2" in pod "busybox" not found

32. 在 Pod 中的指定容器中運行命令

# 在 busybox Pod 中的 busybox3 容器中執行 ls  命令
kubectl exec busybox -c busybox3 -- ls

33. 查看 Pod 裏容器的指標並存入文件中查看

$ kubectl top pod busybox --containers
POD       NAME       CPU(cores)   MEMORY(bytes)
busybox   busybox2   0m           0Mi
busybox   busybox3   0m           0Mi
busybox   busybox1   0m           0Mi
// putting them into file
kubectl top pod busybox --containers > file.log
cat file.log

補充

  • 【1】 通過 top 命令可以查看 node 和 pod 的 CPU 與內存使用,如下
$ kubectl top nodes
NAME            CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
vm-0-2-ubuntu   126m         6%     2142Mi          58%
vm-0-4-ubuntu   138m         6%     2252Mi          61%

# ubuntu @ VM-0-4-ubuntu in ~ [16:32:47]
$ kubectl top pods
NAME                         CPU(cores)   MEMORY(bytes)
busybox                      0m           1Mi
my-app-v1-c9b7f9985-xnwkt    1m           2Mi
my-app-v2-77fc8c9499-9nxv2   1m           2Mi
nginx

34. 創建一個多容器 Pod

該 Pod 要求如下:

  • 主容器:運行 busybox 容器,不斷寫入文本到 index.html 文件
  • sideCar 容器:運行 Nginx,讀取主容器寫入的文件 index.html,對外提供訪問
  • 兩個容器通過 Volume 實現文件的共享

下面是 Pod 的 yaml 文件,

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: multi-cont-pod
  name: multi-cont-pod
spec:
  volumes:
  - name: var-logs
    emptyDir: {}
  containers:
  - image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo 'Hi I am from Main container' >> /var/log/index.html; sleep 5;done"]
    name: main-container
    resources: {}
    volumeMounts:
    - name: var-logs
      mountPath: /var/log
  - image: nginx
    name: sidecar-container
    resources: {}
    ports:
      - containerPort: 80
    volumeMounts:
    - name: var-logs
      mountPath: /usr/share/nginx/html
  dnsPolicy: ClusterFirst
  restartPolicy: Never
status: {}
  • 創建 Pod
kubectl create -f multi-container.yaml

35. 查看 Pod 中主副容器的文件內容

在上面創建的 Pod 中可以看到,

  • 主容器中將 ‘Hi I am from Main container’ 寫入了 /var/log/index.html;,並掛載到了 var-logs
  • 副容器 Nginx 將目錄 /usr/share/nginx/html 掛載到了 var-logs 卷,以爲着在該目錄下我們可以讀到主容器寫入的 index.html 內容,並且可以通過請求訪問。
# 查看主容器的文件
$ kubectl exec -it  multi-cont-pod -c main-container -- sh
/ # cat /var/log/index.html
Hi I am from Main container

# 查看副容器的內容
$ kubectl exec -it  multi-cont-pod -c sidecar-container -- sh
# cat /usr/share/nginx/html/index.html
Hi I am from Main container
Hi I am from Main container
Hi I am from Main container

# 在副容器中通過請求訪問
# 安裝 curl
# apt-get update && apt-get install -y curl
# 請求訪問
# curl localhost
Hi I am from Main container
Hi I am from Main container
Hi I am from Main container
Hi I am from Main container

以上就是前兩部分的練習,只有 35 個不算多,花兩個小時練習下就熟悉了,下一篇主介紹 Pod 設計的練習。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章