您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關如何分析SuperEdge 邊緣容器架構與原理,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
superedge是騰訊推出的Kubernetes-native邊緣計算管理框架。相比openyurt以及kubeedge,superedge除了具備Kubernetes零侵入以及邊緣自治特性,還支持獨有的分布式健康檢查以及邊緣服務訪問控制等高級特性,極大地消減了云邊網絡不穩定對服務的影響,同時也很大程度上方便了邊緣集群服務的發布與治理
Kubernetes-native:superedge在原生Kubernetes基礎上進行了擴展,增加了邊緣計算的某干組件,對Kubernetes完全無侵入;另外通過簡單部署superedge核心組件就可以使原生Kubernetes集群開啟邊緣計算功能;另外零侵入使得可以在邊緣集群上部署任何Kubernetes原生工作負載(deployment, statefulset, daemonset, and etc)
邊緣自治:superedge提供L3級別的邊緣自治能力,當邊端節點與云端網絡不穩定或者斷連時,邊緣節點依舊可以正常運行,不影響已經部署的邊緣服務
分布式健康檢查:superedge提供邊端分布式健康檢查能力,每個邊緣節點會部署edge-health,同一個邊緣集群中的邊緣節點會相互進行健康檢查,對節點進行狀態投票。這樣即便云邊網絡存在問題,只要邊緣端節點之間的連接正常,就不會對該節點進行驅逐;另外,分布式健康檢查還支持分組,把集群節點分成多個組(同一個機房的節點分到同一個組中),每個組內的節點之間相互檢查,這樣做的好處是避免集群規模增大后節點之間的數據交互特別大,難以達成一致;同時也適應邊緣節點在網絡拓撲上天然就分組的情形。整個設計避免了由于云邊網絡不穩定造成的大量的pod遷移和重建,保證了服務的穩定
服務訪問控制:superedge自研了ServiceGroup實現了基于邊緣計算的服務訪問控制。基于該特性只需構建DeploymentGrid以及ServiceGrid兩種Custom Resource,就可以便捷地在共屬同一個集群的不同機房或區域中各自部署一組服務,并且使得各個服務間的請求在本機房或本地域內部即可完成(閉環),避免了服務跨地域訪問。利用該特性可以極大地方便邊緣集群服務的發布與治理
云邊隧道:superedge支持自建隧道(目前支持TCP, HTTP and HTTPS)打通不同網絡環境下的云邊連接問題。實現對無公網IP邊緣節點的統一操作和維護
組件功能總結如下:
云端除了邊緣集群部署的原生Kubernetes master組件(cloud-kube-apiserver,cloud-kube-controller以及cloud-kube-scheduler)外,主要管控組件還包括:
tunnel-cloud:負責維持與邊緣節點tunnel-edge的網絡隧道,目前支持TCP/HTTP/HTTPS協議
application-grid controller:服務訪問控制ServiceGroup對應的Kubernetes Controller,負責管理DeploymentGrids以及ServiceGrids CRDs,并由這兩種CR生成對應的Kubernetes deployment以及service,同時自研實現服務拓撲感知,使得服務閉環訪問
edge-admission:通過邊端節點分布式健康檢查的狀態報告決定節點是否健康,并協助cloud-kube-controller執行相關處理動作(打taint)
邊端除了原生Kubernetes worker節點需要部署的kubelet,kube-proxy外,還添加了如下邊緣計算組件:
lite-apiserver:邊緣自治的核心組件,是cloud-kube-apiserver的代理服務,緩存了邊緣節點組件對apiserver的某些請求,當遇到這些請求而且與cloud-kube-apiserver網絡存在問題的時候會直接返回給client端
edge-health:邊端分布式健康檢查服務,負責執行具體的監控和探測操作,并進行投票選舉判斷節點是否健康
tunnel-edge:負責建立與云端邊緣集群tunnel-cloud的網絡隧道,并接受API請求,轉發給邊緣節點組件(kubelet)
application-grid wrapper:與application-grid controller結合完成ServiceGrid內的閉環服務訪問(服務拓撲感知)
superedge可以支持原生Kubernetes的所有工作負載的應用部署,包括:
deployment
statefulset
daemonset
job
cronjob
而對于邊緣計算應用來說,具備如下獨特點:
邊緣計算場景中,往往會在同一個集群中管理多個邊緣站點,每個邊緣站點內有一個或多個計算節點
同時希望在每個站點中都運行一組有業務邏輯聯系的服務,每個站點內的服務是一套完整的功能,可以為用戶提供服務
由于受到網絡限制,有業務聯系的服務之間不希望或者不能跨站點訪問
為了解決上述問題,superedge創新性地構建了ServiceGroup概念,方便用戶便捷地在共屬同一個集群的不同機房或區域中各自部署一組服務,并且使得各個服務間的請求在本機房或本地域內部即可完成(閉環),避免了服務跨地域訪問
ServiceGroup中涉及幾個關鍵概念:
NodeUnit通常是位于同一邊緣站點內的一個或多個計算資源實例,需要保證同一NodeUnit中的節點內網是通的
ServiceGroup組中的服務運行在一個NodeUnit之內
ServiceGroup允許用戶設置服務在一個NodeUnit中運行的pod(belongs to deployment)數量
ServiceGroup能夠把服務之間的調用限制在本NodeUnit內
NodeGroup包含一個或者多個 NodeUnit
保證在集合中每個NodeUnit上均部署ServiceGroup中的服務
當集群中增加NodeUnit時會自動將ServiceGroup中的服務部署到新增NodeUnit
ServiceGroup包含一個或者多個業務服務
適用場景:
業務需要打包部署;
需要在每一個NodeUnit中均運行起來并且保證pod數量
需要將服務之間的調用控制在同一個 NodeUnit 中,不能將流量轉發到其他NodeUnit上
注意:ServiceGroup是一種抽象資源概念,一個集群中可以創建多個ServiceGroup
下面以一個具體例子說明ServiceGroup功能:
# step1: labels edge nodes $ kubectl get nodes NAME STATUS ROLES AGE VERSION node0 Ready <none> 16d v1.16.7 node1 Ready <none> 16d v1.16.7 node2 Ready <none> 16d v1.16.7 # nodeunit1(nodegroup and servicegroup zone1) $ kubectl --kubeconfig config label nodes node0 zone1=nodeunit1 # nodeunit2(nodegroup and servicegroup zone1) $ kubectl --kubeconfig config label nodes node1 zone1=nodeunit2 $ kubectl --kubeconfig config label nodes node2 zone1=nodeunit2 # step2: deploy echo DeploymentGrid $ cat <<EOF | kubectl --kubeconfig config apply -f - apiVersion: superedge.io/v1 kind: DeploymentGrid metadata: name: deploymentgrid-demo namespace: default spec: gridUniqKey: zone1 template: replicas: 2 selector: matchLabels: appGrid: echo strategy: {} template: metadata: creationTimestamp: null labels: appGrid: echo spec: containers: - image: gcr.io/kubernetes-e2e-test-images/echoserver:2.2 name: echo ports: - containerPort: 8080 protocol: TCP env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP resources: {} EOF deploymentgrid.superedge.io/deploymentgrid-demo created # note that there are two deployments generated and deployed into both nodeunit1 and nodeunit2 $ kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE deploymentgrid-demo-nodeunit1 2/2 2 2 5m50s deploymentgrid-demo-nodeunit2 2/2 2 2 5m50s $ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES deploymentgrid-demo-nodeunit1-65bbb7c6bb-6lcmt 1/1 Running 0 5m34s 172.16.0.16 node0 <none> <none> deploymentgrid-demo-nodeunit1-65bbb7c6bb-hvmlg 1/1 Running 0 6m10s 172.16.0.15 node0 <none> <none> deploymentgrid-demo-nodeunit2-56dd647d7-fh3bm 1/1 Running 0 5m34s 172.16.1.12 node1 <none> <none> deploymentgrid-demo-nodeunit2-56dd647d7-gb2j8 1/1 Running 0 6m10s 172.16.2.9 node2 <none> <none> # step3: deploy echo ServiceGrid $ cat <<EOF | kubectl --kubeconfig config apply -f - apiVersion: superedge.io/v1 kind: ServiceGrid metadata: name: servicegrid-demo namespace: default spec: gridUniqKey: zone1 template: selector: appGrid: echo ports: - protocol: TCP port: 80 targetPort: 8080 EOF servicegrid.superedge.io/servicegrid-demo created # note that there is only one relevant service generated $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 192.168.0.1 <none> 443/TCP 16d servicegrid-demo-svc ClusterIP 192.168.6.139 <none> 80/TCP 10m # step4: access servicegrid-demo-svc(service topology and closed-looped) # execute on onde0 $ curl 192.168.6.139|grep "node name" node name: node0 # execute on node1 and node2 $ curl 192.168.6.139|grep "node name" node name: node2 $ curl 192.168.6.139|grep "node name" node name: node1
通過上面的例子總結ServiceGroup如下:
NodeUnit和NodeGroup以及ServiceGroup都是一種概念,具體來說實際使用中對應關系如下:
NodeUnit是具有相同label key以及value的一組邊緣節點
NodeGroup是具有相同label key的一組NodeUnit(不同value)
ServiceGroup具體由兩種CRD構成:DepolymentGrid以及ServiceGrid,具備相同的gridUniqKey
gridUniqKey值與NodeGroup的label key對應,也即ServiceGroup是與NodeGroup一一對應,而NodeGroup對應多個NodeUnit,同時NodeGroup中的每一個NodeUnit都會部署ServiceGroup對應deployment,這些deployment(deploymentgridName-NodeUnit命名)通過nodeSelector親和性固定某個NodeUnit上,并通過服務拓撲感知限制在該NodeUnit內訪問
邊緣計算場景下,邊緣節點與云端的網絡環境十分復雜,連接并不可靠,在原生Kubernetes集群中,會造成apiserver和節點連接的中斷,節點狀態的異常,最終導致pod的驅逐和endpoint的缺失,造成服務的中斷和波動,具體來說原生Kubernetes處理如下:
失聯的節點被置為ConditionUnknown狀態,并被添加NoSchedule和NoExecute的taints
失聯的節點上的pod被驅逐,并在其他節點上進行重建
失聯的節點上的pod從Service的Endpoint列表中移除
因此,邊緣計算場景僅僅依賴邊端和apiserver的連接情況是不足以判斷節點是否異常的,會因為網絡的不可靠造成誤判,影響正常服務。而相較于云端和邊緣端的連接,顯然邊端節點之間的連接更為穩定,具有一定的參考價值,因此superedge提出了邊緣分布式健康檢查機制。該機制中節點狀態判定除了要考慮apiserver的因素外,還引入了節點的評估因素,進而對節點進行更為全面的狀態判斷。通過這個功能,能夠避免由于云邊網絡不可靠造成的大量的pod遷移和重建,保證服務的穩定
具體來說,主要通過如下三個層面增強節點狀態判斷的準確性:
每個節點定期探測其他節點健康狀態
集群內所有節點定期投票決定各節點的狀態
云端和邊端節點共同決定節點狀態
而分布式健康檢查最終的判斷處理如下:
節點最終狀態 | 云端判定正常 | 云端判定異常 |
---|---|---|
節點內部判定正常 | 正常 | 不再調度新的pod到該節點(NoSchedule taint) |
節點內部判定異常 | 正常 | 驅逐存量pod;從Endpoint列表摘除pod;不再調度新的pod到該節點 |
對于邊緣計算的用戶來說,他們除了想要享受Kubernetes自身帶來的管理運維的便捷之外,同時也想具備弱網環境下的容災能力,具體來說,如下:
節點即使和master失聯,節點上的業務能繼續運行
保證如果業務容器異常退出或者掛掉,kubelet 能繼續拉起
還要保證節點重啟后,業務能繼續重新被拉起來
用戶在廠房內部署的是微服務,需要保證節點重啟后,同一個廠房內的微服務可以訪問
而對于標準的Kubernentes,如果節點斷網失聯并且發生異常重啟的行為后,現象如下:
失聯的節點狀態置為ConditionUnknown狀態
失聯的節點上的業務進程異常退出后,容器可以被拉起
失聯的節點上的 Pod IP 從 Endpoint 列表中摘除
失聯的節點發生重啟后,容器全部消失不會被拉起
superedge自研的邊緣自治就是為了解決上述問題的,具體來說邊緣自治能達到如下效果:
節點會被置為ConditionUnknown狀態,但是服務依舊可用(pod不會被驅逐以及從endpoint列表中剔除)
多節點斷網情況下,Pod 業務正常運行,微服務能力正常提供
多節點斷網情況下并重啟后,Pod 會被重新拉起并正常運行
多節點斷網情況下并重啟后,所有的微服務可以被正常訪問
其中,對于前兩點來說可以通過上述介紹的分布式健康檢查機制來實現,而后續兩點可以通過lite-apiserver,網絡快照以及DNS解決方案實現,如下:
superedge通過在邊端加了一層鏡像lite-apiserver組件,使得所有邊端節點對于云端kube-apiserver的請求,都會指向lite-apiserver組件:
而lite-apiserver其實就是個代理,緩存了一些kube-apiserver請求,當遇到這些請求而且與apiserver不通的時候就直接返回給client:
總的來說:對于邊緣節點的組件,lite-apiserver提供的功能就是kube-apiserver,但是一方面lite-apiserver只對本節點有效,另一方面資源占用很少。在網絡通暢的情況下,lite-apiserver組件對于節點組件來說是透明的;而當網絡異常情況,lite-apiserver組件會把本節點需要的數據返回給節點上組件,保證節點組件不會受網絡異常情況影響
通過lite-apiserver可以實現邊緣節點斷網情況下重啟后pod可以被正常拉起,但是根據原生Kubernetes原理,拉起后的pod ip會發生改變,這在某些情況下是不能允許的,為此superedge設計了網絡快照機制保障邊緣節點重啟,pod拉起后ip保存不變。具體來說就是將節點上組件的網絡信息定期快照,并在節點重啟后進行恢復
通過lite-apiserver以及網絡快照機制可以保障邊緣節點斷網情況下重啟后,Pod會被重新拉起并正常運行,同時微服務也運行正常。而服務之間相互訪問就會涉及一個域名解析的問題:通常來說在集群內部我們使用coredns來做域名解析,且一般部署為Deployment形式,但是在邊緣計算情況下,節點之間可能是不在一個局域網,很可能是跨可用區的,這個時候coredns服務就可能訪問不通。為了保障dns訪問始終正常,superedge設計了專門的本地dns解決方案,如下:
本地dns采用DaemonSet方式部署coredns,保證每個節點都有可用的coredns,同時修改每個節點上kubelet的啟動參數--cluster-dns
,將其指向本機私有IP(每個節點都相同)。這樣就保證了即使在斷網的情況下也能進行域名解析。
總的來說,superedge是以lite-apiserver機制為基礎,并結合分布式健康檢查機制、網絡快照以及本地coredns,保證了邊緣容器集群在弱網環境下的網絡可靠性。另外隨著邊緣自治的級別越高,所需要的組件會越來越多
最后介紹一下superedge的云邊隧道,云邊隧道主要用于:代理云端訪問邊緣節點組件的請求,解決云端無法直接訪問邊緣節點的問題(邊緣節點沒有暴露在公網中)
架構圖如下所示:
實現原理為:
邊緣節點上tunnel-edge主動連接云端tunnel-cloud service,tunnel-cloud service根據負載均衡策略將請求轉到tunnel-cloud的具體pod上
tunnel-edge與tunnel-cloud建立grpc連接后,tunnel-cloud會把自身的podIp和tunnel-edge所在節點的nodeName的映射寫入DNS(tunnel dns)。grpc連接斷開之后,tunnel-cloud會刪除相關podIp和節點名的映射
而整個請求的代理轉發流程如下:
apiserver或者其它云端的應用訪問邊緣節點上的kubelet或者其它應用時,tunnel-dns通過DNS劫持(將host中的節點名解析為tunnel-cloud的podIp)把請求轉發到tunnel-cloud的pod上
tunnel-cloud根據節點名把請求信息轉發到節點名對應的與tunnel-edge建立的grpc連接上
tunnel-edge根據接收的請求信息請求邊緣節點上的應用
本文依次介紹了開源邊緣計算框架SuperEdge的特性,整體架構以及主要功能和原理。其中分布式健康檢查以及邊緣集群服務訪問控制ServiceGroup是SuperEdge獨有的特性功能。分布式健康檢查很大程度避免了由于云邊網絡不可靠造成的大量pod遷移和重建,保證了服務的穩定;而ServiceGroup則極大地方便了用戶在共屬同一個集群的不同機房或區域中各自部署一組服務,并且使得各個服務間的請求在本機房或本地域內部即可完成(閉環),避免了服務跨地域訪問。除此之外還有邊緣自治以及云邊隧道等功能。
整體來說,SuperEdge采用無侵入的方式構建邊緣集群,在原有Kubernetes組件保留不變的基礎上新增了一些組件完成邊緣計算的功能,既保留了Kubernetes強大的編排系統,同時也具備完善的邊緣計算能力。
看完上述內容,你們對如何分析SuperEdge 邊緣容器架構與原理有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。