深入淺出 Kubernetes:初識(shí) Pod(上)

一 概念

Pod 的中文意為: 豆莢,從字面意思不難理解,它就像一個(gè)豆莢,里面包含許多豆子,這些豆子就可以類(lèi)比為 container 。實(shí)際上,Pod 是一個(gè)邏輯概念,Kubernetes 真正處理的,還是宿主機(jī)操作系統(tǒng)上 Linux 容器的 Namespace 和 Cgroups,而并不存在一個(gè)所謂的 Pod 的邊界或者隔離環(huán)境。 Pod 是一組共享了某些資源的容器,Pod里的所有容器,共享的是同一個(gè) Network Namespace,并且可以聲明共享同一個(gè) Volume 。在 Kubernetes 項(xiàng)目里,Pod 的實(shí)現(xiàn)需要使用一個(gè)中間容器,這個(gè)容器叫做Infra容器( Infra容器k8s.gcr.io/pause占用極少的資源,它的鏡像時(shí)用匯編語(yǔ)言編寫(xiě)的,永遠(yuǎn)處于“暫停”狀態(tài)的容器 )。 在Pod中,Infra 容器永遠(yuǎn)都是第一個(gè)被創(chuàng)建的容器,而其他用戶定義的容器,則通過(guò) join Network Namespace的方式,與Infra容器關(guān)聯(lián)在一起,對(duì)于同一個(gè)Pod里面的所有用戶容器,它們的進(jìn)出流量都是通過(guò)Infra容器完成的。同一個(gè) Pod 里面的所有用戶容器來(lái)說(shuō),它們的進(jìn)出流量,也可以認(rèn)為都是通過(guò) Infra 容器完成的。凡是調(diào)度、網(wǎng)絡(luò)、存儲(chǔ),以及安全相關(guān)的屬性,基本上是 Pod 級(jí)別的。

二 Pod 中幾個(gè)重要字段的含義和用法

NodeSelector:是一個(gè)供用戶將 Pod 與 Node 進(jìn)行綁定的字段,用法如下所示:

apiVersion: v1

kind: Pod

metadata:

name: gysl-nodeselect

spec:

nodeSelector:

kubernetes.io/hostname: 172.31.2.12

containers:

- name: gysl-nginx

image: nginx

這就意味著這個(gè) Pod 只能在攜帶 kubernetes.io/hostname 標(biāo)簽的 Node 上運(yùn)行了,否則,調(diào)度失敗。

NodeName:一旦 Pod 的這個(gè)字段被賦值,Kubernetes 項(xiàng)目就會(huì)被認(rèn)為這個(gè) Pod 已經(jīng)經(jīng)過(guò)了調(diào)度,調(diào)度的結(jié)果就是賦值的節(jié)點(diǎn)名字。所以,這個(gè)字段一般由調(diào)度器負(fù)責(zé)設(shè)置,但用戶也可以設(shè)置它來(lái)“騙過(guò)”調(diào)度器,當(dāng)然這個(gè)做法一般是在測(cè)試或者調(diào)試的時(shí)候才會(huì)用到。

apiVersion: v1

kind: Pod

metadata:

name: gysl-nodename

spec:

nodeName: 172.31.2.12

containers:

- name: gysl-nginx

image: nginx

HostAliases:定義了 Pod 的 hosts 文件(比如 /etc/hosts)里的內(nèi)容。

apiVersion: v1

kind: Pod

metadata:

name: gysl-hostaliases

spec:

hostAliases:

- ip: "10.0.0.20"

hostnames:

- "test.gysl"

- "app.gysl"

containers:

- name: gysl-nginx

image: nginx

最下面兩行記錄,就是我通過(guò) HostAliases 字段為 Pod 設(shè)置的。需要指出的是,在 Kubernetes 項(xiàng)目中,如果要設(shè)置 hosts 文件里的內(nèi)容,一定要通過(guò)這種方法。否則,如果直接修改了 hosts 文件的話,在 Pod 被刪除重建之后,kubelet 會(huì)自動(dòng)覆蓋掉被修改的內(nèi)容。

凡是跟容器的 Linux Namespace 相關(guān)的屬性,也一定是 Pod 級(jí)別的。這個(gè)原因也很容易理解:Pod 的設(shè)計(jì),就是要讓它里面的容器盡可能多地共享 Linux Namespace,僅保留必要的隔離和限制能力。

繼續(xù)看以下例子:

apiVersion: v1

kind: Pod

metadata:

name: gysl-shareprocessnamespace

spec:

shareProcessNamespace: true

containers:

- name: nginx

image: nginx

- name: busybox

image: busybox

tty: true

stdin: true

使用以下命令進(jìn)入指定的 container :

kubectl attach -it gysl-shareprocessnamespace -c busybox

進(jìn)入之后查看一下進(jìn)程共享情況:

/ # ps aux

PID USER TIME COMMAND

1 root 0:00 /pause

6 root 0:00 nginx: master process nginx -g daemon off;

11 101 0:00 nginx: worker process

12 root 0:00 sh

32 root 0:00 ps aux

在這個(gè)容器里,我們不僅可以看到它本身的 ps aux 指令,還可以看到 nginx 容器的進(jìn)程,以及 Infra 容器的 /pause 進(jìn)程。這就意味著,整個(gè) Pod 里的每個(gè)容器的進(jìn)程,對(duì)于所有容器來(lái)說(shuō)都是可見(jiàn)的:它們共享了同一個(gè) PID Namespace。凡是 Pod 中的容器要共享宿主機(jī)的 Namespace,也一定是 Pod 級(jí)別的定義。

再看一個(gè)例子:

apiVersion: v1

kind: Pod

metadata:

name: gysl-share-namespace

spec:

hostPID: true

hostIPC: true

hostNetwork: true

nodeName: 172.31.2.11

shareProcessNamespace: true

containers:

- name: nginx-gysl

image: nginx

imagePullPolicy: IfNotPresent

- name: busybox-gysl

image: busybox

stdin: true

tty: true

imagePullPolicy: Always

lifecycle:

postStart:

exec:

command: ['/bin/sh','-c','echo "This is a test of gysl. ">/gysl.txt']

preStop:

exec:

command: ['/bin/sh','-c','echo "This is a demo of gysl."']

上面的例子中,定義了共享宿主機(jī)的 Network、IPC 和 PID Namespace。這就意味著,這個(gè) Pod 里的所有容器,會(huì)直接使用宿主機(jī)的網(wǎng)絡(luò)、直接與宿主機(jī)進(jìn)行 IPC 通信、看到宿主機(jī)里正在運(yùn)行的所有進(jìn)程。

除此之外,ImagePullPolicy 和 Lifecycle 也是值得我們關(guān)注的兩個(gè)字段。

ImagePullPolicy 字段定義了鏡像拉取的策略。而它之所以是一個(gè) Container 級(jí)別的屬性,是因?yàn)槿萜麋R像本來(lái)就是 Container 定義中的一部分。ImagePullPolicy 的值默認(rèn)是 Always,即每次創(chuàng)建 Pod 都重新拉取一次鏡像。如果它的值被定義為 Never 或者 IfNotPresent,則意味著 Pod 永遠(yuǎn)不會(huì)主動(dòng)拉取這個(gè)鏡像,或者只在宿主機(jī)上不存在這個(gè)鏡像時(shí)才拉取。

Lifecycle 字段。它定義的是 Container Lifecycle Hooks。顧名思義,Container Lifecycle Hooks 的作用,是在容器狀態(tài)發(fā)生變化時(shí)觸發(fā)一系列“鉤子”。在這個(gè)字段中,我們看到了 postStart 和 preStop 兩個(gè)參數(shù)。postStart 參數(shù)在容器啟動(dòng)后,立刻執(zhí)行一個(gè)指定的操作。需要明確的是,postStart 定義的操作,雖然是在 Docker 容器 ENTRYPOINT 執(zhí)行之后,但它并不嚴(yán)格保證順序。也就是說(shuō),在 postStart 啟動(dòng)時(shí),ENTRYPOINT 有可能還沒(méi)有結(jié)束。如果 postStart 執(zhí)行超時(shí)或者錯(cuò)誤,Kubernetes 會(huì)在該 Pod 的 Events 中報(bào)出該容器啟動(dòng)失敗的錯(cuò)誤信息,導(dǎo)致 Pod 也處于失敗的狀態(tài)。preStop 發(fā)生的時(shí)機(jī),則是容器被殺死之前(比如,收到了 SIGKILL 信號(hào))。而需要明確的是,preStop 操作的執(zhí)行,是同步的。所以,它會(huì)阻塞當(dāng)前的容器殺死流程,直到這個(gè) Hook 定義操作完成之后,才允許容器被殺死,這跟 postStart 不一樣。

最新免費(fèi)java,架構(gòu),大數(shù)據(jù)AI編程資料獲取添加

薇信:18410263200

通過(guò)驗(yàn)證填寫(xiě)“111”(備注必填)

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

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

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