作者李腾飞,腾讯容器技术研发工程师,腾讯云TKE后台研发,SuperEdge核心开发成员。
在边缘集群中,边缘端和云端为单向网络,云端无法主动连接边缘端,常见的解决方案是边缘端主动和云端(tunnel server)建立长连接,云端通过长连接将请求转发到边缘端。在云端隧道 server 实例扩容后需要考虑新增的实例对已有的边缘端长连接转发的影响。出于系统稳定性的考虑,能通过云边隧道采集到边缘端的监控信息。
ANP 主要用于代理转发 apiserver 的请求,架构图如下图所示:
ANP 的 server 仅支持单实例,如果是多实例会存在问题,下面根据多实例的架构图进行说明:
ANP 项目主要针对 K8s 1.16版本发布的特性 EgressSelector,在这个特性中 apiserver 会首先使用 HTTP CONNECT 方法建立隧道,然后通过隧道把请求边缘端的请求发送到 ANP Server,ANP Server 通过与 ANP Agent 建立的长连接,把请求发送到边缘端。业界常用的监控采集组件 Prometheus 是不支持 EgressSelector 特性的,因此使用 ANP 项目是无法支持节点监控的。
SuperEdge 云边隧道 tunnel 在方案设计时使用 DNS 做边缘节点的注册中心,注册中心存储的是 tunnel-edge 的ID 和 tunnel-edge 连接到 tunnel-cloud 的 podIp,在做 apiserver 到边缘端请求转发时可以根据注册中心的ID将请求转发到边缘端连接到的 tunnel cloud 的 pod 上,具体架构图如下所示:
上图中的 apiserver 组件可以是云端其他组件,比如 Prometheus,下面分别从自动扩缩容和节点监控对 tunnel 的使用场景做进一步的说明。
在多实例的场景下对比 ANP 项目,tunnel 具备以下的优势:
tunnel-cloud 除了根据内存和 CPU 的使用情况自动扩缩容之外,还可以根据与 tunnel-cloud 建立长连接的边缘节点的个数实现自动扩缩容,架构图如下:
{
"__name__": "tunnel_cloud_nodes",
"instance": "172.31.0.10:6000",
"job": "tunnel-cloud-metrics",
"kubernetes_namespace": "edge-system",
"kubernetes_pod_name": "tunnel-cloud-64ff7d9c9d-4lljh"
}
{
"kind": "APIResourceList",
"apiVersion": "v1",
"groupVersion": "custom.metrics.k8s.io/v1beta1",
"resources": [
{
"name": "namespaces/nodes_per_pod",
"singularName": "",
"namespaced": false,
"kind": "MetricValueList",
"verbs": [
"get"
]
},
{
"name": "pods/nodes_per_pod",
"singularName": "",
"namespaced": true,
"kind": "MetricValueList",
"verbs": [
"get"
]
}
]
}
{
"describedObject":{
"kind":"Pod",
"namespace":"edge-system",
"name":"tunnel-cloud-64ff7d9c9d-vmkxh",
"apiVersion":"/v1"
},
"metricName":"nodes_per_pod",
"timestamp":"2021-07-14T10:19:37Z",
"value":"1",
"selector":null
}
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: tunnel-cloud
namespace: edge-system
spec:
minReplicas: 1
maxReplicas: 10
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: tunnel-cloud
metrics:
- type: Pods
pods:
metric:
name: nodes_per_pod
target:
averageValue: 300 #平均每个pod连接的边缘节点的个数,超过这个数目就会触发扩容
type: AverageValue
节点监控主要采集边缘节点 kubelet 的 metrics 和 node-exporter 采集到的硬件、系统指标。在部署 Prometheus 时配置 pod 的 dns 指向 tunnel-dns,Prometheus 使用节点名访问边缘节点上的 kubelet 和 node-exporter,tunnel-dns 会把节点名解析为边缘节点的 tunnel-edge 连接的 tunnel-cloud 的 podIp,Prometheus 根据 podIp 访问 tunnel-cloud(其中获取 kubelet 的 metrics 访问的是10250端口,请求 node-exporter 访问的9100端口),tunnel-cloud 通过长连接隧道将请求转发到 tunnel-edge,由 tunnel-edge 向 kubelet 和 node-exporter 发起请求,整个流程的框图如下所示:
dnsConfig:
nameservers:
- <tunnel-dns的clusterip>
options:
- name: ndots
value: "5"
searches:
- edge-system.svc.cluster.local
- svc.cluster.local
- cluster.local
dnsPolicy: None
- job_name: node-cadvisor
kubernetes_sd_configs:
- role: node
scheme: https
tls_config:
insecure_skip_verify: true
relabel_configs:
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __address__
replacement: ${1}:10250
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /metrics/cadvisor
- source_labels: [__address__]
target_label: "unInstanceId"
replacement: "none"
- job_name: node-exporter
kubernetes_sd_configs:
- role: node
scheme: https
tls_config:
insecure_skip_verify: true
relabel_configs:
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __address__
replacement: ${1}:9100
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /metrics
- source_labels: [__address__]
target_label: "unInstanceId"
replacement: "none"
SuperEdge 的云边隧道方案(tunnel)相比社区的 ANP 方案,具有以下的特点:
当然我们也会继续完善 tunnel 的能力,使其能够满足更多场景的需求,根据社区小伙伴的反馈,接下来 tunnel 组件会支持以下功能:
云边隧道的支持云端 server 自动扩缩容和节点监控新特性已经在 SuperEdge release 0.5.0 开源,欢迎大家体验。我们也会持续提升 Tunnel 的能力,适用更加复杂的边缘网络场景,也欢迎对边缘计算感兴趣的公司、组织及个人一起共建 SuperEdge 边缘容器项目。
扫码了解 SuperEdge release 0.5.0 新特性:
[1]
ANP: 【https://github.com/kubernetes-sigs/apiserver-network-proxy】
[2]
自定义自动扩缩容策略: 【 https://github.com/superedge/superedge/blob/main/docs/components/tunnel-cloud-hpa_CN.md】
[3]
节点监控方案:【 https://github.com/superedge/superedge/blob/main/docs/components/deploy-monitor_CN.md】