Pod是Kubernetes項目中最小的API對象白热。Pod是Kubernetes項目的原子調(diào)度單位噪叙。
kubernetes項目的調(diào)度器钱磅,是統(tǒng)一按照Pod而非容器的資源需求進行計算的檬寂。
Docker的本質(zhì)是進程菠剩。Kubernetes類似于操作系統(tǒng)。
pstree -g 可以查看當(dāng)前系統(tǒng)中正在運行的進程的樹狀結(jié)構(gòu)惜论。
rsyslogd是負責(zé)linux操作系統(tǒng)里的日志處理许赃。
容器的單進程模型不是指容器里只能運行一個進程,而是指容器沒有管理多個進程的能力馆类。
Pod的實現(xiàn)原理
Pod是一個邏輯概念混聊。
Kubernetes真正處理的,還是宿主操作系統(tǒng)上Linux容器的Namespace和Cgroup,并不存在一個所謂的Pod的邊界或者隔離環(huán)境句喜。
Pod是一組共享了某些資源的容器预愤。Pod里的所有容器,共享的是同一個Network Namespace咳胃,并且可以聲明共享同一個Volume植康。
Pod的實現(xiàn)需要一個中間容器,就是infra容器展懈,它永遠都是第一個被創(chuàng)建的容器销睁,其他用戶定義的容器,通過
Join Network Namespace的方式存崖,于Infra容器關(guān)聯(lián)在一起冻记。
一個Pod只有一個IP地址。Pod中的容器共享同一份網(wǎng)絡(luò)資源来惧。Pod和Infra容器的生命周期一致冗栗。
Pod的超緊密關(guān)系是在一個容器中跑多個功能不想管的應(yīng)用。
在Pod中供搀,所有Init Container定義的容器隅居,都會比spec.containers定義的用戶容器先啟動。
并且葛虐,Init Container容器會按照順序逐一啟動胎源,而直到他們都啟動并且退出,用戶容器才會啟動挡闰。
sidecar指的是可以在一個Pod中乒融,啟動一個輔助容器,來完成一些獨立于主進程(主容器)之外的工作摄悯。
凡是調(diào)度赞季、網(wǎng)絡(luò)、存儲奢驯,以及安全相關(guān)的屬性申钩,基本上都是Pod級別的。
Pod的基礎(chǔ)概念
NodeSelector
NodeSelector:是一個供用戶將Pod于Node進行綁定的字段瘪阁。用戶如下:
apiVersion: v1
kind: Pod
...
spec:
nodeSelector:
disktype: ssd
這意味著這個Pod只能運行在懈怠了disktype:ssd標(biāo)簽(Label)的節(jié)點上,否則調(diào)度失敗撒遣。
NodeName
一旦Pod的這個字段被賦值,Kubernetes項目就會認(rèn)為這個Pod已經(jīng)經(jīng)過調(diào)度管跺,調(diào)度的結(jié)果就是賦值的節(jié)點名字义黎。
這個名字一般由調(diào)度器負責(zé)設(shè)置。
HostAlias
HostAlias:定義了Pod的hosts文件里面的內(nèi)容豁跑。(-i 即 stdin廉涕,-t 即 tty)。
凡是Pod中的容器要共享宿主機的Namespace,也一定是Pod級別的定義狐蜕。
Pod中宠纯,只是Init Containers的生命周期,會先于所有的Containers层释,并且嚴(yán)格按照定義的順序執(zhí)行婆瓜。
ImagePullPolicy
ImagePullPolicy:定義了一個鏡像拉取的策略,是conatiner級別的屬性贡羔。
默認(rèn)值為Always廉白,即每次創(chuàng)建Pod都重新拉取一次鏡像。
如果將值設(shè)置為Never/IfNotPresent乖寒,意味著Pod永遠不會主動拉取這個鏡像蒙秒,或者只在宿主機上不存在這個鏡像時才拉取。
LifeCycle
LifeCycle定義了Container Lifecycle Hooks宵统,是容器級別的屬性,在容器狀態(tài)發(fā)生變化時觸發(fā)一系列鉤子覆获。
在postStart啟動時马澈,ENTRYPOINT有可能還沒有結(jié)果。如果在postStart執(zhí)行時出現(xiàn)超時或者錯誤弄息,就會導(dǎo)致Pod處于失敗狀態(tài)痊班。
preStop發(fā)生的時機則是容器被殺死之前,preStop的操作是同步的摹量。它會阻塞當(dāng)前的容器殺死流程涤伐,直到這個Hook定義操作完成之后,
才允許容器被殺死缨称。
Pod生命中周期的變化凝果,主要體現(xiàn)在Pod API對象的Status部分(pod.status.phase)。
Status的值:
- Pending:Pod的YAML文件已經(jīng)提交給Kubernetes睦尽,API對象已經(jīng)被創(chuàng)建并保存在etcd當(dāng)中器净。
- Running:Pod已經(jīng)調(diào)度成功,跟一個具體的節(jié)點綁定当凡。它包含的容器都已經(jīng)創(chuàng)建成功山害,至少有一個正在運行中。
- Succeeded:Pod里面的所有容器都已經(jīng)運行完畢沿量,并且已經(jīng)退出了浪慌。
- Failed:Pod里至少有一個容器以不正常的狀態(tài)退出。
- Unknown:這是一個異常狀態(tài)朴则,Pod的狀態(tài)不能持續(xù)地被kubelet匯報給kube-apiserver权纤,這有可能是主從節(jié)點間的通信出現(xiàn)了問題。
Pod中Condition和Status的對應(yīng)關(guān)系:
Pending(Status) == UnSchedule(Condition),調(diào)度出現(xiàn)了問題;
Running(Status) == Ready(Condition),Ready意味著Pod不僅已經(jīng)正常啟動妖碉,而且還可以對外提供服務(wù)涌庭。
Projected Volume
Projected Volume是Kubernetes在v1.11.1之后的特性。
Projected Volume分為Secret欧宜、ConfigMap坐榆、Downward API,然后Service Account是一種特殊的Secret席镀。
Secret
Secret的作用是:幫助把Pod想要訪問的加密數(shù)據(jù),存放在Etcd中夏漱,然后通過在Pod的容器里掛載Volume的方式豪诲,
訪問到這些Secret里保存的信息。
Secret對象要求這些數(shù)據(jù)必須要經(jīng)過Base64轉(zhuǎn)碼的挂绰,以免出現(xiàn)銘文密碼的安全隱患屎篱。只是進行了轉(zhuǎn)碼,沒有加密葵蒂,
如果要更安全交播,可以開啟Secret加密的插件,增加數(shù)據(jù)的安全性践付。
kubelet會定時維護這些volume秦士。
ConfigMap
ConfigMap中保存的是不需要加密的、應(yīng)用所需的配置信息永高。
Downward API
讓Pod里的容器直接可以獲取到這個Pod API對象本身的信息隧土。
Downward API能夠獲取到的信息,一定是Pod里的容器進程啟動之前就能夠確定下來的信息命爬。
Service Account
Service Account對象的作用就是Kubernetes系統(tǒng)內(nèi)置的一種服務(wù)賬號曹傀,它是Kubernetes進行權(quán)限配置的對象。
Service Account的授權(quán)信息和文件饲宛,保存在它所綁定的一個特殊的Secret對象里的卖毁,成為ServiceAccountToken。
Kubernetes提供了一個默認(rèn)服務(wù)賬號落萎。任何一個運行在Kubernetes里的Pod亥啦,都可以直接使用這個默認(rèn)的Service Account,
則無需顯示地聲明掛載它练链。
把Kubernetes客戶端以容器的方式運行在集群里翔脱,然后使用default service account自動授權(quán)的方式,被成為InClusterConfig媒鼓,
這也是推薦的運行Kubernetes API編程的授權(quán)方式届吁。
健康檢查
Pod里的容器定義了一個健康檢查探針错妖,kubelet會根據(jù)這個探針的返回值來決定這個容器的狀態(tài),而不是直接以容器是否運行作為依據(jù)疚沐。
恢復(fù)機制
Pod恢復(fù)機制:即restartPolicy暂氯,pod.spec.restartPolicy,默認(rèn)值為always亮蛔,即任何時期這個容器發(fā)生了異常痴施,它一定會被重新創(chuàng)建。
Pod的恢復(fù)過程究流,永遠都是發(fā)生在當(dāng)前節(jié)點上辣吃,而不是跑到別的節(jié)點上。一個Pod于以節(jié)點綁定芬探,除非這個綁定發(fā)生變化神得,否則Pod永遠都不會離開這個節(jié)點。
如果這個宿主機宕機了偷仿,這個Pod也不會主動遷移到其他節(jié)點上哩簿。
Pod的恢復(fù)策略:
- Always: 在任何情況下,只要容器不在運行狀態(tài)酝静,就會自動重啟容器卡骂。
- OnFailure: 只在容器異常時才會自動重啟容器。
- Never: 從來不重啟容器形入。
Pod的設(shè)計規(guī)原理:
- 只要Pod的restartPolicy指定的策略允許重啟異常的容器,那么這個Pod就會保持Running狀態(tài)缝左,并進行容器重啟亿遂。
- 對于包含多個容器的Pod,只有它里面所有的容器都進入異常狀態(tài)后渺杉,Pod才會進入Failed狀態(tài)蛇数。
readlinessProbe檢查結(jié)果的成功與否,決定這個Pod是不是能夠被通過Service的方式訪問到是越,并不影響Pod的聲明周期耳舅。
控制器模型的實現(xiàn)
控制器模型的實現(xiàn):
- Deployment控制器從Etcd中后去到所有攜帶指定標(biāo)簽的Pod,然后統(tǒng)計他們的數(shù)量倚评,這是實際狀態(tài)浦徊;
- Deployment對象的Replicas字段的值就是期望值;
- Deployment控制器將兩個狀態(tài)做比較天梧,然后比較結(jié)果盔性,確定是創(chuàng)建Pod,還是刪除已有的Pod呢岗。
一個ReplicaSet對象冕香,其實就是由副本樹木的定義和一個Pod模版組成的蛹尝。
Deployment控制器實際操作的是ReplicaSet對象而不是Pod對象。
Deployment管理的Pod的ownerReference對象是ReplicaSet悉尾。
Deployment突那、ReplicaSet、Pod的關(guān)系
Deployment构眯、ReplicaSet愕难、Pod的關(guān)系是層層控制的關(guān)系。
ReplicaSet負責(zé)通過控制器模式鸵赖,保證系統(tǒng)中Pod的個數(shù)永遠等于指定的個數(shù)务漩。這正是Deployment只允許容器的restartPolicy=Always的
主要原因:只有在容器能保證自己始終是Running狀態(tài)的前提下,ReplicaSet調(diào)整Pod的個數(shù)才有意義它褪。
Deployment同樣通過控制器模式饵骨,來操作ReplicaSet的個數(shù)和屬性,進而實現(xiàn)水平擴展/收縮和滾動更新這兩個編排動作茫打。
通過kubectl get deployments查看返回值的含義:
DESIRED:用戶期望Pod副本個數(shù)(scopes.replicas的值);
CURRENT:當(dāng)前處于Running狀態(tài)的Pod的個數(shù);
UPDATE-TO-DATE:當(dāng)前處于最新版本Pod的個數(shù);
AVAILABLE:當(dāng)前可用Pod的個數(shù)居触,即是Running狀態(tài),有時最新版本老赤,并且處于Ready狀態(tài)的Pod的個數(shù)轮洋。
可以通過kubectl rollout status 容器
查看Deployment對象的狀態(tài)變化。
將一個進群中正在運行的多個Pod版本抬旺,交替地逐一升級的過程弊予,就是滾動更新。
保證服務(wù)的連續(xù)性开财,Deployment Controller還會確保汉柒,在任何時間串口內(nèi),只有指定比例的Pod處于離線狀態(tài)责鳍。
同時碾褂,在創(chuàng)建新的Pod可以指定比例,默認(rèn)都是DESIRED值的25%历葛。
maxUnavailable指的是正塌,在一次滾動中,Deployment控制器可以刪除多少個舊Pod恤溶。
Deployment 版本控制的原理
kubectl set image的指令乓诽,直接修改容器使用的鏡像,這個命令的好處咒程,不用像kubectl edit那樣需求打開編輯器问裕。
kubectl rollout undo命令,把整個Deployment回滾到上一個版本孵坚。
首先粮宛,需要使用kubectl rollout history命令窥淆,查看每次Deployment變更對應(yīng)的版本。
然后巍杈,可以在kubectl rollout undo命令行最后忧饭,加上要會滾到的指定版本的版本號,就可以回滾到指定版本了筷畦。
在更新Deployment前词裤,要執(zhí)行一條kubectl rollout pause指令,然后接下來鳖宾,可以隨意使用kubectl edit或者
kubectl set images吼砂,修改這個Deployment的內(nèi)容了,這些操作不會觸發(fā)滾動更新鼎文。
在對Deployment修改操作都完成之后渔肩,只需要在執(zhí)行一次kubectl rollout resume指令,然后恢復(fù)執(zhí)行操作拇惋。
可以使用spec.revisionHistoryLimit 保留Deployment的版本數(shù)個數(shù)周偎,如果設(shè)置為0,就是不能做回滾操作撑帖。
Deployment控制ReplicaSet(版本)蓉坎,ReplicaSet控制Pod(副本數(shù))。