一 概念
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”(備注必填)