Kubernetes基礎(chǔ):Pod的詳細介紹

1. 基本概念

1.1 Pod是什么

Pod是Kubernetes中能夠創(chuàng)建和部署的最小單元,是Kubernetes集群中的一個應(yīng)用實例,總是部署在同一個節(jié)點Node上。Pod中包含了一個或多個容器,還包括了存儲、網(wǎng)絡(luò)等各個容器共享的資源。Pod支持多種容器環(huán)境,Docker則是最流行的容器環(huán)境。

單容器Pod,最常見的應(yīng)用方式。

多容器Pod,對于多容器Pod,Kubernetes會保證所有的容器都在同一臺物理主機或虛擬主機中運行。多容器Pod是相對高階的使用方式,除非應(yīng)用耦合特別嚴重,一般不推薦使用這種方式。一個Pod內(nèi)的容器共享IP地址和端口范圍,容器之間可以通過 localhost 互相訪問。

Pod并不提供保證正常運行的能力,因為可能遭受Node節(jié)點的物理故障、網(wǎng)絡(luò)分區(qū)等等的影響,整體的高可用是Kubernetes集群通過在集群內(nèi)調(diào)度Node來實現(xiàn)的。通常情況下我們不要直接創(chuàng)建Pod,一般都是通過Controller來進行管理,但是了解Pod對于我們熟悉控制器非常有好處。

1.2 Pod帶來的好處

Pod帶來的好處

Pod做為一個可以獨立運行的服務(wù)單元,簡化了應(yīng)用部署的難度,以更高的抽象層次為應(yīng)用部署管提供了極大的方便。

Pod做為最小的應(yīng)用實例可以獨立運行,因此可以方便的進行部署、水平擴展和收縮、方便進行調(diào)度管理與資源的分配。

Pod中的容器共享相同的數(shù)據(jù)和網(wǎng)絡(luò)地址空間,Pod之間也進行了統(tǒng)一的資源管理與分配。

1.3 常用Pod管理命令

Pod的配置信息中有幾個重要部分,apiVersion、kind、metadata、spec以及status。其中apiVersion和kind是比較固定的,status是運行時的狀態(tài),所以最重要的就是metadata和spec兩個部分。

先來看一個典型的配置文件,命名為 first-pod.yml

apiVersion:v1kind:Podmetadata:? name:first-pod? labels:? ? app:bash? ? tir:backendspec:? containers:? - name:bash-container? ? image:docker.io/busybox? ? command:['sh','-c','echo Hello Kubernetes! && sleep 3600']

在編寫配置文件時,可以通過API Reference來參考,也可以通過命令查看。

[root@devops-101 ~]# kubectl explain podKIND:? ? PodVERSION:? v1DESCRIPTION:? ? 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/api-conventions.md#resourceskind? ? Kind is a string value representing the REST resource this object? ? represents. Servers may infer this from the endpoint the client submits? ? requests to. Cannot be updated. In CamelCase. More info:? ? https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kindsmetadata? ? Standard object's metadata. More info:

? ? https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata

? spec <Object>

? ? Specification of the desired behavior of the pod. More info:

? ? https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

? status <Object>

? ? Most recently observed status of the pod. This data may not be up to date.

? ? Populated by the system. Read-only. More info:

? ? https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

[root@devops-101 ~]# kubectl explain pod.spec

KIND:? ? Pod

VERSION:? v1

RESOURCE: spec <Object>

DESCRIPTION:

? ? Specification of the desired behavior of the pod. More info:

? ? https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

? ? PodSpec is a description of a pod.

FIELDS:

? activeDeadlineSeconds <integer>

? ? Optional duration in seconds the pod may be active on the node relative to

? ? StartTime before the system will actively try to mark it failed and kill

? ? associated containers. Value must be a positive integer.

? affinity <Object>

? ? If specified, the pod's scheduling constraints? automountServiceAccountToken? ? AutomountServiceAccountToken indicates whether a service account token? ? should be automatically mounted.

1.3.1 創(chuàng)建

利用kubectl命令行管理工具,我們可以直接在命令行通過配置文件創(chuàng)建。如果安裝了Dashboard圖形管理界面,還可以通過圖形界面創(chuàng)建Pod。因為最終Pod的創(chuàng)建都是落在命令上的,這里只介紹如何使用kubectl管理工具來創(chuàng)建。

使用配置文件的方式創(chuàng)建Pod。

$ kubectl create -f first-pod.yml

1.3.2 查看配置

如果想了解一個正在運行的Pod的配置,可以通過以下命令獲取。

[root@devops-101 ~]# kubectl get pod first-pod -o yamlapiVersion: v1kind: Podmetadata:? creationTimestamp: 2018-08-08T01:45:16Z? labels:? ? app: bash? name: first-pod? namespace: default? resourceVersion:"184988"selfLink: /api/v1/namespaces/default/pods/first-pod? uid: b2d3d2b7-9aac-11e8-84f4-080027b7c4e9spec:? containers:? -command:? ? - sh? ? - -c? ? -echoHello Kubernetes! && sleep 3600? ? image: docker.io/busybox? ? imagePullPolicy: Always? ? name: bash-container? ? resources: {}? ? terminationMessagePath: /dev/termination-log? ? terminationMessagePolicy: File? ? volumeMounts:? ? - mountPath: /var/run/secrets/kubernetes.io/serviceaccount? ? ? name: default-token-trvqv? ? ? readOnly:truednsPolicy: ClusterFirst? nodeName: devops-102? 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-trvqv? ? secret:? ? ? defaultMode: 420? ? ? secretName: default-token-trvqvstatus:? conditions:? - lastProbeTime: null? ? lastTransitionTime: 2018-08-08T01:45:16Z? ? status:"True"type: Initialized? - lastProbeTime: null? ? lastTransitionTime: 2018-08-08T01:45:16Z? ? message:'containers with unready status: [bash-container]'reason: ContainersNotReady? ? status:"False"type: Ready? - lastProbeTime: null? ? lastTransitionTime: null? ? message:'containers with unready status: [bash-container]'reason: ContainersNotReady? ? status:"False"type: ContainersReady? - lastProbeTime: null? ? lastTransitionTime: 2018-08-08T01:45:16Z? ? status:"True"type: PodScheduled? containerStatuses:? - image: docker.io/busybox? ? imageID:""lastState: {}? ? name: bash-container? ? ready:falserestartCount: 0? ? state:? ? ? waiting:? ? ? ? reason: ContainerCreating? hostIP: 192.168.0.102? phase: Pending? qosClass: BestEffort? startTime: 2018-08-08T01:45:16Z

1.3.3 查看日志

可以查看命令行標準輸出的日志。

[root@devops-101 ~]# kubectl logs first-podHello Kubernetes!

如果Pod中有多個容器,查看特定容器的日志需要指定容器名稱kubectl logs pod-name -c container-name。

1.3.4 標簽管理

標簽是Kubernetes管理Pod的重要依據(jù),我們可以在Pod yaml文件中 metadata 中指定,也可以通過命令行進行管理。

顯示Pod的標簽

[root@devops-101 ~]# kubectl get pods --show-labelsNAME? ? ? ? READY? ? STATUS? ? RESTARTS? AGE? ? ? LABELSfirst-pod? 1/1? ? ? Running? 0? ? ? ? ? 15m? ? ? app=bash

使用 second-pod.yml 我們再創(chuàng)建一個包含兩個標簽的Pod。

[root@devops-101 ~]# kubectl create -f first-pod.yml pod/second-pod created[root@devops-101 ~]# kubectl get pods --show-labelsNAME? ? ? ? READY? ? STATUS? ? ? ? ? ? ? RESTARTS? AGE? ? ? LABELSfirst-pod? ? 1/1? ? ? Running? ? ? ? ? ? 0? ? ? ? ? 17m? ? ? app=bashsecond-pod? 0/1? ? ? ContainerCreating? 0? ? ? ? ? 20s? ? ? app=bash,tir=backend

根據(jù)標簽來查詢Pod。

[root@devops-101 ~]# kubectl get pods -l tir=backend --show-labelsNAME? ? ? ? READY? ? STATUS? ? RESTARTS? AGE? ? ? LABELSsecond-pod? 1/1? ? ? Running? 0? ? ? ? ? 1m? ? ? ? app=bash,tir=backend

增加標簽

[root@devops-101 ~]# kubectl label pod first-pod tir=frontendpod/first-pod labeled[root@devops-101 ~]# kubectl get pods --show-labelsNAME? ? ? ? READY? ? STATUS? ? RESTARTS? AGE? ? ? LABELSfirst-pod? ? 1/1? ? ? Running? 0? ? ? ? ? 24m? ? ? app=bash,tir=frontendsecond-pod? 1/1? ? ? Running? 0? ? ? ? ? 7m? ? ? ? app=bash,tir=backend

修改標簽

[root@devops-101 ~]# kubectl label pod first-pod tir=unkonwn --overwritepod/first-pod labeled[root@devops-101 ~]# kubectl get pods --show-labelsNAME? ? ? ? READY? ? STATUS? ? RESTARTS? AGE? ? ? LABELSfirst-pod? ? 1/1? ? ? Running? 0? ? ? ? ? 25m? ? ? app=bash,tir=unkonwnsecond-pod? 1/1? ? ? Running? 0? ? ? ? ? 8m? ? ? ? app=bash,tir=backend

可以將標簽顯示為列

[root@devops-101 ~]# kubectl get pods -L app,tirNAME? ? ? ? READY? ? STATUS? ? RESTARTS? AGE? ? ? APP? ? ? TIRfirst-pod? ? 1/1? ? ? Running? 0? ? ? ? ? 26m? ? ? bash? ? ? unkonwnsecond-pod? 1/1? ? ? Running? 0? ? ? ? ? 9m? ? ? ? bash? ? ? backend

標簽是Kubernetes中非常強大的一個功能,Node節(jié)點也可以增加標簽,再利用Pod的標簽選擇器,可以將Pod分配到不同類型的Node上。

1.3.5 刪除Pod

[root@devops-101 ~]# kubectl delete pods first-podpod"first-pod"deleted

也可以根據(jù)標簽選擇器刪除。

[root@devops-101 ~]# kubectl delete pods -l tir=backendpod"second-pod"deleted

1.4 Pod的生命周期

像單獨的容器應(yīng)用一樣,Pod并不是持久運行的。Pod創(chuàng)建后,Kubernetes為其分配一個UID,并且通過Controller調(diào)度到Node中運行,然后Pod一直保持運行狀態(tài)直到運行正常結(jié)束或者被刪除。在Node發(fā)生故障時,Controller負責將其調(diào)度到其他的Node中。Kubernetes為Pod定義了幾種狀態(tài),分別如下:

Pending,Pod已創(chuàng)建,正在等待容器創(chuàng)建。經(jīng)常是正在下載鏡像,因為這一步驟最耗費時間。

Running,Pod已經(jīng)綁定到某個Node并且正在運行?;蛘呖赡苷谶M行意外中斷后的重啟。

Succeeded,表示Pod中的容器已經(jīng)正常結(jié)束并且不需要重啟。

Failed,表示Pod中的容器遇到了錯誤而終止。

Unknown,因為網(wǎng)絡(luò)或其他原因,無法獲取Pod的狀態(tài)。

2. 如何對Pod進行健康檢查

Kubernetes利用Handler功能,可以對容器的狀況進行探測,有以下三種形式。

ExecAction:在容器中執(zhí)行特定的命令。

TCPSocketAction:檢查容器端口是否可以連接。

HTTPGetAction:檢查HTTP請求狀態(tài)是否正常。

這部分內(nèi)容展開來也比較多,這部分的內(nèi)容參考Kubernetes中Pod的健康檢查。

3. Init Containers

Pod中可以包含一到多個Init Container,在其他容器之前開始運行。Init Container 只能是運行到完成狀態(tài),即不能夠一直存在。Init Container必須依次執(zhí)行。在App Container運行前,所有的Init Container必須全部正常結(jié)束。

在Pod啟動過程中,Init Container在網(wǎng)絡(luò)和存儲初始化完成后開始按順序啟動。Pod重啟的時候,所有的Init Container都會重新執(zhí)行。

However, if the Pod restartPolicy is set to Always, the Init Containers use RestartPolicy OnFailure.

3.1 好處

運行一些不希望在 App Container 中運行的命令或工具

包含一些App Image中沒有的工具或特定代碼

應(yīng)用鏡像構(gòu)建人員和部署人員可以獨立工作而不需要依賴對方

擁有與App Container不同的命名空間

因為在App Container運行前必須運行結(jié)束,適合做一些前置條件的檢查和配置

3.2 語法

先看一下解釋

[root@devops-101 ~]# kubectl explain pod.spec.initContainersKIND:? ? PodVERSION:? v1RESOURCE: initContainers <[]Object>DESCRIPTION:? ? List of initialization containers belonging to the pod. Init containers are? ? executedinorder prior to containers being started. If any init container? ? fails, the pod is considered to have failed and is handled according to its? ? restartPolicy. The nameforan init container or normal container must be? ? unique among all containers. Init containers may not have Lifecycle? ? actions, Readiness probes, or Liveness probes. The resourceRequirements of? ? an init container are taken into account during scheduling by finding the? ? highest request/limitforeach resourcetype, andthenusing the max of of? ? that value or the sum of the normal containers. Limits are applied to init? ? containersina similar fashion. Init containers cannot currently be added? ? or removed. Cannot be updated. More info:? ? https://kubernetes.io/docs/concepts/workloads/pods/init-containers/? ? A single application container that you want to run within a pod.

具體語法。

apiVersion:v1kind:Podmetadata:? name:myapp-pod? labels:? ? app:myappspec:? containers:? - name:myapp-container? ? image:docker.io/busybox? ? command:['sh','-c','echo The app is running! && sleep 3600']? initContainers:? - name:init-myservice? ? image:docker.io/busybox? ? command:['sh','-c','echo init-service && sleep 2']? - name:init-mydb? ? image:docker.io/busybox? ? command:['sh','-c','echo init-mydb && sleep 2']

兼容性問題

1.5之前的語法都寫在 annotation 中,1.6 以上的版本使用?.spec.initContainers?字段。建議還是使用 1.6 版本的語法。1.6、1.7的版本還兼容1.5以下的版本,1.8之后就不再兼容老版本了。

4. Pod Preset

利用這個特性,可以在Pod啟動過程中向Pod中注入密碼 Secrets、存儲 Volumes、掛載點 Volume Mounts和環(huán)境變量。通過標簽選擇器來指定Pod。利用這個特性,Pod Template的維護人員就不需要為每個Pod顯示的提供相關(guān)的屬性。

具體的工作步驟

檢查所有可用的ProdPresets

檢查是否有ProdPreset的標簽與即將創(chuàng)建的Pod相匹配

將PodPreset中定義的參數(shù)與Pod定義合并

如果參數(shù)合并出錯,則丟棄ProPreset參數(shù),繼續(xù)創(chuàng)建Pod

為Pod增加注解,表示層被ProdPreset修改過,形式為?podpreset.admission.kubernetes.io/podpreset-<pod-preset name>: "<resource version>"

對于?Env、EnvFrom、VolumeMounts?Kubernetes修改Container Spec,對于Volume修改Pod Spec。

4.1 對個別Pod停用

在Spec中增加注解:

podpreset.admission.kubernetes.io/exclude:"true"

5. 中斷

Pod會因為各種各樣的原因發(fā)生中斷。

5.1 計劃內(nèi)中斷

刪除部署 Deployment或者其他控制器

更新部署模版導(dǎo)致的Pod重啟

直接刪除Pod

集群的縮容

手工移除

5.2 計劃外中斷

硬件故障、物理節(jié)點宕機

集群管理員誤刪VM

云供應(yīng)商故障導(dǎo)致的主機不可用

Kernel panic

集群網(wǎng)絡(luò)分區(qū)導(dǎo)致節(jié)點消失

資源耗盡導(dǎo)致的節(jié)點剔除

5.3 PDB Disruption Budgets

Kubernetes offers features to help run highly available applications at the same time as frequent voluntary disruptions. We call this set of features Disruption Budgets.

Kubernetes允許我們創(chuàng)建一個PDB對象,來確保一個RS中運行的Pod不會在一個預(yù)算(個數(shù))之下。

Eviction API。

PDB是用來解決集群管理和應(yīng)用管理職責分離的情況,如果你的單位不存在這種情況,就可以不使用PDB。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容