1. 程式人生 > >Kubernetes學習筆記(二):Pod、標籤、註解

Kubernetes學習筆記(二):Pod、標籤、註解

## pod與容器 一個pod是一組緊密相關的容器,它們總是一起執行在同一個節點上,以及同一個LInux名稱空間中。 每個pod擁有自己的ip,包含若干個容器。pod分佈在不同的節點上。 ### 為什麼需要pod 為什麼需要pod,而不是直接使用容器: 因為容器被設計為只執行一個程序,由於不能夠將多個程序聚集在一個單獨的容器中,就需要另一種結構將容器繫結在一起,並將它們作為一個單元管理,這就是pod的根本原理。 ### pod中容器的隔離共享 在同一個pod中,多個容器有些資源是共享的,有些是隔離的。 同一個pod中的所有容器都執行在相同的network、UTS、IPC空間下。所以它們共享網路介面、主機名,可以通過IPC互相通訊。 同一個pod中的所有容器的檔案系統是隔離的。 ### 何時在pod中使用多個容器 - 它們是否是一個整體? - 它們是否需要在一起執行? - 它們是否要一起擴縮容? ## 執行pod pod和其他Kubernetes資源通常都是通過向Kubernetes REST API提供JSON或者YAML檔案來建立的。 我們使用nginx映象建立一個pod。 ### nginx.yaml ``` apiVersion: v1 # API版本 kind: Pod # 資源型別 metadata: name: nginx # pod的名稱 spec: containers: - image: nginx # 建立容器所用的映象地址 name: nginx # 容器名稱 ports: - containerPort: 80 # 應用監聽的埠 protocol: TCP ``` 這裡只給出了一個簡單的描述檔案,大部分欄位沒有給出。 ### kubectl explain kubectl explain相當於一個文件,可以檢視每個API物件支援哪些欄位。 ``` -> [[email protected]] [~] k explain pod KIND: Pod VERSION: v1 DESCRIPTION: Pod is a collection of containers that can run on a host. This resource is created by clients and scheduled onto hosts. FIELDS: apiVersion APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources kind Kind is a string value representing the REST resource this object ................. ``` ### kubectl create 使用`kubectl create`建立pod ``` -> [[email protected]] [~] k create -f nginx.yaml pod/nginx created ``` ### kubectl get 使用`kubectl get`檢視,指定`-o wide`檢視更多欄位 ``` -> [[email protected]] [~] k get pods NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 11s -> [[email protected]] [~] k get -o wide pods NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 22s 10.244.2.6 kube2.vm ``` ### 完整定義 使用`kubectl get -o yaml`或者`kubectl get -o json`檢視pod的完整定義。這個定義包含以下三大部分: - metadata:包括名稱、名稱空間、標籤和關於該pod的其他資訊 - spec:包含pod內容的實際說明,如容器、卷等 - status:包含執行中pod的當前資訊,如pod IP、宿主機IP、每個容器的描述和狀態 ``` -> [[email protected]] [~] k get -o yaml pod/nginx apiVersion: v1 kind: Pod metadata: creationTimestamp: "2020-05-20T00:32:43Z" name: nginx namespace: default resourceVersion: "109529" selfLink: /api/v1/namespaces/default/pods/nginx uid: a2b83142-9f17-4cfe-a9ac-04f57de82053 spec: containers: - image: nginx imagePullPolicy: Always name: nginx ports: - containerPort: 80 protocol: TCP resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: default-token-vlqvz readOnly: true dnsPolicy: ClusterFirst enableServiceLinks: true nodeName: kube2.vm priority: 0 restartPolicy: Always schedulerName: default-scheduler securityContext: {} serviceAccount: default serviceAccountName: default terminationGracePeriodSeconds: 30 tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 300 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 300 volumes: - name: default-token-vlqvz secret: defaultMode: 420 secretName: default-token-vlqvz status: conditions: - lastProbeTime: null lastTransitionTime: "2020-05-20T02:46:50Z" status: "True" type: Initialized - lastProbeTime: null lastTransitionTime: "2020-05-20T02:46:57Z" status: "True" type: Ready - lastProbeTime: null lastTransitionTime: "2020-05-20T02:46:57Z" status: "True" type: ContainersReady - lastProbeTime: null lastTransitionTime: "2020-05-20T00:32:43Z" status: "True" type: PodScheduled containerStatuses: - containerID: docker://b63c67379def88a5253e8da543655552185f14e6eb962926d65ec74c5a7ab6f7 image: nginx:latest imageID: docker-pullable://nginx@sha256:30dfa439718a17baafefadf16c5e7c9d0a1cde97b4fd84f63b69e13513be7097 lastState: {} name: nginx ready: true restartCount: 0 started: true state: running: startedAt: "2020-05-20T02:46:57Z" hostIP: 192.168.199.212 phase: Running podIP: 10.244.2.6 podIPs: - ip: 10.244.2.6 qosClass: BestEffort startTime: "2020-05-20T02:46:50Z" ``` ### kubectl logs kubectl logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER] [options] 使用`kubectl logs`可以檢視pod中的日誌。如果pod中有多個容器,可以使用`-c `指定容器。比如: ``` -> [[email protected]] [~] k logs nginx -c nginx -f ``` ### kubectl port-forward kubectl port-forward TYPE/NAME [options] [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N] pod已經運行了,那如何向叢集中的pod發出請求呢。我們通過`kubectl port-forward`命令,將本地埠對映到指定pod的埠上。 - 視窗1:執行kubectl port-forward ``` -> [[email protected]] [~] k port-forward nginx 8000:80 Forwarding from 127.0.0.1:8000 -> 80 Forwarding from [::1]:8000 -> 80 Handling connection for 8000 # curl請求發出後出現 ``` - 視窗2:執行kubectl logs ``` -> [[email protected]] [~] k logs nginx -f 127.0.0.1 - - [20/May/2020:03:19:50 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-" # curl請求發出後出現 ``` - 視窗3:curl發出請求 ``` -> [[email protected]] [~] curl http://localhost:8000 Welcome to nginx!
........ ``` ## 標籤 通俗的講,標籤就是用於將Pod和其他Kubernetes資源進行分類,每個資源都可以有多個標籤 標籤是可以附加到資源上的鍵值對,用以選擇具有該標籤的資源(通過標籤選擇器完成)。 ### nginx-labels.yaml 建立一個帶有標籤的描述檔案 ``` -> [[email protected]] [~] cat nginx-labels.yaml apiVersion: v1 kind: Pod metadata: name: nginx-labels labels: # 添加了兩個標籤 env: prod app: order spec: containers: - image: nginx name: nginx ports: - containerPort: 80 protocol: TCP ``` ### 檢視標籤 使用`--show-labels`檢視標籤,po是pod的簡寫 ``` ->
[[email protected]] [~] k create -f nginx-labels.yaml pod/nginx-labels created -> [[email protected]] [~] k get po --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-labels 0/1 ContainerCreating 0 3s app=order,env=prod ``` 使用`-L`檢視指定標籤,並且單獨成列。 ``` -> [[email protected]] [~] k get po -L app,env NAME READY STATUS RESTARTS AGE APP ENV nginx-labels 1/1 Running 0 4m13s order prod ``` ### kubectl label 多個標籤以空格分隔 #### 新增 ``` ->
[[email protected]] [~] k label po nginx-labels test=123 pod/nginx-labels labeled -> [[email protected]] [~] k get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-labels 1/1 Running 0 6m23s app=order,env=prod,test=123 ``` #### 修改 修改已存在的標籤,需要指定`--overwrite`選項 ``` -> [[email protected]] [~] k label po nginx-labels test=456 --overwrite pod/nginx-labels labeled -> [[email protected]] [~] k get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-labels 1/1 Running 0 7m24s app=order,env=prod,test=456 ``` #### 刪除 ``` -> [[email protected]] [~] k label po nginx-labels test- pod/nginx-labels labeled -> [[email protected]] [~] k get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-labels 1/1 Running 0 8m8s app=order,env=prod ``` ## 標籤選擇器 標籤選擇器可以使我們獲取具有特定標籤的pod子集。規則通過`-l`選項指定,多個用逗號分隔。 ### 選擇規則 - key:選擇存在標籤key的 - !key:選擇不存在標籤key的 - key=value:key存在並且值等於value - key!= value:選擇"key=value"的補集。也就存在key並且不等value的,或者不存在key的。 - key in (value1,value2):key存在且值為value1或者value2 - key notin (value1,value2):key存在且值不為value1和value2 ### 實操 準備幾個不同label的pod: ``` -> [[email protected]] [~] k get po --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-labels 1/1 Running 0 40m app=order,env=prod nginx-labels-1 1/1 Running 0 9m42s env=debug nginx-labels-2 1/1 Running 0 8m8s app=user,env=dev ``` app ``` -> [[email protected]] [~] k get po --show-labels -l app NAME READY STATUS RESTARTS AGE LABELS nginx-labels 1/1 Running 0 50m app=order,env=prod nginx-labels-2 1/1 Running 0 18m app=user,env=dev ``` !app ``` -> [[email protected]] [~] k get po --show-labels -l '!app' NAME READY STATUS RESTARTS AGE LABELS nginx-labels-1 1/1 Running 0 20m env=debug ``` app=order ``` -> [[email protected]] [~] k get po --show-labels -l app=order NAME READY STATUS RESTARTS AGE LABELS nginx-labels 1/1 Running 0 77m app=order,env=prod ``` app!=order ``` -> [[email protected]] [~] k get po --show-labels -l app!=order NAME READY STATUS RESTARTS AGE LABELS nginx-labels-1 1/1 Running 0 46m env=debug nginx-labels-2 1/1 Running 0 45m app=user,env=dev ``` env in (dev,prod) ``` -> [[email protected]] [~] k get po --show-labels -l 'env in (dev,prod)' NAME READY STATUS RESTARTS AGE LABELS nginx-labels 1/1 Running 0 78m app=order,env=prod nginx-labels-2 1/1 Running 0 46m app=user,env=dev ``` env notin (prod) ``` -> [[email protected]] [~] k get po --show-labels -l 'env notin (prod)' NAME READY STATUS RESTARTS AGE LABELS nginx-labels-1 1/1 Running 0 48m env=debug nginx-labels-2 1/1 Running 0 46m app=user,env=dev ``` ## 使用標籤選擇器約束pod排程 其核心思想是,為工作節點(node)打上標籤,比如地區、機房、CPU密集、IO密集等。然後在建立pod的描述檔案時指定對應標籤,排程器就會將pod排程到符合標籤選擇器規則的工作節點上。 現在假設一個場景:需要將新建的pod排程到IO密集的工作節點上。 ### 給node打標籤 ``` -> [[email protected]] [~] k label node kube1.vm io=true node/kube1.vm labeled -> [[email protected]] [~] k get node -L io NAME STATUS ROLES AGE VERSION IO kube0.vm Ready master 19h v1.17.3 kube1.vm Ready 19h v1.17.3 true kube2.vm Ready 19h v1.17.3 ``` ### nginx-io.yaml 帶有選擇器的yaml ``` apiVersion: v1 kind: Pod metadata: name: nginx-io spec: nodeSelector: # 選擇器 io: "true" containers: - image: nginx name: nginx ``` 建立pod,檢視結果確實是執行在kube1.vm上。 ``` -> [[email protected]] [~] k create -f nginx-io.yaml pod/nginx-io created -> [[email protected]] [~] k get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-io 1/1 Running 0 42s 10.244.1.7 kube1.vm ``` ## 註解 註解也是鍵值對,與標籤類似,但註解並不用於標識和選擇物件。 註解主要為Pod和其他API物件新增說明,以便每個使用叢集的人可以快速查詢與物件有關的資訊。 ### kubectl annotate 使用`kubectl annotate`為pod添加註解,同樣修改已存在的註解需要指定`--overwrite` ``` -> [[email protected]] [~] k annotate po nginx-io my.com/someannotation="123" pod/nginx-io annotated ``` 檢視 ``` -> [[email protected]] [~] k describe po nginx-io .......... Annotations: my.com/someannotation: 123 .......... ``` ## 名稱空間 簡單講,名稱空間為Pod等資源提供了作用域,在不同名稱空間內的資源名稱可以相同。 我們之前一致使用的是預設名稱空間:`default`,之前的 nginx-xxx 這些pod都位於這個名稱空間。 ### 檢視名稱空間 ``` -> [[email protected]] [~] k get ns #ns是namespace縮寫 NAME STATUS AGE default Active 21h kube-node-lease Active 21h kube-public Active 21h kube-system Active 21h ``` ### kubectl create namespace 使用`kubectl create`建立一個namespace,當然也可以寫一個描述檔案建立(麻煩了點)。 ``` -> [[email protected]] [~] k create ns test namespace/test created -> [[email protected]] [~] k get ns -o wide NAME STATUS AGE ........ test Active 94s ``` ### 為資源指定名稱空間 可以在描述檔案的`metadata`下新增一個欄位`namespace: test`,或者在命令列的時候指定`kubectl create -f xxx.yaml -n test`。 ### 名稱空間的誤解 首先要明確的是:**名稱空間並不提供對正在執行的物件的任何隔離**。 舉個例子:兩個pod並不會因為在不同的名稱空間而無法進行網路通訊,是否可以通訊不取決於名稱空間,而取決於網路解決方案。 ## kubectl delete ### 按名字刪除pod ``` k delete po nginx-io ``` ### 使用標籤選擇器刪除 ``` k delete po -l app ``` ### 刪除所有pod ``` k delete po --all ``` ### 刪除名稱空間 ``` k delete ns test ``` ### 刪除名稱空間(幾乎)所有資源 第一個 all 表示當前名稱空間所有資源型別,第二個 --all 表示所有資源例項。 ``` k delete all --all ``` ## 小結 - 如何決定多個容器是否應該放在一個pod - 通過提交描述檔案建立API物件 - 使用標籤組織API物件 - 通過標籤選擇器排程pod - 名稱空間使不同團隊很方便的使用同一個叢集 - 一些命令:create、get、delete、label、annotate、port-forward、describe、logs