作者杜杨浩,腾讯云高级工程师,热衷于开源、容器和Kubernetes。目前主要从事镜像仓库,Kubernetes集群高可用&备份还原,以及边缘计算相关研发工作。
作者陈凯悦,腾讯云容器工程师,腾讯云边缘容器核心开发成员。
作者张鑫宇,腾讯云容器工程师,目前主要从事Kubernetes集群相关研发工作,边缘容器核心开发者之一。
SuperEdge[1]是腾讯推出的Kubernetes-native边缘计算管理框架。相比openyurt[2]以及kubeedge[3],SuperEdge除了具备Kubernetes零侵入以及边缘自治特性,还支持独有的分布式健康检查以及边缘服务访问控制等高级特性,极大地消减了云边网络不稳定对服务的影响,同时也很大程度上方便了边缘集群服务的发布与治理。
组件功能总结如下:
云端除了边缘集群部署的原生Kubernetes master组件(cloud-kube-APIServer,cloud-kube-controller以及cloud-kube-scheduler)外,主要管控组件还包括:
边端除了原生Kubernetes worker节点需要部署的kubelet,kube-proxy外,还添加了如下边缘计算组件:
SuperEdge可以支持原生Kubernetes的所有工作负载的应用部署,包括:
而对于边缘计算应用来说,具备如下独特点:
为了解决上述问题,SuperEdge创新性地构建了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-fh2bm 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如下:
边缘计算场景下,边缘节点与云端的网络环境十分复杂,连接并不可靠,在原生Kubernetes集群中,会造成APIServer和节点连接的中断,节点状态的异常,最终导致Pod的驱逐和endpoint的缺失,造成服务的中断和波动,具体来说原生Kubernetes处理如下:
因此,边缘计算场景仅仅依赖边端和APIServer的连接情况是不足以判断节点是否异常的,会因为网络的不可靠造成误判,影响正常服务。而相较于云端和边缘端的连接,显然边端节点之间的连接更为稳定,具有一定的参考价值,因此SuperEdge提出了边缘分布式健康检查机制。该机制中节点状态判定除了要考虑APIServer的因素外,还引入了节点的评估因素,进而对节点进行更为全面的状态判断。通过这个功能,能够避免由于云边网络不可靠造成的大量的Pod迁移和重建,保证服务的稳定
具体来说,主要通过如下三个层面增强节点状态判断的准确性:
而分布式健康检查最终的判断处理如下:
节点最终状态 | 云端判定正常 | 云端判定异常 |
---|---|---|
节点内部判定正常 | 正常 | 不再调度新的Pod到该节点(NoSchedule taint) |
节点内部判定异常 | 正常 | 驱逐存量Pod;从Endpoint列表摘除Pod;不再调度新的Pod到该节点 |
对于边缘计算的用户来说,他们除了想要享受Kubernetes自身带来的管理运维的便捷之外,同时也想具备弱网环境下的容灾能力,具体来说,如下:
而对于标准的Kubernentes,如果节点断网失联并且发生异常重启的行为后,现象如下:
SuperEdge自研的边缘自治就是为了解决上述问题的,具体来说边缘自治能达到如下效果:
其中,对于前两点来说可以通过上述介绍的分布式健康检查机制来实现,而后续两点可以通过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的云边隧道,云边隧道主要用于:代理云端访问边缘节点组件的请求,解决云端无法直接访问边缘节点的问题(边缘节点没有暴露在公网中)
架构图如下所示:
实现原理为:
而整个请求的代理转发流程如下:
本文依次介绍了开源边缘计算框架SuperEdge的特性,整体架构以及主要功能和原理。其中分布式健康检查以及边缘集群服务访问控制ServiceGroup是SuperEdge独有的特性功能。分布式健康检查很大程度避免了由于云边网络不可靠造成的大量Pod迁移和重建,保证了服务的稳定;而ServiceGroup则极大地方便了用户在共属同一个集群的不同机房或区域中各自部署一组服务,并且使得各个服务间的请求在本机房或本地域内部即可完成(闭环),避免了服务跨地域访问。除此之外还有边缘自治以及云边隧道等功能。
整体来说,SuperEdge采用无侵入的方式构建边缘集群,在原有Kubernetes组件保留不变的基础上新增了一些组件完成边缘计算的功能,既保留了Kubernetes强大的编排系统,同时也具备完善的边缘计算能力。
[1]
SuperEdge: https://github.com/superedge/superedge
[2]
openyurt: https://github.com/alibaba/openyurt
[3]
kubeedge: https://github.com/kubeedge/kubeedge
[4]
tunnel-cloud & tunnel-edge: https://github.com/superedge/superedge/blob/main/docs/components/tunnel.md
[5]
application-grid controller: https://github.com/superedge/superedge/blob/main/docs/components/service-group.md
[6]
edge-admission: https://github.com/superedge/superedge/blob/main/docs/components/edge-health.md
[7]
lite-apiserver: https://github.com/superedge/superedge/blob/main/docs/components/lite-apiserver.md
[8]
edge-health: https://github.com/superedge/superedge/blob/main/docs/components/edge-health.md
插播福利!!!
腾讯云原生后台回复关键字“手册” 即可获取
《腾讯云原生路线图手册》&《腾讯云原生最佳实践》