您好,登錄后才能下訂單哦!
這篇文章主要介紹了kubernetes核心原理是什么的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇kubernetes核心原理是什么文章都會有所收獲,下面我們一起來看看吧。
控制器邏輯中包括controller, sensor 和system 三個邏輯組件,通過修改spec中相關(guān)的字段來觸發(fā)事件,controller通過比較當(dāng)前狀態(tài)和期望狀態(tài),來觸發(fā)對系統(tǒng)的具體操作。
sensor中則包括reflector, informer, indexer 三個組件,
reflector通過list&watch apiserver 來獲取資源的數(shù)據(jù),
list 用來在controller重啟或者watch中斷的情況下,對資源進(jìn)行全量的更新。
watch則在多次list之間進(jìn)行增量的更新。
reflector會在獲取資源信息之后,會在delta queue中加入一個包括資源信息本身和資源對象事件類型的delta數(shù)據(jù),delta隊(duì)列可以保證同一個對象在隊(duì)列中僅有一條記錄,從而避免在reflector list&watch的時候產(chǎn)生重復(fù)的記錄。
informer組件不斷從delta隊(duì)列中彈出delta記錄,一方面把資源對象交給資源回調(diào)函數(shù),同時又把資源對象交給indexer, indexer默認(rèn)將資源對象記錄在緩存中,通 過namespace作為其索引值,并且能被controller-manager的多個controller進(jìn)行資源共享。
控制循環(huán)的控制器函數(shù),主要由事件處理函數(shù)
和worker組成。
事件處理函數(shù),會監(jiān)聽資源的新增、更新、刪除事件,并根據(jù)控制器的邏輯,決定是否需要處理。
對于需要處理的事件,會把事件關(guān)聯(lián)資源的命名空間,以及資源的名字塞入一個工作隊(duì)列中,并且由worker池中的一個worker進(jìn)行處理。
工作隊(duì)列會對存儲的事件進(jìn)行去重,從而避免多個worker處理同一個資源的情況。
worker在處理資源對象時,一般會根據(jù)其名字來獲取最新的數(shù)據(jù),用來創(chuàng)建/更新資源對象,或調(diào)用其他外部服務(wù)。
worker處理失敗的時候,會把資源事件重新加入工作隊(duì)列中,方便之后重試。
控制器模式總結(jié):
聲明式api驅(qū)動- 對k8s資源對象的修改
控制器異步控制系統(tǒng)向終態(tài)趨近
使系統(tǒng)的自動化和無人值守成為可能
自定義資源和控制器(operator)便于系統(tǒng)擴(kuò)展
定義一組pod的期望數(shù)量,controller會維持pod數(shù)量與期望數(shù)量一致。
配置pod發(fā)布方式,controller會按照給定的策略更新pod,保證更新過程中不可用的pod數(shù)量在限定范圍內(nèi)。
如果發(fā)布有問題,支持“一鍵”回滾。
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1
kubectl rollout undo deployment/nginx-deployment
kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2
kubectl rollout history deployment.v1.apps/nginx-deployment
Deployment只負(fù)責(zé)管理不同版本的ReplicaSet, 由ReplicaSet管理Pod副本數(shù)。每個ReplicaSe對應(yīng)Deployment template的一個版本,一個RS下的pod都是相同版本。
checkpaused: 檢查dp是否需要禁止新的發(fā)布,
dp的控制器實(shí)際上做了一些更復(fù)雜的事情,包括版本管理,而將具體版本下的數(shù)量維持工作交給replicaset來做。
擴(kuò)容-發(fā)布-回滾
MinReadySeconds: 判斷Pod available的最小ready時間
RevisionHistoryLimit: 保留歷史revision(replicaset)的數(shù)量,默認(rèn)值為10
paused: 標(biāo)識deployment制作數(shù)量維持,不做新的發(fā)布
progressDealineSeconds: 判斷dp status condition 為failed的最大時間。(dp處于processing最大多長時間,則認(rèn)為dp status 為failed.)
MaxUnavailable: 滾動過程中最多有多少個pod不可用。
MaxSurge: 滾動過程最多存在多少個pod超過期望replicas數(shù)量。
maxunavailable 和 max surge不能同時為0?
因?yàn)椋?dāng)maxsurge=0時,就必須先刪一個pod再創(chuàng)建一個新pod,因?yàn)樾聰U(kuò)出來一個pod,會導(dǎo)致rs超過期望數(shù)量。
maxsurge保證不能新擴(kuò)pod,maxunavailable保證不能有pod不可用。
創(chuàng)建一個或多個pod確保指定數(shù)量的pod可以成功地運(yùn)行終止。
跟蹤pod狀態(tài),根據(jù)配置及時重試失敗的pod。
確定依賴關(guān)系,保證上一個任務(wù)運(yùn)行完畢后再運(yùn)行下一個任務(wù)。
控制任務(wù)并行度,并根據(jù)配置確保pod隊(duì)列大小。
completions: 代表本pod隊(duì)列執(zhí)行次數(shù),這里8代表這個任務(wù)將被執(zhí)行8次。
parallelism: 代表并行執(zhí)行個數(shù),這里的2代表并行執(zhí)行的pod數(shù)量,也就是會有2個pod同時運(yùn)行。
schedule: crontab時間格式相同
startingDeadlineSeconds: job最長啟動時間
concurrencyPolicy: 是否允許并行運(yùn)行
successfulJobsHistoryLimit: 允許留存歷史job個數(shù)
Job controller 負(fù)責(zé)根據(jù)配置創(chuàng)建pod
job controller跟蹤job狀態(tài),根據(jù)配置及時重試pod或者繼續(xù)創(chuàng)建
job controller會自動添加label,來跟蹤對應(yīng)pod,并根據(jù)配置并行或串行創(chuàng)建pod
所有的job都是一個controller,它會去watch kube-apiserver,我們每次提交一個yaml,會經(jīng)過apiserver存到etcd里,然后job controller 會注冊幾個handler,每次我們有添加/更新/刪除等操作時,他會通過一個消息隊(duì)列發(fā)送到j(luò)ob controller里,job controller檢查當(dāng)前存在的active pod, ……
保證集群內(nèi)每一個(或者一些)節(jié)點(diǎn)都運(yùn)行一組相同的pod
跟蹤集群節(jié)點(diǎn)狀態(tài),保證新加入的節(jié)點(diǎn)自動創(chuàng)建對應(yīng)的pod
跟蹤集群節(jié)點(diǎn)狀態(tài),保證移除的節(jié)點(diǎn)刪除對應(yīng)的pod
跟蹤pod狀態(tài),保證每個節(jié)點(diǎn)pod處于運(yùn)行狀態(tài)
RollingUpdate: DaemonSet默認(rèn)更新策略,當(dāng)更新Daemonset模板后,老的pod會被先刪除,然后再去創(chuàng)建新的pod,可以配合健康檢查做滾動更新。
OnDelete: 當(dāng)DaemonSet模板更新后,只有手動的刪除某一個對應(yīng)的pod,此節(jié)點(diǎn)Pod才會被更新。
DaemonSet Controller負(fù)責(zé)根據(jù)配置創(chuàng)建Pod
DaemonSet Controller跟蹤pod狀態(tài),根據(jù)配置及其重試pod或者繼續(xù)創(chuàng)建
DaemonSet Controller會自動添加affinity&label來跟蹤對應(yīng)的pod,并根據(jù)配置在每個節(jié)點(diǎn)或者適合的部分節(jié)點(diǎn)創(chuàng)建pod
pod的配置管理包括:
可變配置(configmap),
敏感信息(secret),
身份認(rèn)證(serviceAccount),
資源配置(spec.containers[].Resources.limits/requests),
安全管控(spec.containers[].securitycontext),
前置校驗(yàn)(spec.Initcontainers)。
主要管理容器運(yùn)行所需的配置文件,環(huán)境變量,命令行參數(shù)等可變配置。用于解耦容器鏡像和可變配置,從而保障工作負(fù)載(pod)的可移植性。
kubectl create configmap kube-flannel-cfg --from-file=configure-pod-container/configmap/cni-conf.json -n kube-system kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
configmap文件大小限制: 1MB (etcd要求)
pod只能引用相同namespace中的configmap
pod引用的configmap不存在時,pod無法創(chuàng)建成功。即pod創(chuàng)建前需要先創(chuàng)建好configmap.
使用envFrom從configmap來配置環(huán)境變量時,如果configmap中的某些key認(rèn)為無效(比如key中帶有數(shù)字),該環(huán)境變量將不會注入容器,但是pod可以正常創(chuàng)建。
只有通過k8s api創(chuàng)建的pod才能使用configmap, 其他方式創(chuàng)建的pod(如manifest創(chuàng)建的static pod)不能使用configmap.
在集群中用于存儲密碼,token等敏感信息用的資源對象。其中敏感數(shù)據(jù)采用base-64編碼保存,相比存儲在明文的configmap中更規(guī)范和安全。
kubectl create secret generic myregistrykey --from-file=.dockerconfigjson=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
secret文件大小限制: 1MB
secret雖然采用base-64編碼,但可以簡單解碼查看原始信息。對secret加密有較強(qiáng)需求,可以考慮結(jié)合k8s+vault來解決敏感信息的加密和權(quán)限管理。
secret最佳實(shí)踐:因?yàn)閘ist/watch的一般處理將獲取到namespace下所有的secret,因此不建議采取list/watch的方式獲取secret信息,而推薦使用GET,從而減少更多secret暴露的可能性。
主要用于解決pod在集群中的身份認(rèn)證問題。其中認(rèn)證使用的授權(quán)信息,則利用前面講到的secret(type=kubernetes.io/service-account-token)進(jìn)行管理。
實(shí)現(xiàn)原理:
pod創(chuàng)建時admission controller會根據(jù)指定的service account(默認(rèn)為default)把對應(yīng)的secret掛載到容器中固定的目錄下(/var/run/secrets/kubernetes.io/serviceaccount).
當(dāng)pod訪問集群時,可以默認(rèn)利用secret其中的token文件來認(rèn)證pod的身份。
默認(rèn)token的認(rèn)證信息為:
Group: system:serviceaccounts:[namespaces-name]
User: system:serviceaccount:[namespace-name]:[pod-name]
如果一個pod中某一個容器異常退出,被kubelet拉起如何保證之前產(chǎn)生的重要數(shù)據(jù)不丟?
同一個pod的多個容器如何共享數(shù)據(jù)?
k8s volume類型:
1)本地存儲: emptydir/hostpath
2)網(wǎng)絡(luò)存儲:
in-tree: awsEBS/gcePersistentDisk/nfs...
out-tree: flexvolume/csi volume plugin
3)projected volume: secret/configmap/downwardAPI/serviceAccountToken
4)pvc、pv
pod中聲明的volume的生命周期與pod相同,以下常見場景:
pod銷毀重建(dp管理的pod鏡像升級)
宿主機(jī)故障遷移(statefulset管理的pod帶遠(yuǎn)程volume遷移)
多pod共享同一個數(shù)據(jù)volume
數(shù)據(jù)volume快照,resize等功能的擴(kuò)展實(shí)現(xiàn)
一個PV可以設(shè)置多個訪問策略,PVC與PV bound時,PV controller會優(yōu)先找到AccessModes列表最短并且匹配的PVC Acessmodes列表的pv集合,然后從集合中找到capacity最小且符合pvc size需求的pv對象。
職責(zé)分離,PVC中只用聲明自己需要的存儲size、access mode(單node獨(dú)占還是多node共享?只讀還是讀寫訪問?)等業(yè)務(wù)真正關(guān)心的存儲需求(不用關(guān)心存儲實(shí)現(xiàn)細(xì)節(jié)),PV和其對應(yīng)的后端存儲信息則由交給集群管理員統(tǒng)一運(yùn)維和管控,安全訪問策略更容易控制。
PVC簡化了用戶對存儲的需求,pv才是存儲的實(shí)際信息承載體。通過kube-controller-manager中的PersisentVolumeController將PVC與合適的pv bound到一起,從而滿足用戶對存儲的實(shí)際需求。
PVC像是面向?qū)ο缶幊讨谐橄蟪鰜淼慕涌冢琍V是接口對應(yīng)的實(shí)現(xiàn)。
前者需要集群管理員提前規(guī)劃或預(yù)測存儲需求,后者可以通過stroageclass創(chuàng)建不同的PV模板,user無需關(guān)心這些PV的細(xì)節(jié),k8s結(jié)合PVC和storageclasss兩者動態(tài)創(chuàng)建PV對象。
StorageClassName:
pvc 可通過該字段找到相同值的PV(靜態(tài)provisioning)
也可通過該字段對應(yīng)的storageclass從而動態(tài)provisioning新PV對象。
說明:到達(dá)released狀態(tài)的PV無法根據(jù)reclaim policy回到available狀態(tài)而再次bound新的PVC。
此時,如果想復(fù)用原來PV對應(yīng)的存儲中的數(shù)據(jù),只有兩種方式:
復(fù)用old pv中記錄的存儲信息,新建pv對象。
直接從pvc對象復(fù)用,即不unbound pvc和pv。(即:statefulset處理存儲狀態(tài)的原理)
用戶創(chuàng)建一個pvc對象,會被csi-provisioner watch到,結(jié)合pvc對象以及在其中聲明的storageclass,通過grpc調(diào)用csi plugin. 會請求云存儲服務(wù)并實(shí)際申請pv存儲。
之后pvcontroller 會將pvc和申請到的pv做bound,之后這塊pv就可被使用了。
當(dāng)用戶創(chuàng)建pod對象,通過kube-scheduler調(diào)度到具體的node節(jié)點(diǎn)后,通過csi-node-server將申請的pvmount到pod可以使用的路徑,然后再create/start container.
create /attach/ mount 三個階段:
本質(zhì)問題
PV在Binding或者Dynamic Provisioning時,并不知道使用它的pod會被調(diào)度到哪些Node上?但PV本身的訪問對node的“位置”(拓?fù)洌┯邢拗啤?/p>
流程改進(jìn)
Binding/Dynamic Provisioning PV的操作Delay到Pod調(diào)度結(jié)果確定之后做,好處:
對于pre-provisioned的含有node affinity的pv對象,可以在pod運(yùn)行的node確認(rèn)之后,根據(jù)node找到合適的pv對象,然后與pod中使用的pvc binding,保證pod運(yùn)行的node滿足pv對訪問“位置”的要求。
對于dynamic provisioning PV場景,在pod運(yùn)行的node確認(rèn)之后,可以結(jié)合node的“位置”信息創(chuàng)建可被該node訪問的pv對象。
k8s相關(guān)組件改進(jìn)
PV controller: 支持延遲binding操作
dynamic pv provisioner: 動態(tài)創(chuàng)建pv時要結(jié)合pod待運(yùn)行的node的“位置”信息
scheduler: 選擇node時要考慮pod的pvc binding需求,也就是要結(jié)合pre-provisioned 的PV 的node affinity以及dynamic provisioning時 pvc指定的storageclass.allowedTopologies的限制
當(dāng)該P(yáng)VC對象被創(chuàng)建之后由于對應(yīng)StorageClass的BindingMode為 WaitForFirstConsumer并不會馬上動態(tài)生成PV對象,而是要等到使用該P(yáng)VC對象的第一個pod調(diào)度出結(jié)果之后,而且kube-scheduler在調(diào)度pod的時候會去選擇滿足storageclass.allowedTopologies中指定的拓?fù)湎拗频膎odes.
用戶創(chuàng)建一個包含pvc的pod(使用動態(tài)存儲卷);
PV controller發(fā)現(xiàn)這個pvc處于待綁定狀態(tài),調(diào)用volume plugin(in-tree 或 out-of-tree)創(chuàng)建存儲卷,并創(chuàng)建PV對象;并將創(chuàng)建的PV與pvc綁定。
Scheduler根據(jù)pod配置、節(jié)點(diǎn)狀態(tài)、pv配置等信息,把pod調(diào)度到某個node節(jié)點(diǎn)上。
AD controller發(fā)現(xiàn)pod和pvc處于待掛載狀態(tài),調(diào)用volume plugin(in-tree 或 out-of-tree)實(shí)現(xiàn)設(shè)備掛載到目標(biāo)節(jié)點(diǎn)(/dev/vdb);
在node節(jié)點(diǎn)上,kubelet(volume manager)等待設(shè)備掛載完成,通過volume plugin將設(shè)備掛載到指定目錄:/var/lib/kubelet/pods/646154cf-xxx-xxx-xxx/volumes/alicloud~disk/pv-disk
kubelet在被告知掛載目錄準(zhǔn)備好后,啟動pod中的containers,用docker -v方式(bind mount)將已經(jīng)掛載到本地的卷映射到容器中。
主要概念:
PersistentVolume: 持久化存儲卷,詳細(xì)定義預(yù)掛載存儲空間的各項(xiàng)參數(shù);無namespace限制,一般由集群管理員創(chuàng)建維護(hù)PV;
PersistentVolumeClaim: 持久化存儲卷聲明,用戶使用的存儲接口,對存儲細(xì)節(jié)無感知,屬于某namespace.
StorageClass: 存儲類,創(chuàng)建PV存儲的模板類,即系統(tǒng)會按照StorageClass定義的存儲模板創(chuàng)建存儲卷(包括真實(shí)存儲空間和PV對象);
主要任務(wù):
PV、PVC聲明周期管理:創(chuàng)建、刪除PV對象;負(fù)責(zé)PV、PVC的狀態(tài)遷移;
綁定PVC、PV對象:一個pvc必須與一個PV綁定后才能被應(yīng)用使用;pv-controller會根據(jù)綁定條件和對象狀態(tài)對pv、pvc進(jìn)行bound、unbound操作。
ClaimWorker:
實(shí)現(xiàn)PVC的狀態(tài)遷移;
通過系統(tǒng)標(biāo)簽“pv.kubernetes.io/bind-completed"來標(biāo)識一個pvc是為bound狀態(tài);
當(dāng)pvc為unbound時,觸發(fā)PV篩選邏輯,如果找到合適的PV則bound,如果找不到則觸發(fā)provision。(如果不是in-tree provisioner則等待)
VolumeWorker:
實(shí)現(xiàn)PV的狀態(tài)遷移;
通過ClaimRef來判斷PV是bound還是released,pv狀態(tài)為released時,若reclaim為delete,則執(zhí)行刪除邏輯。
AD controller負(fù)責(zé)將數(shù)據(jù)卷掛載/卸載到特定節(jié)點(diǎn)上;
核心對象:DesiredStateOfWorld, ActualStateOfWorld
核心邏輯:Reconcile, desiredStateOfWorldPopulator
DesiredStateOfWorld: 集群中預(yù)期要達(dá)到的數(shù)據(jù)卷掛載狀態(tài)
ActualStateOfWorld:集群中實(shí)際存在的數(shù)據(jù)卷掛載狀態(tài)
desiredStateOfWorldPopulator:根據(jù)卷掛載狀態(tài),更新DSW,ASW數(shù)據(jù);
reconcile: 根據(jù)DSW, ASW對象狀態(tài),輪詢執(zhí)行attach, detach操作。
它是kubelet中的一個manager,調(diào)用本節(jié)點(diǎn)Volume的attach/detach/mount/umount操作;
volumeManager實(shí)時掃描本節(jié)點(diǎn)的pod狀態(tài),對需要更新狀態(tài)的volume通過調(diào)用volume plugin執(zhí)行相應(yīng)操作。
volumeManager根據(jù)存儲類型需要還會執(zhí)行一些公共操作,例如:塊設(shè)備的格式化、掛載塊設(shè)備到公共目錄等。
數(shù)據(jù)結(jié)構(gòu):
VolumePluginMgr:管理本節(jié)點(diǎn)上in-tree/out-of-tree的插件列表;
desiredStateOfWorld: 記錄節(jié)點(diǎn)上數(shù)據(jù)卷的期望掛載狀態(tài);
actualStateOfWorld:記錄節(jié)點(diǎn)上數(shù)據(jù)卷的實(shí)際掛載狀態(tài);
核心邏輯:
desiredStateOfWorldPopulator:同步包含數(shù)據(jù)卷的pod狀態(tài);
Reconciler:循環(huán)執(zhí)行attach/detach/mount/unmount, 具體操作通過調(diào)用volume plugin實(shí)現(xiàn)的接口完成。
AD controller還是volume manager做attach/detach操作?
通過--enable-controller-attach-detach來控制
根據(jù)不同的存儲類型提供數(shù)據(jù)卷Provision, Delete, Attach, Detach, Mount, Unmount具體操作實(shí)現(xiàn),是多種具體存儲類型的功能抽象接口。
關(guān)于“kubernetes核心原理是什么”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“kubernetes核心原理是什么”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。