SuperEdge介紹
SuperEdge是Kubernetes原生的邊緣容器方案,它將Kubernetes強大的容器管理能力擴展到邊緣計算場景中,針對邊緣計算場景中常見的技術挑戰(zhàn)提供了解決方案,如:單集群節(jié)點跨地域、云邊網(wǎng)絡不可靠、邊緣節(jié)點位于NAT網(wǎng)絡等。這些能力可以讓應用很容易地部署到邊緣計算節(jié)點上,并且可靠地運行,可以幫助您很方便地把分布在各處的計算資源放到一個Kubernetes集群中管理,包括但不限于:邊緣云計算資源、私有云資源、現(xiàn)場設備,打造屬于您的邊緣PaaS平臺。SuperEdge[1]支持所有Kubernetes資源類型、API接口、使用方式、運維工具,無額外的學習成本,也兼容其他云原生項目,如:Promethues,使用者可以結合其他所需的云原生項目一起使用。項目由以下公司共同發(fā)起:騰訊、Intel、VMware、虎牙直播、寒武紀、首都在線和美團。
SuperEdge中的ServiceGroup功能可以便捷地在共屬同一個集群的不同機房或區(qū)域中各自部署一組服務,只需要使用ServiceGroup提供的DeploymentGrid和ServiceGrid兩種資源,即可方便地將服務分別部署到這些節(jié)點組中,保證各區(qū)域服務數(shù)量及容災,并進行服務流量管控,使得各個服務間的請求在本機房或本地域內部即可完成,避免服務跨地域訪問。
在最新發(fā)布的SuperEdge release 0.2.0版本中:SuperEdge擴展了有狀態(tài)應用類型,引入了對應StatefulSets的StatefulSetGrid,方便有狀態(tài)應用在多地域的獨立部署和擴展;流量區(qū)域自治能力相應也支持了StatefulSets常配對的Headless Service;同時新增了按照地域進行灰度的功能,也即各NodeUnit內獨立部署的workload版本可以不同。
有狀態(tài)應用的支持
支持StatefulSets
最新版本的SuperEdge中,ServiceGroup支持了有狀態(tài)應用StatefulSets。除了保持和原生StatefulSets字段的完全一致、方便已有應用改造、無需擔心同步社區(qū)最新特性的同時,也繼續(xù)保持了ServiceGroup的核心特性,能便捷地在一個集群中的多個地域進行邊緣應用的獨立部署和統(tǒng)一運維。
如下圖所示,一個CDN集群需要在zone-1和zone-2兩個地域的機房內各完整部署一套StatefulSets應用,但是兩個地域網(wǎng)絡不互通
此時可以在云端部署下發(fā)如下格式的StatefulSetGrid
apiVersion: superedge.io/v1
kind: StatefulSetGrid
metadata:
spec:
gridUniqKey: <NodeLabel Key>
<statefulset-template>
即可方便地在兩個機房內自動部署對應的StatefulSets:StatefulSets-zone-1,StatefulSets-zone-2;同時保證云端與邊緣端應用的強一致,修改云端資源即可同步到邊端。
同時其中的拓撲key,也即gridUniqKey可以自行定義,相較于社區(qū)目前實現(xiàn)的三種選擇:"kubernetes.io/hostname","topology.kubernetes.io/zone"以及"topology.kubernetes.io/region",使用起來更加靈活。
另外,當該CDN集群納管了新區(qū)域的機房時,無需在新的機房內手動部署StatefulSets,ServiceGroup會自動在該新增地域內部署一套獨立的StatefulSets,極大地方便了邊緣有狀態(tài)應用的部署和運維。
流量區(qū)域自治能力支持Headless Service
由于地域之間的網(wǎng)絡限制,不同地域的機房并不互通,ServiceGroup提出了ServiceGrid的概念,無需在各個地域都部署一個對應本地workload的Service。只需部署ServiceGrid資源,生成的一個Service就會對應所有地域的workload,但在各地域內訪問Service時能夠保證流量的后端只限制在本地域內,保證了流量的區(qū)域自治能力。
對于StatefulSets而言,其每個Pod的名稱都是有序且固定的,因為這個特性,經(jīng)常和Headless Service搭配起來使用。Headless Service對應的每一個Endpoints都會有一個固定的對應的DNS域名,Pod之間可以相互訪問,集群也可以單獨訪問指定的Pod。
針對這個特點,StatefulSetGrid支持使用Headless Service的方式進行訪問,如下所示:
StatefulSetGrid提供屏蔽NodeUnit的統(tǒng)一Headless Service訪問形式:{StatefulSetGrid}-{0..N-1}.{ServiceGrid}-svc.ns.svc.cluster.local,上述訪問會對應實際各個NodeUnit的具體Pod:{StatefulSetGrid}-{NodeUnit}-{0..N-1}.{ServiceGrid}-svc.ns.svc.cluster.local。
舉個例子,部署如下的StatefulsetGrid和ClusterIP為None的ServiceGrid
apiVersion: superedge.io/v1
kind: StatefulSetGrid
metadata:
name: statefulsetgrid-demo
namespace: default
spec:
gridUniqKey: zone
template:
selector:
matchLabels:
appGrid: echo
serviceName: "servicegrid-demo-svc"
replicas: 3
template:
metadata:
labels:
appGrid: echo
spec:
terminationGracePeriodSeconds: 10
containers:
- image: superedge/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: {}
apiVersion: superedge.io/v1
kind: ServiceGrid
metadata:
name: servicegrid-demo
namespace: default
spec:
gridUniqKey: zone
template:
selector:
appGrid: echo
ports:
- protocol: TCP
port: 80
targetPort: 8080
clusterIP: None
如上資源會創(chuàng)建出一個名為servicegrid-demo-svc的Service,同時在各地域創(chuàng)建名為statefulsetgrid-demo-的StatefulSets。
每個NodeUnit內通過相同的Headless Service只會訪問本組內的Pod。也即,對于NodeUnit:zone-1來說,會訪問statefulsetgrid-demo-zone-1(StatefulSets)對應的Pod;而對于NodeUnit:zone-2來說,會訪問statefulsetgrid-demo-zone-2(StatefulSets)對應的Pod。
# execute on zone-1 nodeunit
[~]# curl statefulsetgrid-demo-0.servicegrid-demo-svc.default.svc.cluster.local|grep "pod name"
pod name: statefulsetgrid-demo-zone-1-0
[~]# curl statefulsetgrid-demo-1.servicegrid-demo-svc.default.svc.cluster.local|grep "pod name"
pod name: statefulsetgrid-demo-zone-1-1
[~]# curl statefulsetgrid-demo-2.servicegrid-demo-svc.default.svc.cluster.local|grep "pod name"
pod name: statefulsetgrid-demo-zone-1-2
...
# execute on zone-2 nodeunit
[~]# curl statefulsetgrid-demo-0.servicegrid-demo-svc.default.svc.cluster.local|grep "pod name"
pod name: statefulsetgrid-demo-zone-2-0
[~]# curl statefulsetgrid-demo-1.servicegrid-demo-svc.default.svc.cluster.local|grep "pod name"
pod name: statefulsetgrid-demo-zone-2-1
[~]# curl statefulsetgrid-demo-2.servicegrid-demo-svc.default.svc.cluster.local|grep "pod name"
pod name: statefulsetgrid-demo-zone-2-2
由于Kube-Proxy不會處理Headless Service,所以之前通過wrapper代理Kube-Proxy的方式行不通。
這里設計新增了statefulset-grid-daemon組件,該組件根據(jù)StatefulSets構建和更新對應的{StatefulSetGrid}-{0..N-1}.{StatefulSetGrid}-svc.ns.svc.cluster.local DNS A record,結合CoreDns的Host plugins,使得statefulset-grid-daemon可以添加原來CoreDns不存在的domain record,并且生效。
灰度功能
基于系統(tǒng)穩(wěn)定性和快速業(yè)務迭代的考慮,許多團隊使用了服務灰度發(fā)布的方式,也就是并非一次性將服務發(fā)布到全部的地域,而是只發(fā)布指定的幾個地域,經(jīng)過驗證沒有問題后再全量發(fā)布;抑或是進行A/B Test,可能同時存在v1、v2、v3等多個版本的實例,根據(jù)實際反饋和對比選擇更為適合的版本進行全量發(fā)布。
在邊緣場景中,還會存在一個集群納管的不同地域的機房需要部署不同版本應用程序的情況。比如一條高速公路上不同省份段的攝像頭,都需要獨立部署應用,該應用具有A,B,C等多種功能,可以通過應用的啟動參數(shù)進行控制。但由于道路跨多省,不同省份的攝像頭需要的功能不同,有的只需要A功能,有的只需要B功能,也即有不同地域部署不同應用的需求。這種場景下,也需要用到灰度的功能。
最新版SuperEdge的ServiceGroup支持了灰度功能,同時由于ServiceGroup的地域屬性,DeploymentGrid和StatefulSetGrid均支持按照NodeUnit進行地域維度的灰度。
所有地域使用相同的版本
這種情況使用相同的template創(chuàng)建workload,則無需添加任何額外字段
使用不同的template創(chuàng)建workload
支持template中包含image,replicas等在內的任意字段的灰度
apiVersion: superedge.io/v1
kind: DeploymentGrid
metadata:
name: deploymentgrid-demo
namespace: default
spec:
defaultTemplateName: test1
gridUniqKey: zone
template:
replicas: 1
selector:
matchLabels:
appGrid: echo
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
appGrid: echo
spec:
containers:
- image: superedge/echoserver:2.2
name: echo
templatePool:
test1:
replicas: 2
selector:
matchLabels:
appGrid: echo
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
appGrid: echo
spec:
containers:
- image: superedge/echoserver:2.5
name: echo
test2:
replicas: 3
selector:
matchLabels:
appGrid: echo
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
appGrid: echo
spec:
containers:
- image: superedge/echoserver:2.3
name: echo
ports:
- containerPort: 8080
protocol: TCP
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
templates:
zone1: test1
zone2: test2
templatePool代表待用的template實例列表,templates代表template和NodeUnit的對應關系。這個例子中,NodeUnit zone1地域將會使用名為test1的template,NodeUnit zone2地域將會使用名為test2的template,其余NodeUnit地域將會使用defaultTemplateName中指定的template,這里指定的是test1 template,如果defaultTemplateName不指定或者指定為default,則使用spec.template中的模板。更多字段和功能說明可以查看文檔介紹[2]
另外針對由ServiceGroup生成的各地域workload可能存在的負載不同情況,可以針對各地域workload分別設置不同的HPA策略,replicas字段不會被強制更新。
總結
當前ServiceGroup已具備常用的邊緣應用管理能力,也在多個實際業(yè)務場景中應用落地,獲得業(yè)務廣泛認可。我們仍然會繼續(xù)演進,提供更多有意義的能力,也歡迎對邊緣計算感興趣的公司、組織及個人一起共建SuperEdge邊緣容器項目。
參考資料
[1]SuperEdge:(https://github.com/superedge/superedge)
[2]文檔介紹:(https://github.com/superedge/superedge/blob/main/docs/components/serviceGroup.md#canary-deployment)