参考文章:
- KubeEdge 官方文档: kubeedge 入门指南
- EdgeMesh 官方文档: EdgeMesh 官方文档
介绍
kubeedge
KubeEdge是一个开源系统,将原生的容器化的业务流程和设备管理功能扩展到边缘节点。KubeEdge是基于Kubernetes构建的,并为云,边缘之间的网络通信,应用程序部署以及元数据同步提供核心基础架构支持。同时KubeEdge还支持MQTT,并允许开发人员编写自定义逻辑并在Edge上启用一定资源的设备进行通信。
kubeedge 的优势
- 边缘计算: 借助在Edge上运行的业务逻辑,可以让本地生成的数据,进行大量数据处理操作并对其进行保护。这样可以减少边缘和云之间的网络带宽需求和消耗,提高响应速度,降低成本并保护客户的数据隐私。
- 简化开发: 开发人员可以编写基于 HTTP 或 MQTT 的常规应用程序,对其进行容器化,然后在 Edge 或 Cloud 中的任何一个更合适的位置运行应用程序。
- Kubernetes原生支持: 借助KubeEdge,用户可以像在传统的Kubernetes集群一样,在Edge节点上编排应用程序,管理设备并监视应用程序和设备状态。
- 丰富的应用: 可以轻松地将现有的复杂机器学习,图像识别,事件处理等其他高级应用程序部署到Edge。
组件
- edged: 在边缘节点上运行并管理容器化应用程序的代理。
- EdgeHub: Web套接字客户端,负责与Cloud Service进行交互以进行边缘计算(例如KubeEdge体系结构中的Edge Controller)。这包括将云侧资源更新同步到边缘,并将边缘侧主机和设备状态变更报告给云。
- CloudHub: Web套接字服务器,负责在云端缓存信息、监视变更,并向EdgeHub端发送消息。
- EdgeController: kubernetes 的扩展控制器,用于管理边缘节点和 pod 的元数据,以便可以将数据定位到对应的边缘节点。
- EventBus: 一个与 MQTT 服务器(mosquitto)进行交互的 MQTT 客户端,为其他组件提供发布和订阅功能。
- DeviceTwin: 负责存储设备状态并将设备状态同步到云端。它还为应用程序提供查询接口。
- MetaManager: Edged端和 Edgehub端之间的消息处理器。它还负责将元数据存储到轻量级数据库(SQLite)或从轻量级数据库(SQLite)检索元数据。
EdgeMesh
EdgeMesh 作为 KubeEdge 集群的数据面组件,为应用程序提供了简单的服务发现与流量代理功能,从而屏蔽了边缘场景下复杂的网络结构。KubeEdge 基于 Kubernetes 构建,将云原生容器化应用程序编排能力延伸到了边缘。但是,在边缘计算场景下,网络拓扑较为复杂,不同区域中的边缘节点往往网络不互通,并且应用之间流量的互通是业务的首要需求,而 EdgeMesh 正是对此提供了一套解决方案。
EdgeMesh 的优势
- 高可用性:
- 利用 LibP2P 提供的能力,来打通边缘节点间的网络
- 将边缘节点间的通信分为局域网内和跨局域网
- 局域网内的通信:直接通信,
- 跨局域网的通信:打洞成功时 Agent 之间建立直连通道,否则通过 Server 中继转发
- 高可靠性(离线场景):
- 元数据通过 KubeEdge 边云通道下发,无需访问云端 apiserver
- EdgeMesh 内部集成轻量的节点级 DNS 服务器,服务发现不依赖云端 CoreDNS
- 极致轻量化:
- 每个节点有且仅有一个 Agent,节省边缘资源
用户价值
- 使用户具备了跨越不同局域网边到边/边到云/云到边的应用互访能力
- 相对于部署 CoreDNS + Kube-Proxy + CNI 这一套组件,用户只需要在节点部署一个 Agent 就能完成目标
关键功能
- 服务发现: 支持
- 流量治理:
- HTTP: 支持
- TCP: 支持
- Websocket: 支持
- HTTPS: 支持
- UDP: 支持
- 负载均衡:
- 轮训: 支持
- 随机: 支持
- 会话保持: 支持
- 边缘网关:
- 外部访问: 支持
- 多网卡监听: 支持
- 跨子网通信:
- 跨边云通信: 支持
- 跨局域网边边通信: 支持
- 边缘CNI: 暂时不具备的功能,但在后续版本中会支持
安装 KubeEdge
KubeEdge 依赖条件
- 已经部署好并正常的的 kubernetes 集群
- 云节点有一个固定的公网IP,确保边缘节点可以使用云节点的本地IP连接云节点
- 如果有防火墙或安全组,确保开放以下端口
- 10000: kubeedge-cloudcore
- 10002: kubeedge-cloudcore
- 10004: kubeedge-tunnelPort,和边缘节点通信,传输日志信息
安装 kubeedge 主要有两种方式: keadm 方式以及二进制手动部署方式,这里主要介绍使用 keadm 方式部署 kubeedge;
使用 keadm 部署时的唯一难点就是很多文件可能因为墙的原因无法直接下载到,所以需要自行下载好相关文件并放置到对应的目录下(/etc/kubeedge
)。
云端部署(CloudCore)
下载文件(云端)
从 Releases 下载适合自己 kubernetes 集群版本的 keadm,kubeedge 与 kubernetes 版本的兼容信息可以在 GitHub 的 README 上看到,这里选择下载的是 1.9.2 版本的 keadm
1
wget https://github.com/kubeedge/kubeedge/releases/download/v1.9.2/keadm-v1.9.2-linux-amd64.tar.gz
下载指定版本的 CRDS 文件,并放到云端节点的 /etc/kubeedge/crds 目录下
下载 cloudcore.service 文件,并放到云端节点 /etc/kubeedge 目录下
下载指定版本的 kubeedge 安装包并放到 /etc/kubeedge 目录下
1
wget https://github.com/kubeedge/kubeedge/releases/download/v1.9.2/kubeedge-v1.9.2-linux-amd64.tar.gz -P /etc/kubeedge
下载对应版本的 checksum 文件并放到 /etc/kubeedge 目录
1
wget https://github.com/kubeedge/kubeedge/releases/download/v1.9.2/checksum_kubeedge-v1.9.2-linux-amd64.tar.gz.txt -P /etc/kubeedge
安装 CloudCore
安装 keadm
1
2tar xf keadm-v1.9.2-linux-amd64.tar.gz
mv keadm-v1.9.2-linux-amd64/keadm/keadm /usr/local/bin/安装 CloudCore
1
keadm init --advertise-address="8.130.21.172" --kubeedge-version=1.9.2
如果家目录没有
.kube/config
文件,可以使用--kube-config={config_path}
指定 kubeconfig 文件所在位置配置 cloudcore 开机启动
1
systemctl enable --now cloudcore
边端部署(EdgeCore)
注意:
- 边端服务器只需要安装 Docker
- 边端服务器靠 EdgeMesh 实现服务发现与流量代理,所以不需要安装 kube-proxy
下载文件(边端)
从 Releases 下载适合自己 kubernetes 集群版本的 keadm,kubeedge 与 kubernetes 版本的兼容信息可以在 GitHub 的 README 上看到,这里选择下载的是 1.9.2 版本的 keadm
1
wget https://github.com/kubeedge/kubeedge/releases/download/v1.9.2/keadm-v1.9.2-linux-amd64.tar.gz
下载 edgecore.service 文件,并放到云端节点
/etc/kubeedge
目录下下载指定版本的 kubeedge 安装包并放到
/etc/kubeedge
目录下1
wget https://github.com/kubeedge/kubeedge/releases/download/v1.9.2/kubeedge-v1.9.2-linux-amd64.tar.gz -P /etc/kubeedge
下载对应版本的 checksum 文件并放到
/etc/kubeedge
目录1
wget https://github.com/kubeedge/kubeedge/releases/download/v1.9.2/checksum_kubeedge-v1.9.2-linux-amd64.tar.gz.txt -P /etc/kubeedge
安装 EdgeCore
安装 keadm
1
2tar xf keadm-v1.9.2-linux-amd64.tar.gz
mv keadm-v1.9.2-linux-amd64/keadm/keadm /usr/local/bin/在云端使用以下命令获取 token
1
keadm gettoken
在边端输入以下命令加入云端集群
1
2
3
4keadm join \
--cloudcore-ipport=8.130.21.172:10000 \
--kubeedge-version=1.9.2 \
--token=fd0b3de414624414cbe53cbc78da3fb19f3d9d3149cedae7c240245dd98d4eb8.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NTEwMTk5MDJ9.cUTfB2n2LFeHUXxB3OnPx-p4SR3EgdOEd9TA8h7gHGIedgeCore 默认使用的 cgroupDriver 为 cgroups,由于 Docker 以及 k8s 配置的是使用的 systemd,所以这里也需要修改
/etc/kubeedge/config/edgecore.yaml
配置文件,将modules.edged.cgroupDriver
的值改成 systemd1
2
3
4
5modules:
...
edged:
cgroupDriver: systemd
...修改完配置文件后重启 edgecore 服务
1
systemctl restart edgecore
配置开机启动 edgecore
1
systemctl enable edgecore
启用 kubectl logs 功能
kubectl logs
必须在使用 metrics-server 之前部署,通过以下操作激活功能:
以下步骤在云端操作
下载
certgen.sh
文件并放到 /etc/kubeedge 目录下,certgen.sh 文件可以在[项目仓库的](https://github.com/kubeedge/kubeedge/tree/master/build/tools)
找到修改 certgen.sh 文件中关于 kubernetes 集群 ca.pem 与 ca-key.pem 文件的位置
执行以下命令生成证书
1
2chmod +x certgen.sh
./certgen.sh stream在每个 k8s Master 节点执行以下命令设置 iptables
1
2
3
4
5
6
7
8
9
10
11
12
13export CLOUDCOREIPS="8.130.21.172"
iptables -t nat -A OUTPUT -p tcp --dport 10350 -j DNAT --to $CLOUDCOREIPS:10003
# 具体的端口可以使用以下命令查看
# kubectl describe cm -n kubeedge tunnelport
Name: tunnelport
Namespace: kubeedge
Labels: <none>
Annotations: tunnelportrecord.kubeedge.io: {"ipTunnelPort":{"172.18.24.158":10351},"port":{"10351":true}}
Data
====
Events: <none>端口 10003 和 10350 是 CloudStream 和 Edgecore 的默认端口,如果已发生变更,请使用您自己设置的端口。
如果不确定是否设置了 iptables,并且希望清除所有这些表。(如果您错误地设置了 iptables,它将阻止您使用 kubectl logs 功能)可以使用以下命令清理 iptables 规则1
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
修改 edgecore 与 cloudcore 服务的配置文件,将
cloudStream
和edgeStream
设置为enable: true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28# /etc/kubeedge/config/cloudcore.yaml 配置文件
modules:
...
cloudStream:
enable: true
streamPort: 10003
tlsStreamCAFile: /etc/kubeedge/ca/streamCA.crt
tlsStreamCertFile: /etc/kubeedge/certs/stream.crt
tlsStreamPrivateKeyFile: /etc/kubeedge/certs/stream.key
tlsTunnelCAFile: /etc/kubeedge/ca/rootCA.crt
tlsTunnelCertFile: /etc/kubeedge/certs/server.crt
tlsTunnelPrivateKeyFile: /etc/kubeedge/certs/server.key
tunnelPort: 10004
...
# /etc/kubeedge/config/edgecore.yaml 配置文件
modules:
...
edgeStream:
enable: true
handshakeTimeout: 30
readDeadline: 15
server: 8.130.21.172:10004
tlsTunnelCAFile: /etc/kubeedge/ca/rootCA.crt
tlsTunnelCertFile: /etc/kubeedge/certs/server.crt
tlsTunnelPrivateKeyFile: /etc/kubeedge/certs/server.key
writeDeadline: 15
...重新启动所有cloudcore和edgecore。
1
2
3
4
5# 云端
systemctl restart cloudcore
# 边端
systemctl restart edgecore
云端配置 Metrics-server
实现该功能点的是重复使用了 cloudstream 和 edgestream 模块。因此,您还需要执行 启用 kubectl logs 功能 的所有步骤。
配置 metrics-server 需要编译镜像,依赖 go 环境,所以需要先安装 go 编译环境
安装 go 环境
1
yum install -y golang
下载 metrics-server 源码
1
git clone https://github.com/kubernetes-sigs/metrics-server.git
构建容器镜像,由于仓库里面的 Dockerfile 中有个基础镜像
gcr.io/distroless/static:latest-$ARCH
要从国外gcr.io
下载,这里可以使用阿里云先同步该基础镜像到阿里云镜像仓库,然后修改 Dockerfile。还有就是 go 编译时需要下载一些依赖也是需要从国外下载,所系需要在 Dockerfile 中添加代理1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35# 进入到项目目录
cd metrics-server
# 修改后的 Dockerfile 内容如下
# Update the base image in Makefile when updating golang version. This has to
# be pre-pulled in order to work on GCB.
ARG ARCH
FROM golang:1.17.6 as build
WORKDIR /go/src/sigs.k8s.io/metrics-server
COPY go.mod .
COPY go.sum .
ENV http_proxy=http://10.1.10.4:8888
ENV https_proxy=http://10.1.10.4:8888
RUN go mod download
COPY pkg pkg
COPY cmd cmd
COPY Makefile Makefile
ARG ARCH
ARG GIT_COMMIT
ARG GIT_TAG
RUN make metrics-server
FROM registry.cn-hangzhou.aliyuncs.com/59izt/distroless-static:latest-$ARCH
COPY --from=build /go/src/sigs.k8s.io/metrics-server/metrics-server /
USER 65534
ENTRYPOINT ["/metrics-server"]
# 构建镜像
make container查看后建好的镜像
1
2
3
4docker images
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
gcr.io/k8s-staging-metrics-server/metrics-server-amd64 ac58d68b7c28d3e82902b66688379fe2 522585e2c2dc 14 minutes ago 69MB重新添加 tag,由于这里是异地构建镜像,所以需要将镜像上传到阿里云仓库
1
2docker tag 522585e2c2dc registry.cn-hangzhou.aliyuncs.com/59izt/metrics-server-kubeedge:latest
docker push registry.cn-hangzhou.aliyuncs.com/59izt/metrics-server-kubeedge:latest在 k8s-master01 节点下载镜像到本地,下载最新的 metrics-server 资源清单
1
2
3
4
5# 下载构建好的 metrics-server-kubeedge 镜像
docker pull registry.cn-hangzhou.aliyuncs.com/59izt/metrics-server-kubeedge:latest
# 下载最新的 metrics-server 资源清单
wget https://github.com/kubernetes-sigs/metrics-server/releases/download/metrics-server-helm-chart-3.8.2/components.yaml修改下载好的 metrics-server 资源清单,主需要修改的地方如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41spec:
# 0. 添加节点亲和性,将 metrics 服务部署到 master 节点
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values: k8s-master01
containers:
- args:
- --cert-dir=/tmp
- --secure-port=4443 # 1. 修改安全端口为 4443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls # 2. 添加以下内容
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem # change to front-proxy-ca.crt for kubeadm
- --requestheader-username-headers=X-Remote-User
- --requestheader-group-headers=X-Remote-Group
- --requestheader-extra-headers-prefix=X-Remote-Extra-
image: registry.cn-hangzhou.aliyuncs.com/59izt/metrics-server-kubeedge:latest # 3. 修改镜像使用自己同步的阿里云镜像
...
ports:
- containerPort: 4443 # 4. 修改容器暴露端口为 4443
name: https
protocol: TCP
...
volumeMounts:
- mountPath: /tmp
name: tmp-dir
- mountPath: /etc/kubernetes/pki # 5. 挂载卷到容器
name: ca-ssl
...
volumes:
- emptyDir: {}
name: tmp-dir
- name: ca-ssl # 6. 挂载证书到卷
hostPath:
path: /usr/local/kubernetes/ssl在需要部署 metrics-server 服务的节点上执行以下命令,添加 iptables 规则(必须项)
1
2export CLOUDCOREIPS="8.130.21.172"
iptables -t nat -A OUTPUT -p tcp --dport 10350 -j DNAT --to $CLOUDCOREIPS:10003执行以下命令创建 metrics-server 服务
1
2
3
4
5
6kubectl create -f components.yaml
# 查看服务状态
# kubectl get pod -n kube-system -l k8s-app=metrics-server -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
metrics-server-795cbdf57f-pwkv2 1/1 Running 0 9m19s 192.169.244.197 k8s-master01 <none> <none>验证是否能正常获取到 edge 节点的状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-edge-01 27m 1% 920Mi 26%
k8s-edge02 30m 1% 1180Mi 30%
k8s-edge03 37m 1% 949Mi 25%
k8s-master01 205m 5% 2840Mi 37%
k8s-node01 129m 3% 1709Mi 22%
k8s-node02 148m 3% 1688Mi 22%
# kubectl top pods
NAME CPU(cores) MEMORY(bytes)
alpine-test 0m 0Mi
hostname-edge-84cb45ccf4-gl7r9 0m 6Mi
hostname-lb-edge-5cdf5c758c-48cpz 1m 7Mi
hostname-lb-edge-5cdf5c758c-5w4bc 0m 6Mi
hostname-lb-edge-5cdf5c758c-f2z8c 1m 6Mi
nginx-deployment-67d7cd9d48-k8k68 0m 2Mi
nginx-https-84c9fc57f8-hs9tq 0m 3Mi
tcp-echo-deployment-85654c8b8f-q7s8l 0m 7Mi
websocket-test 0m 7Mi
ws-edge-5978d75769-4l7qk 0m 6Mi注意: metrics-server 服务必须部署在 cloudCore 服务所在的节点上,也就是 k8s master 节点,否则会出现无法访问 边缘节点的 10351 端口服务,如下:
1
E0905 03:57:32.195961 1 scraper.go:142] "Failed to scrape node, timeout to access kubelet" err="Get \"https://172.19.190.77:10351/metrics/resource\": context deadline exceeded" node="k8s-dev-edge01" timeout="10s"
安装 EdgeMesh
EdgeMesh 依赖条件
- 已经部署好并正常的的 kubernetes 集群
- 云节点有一个固定的公网IP,确保边缘节点可以使用云节点的本地IP连接云节点
- 如果有防火墙或安全组,确保开放以下端口
- 20004: edgemesh-serv
- 20006: edgemesh-agent
Helm 安装方式
修改 KubeEdge 配置
开启 Local APIServer,在云端,开启 dynamicController 模块,并重启 cloudcore
1
2
3
4
5
6
7
8
9# vim /etc/kubeedge/config/cloudcore.yaml
modules:
...
dynamicController:
enable: true
...
# 重启 cloudcore
systemctl restart cloudcore在边缘节点,打开 metaServer 模块(如果你的 KubeEdge < 1.8.0,还需关闭 edgeMesh 模块)
1
2
3
4
5
6
7
8
9
10# vim /etc/kubeedge/config/edgecore.yaml
modules:
...
edgeMesh:
enable: true # 由于这里安装的 kubeedge 版本是 1.9.2,所以可以启动 edgeMesh 模块
...
metaManager:
metaServer:
enable: true
...在边缘节点,配置 clusterDNS,clusterDomain,并重启 edgecore
1
2
3
4
5
6
7
8
9
10
11# vim /etc/kubeedge/config/edgecore.yaml
modules:
...
edged:
clusterDNS: 169.254.96.16
clusterDomain: cluster.local
...
# 重启 edgecore
systemctl restart edgecoreclusterDNS 设置的值 ‘169.254.96.16’ 来自于 commonConfig 中 dummyDeviceIP 的默认值,如需修改请保持两者一致,修改方式可以将 Chart 包下载到本地,然后修改其中 values.yaml 文件中的值即可
在边缘节点,测试 Local APIServer 是否开启
1
curl 127.0.0.1:10550/api/v1/services
安装 Charts
确保已经安装了 Helm 命令行工具
使用以下命令安装 edgeMesh
1
2
3
4
5# 实现下载好 chart 包到本地
wget https://raw.githubusercontent.com/kubeedge/edgemesh/main/build/helm/edgemesh.tgz
# 安装 edgemesh
helm install edgemesh --set server.nodeName=k8s-master01 --set server.advertiseAddress="{8.130.21.172}" edgemesh.tgzserver.nodeName 指定 edgemesh-server 部署的节点,server.advertiseAddress 指定 edgemesh-server 对外暴露的服务 IP 列表,多个 IP 之间使用逗号分隔,比如{119.8.211.54,100.10.1.4}。其中 server.advertiseAddress 是可以省略的,因为 edgemesh-server 会自动探测并配置这个列表,但不保证正确和齐全。
检查安装结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22# helm ls
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
edgemesh default 1 2022-04-26 10:14:53.534211625 +0800 CST deployed edgemesh-0.1.0 latest
# kubectl get all -n kubeedge -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/edgemesh-agent-5bkvn 1/1 Running 1 6h57m 10.1.30.36 k8s-edge02 <none> <none>
pod/edgemesh-agent-bddhn 1/1 Running 0 6h57m 172.24.22.86 k8s-node01 <none> <none>
pod/edgemesh-agent-nqw6c 1/1 Running 2 6h57m 10.206.0.7 k8s-edge-01 <none> <none>
pod/edgemesh-agent-r5zjd 1/1 Running 0 6h57m 172.18.24.158 k8s-master01 <none> <none>
pod/edgemesh-agent-rd7k9 1/1 Running 0 6h57m 172.24.22.87 k8s-node02 <none> <none>
pod/edgemesh-agent-vtflr 1/1 Running 0 111m 10.0.4.12 k8s-edge03 <none> <none>
pod/edgemesh-server-5b5d5c4d9f-z85wf 1/1 Running 0 6h57m 172.18.24.158 k8s-master01 <none> <none>
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
daemonset.apps/edgemesh-agent 6 6 6 6 6 <none> 6h57m edgemesh-agent kubeedge/edgemesh-agent:latest k8s-app=kubeedge,kubeedge=edgemesh-agent
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/edgemesh-server 1/1 1 1 6h57m edgemesh-server kubeedge/edgemesh-server:latest k8s-app=kubeedge,kubeedge=edgemesh-server
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/edgemesh-server-5b5d5c4d9f 1 1 1 6h57m edgemesh-server kubeedge/edgemesh-server:latest k8s-app=kubeedge,kubeedge=edgemesh-server,pod-template-hash=5b5d5c4d9f
测试用例
详细测试步骤参考 测试用例