Kubernetes對象之Pod

學(xué)習(xí)本節(jié)內(nèi)容之前,希望你已經(jīng)對Kubernetes有了初步的概念。具體請參考這篇文章:

Pod是Kubernetes調(diào)度的最小單元。一個(gè)Pod可以包含一個(gè)或多個(gè)容器,因此它可以被看作是內(nèi)部容器的邏輯宿主機(jī)。Pod的設(shè)計(jì)理念是為了支持多個(gè)容器在一個(gè)Pod中共享網(wǎng)絡(luò)和文件系統(tǒng)。因此處于一個(gè)Pod中的多個(gè)容器共享以下資源:

  • PID命名空間:Pod中不同的應(yīng)用程序可以看到其他應(yīng)用程序的進(jìn)程ID。
  • network命名空間:Pod中多個(gè)容器處于同一個(gè)網(wǎng)絡(luò)命名空間,因此能夠訪問的IP和端口范圍都是相同的。也可以通過localhost相互訪問。
  • IPC命名空間:Pod中的多個(gè)容器共享Inner-process Communication命名空間,因此可以通過SystemV IPC或POSIX進(jìn)行進(jìn)程間通信。
    UTS命名空間:Pod中的多個(gè)容器共享同一個(gè)主機(jī)名。
    Volumes:Pod中各個(gè)容器可以共享在Pod中定義分存儲卷(Volume)。

Pod,容器與Node(工作主機(jī))之間的關(guān)系如下圖所示:


Pod,Container與Node之間的關(guān)系

1. Pod的定義

通過yaml文件或者json描述Pod和其內(nèi)容器的運(yùn)行環(huán)境和期望狀態(tài),例如一個(gè)最簡單的運(yùn)行nginx應(yīng)用的pod,定義如下:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80

在生產(chǎn)環(huán)境中,推薦使用諸如Deployment,StatefulSet,Job或者CronJob等控制器來創(chuàng)建Pod,而不是直接創(chuàng)建。

將上述pod描述文件保存為nginx-pod.yaml,使用kubectl apply命令運(yùn)行pod

kubectl apply -f nginx-pod.yaml

下面簡要分析一下上面的Pod定義文件:

  • apiVersion: 使用哪個(gè)版本的Kubernetes API來創(chuàng)建此對象
  • kind:要?jiǎng)?chuàng)建的對象類型,例如Pod,Deployment等
  • metadata:用于唯一區(qū)分對象的元數(shù)據(jù),包括:name,UID和namespace
  • labels:是一個(gè)個(gè)的key/value對,定義這樣的label到Pod后,其他控制器對象可以通過這樣的label來定位到此Pod,從而對Pod進(jìn)行管理。(參見Deployment等控制器對象)
  • spec: 其它描述信息,包含Pod中運(yùn)行的容器,容器中運(yùn)行的應(yīng)用等等。不同類型的對象擁有不同的spec定義。詳情參見API文檔:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/

Kubernetes在每個(gè)Pod啟動(dòng)時(shí),會自動(dòng)創(chuàng)建一個(gè)鏡像為gcr.io/google_containers/pause:version的容器,所有處于該P(yáng)od中的容器在啟動(dòng)時(shí)都會添加諸如--net=container:pause --ipc=contianer:pause --pid=container:pause的啟動(dòng)參數(shù),因此pause容器成為Pod內(nèi)共享命名空間的基礎(chǔ)。所有容器共享pause容器的IP地址,也被稱為Pod IP。

如果我們希望從外部訪問這nginx應(yīng)用,那么我們還需要?jiǎng)?chuàng)建Service對象來暴露IP和port。具體請參考后面的這篇文章:Kubernetes對象之Service

2. Pod的生命周期

Pod的生命周期是Replication Controller進(jìn)行管理的。一個(gè)Pod的生命周期過程包括:

  • 通過yaml或json對Pod進(jìn)行描述
  • apiserver(運(yùn)行在Master主機(jī))收到創(chuàng)建Pod的請求后,將此Pod對象的定義存儲在etcd中
  • scheduler(運(yùn)行在Master主機(jī))將此Pod分配到Node上運(yùn)行
  • Pod內(nèi)所有容器運(yùn)行結(jié)束后此Pod也結(jié)束

在整個(gè)過程中,Pod通常處于以下的五種階段之一:

  • Pending:Pod定義正確,提交到Master,但其所包含的容器鏡像還未完全創(chuàng)建。通常,Master對Pod進(jìn)行調(diào)度需要一些時(shí)間,Node進(jìn)行容器鏡像的下載也需要一些時(shí)間,啟動(dòng)容器也需要一定時(shí)間。(寫數(shù)據(jù)到etcd,調(diào)度,pull鏡像,啟動(dòng)容器)。
  • Running:Pod已經(jīng)被分配到某個(gè)Node上,并且所有的容器都被創(chuàng)建完畢,至少有一個(gè)容器正在運(yùn)行中,或者有容器正在啟動(dòng)或重啟中。
  • Succeeded:Pod中所有的容器都成功運(yùn)行結(jié)束,并且不會被重啟。這是Pod的一種最終狀態(tài)。
  • Failed:Pod中所有的容器都運(yùn)行結(jié)束了,其中至少有一個(gè)容器是非正常結(jié)束的(exit code不是0)。這也是Pod的一種最終狀態(tài)。
  • Unknown:無法獲得Pod的狀態(tài),通常是由于無法和Pod所在的Node進(jìn)行通信。

2.1 Restart policy

定義Pod時(shí),可以指定restartPolicy字段,表明此Pod中的容器在何種條件下會重啟。restartPolicy擁有三個(gè)候選值:

  • Always:只要退出就重啟
  • OnFailure:失敗退出時(shí)(exit code不為0)才重啟
  • Never:永遠(yuǎn)不重啟

2.2 通過controller管理Pod

Pod本身不具備容錯(cuò)性,這意味著如果Pod運(yùn)行的Node宕機(jī)了,那么該P(yáng)od無法恢復(fù)。因此推薦使用Deployment等控制器來創(chuàng)建Pod并管理。

一般來說,Pod不會自動(dòng)消失,只能手動(dòng)銷毀或者被預(yù)先定義好的controller銷毀。但有一種特殊情況,當(dāng)Pod處于Succeeded或Failed階段,并且超過一定時(shí)間后(由master決定),會觸發(fā)超時(shí)過期從而被銷毀。

總體上來說,Kubernetes中擁有三種類型的controller:

  • Job。通常用于管理一定會結(jié)束的Pod。如果希望Pod被Job controller管理,那么restartPolicy必須指定為OnFailure或Never。
  • ReplicationController,ReplicaSet和Deployment。用于管理永遠(yuǎn)處于運(yùn)行狀態(tài)的Pod。如果希望Pod被此類controller管理,那么restartPolicy必須指定為Always。
  • DaemonSet。它能夠保證你的Pod在每一臺Node都運(yùn)行一個(gè)副本。

參考文章

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

相關(guān)閱讀更多精彩內(nèi)容

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