學(xué)習(xí)本節(jié)內(nèi)容之前,希望你已經(jīng)對(duì)Kubernetes有了初步的概念铭污。具體請(qǐng)參考這篇文章:
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ò)命名空間疹启,因此能夠訪問(wèn)的IP和端口范圍都是相同的。也可以通過(guò)localhost相互訪問(wèn)蔼卡。
- IPC命名空間:Pod中的多個(gè)容器共享Inner-process Communication命名空間喊崖,因此可以通過(guò)SystemV IPC或POSIX進(jìn)行進(jìn)程間通信。
UTS命名空間:Pod中的多個(gè)容器共享同一個(gè)主機(jī)名雇逞。
Volumes:Pod中各個(gè)容器可以共享在Pod中定義分存儲(chǔ)卷(Volume)荤懂。
Pod,容器與Node(工作主機(jī))之間的關(guān)系如下圖所示:
1. Pod的定義
通過(guò)yaml文件或者json描述Pod和其內(nèi)容器的運(yùn)行環(huán)境和期望狀態(tài)节仿,例如一個(gè)最簡(jiǎn)單的運(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等控制器來(lái)創(chuàng)建Pod,而不是直接創(chuàng)建箭启。
將上述pod描述文件保存為nginx-pod.yaml壕翩,使用kubectl apply命令運(yùn)行pod
kubectl apply -f nginx-pod.yaml
下面簡(jiǎn)要分析一下上面的Pod定義文件:
- apiVersion: 使用哪個(gè)版本的Kubernetes API來(lái)創(chuàng)建此對(duì)象
- kind:要?jiǎng)?chuàng)建的對(duì)象類(lèi)型,例如Pod册烈,Deployment等
- metadata:用于唯一區(qū)分對(duì)象的元數(shù)據(jù)戈泼,包括:name,UID和namespace
- labels:是一個(gè)個(gè)的key/value對(duì)赏僧,定義這樣的label到Pod后大猛,其他控制器對(duì)象可以通過(guò)這樣的label來(lái)定位到此Pod,從而對(duì)Pod進(jìn)行管理淀零。(參見(jiàn)Deployment等控制器對(duì)象)
- spec: 其它描述信息挽绩,包含Pod中運(yùn)行的容器,容器中運(yùn)行的應(yīng)用等等驾中。不同類(lèi)型的對(duì)象擁有不同的spec定義唉堪。詳情參見(jiàn)API文檔:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/
Kubernetes在每個(gè)Pod啟動(dòng)時(shí),會(huì)自動(dòng)創(chuàng)建一個(gè)鏡像為gcr.io/google_containers/pause:version的容器肩民,所有處于該P(yáng)od中的容器在啟動(dòng)時(shí)都會(huì)添加諸如
--net=container:pause --ipc=contianer:pause --pid=container:pause
的啟動(dòng)參數(shù)唠亚,因此pause容器成為Pod內(nèi)共享命名空間的基礎(chǔ)。所有容器共享pause容器的IP地址持痰,也被稱(chēng)為Pod IP灶搜。
如果我們希望從外部訪問(wèn)這nginx應(yīng)用,那么我們還需要?jiǎng)?chuàng)建Service對(duì)象來(lái)暴露IP和port工窍。具體請(qǐng)參考后面的這篇文章:Kubernetes對(duì)象之Service
2. Pod的生命周期
Pod的生命周期是Replication Controller進(jìn)行管理的割卖。一個(gè)Pod的生命周期過(guò)程包括:
- 通過(guò)yaml或json對(duì)Pod進(jìn)行描述
- apiserver(運(yùn)行在Master主機(jī))收到創(chuàng)建Pod的請(qǐng)求后,將此Pod對(duì)象的定義存儲(chǔ)在etcd中
- scheduler(運(yùn)行在Master主機(jī))將此Pod分配到Node上運(yùn)行
- Pod內(nèi)所有容器運(yùn)行結(jié)束后此Pod也結(jié)束
在整個(gè)過(guò)程中患雏,Pod通常處于以下的五種階段之一:
- Pending:Pod定義正確鹏溯,提交到Master,但其所包含的容器鏡像還未完全創(chuàng)建淹仑。通常丙挽,Master對(duì)Pod進(jìn)行調(diào)度需要一些時(shí)間,Node進(jìn)行容器鏡像的下載也需要一些時(shí)間匀借,啟動(dòng)容器也需要一定時(shí)間取试。(寫(xiě)數(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é)束萨赁,并且不會(huì)被重啟。這是Pod的一種最終狀態(tài)兆龙。
- Failed:Pod中所有的容器都運(yùn)行結(jié)束了杖爽,其中至少有一個(gè)容器是非正常結(jié)束的(exit code不是0)。這也是Pod的一種最終狀態(tài)紫皇。
- Unknown:無(wú)法獲得Pod的狀態(tài)慰安,通常是由于無(wú)法和Pod所在的Node進(jìn)行通信。
2.1 Restart policy
定義Pod時(shí)聪铺,可以指定restartPolicy字段化焕,表明此Pod中的容器在何種條件下會(huì)重啟。restartPolicy擁有三個(gè)候選值:
- Always:只要退出就重啟
- OnFailure:失敗退出時(shí)(exit code不為0)才重啟
- Never:永遠(yuǎn)不重啟
2.2 通過(guò)controller管理Pod
Pod本身不具備容錯(cuò)性铃剔,這意味著如果Pod運(yùn)行的Node宕機(jī)了撒桨,那么該P(yáng)od無(wú)法恢復(fù)。因此推薦使用Deployment等控制器來(lái)創(chuàng)建Pod并管理键兜。
一般來(lái)說(shuō)凤类,Pod不會(huì)自動(dòng)消失,只能手動(dòng)銷(xiāo)毀或者被預(yù)先定義好的controller銷(xiāo)毀普气。但有一種特殊情況谜疤,當(dāng)Pod處于Succeeded或Failed階段,并且超過(guò)一定時(shí)間后(由master決定)棋电,會(huì)觸發(fā)超時(shí)過(guò)期從而被銷(xiāo)毀茎截。
總體上來(lái)說(shuō),Kubernetes中擁有三種類(lèi)型的controller:
- Job赶盔。通常用于管理一定會(huì)結(jié)束的Pod企锌。如果希望Pod被Job controller管理,那么restartPolicy必須指定為OnFailure或Never于未。
- ReplicationController撕攒,ReplicaSet和Deployment。用于管理永遠(yuǎn)處于運(yùn)行狀態(tài)的Pod烘浦。如果希望Pod被此類(lèi)controller管理抖坪,那么restartPolicy必須指定為Always。
- DaemonSet闷叉。它能夠保證你的Pod在每一臺(tái)Node都運(yùn)行一個(gè)副本擦俐。