天天看點

軟體測試 | K8S管理指令

作者:霍格沃茲測試

接下來講解一下 K8S 的标準指令行 kubectl 的使用。 在 K8S 叢集安裝的章節中已經介紹了如何擷取 kubeconfig 檔案并複制到對應的位置。 這裡要注意如果你希望讓某個使用者擁有操作 kubectl 的權限,就 需要将 kubeconfig 檔案拷貝到該使用者的家目錄下。 否則該使用者是無法與 K8S 建立通信的。 講解 kubectl 指令之前需要先介紹一下 K8S 中對于資源的概念。 在 K8S 中一切皆資源, 之前介紹過的 POD 就是一種資源,同樣 job 也是一種資源。

你可以了解為在 K8S 中資源是用來描述容器的行為的, 所有的資源都是在某個次元控制如何運作容器。 比如 POD 描述的是容器之間如何連接配接在一起, config map 是用來将外部的配置檔案挂載到容器中為應用程式提供配置管理的,後面要講解的 Service 是用來 接管容器網絡的,Role,RoleBinding 和 Service account 是用來控制容器的角色和權限的。 一切資源對 象都是為了提供更加強大的容器編排能力而誕生的,是以在 K8S 中一切皆資源--重要的事情需要重 複聲明一遍。 是以對于 kubectl 指令來說它也就有了固定的模式。

kubectl 動作 資源 options           

比如需要檢視目前叢集中所有節點的時候運作的指令如下:

kubectl get node           

在這個指令中get就是動作而node就是資源。那再看另一個指令:

kubectl delete pod jenkins -n test           

這個指令是删除在名稱空間 test 中的一個名字叫 jenkins 的 POD。 你可以看到它依然遵循剛才的指令 模式。 delete 是删除這個動作而 POD 是資源對象,隻不過這裡需要指定額外的 options, 第一個是指 定 POD 的名字來表明到底要删除哪一個 POD。 -n 這個參數表明這個 POD 是屬于哪個名稱空間的, 這裡接觸到了 K8S 的另一個資源--名稱空間(namespace)。 名稱空間是 K8S 的一個邏輯概念,它 并不具備實體,你看不見摸不着,它主要的作用是為其他資源進行分類并友善管理。

可以把名稱空間類 比為檔案夾一樣的東西,而 K8S 中大部分的資源類型都是一個個的檔案,檔案是放置到某個檔案夾下 的。 這樣就擁有了更高次元的管理能力。 比如可以隻檢視某個名稱空間下的 POD。 比如 K8S 中所有 的關鍵服務都是放到 kube-system 這個名稱空間下的,一般這裡面的 POD 直接影響着整個叢集的運作 狀态。 在叢集出現故障的時候經常會去看這個名稱空間下的 POD 是否都運作正常。這個時候使用的命 令就是:

kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-69496d8b75-mpd8h 1/1 Running 0 123m
calico-node-59xrp 1/1 Running 0 123m
coredns-7f89b7bc75-ddrbd 1/1 Running 0 137m
coredns-7f89b7bc75-pkv5w 1/1 Running 0 137m
etcd-k8s.ceshiren.com 1/1 Running 0 137m
kube-apiserver-k8s.ceshiren.com 1/1 Running 0 137m
kube-controller-manager-k8s.ceshiren.com 1/1 Running 0 137m
kube-proxy-swchx 1/1 Running 0 137m
kube-scheduler-k8s.ceshiren.com 1/1 Running 0 137m           

同時名稱空間也可以有更強的控制能力, 比如可以給某個名稱空間添加資源配額, 這又涉及到了 K8S 的資源管理子產品了。 在這裡可以不用深入的了解,隻需要知道可以為某個名稱空間申請特定數量的資源 (CPU, 記憶體,GPU)這樣 K8S 會為這個名稱空間預留相應數量的資源,保證這些資源不會被其他服務 搶占。 同時也可以限制某個名稱空間資源的最大用量, 這樣保證這個名稱空間内的所有服務所使用的資源總量不超過某個值。 一般來說這種資源配額的機制常常用來實作資源的管理和超賣能力。

事實上隻 有特定的一些資源類型是可以不用放到名稱空間内的, 比如 clusterrole,這是叢集級别的角色對象,作 用域更大不限于某個名稱空間,是以不依附于某個名稱空間。而與之對應的 role 就屬于某個名稱空間内 生效的角色。回到當才的指令上, 如果在指令行裡增加一個額外的 options -o wide 你會發現不一樣的 效果。

kubectl get pods -n kube-system -o wide
NAME READY STATUS RESTARTS AGE 
IP NODE NOMINATED NODE READINESS GATES
calico-kube-controllers-69496d8b75-mpd8h 1/1 Running 0 129m 
10.244.178.2 k8s.ceshiren.com <none> <none>
calico-node-59xrp 1/1 Running 0 129m 
172.17.56.102 k8s.ceshiren.com <none> <none>
coredns-7f89b7bc75-ddrbd 1/1 Running 0 143m 
10.244.178.1 k8s.ceshiren.com <none> <none>
coredns-7f89b7bc75-pkv5w 1/1 Running 0 143m 
10.244.178.3 k8s.ceshiren.com <none> <none>
etcd-k8s.ceshiren.com 1/1 Running 0 143m 
172.17.56.102 k8s.ceshiren.com <none> <none>
kube-apiserver-k8s.ceshiren.com 1/1 Running 0 143m 
172.17.56.102 k8s.ceshiren.com <none> <none>
kube-controller-manager-k8s.ceshiren.com 1/1 Running 0 143m 
172.17.56.102 k8s.ceshiren.com <none> <none>
kube-proxy-swchx 1/1 Running 0 143m 
172.17.56.102 k8s.ceshiren.com <none> <none>
kube-scheduler-k8s.ceshiren.com 1/1 Running 0 143m 
172.17.56.102 k8s.ceshiren.com <none> <none>           

可以看到增加了-o wide 後 輸出的資訊變多了。 -o 也是一個常用的 options,代表着 output, 作用是 針對輸出的資訊進行格式化。 可以看到指令依然保持着 kubectl {動作} {資源} {options}這個特定的模 式。是以 K8S 的指令行其實非常容易掌握, 隻要了解了這樣一個模式就可以在不看任何文檔的情況下 完成大部分的日常工作,不論你面對的是哪種資源類型。 幾個常用的動作:

get:查詢某個資源清單。

delete:删除某個資源。

edit:實時編輯某個資源的配置檔案,這個動作非常有用,使用者可以使用它動态編輯一個 POD 的配 置檔案,它會為使用者提供一個 vi 編輯視窗,當你修改并儲存後,k8s 會根據最新的配置更新這個 POD

describe:檢視某個資源對象的詳情。

logs: 檢視某個 POD 中的日志,專門針對 POD,是以指令中可以不帶資源類型。eg. kubectl logs -f {Pod 名稱} -c {容器名稱} 如果不使用-c 則會檢視第一個容器的日志

exec: 讓某個 POD 中的容器執行特定的指令。 一般使用這個指定登入到某個容器中。eg. kubectl exec -it {Pod 名稱} -c {容器名稱} bash t

aint: 給某個 Node 增加或者删除污點。 eg. kubectl taint nodes k8s http://noderole.kubernetes.io/master:NoSchedule

create -f:根據某個配置檔案建立資源對象。 eg. kubectl create -f {檔案路徑}

apply -f: 根據某個配置檔案更新資源對象。 eg. kubectl apply -f {檔案路徑}

delete -f: 根據某個配置檔案删除資源對象。 eg. kubectl delete -f {檔案路徑}

上面列舉的指令基本上可以滿足在工作中 99%的場景了,其他還有類似 label,cp 等等,不過都不太常 用是以我就不詳細介紹了。這裡強調一下 kubectl create/apply/delete -f {檔案路徑} 這個指令。 它不再是操作某個資源對象的而是操作某一組儲存在 yaml 或 json 格式的檔案下的多個資源的。 這也是日常最常用的建立和删除資源的方式,一般習慣把所有的配置都儲存在這樣的一個或多個檔案裡 并對他們進行管理。比如在之前的章節裡提到的定時任務:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
 name: k8scleaner
spec:
 schedule: '0 * */1 * *'
 jobTemplate:
 spec:
 template:
 spec:
 containers:
 - name: k8scleaner
 image: reg.gaofei.com/qa/k8s-cleaner:v2
 imagePullPolicy: Always
 restartPolicy: Never           

把上述配置檔案儲存為一個 yaml 檔案,然後運作 kubectl create -f {檔案路徑} , 這樣就可以立 刻建立出這個 CronJob 了。 而如果修改了這個配置檔案後比如修改了這個定時任務的 cron 表達式,希 望他在别的時間點觸發任務,那麼也隻需要運作 kubectl apply -f {檔案路徑} 即可。 K8S 會為自 動的對比目前資源和更新的請求之間在配置上不同的地方并進行更新。 這是 K8S 聲明式 API 的強大之 處。使用者隻需要在配置檔案中聲明期望的樣子,K8S 會自動讀取并保證使用者期望的運作方式一定會發 生。

接下來再看一下幾個常用的 options,首先就是之前看到過的-o,用來對輸出資訊進行格式化。它 有很多的值但最常用的隻有 3 種,分别是:json|yaml|wide 。 其中 wide 已經看過了它會輸出很多額外 的資訊,包括 POD 的 ip 位址和 POD 排程到了哪一個節點上。 而 json 和 yaml 則會保證你檢視的資 源對象資訊可以用對應格式列印在螢幕上。 比如要檢視某個 POD 的資訊:

kubectl get pod coredns-7f89b7bc75-ddrbd -n kube-system -o yaml           
apiVersion: v1
kind: Pod
metadata:
 annotations:
 cni.projectcalico.org/podIP: 10.244.178.1/32
 cni.projectcalico.org/podIPs: 10.244.178.1/32
 creationTimestamp: '2021-04-05T04:54:33Z'
 generateName: coredns-7f89b7bc75-
 labels:
 k8s-app: kube-dns
 pod-template-hash: 7f89b7bc75
 managedFields:
 - apiVersion: v1
 fieldsType: FieldsV1
 fieldsV1:
 f:metadata:
 f:generateName: {}
 f:labels:
 .: {}
 f:k8s-app: {}
 f:pod-template-hash: {}
 f:ownerReferences:
 .: {}
 k:{"uid":"ee53f769-8115-435a-9ee1-e649d9a93fb1"}:           

通過這樣的指令就把檢視到的資訊以 yaml 格式列印在螢幕上了, 如果需要可以通過 > 符号把内容保 存到标準 yaml 檔案中待後續處理, 實際上一些測試或運維工具就是這麼做的。 另外再介紹一個常用 的 options 就是--all-namespaces。 知道大多數的資源類型都是屬于某個名稱空間的,但是有些時候在操 作對象的時候希望能夠操作整個叢集所有名稱空間下的資源。 這個時候就輪到 --all-namespaces 出場 了。

kubectl get pod --all-namespaces           

最後一個常用的 options 是 -l, 它是一種标簽(label)選擇器。 這裡又涉及到了 K8S 中的标簽管理 了,這是 K8S 中一種主要的排程政策。 通過在特定的資源對象上打上對應的 label,後續可以通過 label 來進行管理和排程。 比如給某個 Node 上打了一個 ssd=true 的标簽,代表着在這個 Node 上存在 SSD 磁盤。 而在建立 POD 的時候可以顯示的使用 nodeSelector 來指定我的 POD 必須排程到打了 ssd 标簽的 Node 上。 這是 K8S 的一種排程政策。在 K8S 中任何對象都可以打上 label,包括 POD。而 其他資源對象就可以通過 label 找到對應的 pod 集合。 比如後面要講的 Service 就是通過指定對應的 label 來覺得都接管哪些 POD 的網絡并做負載均衡政策。同樣的指令行中也可以通過 -l 來指定隻查詢 擁有對應的 label 的資源對象:

kubectl get pods -l app=nginx-web           

搜尋微信公衆号:TestingStudio霍格沃茲的幹貨都很硬核