Kubernetes基础:Pod的详细介绍
本文的演練環境為基于Virtualbox搭建的Kubernetes集群,具體搭建步驟可以參考kubeadm安裝kubernetes V1.11.1 集群
1. 基本概念
1.1 Pod是什么
Pod是Kubernetes中能夠創建和部署的最小單元,是Kubernetes集群中的一個應用實例,總是部署在同一個節點Node上。Pod中包含了一個或多個容器,還包括了存儲、網絡等各個容器共享的資源。Pod支持多種容器環境,Docker則是最流行的容器環境。
- 單容器Pod,最常見的應用方式。
- 多容器Pod,對于多容器Pod,Kubernetes會保證所有的容器都在同一臺物理主機或虛擬主機中運行。多容器Pod是相對高階的使用方式,除非應用耦合特別嚴重,一般不推薦使用這種方式。一個Pod內的容器共享IP地址和端口范圍,容器之間可以通過 localhost 互相訪問。
Pod并不提供保證正常運行的能力,因為可能遭受Node節點的物理故障、網絡分區等等的影響,整體的高可用是Kubernetes集群通過在集群內調度Node來實現的。通常情況下我們不要直接創建Pod,一般都是通過Controller來進行管理,但是了解Pod對于我們熟悉控制器非常有好處。
1.2 Pod帶來的好處
Pod帶來的好處
- Pod做為一個可以獨立運行的服務單元,簡化了應用部署的難度,以更高的抽象層次為應用部署管提供了極大的方便。
- Pod做為最小的應用實例可以獨立運行,因此可以方便的進行部署、水平擴展和收縮、方便進行調度管理與資源的分配。
- Pod中的容器共享相同的數據和網絡地址空間,Pod之間也進行了統一的資源管理與分配。
1.3 常用Pod管理命令
Pod的配置信息中有幾個重要部分,apiVersion、kind、metadata、spec以及status。其中apiVersion和kind是比較固定的,status是運行時的狀態,所以最重要的就是metadata和spec兩個部分。
先來看一個典型的配置文件,命名為 first-pod.yml
apiVersion: v1 kind: Pod metadata:name: first-podlabels:app: bashtir: backend spec:containers:- name: bash-containerimage: docker.io/busyboxcommand: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']在編寫配置文件時,可以通過API Reference來參考,也可以通過命令查看。
[root@devops-101 ~]# kubectl explain pod KIND: Pod VERSION: v1DESCRIPTION:Pod is a collection of containers that can run on a host. This resource iscreated by clients and scheduled onto hosts.FIELDS:apiVersion <string>APIVersion defines the versioned schema of this representation of anobject. Servers should convert recognized schemas to the latest internalvalue, and may reject unrecognized values. More info:https://git.k8s.io/community/contributors/devel/api-conventions.md#resourceskind <string>Kind is a string value representing the REST resource this objectrepresents. Servers may infer this from the endpoint the client submitsrequests to. Cannot be updated. In CamelCase. More info:https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kindsmetadata <Object>Standard object's metadata. More info:https://git.k8s.io/community/contributors/devel/api-conventions.md#metadataspec <Object>Specification of the desired behavior of the pod. More info:https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-statusstatus <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: v1RESOURCE: 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-statusPodSpec is a description of a pod.FIELDS:activeDeadlineSeconds <integer>Optional duration in seconds the pod may be active on the node relative toStartTime before the system will actively try to mark it failed and killassociated containers. Value must be a positive integer.affinity <Object>If specified, the pod's scheduling constraintsautomountServiceAccountToken <boolean>AutomountServiceAccountToken indicates whether a service account tokenshould be automatically mounted.1.3.1 創建
利用kubectl命令行管理工具,我們可以直接在命令行通過配置文件創建。如果安裝了Dashboard圖形管理界面,還可以通過圖形界面創建Pod。因為最終Pod的創建都是落在命令上的,這里只介紹如何使用kubectl管理工具來創建。
使用配置文件的方式創建Pod。
$ kubectl create -f first-pod.yml1.3.2 查看配置
如果想了解一個正在運行的Pod的配置,可以通過以下命令獲取。
[root@devops-101 ~]# kubectl get pod first-pod -o yaml apiVersion: v1 kind: Pod metadata:creationTimestamp: 2018-08-08T01:45:16Zlabels:app: bashname: first-podnamespace: defaultresourceVersion: "184988"selfLink: /api/v1/namespaces/default/pods/first-poduid: b2d3d2b7-9aac-11e8-84f4-080027b7c4e9 spec:containers:- command:- sh- -c- echo Hello Kubernetes! && sleep 3600image: docker.io/busyboximagePullPolicy: Alwaysname: bash-containerresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilevolumeMounts:- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: default-token-trvqvreadOnly: truednsPolicy: ClusterFirstnodeName: devops-102restartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}serviceAccount: defaultserviceAccountName: defaultterminationGracePeriodSeconds: 30tolerations:- effect: NoExecutekey: node.kubernetes.io/not-readyoperator: ExiststolerationSeconds: 300- effect: NoExecutekey: node.kubernetes.io/unreachableoperator: ExiststolerationSeconds: 300volumes:- name: default-token-trvqvsecret:defaultMode: 420secretName: default-token-trvqv status:conditions:- lastProbeTime: nulllastTransitionTime: 2018-08-08T01:45:16Zstatus: "True"type: Initialized- lastProbeTime: nulllastTransitionTime: 2018-08-08T01:45:16Zmessage: 'containers with unready status: [bash-container]'reason: ContainersNotReadystatus: "False"type: Ready- lastProbeTime: nulllastTransitionTime: nullmessage: 'containers with unready status: [bash-container]'reason: ContainersNotReadystatus: "False"type: ContainersReady- lastProbeTime: nulllastTransitionTime: 2018-08-08T01:45:16Zstatus: "True"type: PodScheduledcontainerStatuses:- image: docker.io/busyboximageID: ""lastState: {}name: bash-containerready: falserestartCount: 0state:waiting:reason: ContainerCreatinghostIP: 192.168.0.102phase: PendingqosClass: BestEffortstartTime: 2018-08-08T01:45:16Z1.3.3 查看日志
可以查看命令行標準輸出的日志。
[root@devops-101 ~]# kubectl logs first-pod Hello Kubernetes!如果Pod中有多個容器,查看特定容器的日志需要指定容器名稱kubectl logs pod-name -c container-name。
1.3.4 標簽管理
標簽是Kubernetes管理Pod的重要依據,我們可以在Pod yaml文件中 metadata 中指定,也可以通過命令行進行管理。
顯示Pod的標簽
[root@devops-101 ~]# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS first-pod 1/1 Running 0 15m app=bash使用 second-pod.yml 我們再創建一個包含兩個標簽的Pod。
[root@devops-101 ~]# kubectl create -f first-pod.yml pod/second-pod created [root@devops-101 ~]# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS first-pod 1/1 Running 0 17m app=bash second-pod 0/1 ContainerCreating 0 20s app=bash,tir=backend根據標簽來查詢Pod。
[root@devops-101 ~]# kubectl get pods -l tir=backend --show-labels NAME READY STATUS RESTARTS AGE LABELS second-pod 1/1 Running 0 1m app=bash,tir=backend增加標簽
[root@devops-101 ~]# kubectl label pod first-pod tir=frontend pod/first-pod labeled [root@devops-101 ~]# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS first-pod 1/1 Running 0 24m app=bash,tir=frontend second-pod 1/1 Running 0 7m app=bash,tir=backend修改標簽
[root@devops-101 ~]# kubectl label pod first-pod tir=unkonwn --overwrite pod/first-pod labeled [root@devops-101 ~]# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS first-pod 1/1 Running 0 25m app=bash,tir=unkonwn second-pod 1/1 Running 0 8m app=bash,tir=backend可以將標簽顯示為列
[root@devops-101 ~]# kubectl get pods -L app,tir NAME READY STATUS RESTARTS AGE APP TIR first-pod 1/1 Running 0 26m bash unkonwn second-pod 1/1 Running 0 9m bash backend標簽是Kubernetes中非常強大的一個功能,Node節點也可以增加標簽,再利用Pod的標簽選擇器,可以將Pod分配到不同類型的Node上。
1.3.5 刪除Pod
[root@devops-101 ~]# kubectl delete pods first-pod pod "first-pod" deleted也可以根據標簽選擇器刪除。
[root@devops-101 ~]# kubectl delete pods -l tir=backend pod "second-pod" deleted1.4 Pod的生命周期
像單獨的容器應用一樣,Pod并不是持久運行的。Pod創建后,Kubernetes為其分配一個UID,并且通過Controller調度到Node中運行,然后Pod一直保持運行狀態直到運行正常結束或者被刪除。在Node發生故障時,Controller負責將其調度到其他的Node中。Kubernetes為Pod定義了幾種狀態,分別如下:
- Pending,Pod已創建,正在等待容器創建。經常是正在下載鏡像,因為這一步驟最耗費時間。
- Running,Pod已經綁定到某個Node并且正在運行。或者可能正在進行意外中斷后的重啟。
- Succeeded,表示Pod中的容器已經正常結束并且不需要重啟。
- Failed,表示Pod中的容器遇到了錯誤而終止。
- Unknown,因為網絡或其他原因,無法獲取Pod的狀態。
2. 如何對Pod進行健康檢查
Kubernetes利用Handler功能,可以對容器的狀況進行探測,有以下三種形式。
- ExecAction:在容器中執行特定的命令。
- TCPSocketAction:檢查容器端口是否可以連接。
- HTTPGetAction:檢查HTTP請求狀態是否正常。
這部分內容展開來也比較多,這部分的內容參考Kubernetes中Pod的健康檢查。
3. Init Containers
Pod中可以包含一到多個Init Container,在其他容器之前開始運行。Init Container 只能是運行到完成狀態,即不能夠一直存在。Init Container必須依次執行。在App Container運行前,所有的Init Container必須全部正常結束。
在Pod啟動過程中,Init Container在網絡和存儲初始化完成后開始按順序啟動。Pod重啟的時候,所有的Init Container都會重新執行。
However, if the Pod restartPolicy is set to Always, the Init Containers use RestartPolicy OnFailure.
3.1 好處
- 運行一些不希望在 App Container 中運行的命令或工具
- 包含一些App Image中沒有的工具或特定代碼
- 應用鏡像構建人員和部署人員可以獨立工作而不需要依賴對方
- 擁有與App Container不同的命名空間
- 因為在App Container運行前必須運行結束,適合做一些前置條件的檢查和配置
3.2 語法
先看一下解釋
[root@devops-101 ~]# kubectl explain pod.spec.initContainers KIND: Pod VERSION: v1RESOURCE: initContainers <[]Object>DESCRIPTION:List of initialization containers belonging to the pod. Init containers areexecuted in order prior to containers being started. If any init containerfails, the pod is considered to have failed and is handled according to itsrestartPolicy. The name for an init container or normal container must beunique among all containers. Init containers may not have Lifecycleactions, Readiness probes, or Liveness probes. The resourceRequirements ofan init container are taken into account during scheduling by finding thehighest request/limit for each resource type, and then using the max of ofthat value or the sum of the normal containers. Limits are applied to initcontainers in a similar fashion. Init containers cannot currently be addedor 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: v1 kind: Pod metadata:name: myapp-podlabels:app: myapp spec:containers:- name: myapp-containerimage: docker.io/busyboxcommand: ['sh', '-c', 'echo The app is running! && sleep 3600']initContainers:- name: init-myserviceimage: docker.io/busyboxcommand: ['sh', '-c', 'echo init-service && sleep 2']- name: init-mydbimage: docker.io/busyboxcommand: ['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和環境變量。通過標簽選擇器來指定Pod。利用這個特性,Pod Template的維護人員就不需要為每個Pod顯示的提供相關的屬性。
具體的工作步驟
- 檢查所有可用的ProdPresets
- 檢查是否有ProdPreset的標簽與即將創建的Pod相匹配
- 將PodPreset中定義的參數與Pod定義合并
- 如果參數合并出錯,則丟棄ProPreset參數,繼續創建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會因為各種各樣的原因發生中斷。
5.1 計劃內中斷
- 刪除部署 Deployment或者其他控制器
- 更新部署模版導致的Pod重啟
- 直接刪除Pod
- 集群的縮容
- 手工移除
5.2 計劃外中斷
- 硬件故障、物理節點宕機
- 集群管理員誤刪VM
- 云供應商故障導致的主機不可用
- Kernel panic
- 集群網絡分區導致節點消失
- 資源耗盡導致的節點剔除
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允許我們創建一個PDB對象,來確保一個RS中運行的Pod不會在一個預算(個數)之下。
Eviction API。
PDB是用來解決集群管理和應用管理職責分離的情況,如果你的單位不存在這種情況,就可以不使用PDB。
參考資料
總結
以上是生活随笔為你收集整理的Kubernetes基础:Pod的详细介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kindeditor项目集成
- 下一篇: 2018.09.28python学习第十