Kubernetes 与 OpenYurt 无缝转换(命令式)
作者:adamzhoul,OpenYurt 成員
打開 openYurt 的 README.md,在簡單介紹之后就是 Getting started:
yurtctl convert --provider [minikube|kubeadm|kind] // To convert an existing Kubernetes cluster to an OpenYurt clusteryurtctl revert // To uninstall and revert back to the original cluster settings簡單一行命令就可體驗 OpenYurt 了,感覺非常方便。
稍等!為什么是 convert/revert 而不是 install/uninstall ?
這個命令對集群做了什么?
看來,在執行它之前有必要搞清楚它到底做了什么。
yurtctl convert 到底做了些什么?
核心流程
跟隨 openYurt 源代碼(詳情請見文末相關鏈接),梳理了 convert 的核心流程:
可見 1、2 并沒有什么特別,只是常規的服務部署。
3,則是對原有 k8s 系統組件的操作,需要特別注意。
4,節點轉換看著也并不復雜,卻對邊緣至關重要。****
disable nodelifecycle controller 做了什么
工作內容:
1. 查詢控制面節點
2. 創建 job,通過nodeName: {{.nodeName}} 確保 job 的 pod 調度到對應 node 上執行(通過 nsenter 的方式執行,修改宿主機上文件)。
3. sed -i ‘s/–controllers=/–controllers=-nodelifecycle,/g’ /etc/kubernetes/manifests/kube-controller-manager.yaml
查看 kube-controller-manager.yaml
... containers: - command: - kube-controller-manager - --allocate-node-cidrs=true... - --controllers=-nodelifecycle,*,bootstrapsigner,tokencleaner ...可見,上面的一系列操作最終就是修改了 kube-controller-manager 的啟動命令。
查看 kube-controller-manager 啟動參數說明:
–controllers 代表需要開啟的controller列表\
可見,sed 命令就是去掉了 nodelifecycle 這個 controller。
那,nodelifecycle controller 是做什么的?
簡單來說:
1. 不斷監聽,kubelet 上報上來的 node 信息
2. 如果某個 node 狀態異常,或者說長時間沒有上報等
?2.1 驅逐這個 node 節點或者其他 —> 導致上面的 pod 被重新調度
可見,對于處于弱網環境的邊緣節點,很容易就命中異常狀態,導致 node 被驅逐,pod 被重新調度。
所以這里把它去掉了。使用 yurt-controller-manager 來代替它。
即使節點心跳丟失,處于自治模式的節點中的 pod 也不會從 APIServer 中驅逐。
注:這里自治模式的節點,指的就是邊緣節點。我們通常會通過加 annotation 的方式把節點標記為自治節點。
節點轉換是怎么實現的,云端節點和邊緣節點有什么差異?
同樣,是通過跑 job 的方式,在目標宿主機上下文中執行相關操作。
不過,相比于暴力使用 nsenter,這里用了更加優雅的方式。通過將宿主機根路徑 volume 掛載到容器里的方式。
kubelet 的修改
在文件/var/lib/kubelet/kubeadm-flags.env 中為 KUBELET_KUBEADM_ARGS 添加配置:
–kubeconfig=/var/lib/openyurt/kubelet.conf --bootstrap-kubeconfig=
作用:
?1. 參數:–kubeconfig , 給kubelet指定了訪問apiServer的配置文件。 ?
?2. 當–kubeconfig 文件存在,–bootstrap-kubeconfig為空時, ?? kubelet 啟動就不需要通過 bootstrap-token 置換文件證書等過程,直接讀取 kubeconfig 文件訪問 apiServer。 ?*
*
?3. 由于 KUBELET_KUBEADM_ARGS 是 kubelet 啟動參數的最后一部分,所以可以起到覆蓋前面參數的作用。 ?
其中??/var/lib/openyurt/kubelet.conf??內容如下,直接將流量指定到 yurthub:
apiVersion: v1 clusters: - cluster: server: http://127.0.0.1:10261 name: default-cluster contexts: - context: cluster: default-cluster namespace: default user: default-auth name: default-context current-context: default-context kind: Config preferences: {}yurthub 的啟動細節
yurthub 容器啟動參數如下:
command: - yurthub - --v=2 - --server-addr=__kubernetes_service_addr__ - --node-name=$(NODE_NAME) - --join-token=__join_token__ - --working-mode=__working_mode__通過參數我們可看出:
?1. server-addr 指定了云端 apiServer 地址。注意這里的地址一定是公網可訪問地址,否則異構網絡下會有問題。 ?
?2. join-token 就是加入節點的 token,可使用kubeadm token create來創建。k8s 提供機制,通過 token 置換出正常訪問的 kubeconf 文件。 ?
?3. working-mode:cloud/edge。這就是邊緣節點和云端節點的差異。 ?
我們都知道 yurthub 可以用來做緩存,是解決邊緣自治的重要環節。那么云端為什么也需要部署?為什么還要區分 edge 或者 cloud 工作模式?簡單查看 yurthub 源代碼 cmd/yurthub/app/start.go:
if cfg.WorkingMode == util.WorkingModeEdge {cacheMgr, err = cachemanager.NewCacheManager(cfg.StorageWrapper, cfg.SerializerManager, cfg.RESTMapperManager, cfg.SharedFactory)... } else {klog.Infof("%d. disable cache manager for node %s because it is a cloud node", trace, cfg.NodeName) } if cfg.WorkingMode == util.WorkingModeEdge {...gcMgr, err := gc.NewGCManager(cfg, restConfigMgr, stopCh) } else {klog.Infof("%d. disable gc manager for node %s because it is a cloud node", trace, cfg.NodeName) }可見,云端 yurthub,少做了 cache、GC 的工作。
查看 issue(詳情請見文末相關鏈接)可了解:云端也可以利用 yurthub 提供的 data-filtering 能力來控制 service 的流量。
當然,云端也不需要做 cache 等工作。
命令行參數
在執行過程中,有幾個參數比較重要:
–cloud-nodes 用于標識哪些是云端節點,多個節點用逗號分隔:node1,node2
–deploy-yurttunnel 標記是否要部署 yurttunnel
–kubeadm-conf-path 標記節點機器上 kubeadm 配置文件路徑。默認:/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
更多參數,可使用 yurtctl convert --help 來查看。
總結
簡單來說,convert 核心做了幾個事情:
?1. disable K8s 的 nodelifecontroller,用自己的 yurtcontrollermanager 來替換它的職責。 ?
?2. 安裝自己的各類組件,deployment、damenonset 等模式部署。(這類資源部署無需任何擔心,因為搞不壞集群,也不太會出現問題。) ?
?3. 邊緣節點:啟動 yurthub 靜態 pod;將 kubelet 流量轉發到 yurthub。 ?
可見,convert 的事情還是比較可控的。執行 yurtctl convert 也不用太擔心。當然,最后的擔心也應該由 yurtctl revert 來徹底消除!
yurtctl revert 又干了些什么?
核心流程
整個 revert 的過程就是 convert 的反向操作,還比較好理解。
需要注意的是。如果 convert 失敗,比如 job 執行超時或者失敗。job 是不會被刪除的。
即使 yurtctl revert 也不會刪除。目的是為了保留現場方便定位問題。
如果需要重新執行 yurtctl convert, 需要手動刪除 job。
kubectl get job -n kube-system -A |grep convert kubectl delete job -n kube-system < job-name>總結
yurtctl convert/revert 命令是最快捷體驗 OpenYurt 功能的方法之一。
在了解了這兩個命令的實現原理,也就對 OpenYurt 的技術方案了解大半了。
執行命令也不擔心了,so easy!
相關鏈接
1)源代碼:
??https://github.com/openyurtio/openyurt/blob/5063752a9f6645270e3177e39a46df8c23145af2/pkg/yurtctl/cmd/convert/convert.go#L300??
2)issue:
??https://github.com/openyurtio/openyurt/issues/450??
點擊??【此處】??閱讀網站原文。
總結
以上是生活随笔為你收集整理的Kubernetes 与 OpenYurt 无缝转换(命令式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 看云原生实战就来这里,侬晓得伐?
- 下一篇: 2022 年第一场云原生技术实践营开启报