本文是《深入剖析k8s》學(xué)習(xí)筆記的第二篇烤礁,主要解析pod的意義及其使用方法。
pod滋捶,是k8s中最小的API對(duì)象逆日,是原子調(diào)度單位。是超親密關(guān)系容器之間組織和部署的單位屈暗。類(lèi)比地說(shuō)拆讯,pod就是虛擬機(jī),其中的容器就是這個(gè)虛擬機(jī)里面運(yùn)行的用戶(hù)進(jìn)程养叛。
pod中的所有容器共享network种呐、volume、IP地址弃甥,在pod啟動(dòng)的時(shí)候爽室,需要先啟動(dòng)一個(gè)Infra中間容器,而其它容器都是通過(guò)join的方式加入到Infra容器的資源中的淆攻。Infra容器是一個(gè)用匯編語(yǔ)言編寫(xiě)的阔墩,永遠(yuǎn)處于暫停狀態(tài)的容器,其唯一的作用就是hold住資源瓶珊,和pod同生命周期啸箫。
initcontainers是一種容器類(lèi)型,相較于containers類(lèi)型伞芹,前者總是先于后者啟動(dòng)忘苛,initcontainers如果有多個(gè),則會(huì)按照定義的順序先后啟動(dòng)唱较,只有當(dāng)所有的initcontainers都啟動(dòng)成功且退出了扎唾,containers用戶(hù)容器才會(huì)啟動(dòng)。
sidecar南缓,是一種容器設(shè)計(jì)模式胸遇,指的是我們可以在一個(gè)pod中,啟動(dòng)一個(gè)輔助容器來(lái)完成一些獨(dú)立于主容器之外的工作汉形。比如initcontainers容器纸镊、Infra容器倍阐,都屬于sidecar。
在進(jìn)行上云工作的時(shí)候薄腻,我們可以把虛擬機(jī)類(lèi)同為一個(gè)pod收捣,把里面的進(jìn)程類(lèi)同為容器鏡像届案,把有順序關(guān)系的容器庵楷,定義為initcontainers。如此才是合理的楣颠、松耦合的容器編排訣竅尽纽,也是傳統(tǒng)應(yīng)用架構(gòu)演變到微服務(wù)架構(gòu)最自然的過(guò)渡方式。
pod有如下幾個(gè)重要的屬性需要掌握童漩。
-
nodeSelector弄贿,是一個(gè)供用戶(hù)將pod和node進(jìn)行綁定的字段。
apiVersion: v1 kind: Pod ... spec: # 該pod只能被調(diào)度到含有"disktye: ssd"標(biāo)簽的節(jié)點(diǎn)上矫膨,否則就調(diào)度失敗 nodeSelector: disktye: ssd
-
hostAliases差凹,定義了pod中的hosts文件。
apiVersion: v1 kind: Pod ... spec: # /etc/hosts文件的內(nèi)容將增加如下內(nèi)容: # 10.1.2.3 foo.remote # bar.remote foo.remote # 這是k8s中唯一設(shè)置pod中hosts文件內(nèi)容的方式 hostAliases: - ip: "10.1.2.3" hostnames: - "foo.remote" - "bar.remote"
-
shareProcessNamespace侧馅,表示pod中的各個(gè)容器共享pid namespace危尿。
apiVersion: v1 kind: Pod ... spec: # pod中的nginx容器和shell容器共享進(jìn)程空間,可以相互看到pod中所有的進(jìn)程信息 shareProcessNamespace: true containers: - name: nginx image: nginx - name: shell image: busybox stdin: true tty: true
-
hostNetwork馁痴、hostIPC谊娇、hostPID,表示pod中的各個(gè)容器共享宿主機(jī)的網(wǎng)絡(luò)罗晕、IPC和進(jìn)程空間資源济欢。
apiVersion: v1 kind: Pod ... spec: # pod中的nginx容器和shell容器共享宿主機(jī)的網(wǎng)絡(luò) hostNetwork: true # pod中的nginx容器和shell容器可以直接和宿主機(jī)進(jìn)行IPC通信 hostIPC: true # pod中的nginx容器和shell容器共享宿主機(jī)的進(jìn)程空間,可以看到宿主機(jī)里面運(yùn)行的所有進(jìn)程信息 hostPID: true containers: - name: nginx image: nginx - name: shell image: busybox stdin: true tty: true
-
volumes小渊,表示容器需要掛載的數(shù)據(jù)卷法褥。常用的類(lèi)型有:
- emptyDir,臨時(shí)空目錄酬屉,會(huì)在宿主機(jī)中特定位置建立匿名目錄供pod中的多個(gè)容器掛載半等,從而實(shí)現(xiàn)數(shù)據(jù)共享;
- hostPath梆惯,指定宿主機(jī)中的具名掛載路徑酱鸭;
-
containers、initContainers垛吗,表示容器的類(lèi)型凹髓。其中initContainers是初始化容器,總是先于用戶(hù)容器containers運(yùn)行怯屉,并且會(huì)按照定義的順序同步執(zhí)行蔚舀。
apiVersion: v1 kind: Pod ... spec: # 初始化容器饵沧,僅執(zhí)行cp命令,執(zhí)行完成就結(jié)束赌躺,目的是將war拷貝到tomcat的默認(rèn)目錄下 initContainers: - image: zhangxun/sample:v2 name: war command: ["cp", "/sample.war", "/app"] # 掛載到當(dāng)前容器的/app目錄 volumeMounts: - mountPath: /app name: app-volume # 用戶(hù)容器狼牺,等待初始化容器執(zhí)行完畢后才啟動(dòng),運(yùn)行默認(rèn)目錄下的war對(duì)外提供服務(wù) containers: - image: zhangxun/tomcat:7.0 name: tomcat command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"] # 掛載到當(dāng)前容器的/root/apache-tomcat-7.0.42-v2/webapps目錄 volumeMounts: - mountPath: /root/apache-tomcat-7.0.42-v2/webapps name: app-volume ports: - containerPort: 8080 hostPort: 8001 # 該pod掛載的數(shù)據(jù)卷礼患,類(lèi)型是宿主機(jī)中的匿名存儲(chǔ)路徑 volumes: - name: app-volume emptyDir: {}
在containers屬性下面是钥,又有如下幾個(gè)需要重點(diǎn)關(guān)注的屬性:
- image,使用的鏡像缅叠;
- command悄泥,啟動(dòng)命令;
- workingDir肤粱,工作目錄弹囚;
- ports,暴露的容器端口及綁定的宿主機(jī)端口领曼;
- volumeMounts鸥鹉,掛載數(shù)據(jù)卷的信息;
- imagePullPolicy庶骄,鏡像拉取策略毁渗,通常由always、ifNotPresent瓢姻、never三個(gè)級(jí)別祝蝠;
- lifeCycle,生命周期鉤子幻碱,在容器狀態(tài)發(fā)生改變的時(shí)候可以設(shè)置觸發(fā)一些鉤子事件绎狭;
- postStart,容器啟動(dòng)后立即執(zhí)行指定操作褥傍,雖然在ENTRYPOINT之后執(zhí)行儡嘶,但不能保證ENTRYPOINT已經(jīng)執(zhí)行完畢;
- preStop恍风,容器被終結(jié)之前執(zhí)行指定操作蹦狂,容器的終結(jié)會(huì)因?yàn)檫@個(gè)命令被打斷,只有當(dāng)其執(zhí)行完畢朋贬,容器終結(jié)才會(huì)繼續(xù)執(zhí)行凯楔;
pod有如下幾個(gè)狀態(tài)需要掌握:
- pending,pod創(chuàng)建請(qǐng)求已經(jīng)提交锦募,但是pod中的某些容器因?yàn)槟撤N原因不能被順利創(chuàng)建摆屯;
- running,pod已經(jīng)成功調(diào)度到某個(gè)節(jié)點(diǎn)糠亩,并且其中的容器都已經(jīng)創(chuàng)建成功虐骑,且至少有一個(gè)正在運(yùn)行中准验;
- succeeded,pod里面的所有容器都正常運(yùn)行完畢廷没,并且已經(jīng)退出了糊饱,在運(yùn)行一次性任務(wù)時(shí)比較常見(jiàn);
- failed颠黎,pod里面至少有一個(gè)容器以非正常的狀態(tài)退出另锋;
- unknown,pod的狀態(tài)不能被持續(xù)地匯報(bào)給kube-apiserver盏缤,可能是主從節(jié)點(diǎn)通信出現(xiàn)了問(wèn)題砰蠢;
有幾種特殊的volume,它們并不是為了存放容器中的數(shù)據(jù)唉铜,也不是為了進(jìn)行容器之間或者和宿主機(jī)之間進(jìn)行數(shù)據(jù)共享,而是為了給容器提供預(yù)先定義好的數(shù)據(jù)律杠。這種數(shù)據(jù)卷被稱(chēng)為”投射數(shù)據(jù)卷“潭流,projected volume。
- secret柜去,存放需要加密的數(shù)據(jù)灰嫉;
- configmap,存放不需要加密的嗓奢,但是應(yīng)用需要的配置信息讼撒;
- downward api,讓pod里面的容器直接獲取到這個(gè)api對(duì)象的信息股耽;
- service account根盒,讓pod里面可以調(diào)用k8s的API來(lái)控制集群;
pod可以為其中的容器配置探針(probe)物蝙,用以監(jiān)控容器的健康檢查炎滞,而不是以容器鏡像是否運(yùn)行來(lái)作為健康檢查的依據(jù),因?yàn)闀?huì)存在很多情況诬乞,容器是正常運(yùn)行的册赛,但是無(wú)法對(duì)外提供服務(wù)了,因此探針的健康檢查方式更加準(zhǔn)確震嫉。k8s一旦檢測(cè)到容器探針發(fā)生異常森瘪,就會(huì)根據(jù)設(shè)置好的pod恢復(fù)機(jī)制進(jìn)行操作,恢復(fù)機(jī)制restartPolicy有如下幾種:
- always票堵,任何時(shí)候容器不在運(yùn)行狀態(tài)扼睬,就進(jìn)行重新創(chuàng)建;
- onFailure换衬,只在容器異常時(shí)才進(jìn)行重新創(chuàng)建痰驱;
- never证芭,從來(lái)不重啟容器;
默認(rèn)情況下pod的恢復(fù)機(jī)制是always担映,但并不是所有場(chǎng)景下都是合適的废士,比如initContainers初始化容器執(zhí)行任務(wù)之后就結(jié)束了,就不應(yīng)該設(shè)置為always蝇完。
如下文檔提供了全量的yaml屬性官硝,特別是關(guān)于PodSpec的屬性可以在3050行看到:api/types.go at master · kubernetes/api · GitHub