OpenYurt入门-在树莓派上玩转OpenYurt
作者 |?唐炳昌
來源|阿里巴巴云原生公眾號
隨著邊緣計算的快速發展,越來越多的數據需要到網絡的邊緣側進行存儲、處理和分析,邊緣的設備和應用呈爆發式增長。如何高效的管理邊緣側的資源和應用是業界面臨的一個主要問題。當前,采用云原生的方法,將云計算的能力下沉到邊緣并在云端做統一調度、管控的云邊端一體化架構得到了業界的廣泛認可。
2020 年 5 月,阿里巴巴開源首個 Kubernetes 無侵入的邊緣計算云原生項目?OpenYurt,并于同年 9 月份進入 CNCF SandBox。OpenYurt 針對邊緣場景中網絡不穩定、云邊運維困難等問題,對原生 Kubernetes 無侵入地增強,重點提供了邊緣節點自治、云邊運維通道、邊緣單元化的能力。
如圖 1 所示,本文通過在云端部署 Kubernetes 集群的控制面,并將樹莓派接入集群來搭建云管邊場景。基于這個環境演示 OpenYurt 的核心能力,帶大家快速上手 OpenYurt。
圖 1? 原生 Kubernetes 集群
環境準備
1. 基礎環境介紹
在云端,購買 ENS 節點(ENS 節點具有公網 IP,方便通過公網對外暴露服務)來部署原生 K8s 集群的管控組件。其中系統采用 ubuntu18.04、hostname 為 master-node、docker 版本為 19.03.5。
在邊緣,如圖 2 所示,將樹莓派 4 與本地的路由器連接,組成邊緣私網環境,路由器通過 4G 網卡訪問互聯網。其中樹莓派 4 預裝系統為 ubuntu18.04、hostname為 edge-node、docker 版本為 19.03.5。
圖 2? 邊緣環境實體圖
2. 原生 K8s 集群搭建
本文演示環境基于社區1.16.6版本的K8s集群,并采用社區提供的kubeadm工具來搭建集群,具體操作如下:
- 在云端節點和樹莓派上分別執行如下命令安裝 Kubernetes 組件。
- 使用 kubeadm 初始化云端節點(在云端節點上執行如下命令),部署過程中采用阿里云的鏡像倉庫,為了支持樹莓派的接入,該倉庫的鏡像做了 manifest 列表,能夠支持 amd64/arm64 兩種不同的 CPU 架構。
依據初始化完成之后的提示,拷貝 config 文件到 $HOME/.kube 中: ``` mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
kubeadm join 183.195.233.42:6443 --token XXXX \
--discovery-token-ca-cert-hash XXXX
{
"cniVersion": "0.3.0",
"name": "lo",
"type": "loopback"
}
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
edge-node Ready 74s v1.16.6 192.168.0.100 Ubuntu 18.04.4 LTS 4.19.105-v8-28 docker://19.3.5
master-node Ready master 2m5s v1.16.6 183.195.233.42 Ubuntu 18.04.2 LTS 4.15.0-52-generic docker://19.3.5
kubectl delete deployment coredns -n kube-system
kubectl taint node master-node node-role.kubernetes.io/master-
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
tolerations:
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 5 - key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 5
nodeSelector:
kubernetes.io/hostname: edge-node
containers: - name: nginx
image: nginx
hostNetwork: true
查看部署結果:
root@master-node:~# kubectl get pods -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 11s 192.168.0.100 edge-node <none> <none>1. 測試常用的集群運維指令,包括 logs、exec、port-forward。
在 master 節點上運維邊緣節點應用,執行 logs/exec/port-forward 等指令,查看結果。
root@master-node:~# kubectl logs nginx Error from server: Get https://192.168.0.100:10250/containerLogs/default/nginx/nginx: dial tcp 192.168.0.100:10250: connect: connection refusedroot@master-node:~# kubectl exec -it nginx sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. Error from server: error dialing backend: dial tcp 192.168.0.100:10250: connect: connection refusedroot@master-node:~# kubectl port-forward pod/nginx 8888:80 error: error upgrading connection: error dialing backend: dial tcp 192.168.0.100:10250: connect: connection refused從執行結果看,原生的k8s在云管邊的場景中,無法提供從云端運維邊緣應用的能力。這是因為邊緣節點部署在用戶的私網環境,從云端無法通過邊緣節點的 IP 地址直接訪問邊緣節點。
2. 測試邊緣斷網時對業務的影響
邊緣節點與云端管控通過公網連接,經常會出現網絡不穩定,云端斷連的情況。這里我們將做兩個斷網相關的測試:
-
斷網 1 分鐘->恢復網絡
-
斷網 1 分鐘->重啟邊緣節點->恢復網絡
觀察兩個測試過程中節點和 Pod 的狀態變化。本文 Demo 中的斷網方式是將路由器的公網連接斷開。
1)斷網 1 分鐘->恢復網絡
斷開網絡,大約 40s 后,節點變成 NotReady(正常節點 10s 鐘上報一次心跳,當 4 次沒有上報心跳時,管控組件認為節點異常)。
root@master-node:~# kubectl get nodes NAME STATUS ROLES AGE VERSION edge-node NotReady <none> 5m13s v1.16.6 master-node Ready master 6m4s v1.16.6繼續等待 5s 之后(正常節點變為 NotReady 之后,5m 才開始驅逐 pod,此處為了測試效果,將 pod 的容忍時間配成了 5s),應用 pod 被驅逐,狀態變為 Terminating。
root@master-node:~# kubectl get pods NAME READY STATUS RESTARTS AGE nginx 1/1 Terminating 0 3m45s將網絡恢復,觀察節點及 pod 變化。
root@master-node:~# kubectl get pods No resources found in default namespace.網絡恢復后,節點狀態變成 ready,業務 pod 被清除,這是因為邊緣節點的 Kubelet 獲取到業務 Pod 的 Terminating 狀態,對業務 Pod 做刪除操作,并返回刪除成功,云端也做了相應的清理。至此,業務 Pod 由于云邊網絡的不穩定而被驅逐,然而在斷網期間,邊緣節點其實是可以正常工作的。
重新創建應用 nginx,用于下面測試。
root@master-node:~# kubectl get pods -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 4s 192.168.0.100 edge-node <none> <none>2)斷網 1 分鐘->重啟邊緣節點->恢復網絡
接下來,我們測試在斷網的情況下,邊緣節點的重啟對業務的影響。斷網 1 分鐘之后,Node 和 Pod 狀態同上面測試結果,Node 變為 NotReady,Pod 的狀態變為 Terminating。此時,切換到私有網絡環境,登錄到樹莓派上,將樹莓派重啟,重啟完成后等待大約 1 分鐘,觀察重啟前后節點上的容器列表。
重啟前邊緣節點容器列表(此時云邊端開,雖然在云端獲取的 pod 是 Terminating 狀態,但是邊緣并未 Watch 到 Terminating 的操作,所以邊緣的應用還正常運行)。
root@edge-node:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9671cbf28ca6 e86f991e5d10 "/docker-entrypoint.…" About a minute ago Up About a minute k8s_nginx_nginx_default_efdf11c6-a41c-4b95-8ac8-45e02c9e1f4d_0 6272a46f93ef registry.cn-hangzhou.aliyuncs.com/edge-kubernetes/pause:3.1 "/pause" 2 minutes ago Up About a minute k8s_POD_nginx_default_efdf11c6-a41c-4b95-8ac8-45e02c9e1f4d_0 698bb024c3db f9ea384ddb34 "/usr/local/bin/kube…" 8 minutes ago Up 8 minutes k8s_kube-proxy_kube-proxy-rjws7_kube-system_51576be4-2b6d-434d-b50b-b88e2d436fef_0 31952700c95b registry.cn-hangzhou.aliyuncs.com/edge-kubernetes/pause:3.1 "/pause" 8 minutes ago Up 8 minutes k8s_POD_kube-proxy-rjws7_kube-system_51576be4-2b6d-434d-b50b-b88e2d436fef_0重啟后節點容器列表,斷網重啟后,kubelet 無法從云端獲取 Pod 信息,不會重建 Pod。
root@edge-node:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES root@edge-node:~#從重啟前后的對比看,邊緣節點在斷網重啟之后,節點上的 Pod 全部無法恢復。這就會導致在云邊斷網時,一旦節點重啟,應用將無法工作。
將網絡恢復,觀察節點及 pod 變化,同上面測試結果,網絡恢復后,節點變為 Ready,業務 Pod 被清除。
root@master-node:~# kubectl get nodes NAME STATUS ROLES AGE VERSION edge-node Ready <none> 11m v1.16.6 master-node Ready master 12m v1.16.6 root@master-node:~# kubectl get pods No resources found in default namespace.接下來,再次部署業務 nginx,測試 OpenYurt 集群對云邊運維的支持和對云邊斷網時的反應。
root@master-node:~# kubectl get pods -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 12s 192.168.0.100 edge-node <none> <none>原生 K8s 集群一鍵轉換為 OpenYurt 集群
探究了原生 Kubernetes 在云邊一體化架構中的不足之后,我們來看下 OpenYurt 集群是否能滿足這種場景。現在,我們利用 OpenYurt 社區提供的集群轉換工具 yurtctl,來將原生 K8s 集群轉換成 OpenYurt 集群。在 master 節點上執行如下命令,?該命令指定了組件的鏡像以及云端節點,并指定安裝云邊運維通道 yurt-tunnel。
yurtctl convert --yurt-controller-manager-image=registry.cn-hangzhou.aliyuncs.com/openyurt/yurt-controller-manager:v0.2.1 --yurt-tunnel-agent-image=registry.cn-hangzhou.aliyuncs.com/openyurt/yurt-tunnel-agent:v0.2.1 --yurt-tunnel-server-image=registry.cn-hangzhou.aliyuncs.com/openyurt/yurt-tunnel-server:v0.2.1 --yurtctl-servant-image=registry.cn-hangzhou.aliyuncs.com/openyurt/yurtctl-servant:v0.2.1 --yurthub-image=registry.cn-hangzhou.aliyuncs.com/openyurt/yurthub:v0.2.1 --cloud-nodes=master-node --deploy-yurttunnel轉換大概需要 2min,轉換完成之后,觀察業務 pod 的狀態,可以看到轉換過程中對業務 pod 無影響(也可以在轉換過程中在新的終端使用 kubectl get pod -w 觀察業務 pod 的狀態)。
root@master-node:~# kubectl get pods -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 2m4s 192.168.0.100 edge-node <none> <none>執行完成之后的組件分布如圖 3 所示,其中橙色部分是 OpenYurt 相關的組件,藍色部分是原生 K8s 組件。相應地,我們觀察云端節點和邊緣節點的 pod。
圖 3? OpenYurt 集群組件分布圖
云端節點 yurt 相關的 pod:yurt-controller-manager 和 yurt-tunnel-server。
root@master-node:~# kubectl get pods --all-namespaces -owide | grep master | grep yurt kube-system yurt-controller-manager-7d9db5bf85-6542h 1/1 Running 0 103s 183.195.233.42 master-node <none> <none> kube-system yurt-tunnel-server-65784dfdf-pl5bn 1/1 Running 0 103s 183.195.233.42 master-node <none> <none>邊緣節點新增 yurt 相關的 pod: yurt-hub(static pod)和 yurt-tunnel-agent。
root@master-node:~# kubectl get pods --all-namespaces -owide | grep edge | grep yurt kube-system yurt-hub-edge-node 1/1 Running 0 117s 192.168.0.100 edge-node <none> <none> kube-system yurt-tunnel-agent-7l8nv 1/1 Running 0 2m 192.168.0.100 edge-node <none> <none>測試 OpenYurt 集群在邊緣場景中的能力
1. 測試 logs/exec/port-forward 等運維指令,查看結果
root@master-node:~# kubectl logs nginx /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh /docker-entrypoint.sh: Configuration complete; ready for start uproot@master-node:~# kubectl exec -it nginx sh kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. # ls bin dev docker-entrypoint.sh home media opt root sbin sys usr boot docker-entrypoint.d etc lib mnt proc run srv tmp var # exitroot@master-node:~# kubectl port-forward pod/nginx 8888:80 Forwarding from 127.0.0.1:8888 -> 80 Handling connection for 8888測試 port-forward 時,在 master 節點上執行 curl 127.0.0.1:8888,可以訪問 nginx 服務。
從演示結果看,OpenYurt 能夠很好地支持常用的云邊運維指令。
2. 測試邊緣斷網時對業務的影響
同樣我們重復原生 K8s 中斷網的兩個測試,在測試之前我們先為邊緣節點 edge-node 開啟自治。在 OpenYurt 集群中,邊緣節點的自治是通過一個 annotation 來標識的。
root@master-node:~# kubectl annotate node edge-node node.beta.alibabacloud.com/autonomy=true node/edge-node annotated1)斷網 1 分鐘->網絡恢復
同樣,將路由器公網斷開,觀察 Node 和 Pod 的狀態。大約過了 40s,節點的狀態變成 NotReady,而大約過 1min 以后,Pod 的狀態一直是 Running,并不會被驅逐。
root@master-node:~# kubectl get nodes NAME STATUS ROLES AGE VERSION edge-node NotReady <none> 24m v1.16.6 master-node Ready master 25m v1.16.6 root@master-node:~# kubectl get pods NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 5m7s恢復網絡,觀察 Node 和 Pod 的狀態,Node 狀態變為 Ready,Pod 保持 Running。可見云邊網絡不穩定時,對邊緣節點的業務 Pod 無影響。
root@master-node:~# kubectl get nodes NAME STATUS ROLES AGE VERSION edge-node Ready <none> 25m v1.16.6 master-node Ready master 26m v1.16.6 root@master-node:~# kubectl get pods NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 6m30s2)斷網 1 分鐘->重啟邊緣節點->恢復網絡
接下來,我們測試在斷網的情況下,邊緣節點的重啟對業務的影響。斷網 1 分鐘之后,Node 和 Pod 狀態同上面測試結果,Node 變為 NotReady,Pod 保持 Running。同樣,我們登錄到樹莓派上,將樹莓派重啟,觀察重啟前后節點上的容器列表。
重啟前邊緣節點容器列表:
root@edge-node:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 38727ec9270c 70bf6668c7eb "yurthub --v=2 --ser…" 7 minutes ago Up 7 minutes k8s_yurt-hub_yurt-hub-edge-node_kube-system_d75d122e752b90d436a71af44c0a53be_0 c403ace1d4ff registry.cn-hangzhou.aliyuncs.com/edge-kubernetes/pause:3.1 "/pause" 7 minutes ago Up 7 minutes k8s_POD_yurt-hub-edge-node_kube-system_d75d122e752b90d436a71af44c0a53be_0 de0d693e9e74 473ae979be68 "yurt-tunnel-agent -…" 7 minutes ago Up 7 minutes k8s_yurt-tunnel-agent_yurt-tunnel-agent-7l8nv_kube-system_75d28494-f577-43fa-9cac-6681a1215498_0 a0763f143f74 registry.cn-hangzhou.aliyuncs.com/edge-kubernetes/pause:3.1 "/pause" 7 minutes ago Up 7 minutes k8s_POD_yurt-tunnel-agent-7l8nv_kube-system_75d28494-f577-43fa-9cac-6681a1215498_0 80c247714402 e86f991e5d10 "/docker-entrypoint.…" 7 minutes ago Up 7 minutes k8s_nginx_nginx_default_b45baaac-eebc-466b-9199-2ca5c1ede9fd_0 01f7770cb0f7 registry.cn-hangzhou.aliyuncs.com/edge-kubernetes/pause:3.1 "/pause" 7 minutes ago Up 7 minutes k8s_POD_nginx_default_b45baaac-eebc-466b-9199-2ca5c1ede9fd_0 7e65f83090f6 f9ea384ddb34 "/usr/local/bin/kube…" 17 minutes ago Up 17 minutes k8s_kube-proxy_kube-proxy-rjws7_kube-system_51576be4-2b6d-434d-b50b-b88e2d436fef_1 c1ed142fc75b registry.cn-hangzhou.aliyuncs.com/edge-kubernetes/pause:3.1 "/pause" 17 minutes ago Up 17 minutes k8s_POD_kube-proxy-rjws7_kube-system_51576be4-2b6d-434d-b50b-b88e2d436fef_1重啟后邊緣節點容器列表:
root@edge-node:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0c66b87066a0 473ae979be68 "yurt-tunnel-agent -…" 12 seconds ago Up 11 seconds k8s_yurt-tunnel-agent_yurt-tunnel-agent-7l8nv_kube-system_75d28494-f577-43fa-9cac-6681a1215498_2 a4fb3e4e8c8f e86f991e5d10 "/docker-entrypoint.…" 58 seconds ago Up 56 seconds k8s_nginx_nginx_default_b45baaac-eebc-466b-9199-2ca5c1ede9fd_1 fce730d64b32 f9ea384ddb34 "/usr/local/bin/kube…" 58 seconds ago Up 57 seconds k8s_kube-proxy_kube-proxy-rjws7_kube-system_51576be4-2b6d-434d-b50b-b88e2d436fef_2 c78166ea563f registry.cn-hangzhou.aliyuncs.com/edge-kubernetes/pause:3.1 "/pause" 59 seconds ago Up 57 seconds k8s_POD_yurt-tunnel-agent-7l8nv_kube-system_75d28494-f577-43fa-9cac-6681a1215498_1 799ad14bcd3b registry.cn-hangzhou.aliyuncs.com/edge-kubernetes/pause:3.1 "/pause" 59 seconds ago Up 57 seconds k8s_POD_nginx_default_b45baaac-eebc-466b-9199-2ca5c1ede9fd_1 627673da6a85 registry.cn-hangzhou.aliyuncs.com/edge-kubernetes/pause:3.1 "/pause" 59 seconds ago Up 58 seconds k8s_POD_kube-proxy-rjws7_kube-system_51576be4-2b6d-434d-b50b-b88e2d436fef_2 04da705e4120 70bf6668c7eb "yurthub --v=2 --ser…" About a minute ago Up About a minute k8s_yurt-hub_yurt-hub-edge-node_kube-system_d75d122e752b90d436a71af44c0a53be_1 260057d935ee registry.cn-hangzhou.aliyuncs.com/edge-kubernetes/pause:3.1 "/pause" About a minute ago Up About a minute k8s_POD_yurt-hub-edge-node_kube-system_d75d122e752b90d436a71af44c0a53be_1從重啟前后的對比看,邊緣節點在斷網重啟之后,節點上的 pod 能正常拉起,OpenYurt 的節點自治能力可以在斷網下保證業務的穩定運行。
恢復網絡,節點 Ready,觀察業務 pod 的狀態,網絡恢復后,業務 pod 狀態保持 running,有一次重啟記錄,符合預期。
root@master-node:~# kubectl get pods -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 1 11m 192.168.0.100 edge-node <none> <none>最后,我們利用 yurtctl 的能力將 OpenYurt 集群,轉換為原生 K8s 集群。同樣,可以觀察轉換過程中對現有業務不會有影響。
yurtctl revert --yurtctl-servant-image=registry.cn-hangzhou.aliyuncs.com/openyurt/yurtctl-servant:v0.2.1OpenYurt 作為阿里首個邊緣云原生開源項目,基于商業化產品 ACK@Edge,在集團內部經歷了長時間的打磨。已經應用在 CDN、IoT、盒馬、ENS、菜鳥物流等眾多場景。針對邊緣場景,該項目堅持保持原生 K8s 的特性,以 Addon 的形式提供了邊緣節點自治、云邊端一體化運維通道等能力。最近在社區同學的一起努力下又開源了邊緣單元化管理能力,同時后續還會繼續開源更多的邊緣管理能力,歡迎大家積極參與貢獻。釘釘搜索群號:31993519,即可進群交流。
原文鏈接:https://developer.aliyun.com/article/780961?
版權聲明:本文內容由阿里云實名注冊用戶自發貢獻,版權歸原作者所有,阿里云開發者社區不擁有其著作權,亦不承擔相應法律責任。具體規則請查看《阿里云開發者社區用戶服務協議》和《阿里云開發者社區知識產權保護指引》。如果您發現本社區中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社區將立刻刪除涉嫌侵權內容。總結
以上是生活随笔為你收集整理的OpenYurt入门-在树莓派上玩转OpenYurt的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 疫情之下的科技普惠:阿里云科技驱动中小企
- 下一篇: 客户端证书错误避坑指南