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