KubeEdge 1.2.0 部署

本文介绍了如何在两台 ubuntu 16.04 64 bit 双核 CPU 虚拟机上从源码开始部署 KubeEdge 1.2.0 集群的过程,云端 Kubernetes 版本为 1.17.3,Golang 版本为1.12.4。本文基于 KubeEdge 1.1.0 部署文章,具有一定实践参考意义。限于精力和能力,对本文所述不提供技术支持。

一、概述

1.1 环境

云端:ubuntu 16.04 64 bit,用户名为 ubuntu。IP 为 192.168.0.102。
边缘端:同上,IP 为 192.168.0.140。
KubeEdge部署涉及两端:

  • 云端
    docker, kubernetes 集群和 KubeEdge 云端核心模块。
  • 边缘端
    docker, mqtt 和 KubeEdge 边缘端核心模块。

技术总结:
1、搭建编译环境(建议自行编译源码),编译系统内存需足够大(如4GB)。
2、部署k8s,其中需要安装docker,安装k8s master节点,node不需要安装。
3、编译 KubeEdge,生成证书,分发证书。创建crds。
4、先运行得到配置文件,再修改。注意配置文件位置,注意系统平台框架。
5、检查主机名称,必须合规,否则注册不了。
6、运行。
7、KubeEdge 不完全等同于 k8s,k8s的部分命令还没有实现。

1.2版本使用情况:
1、边缘端系统设置默认网关,否则会有段错误,一般PC系统均有默认值,但 ARM 平台不一定,故可能会出现。1.2版本发布后已修正。
2、边缘端连接上云端,但边缘端停止,后再启动,此时需要花费几分钟才能连上云端。

1.2 依赖

依赖组件(含工具、编译器)及版本:

本文部署时间约为2020年2月中下旬。KubeEdge目前在快速开发中,请注时效性,以官方文档为准,本文仅针对 KubeEdge 1.2.0 有效。

1.3 方法论

最权威的莫过于 KubeEdge 官方安装文档:https://docs.kubeedge.io/en/latest/setup/setup.html 。该文档从源码编译到安装,均有涉及。然作为初学者,个人认为官方的文档还不够细致。网上也有很多安装部署教程,虽然方法不同,但目的是一样的。这里根据笔者经验简述如下:

  • 步步为营
    根据官方文档安装,先产生证书,再编译源码得到云端和边缘端核心程序。再修改配置文件,最后运行。

  • 事预则立
    下载官方编译好的二进制文件(cloudcore、edgecore),或者自行编译源码得到这两个二进制文件。准备好配置文件(并做适应性修改)。然后再运行。本文采用此方式。先准备好所有的文件,并统一放置到部署工程目录。

需要注意的是,KubeEdge 官方文档只涉及 KubeEdge 有关的部署,KubeEdge 还要依赖 docker 和 kubernetes(边缘端还要依赖 mosquitto)。而这些需要实践者额外进行,为减少篇幅,本文不过多涉及,但给出部署文章链接。

1.4 新版本主要变化

1.2.0 版本的云边端配置由各自的程序生成默认的配置,再手动修改,相比 1.1.0 版本方便很多。
新版本的边缘端默认自动注册云端(需在配置文件中指定云端IP)。
新版本加强了异步通信。

二、准备

在开始之前,必须先安装 Docker 并部署k8s集群
Docker 安装可参考这里,kubernetes 安装可参考这里。需要指出的是,kubernetes 只部署 master 即可,node 无须部署。但必须安装网络插件(此处存疑,如果不安装,状态不是 Ready)。

2.1 创建部署文件目录

官方文档建议创建单独的目录存储二进制文件,如~/cmd/,在部署 1.1.0 版本时笔者也创建目录,但新版本做了优化,笔者认为无须部署目录,故省略。

2.2 KubeEdge 二进制

本文使用的 KubeEdge 是从源码编译得到。

2.2.1 官方编译好的文件

https://github.com/kubeedge/kubeedge/releases 下载官方编译好的二进制。压缩包名称为 kubeedge-v1.2.0-linux-amd64.tar.gz 。
也可以通过编译源码得到,方法参考文后。
另外,除了编译好的二进制外,还需要下载源码,地址为: https://github.com/kubeedge/kubeedge 。因为部分配置文件只在仓库源码中才可找到(当然,也可以直接在 github 仓库上找到对应的文件下载)。

2.2.2 KubeEdge 源码编译

1、Golang 环境搭建
下载好 golang,并解压:

1
2
# mkdir ~/tools
# tar xf go1.12.14.linux-amd64.tar.gz -C ~/tools

在 ~/.bashrc 文件最后添加:

1
2
3
export PATH=$PATH:/home/ubuntu/tools/go/bin
export GOROOT=/home/ubuntu/kubeedge
export GOPATH=/home/ubuntu/kubeedge

执行 source ~/.bashrc 生效。验证:

1
2
# ubuntu@ubuntu:~/kubeedge$ go version
go version go1.12.14 linux/amd64

2、克隆仓库:

1
# git clone https://github.com/kubeedge/kubeedge.git $GOPATH/src/github.com/kubeedge/kubeedge

如果克隆速度慢,可以直接下载zip包,并解压源码到 $GOPATH/src/github.com/kubeedge/kubeedge,注意,这个目录一定是源码所在目录。
切换 1.2.0 分支:

1
# git checkout -b release-1.2 remotes/origin/release-1.2

3、检测 gcc 版本:

1
2
3
# gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.

如果没有安装 gcc,则自行安装。

编译云端:

1
2
3
# cd $GOPATH/src/github.com/kubeedge/kubeedge/
# make all WHAT=cloudcore (注:进行coloud目录,执行make cloudcore 也可以,下类似)

编译边缘端:

1
2
3
# cd $GOPATH/src/github.com/kubeedge/kubeedge
# make all WHAT=edgecore

生成的二进制位于_output/local/bin/目录下。

2.3 生成证书

1
2
# $GOPATH/src/github.com/kubeedge/kubeedge/build/tools/certgen.sh genCertAndKey edge

ca 和 certs 分别位于 /etc/kubeedge/ca 和 /etc/kubeedge/certs 目录。
注:实际上,生成的证书可以复用,这样在迁移时比较方便,但如果是不同的项目,建议用不同的证书。

2.4 创建设备模块和设备CRD yaml 文件

1
2
3
4
5
6
7
# cd $GOPATH/src/github.com/kubeedge/kubeedge/build/crds/devices
# kubectl create -f devices_v1alpha1_devicemodel.yaml
# kubectl create -f devices_v1alpha1_device.yaml

# cd $GOPATH/src/github.com/kubeedge/kubeedge/build/crds/reliablesyncs
# kubectl create -f cluster_objectsync_v1alpha1.yaml
# kubectl create -f objectsync_v1alpha1.yaml

注:新版本的 yaml 文件有两类,在 devices 和 reliablesyncs 目录。可用kubectl get crds查看。

2.6 配置云端节点

新版本配置文件由 cloudcore 程序生成,执行:

1
2
3
# cd $GOPATH/src/github.com/kubeedge/kubeedge/cloud
# mkdir -p /etc/kubeedge/config/
# ./cloudcore --minconfig > /etc/kubeedge/config/cloudcore.yaml

注1:cloudcore --minconfig生成最小配置,类似有cloudcore --defaultconfig
注2:cloudcore 默认使用的配置文件为/etc/kubeedge/config/cloudcore.yaml
边缘端类似,下省略。

接着修改配置文件:

1
# vim /etc/kubeedge/config/cloudcore.yaml 

官方默认为kubeconfig: "/root/.kube/config",本文改为 kubeconfig: "/home/ubuntu/.kube/config"。其它保持默认。

2.7 配置边缘节点

新版本配置文件由 edgecore 程序生成,因此,需要在边缘端机器上执行。具体参考下文。

2.8 mqtt

mqtt 只有边缘端需要
如果边缘端为 ubuntu 系统,直接使用源安装:

1
2
3
4
5
# add-apt-repository ppa:mosquitto-dev/mosquitto-ppa // 添加源
# apt-get update // 更新
# apt-get install mosquitto // 安装mqtt服务端
# apt-get install mosquitto-clients // 如果需要测试,则安装mqtt客户端

另外也可以使用源码编译。

在 ubuntu 系统,安装 mosquitto 成功后会自动启动服务。由于 KubeEdge 使用多个端口,故需用配置文件。服务端添加多端口:

1
2
3
4
5
vim /etc/mosquitto/conf.d/port.conf
port 1883
listener 1884
```
此处指定 1883 和 1884 端口,从 KubeEdge 生成配置文件可知。没有指定协议,默认使用 mqtt。修改配置后需要重启:

/etc/init.d/mosquitto restart

1
2

或者手动启动:

/usr/sbin/mosquitto -d -c /etc/mosquitto/mosquitto.conf

1
2
3
建议使用系统级别服务,预防漏掉此步骤,导致 KubeEdge 测试失败。  

可用如下命令验证服务是否正常:

mosquitto_pub -h <mqtt服务IP> -p 1884 -t “hello” -m “this is hello world”

1
2
3
如果出现`Error: Connection refused`表示服务(及对应的端口)未启动。  

在嵌入式 ARM Linux 环境中,Buildroot 已包含 mosquitto,可直接勾选。此处略,根据笔者实验,Buildroot 的 mosquitto 所有配置均在文件 /etc/mosquitto/mosquitto.conf 中。使用如下命令操作:

systemctl restart mosquitto // 重启
systemctl stop mosquitto // 停止

1
2
3
4
5
6
7

## 三、部署

### 3.1 云端

#### 3.1.1 查看 k8s 集群
查看节点状态:

kubectl get node

NAME STATUS ROLES AGE VERSION
latelee-master Ready master 2m v1.17.0

1
2
3
4
此刻只有云端节点就绪。  

#### 3.1.3 运行云端核心
可以另建目录运行程序,也可以在源码目录,此处选择后者,方便调试。

cd $GOPATH/src/github.com/kubeedge/kubeedge/cloud

./cloudcore // 建议先如此,方便观察日志

也可以:

nohup ./cloudcore > cloudcore.log 2>&1 &

1
2
如果使用系统服务方式,启动脚本为`build/tools/cloudcore.service`,需修改`ExecStart`为真实值。  
示例如下:

[Unit]
Description=cloudcore.service

[Service]
Type=simple
Restart=always
ExecStart=/etc/kubeedge/cloudcore

[Install]
WantedBy=multi-user.target

1
添加服务命令:

cp build/tools/cloudcore.service /etc/systemd/system/cloudcore.service
sudo systemctl daemon-reload
sudo systemctl start cloudcore

1
2
3
4

### 3.2 边缘端
#### 3.2.1 分发
前面已经准备好了文件,直接部署就方便很多。注意,需要将证书和边缘端文件拷贝到边缘机器上。方式多种,建议使用 scp 命令。前提是安装了 SSH 协议。**在边缘端机器上执行拷贝(也称为分发)示例**:

mkdir -p /etc/kubeedge/config ~/kubeedge/

cd ~/kubeedge/

scp -r 192.168.0.102:/etc/kubeedge/ca /etc/kubeedge

scp -r 192.168.0.102:/etc/kubeedge/certs /etc/kubeedge

scp -r 192.168.0.102:/home/ubuntu/kubeedge/src/github.com/kubeedge/kubeedge/edge/edgecore ~/kubeedge/

1
2
3
4
5
6
7
注1:此操作在边缘端机器上,非云端。假设部署工程目录为`~/kubeedge`。  
注2:此处直接将云端位于`/etc`目录的证书拷贝到边缘端机器的 /etc/kubeedge 目录。将边缘端文件拷贝到 ~/kubeedge 目录。
笔者配置了 SSH 允许 root 登陆,并添加了公钥。所以无须输入密码。如无此方式,可手动拷贝。
注3:接注2,如果以其它登陆用户身份拷贝,可在IP地址前加用户名,如`sudo scp -r latelee@192.168.0.102:/etc/kubeedge/* /etc/kubeedge`。

#### 3.2.2 配置
并生成配置文件:

./edgecore –minconfig > /etc/kubeedge/config/edgecore.yaml

1
修改配置文件:

vim /etc/kubeedge/config/edgecore.yaml

1
2
3
4
5
注意2处地方。修改`websocket`下的`server`,默认为`127.0.0.1:10000`,需改为实际云端 IP 地址,此处为`192.168.0.102:10000`。另一处是`podSandboxImage`,X86平台为`podSandboxImage: kubeedge/pause:3.1`,ARM 平台根据位数不同,可设为`kubeedge/pause-arm:3.1`或`ubeedge/pause-arm64:3.1`。  
其它要点:cgroup 驱动默认值为:`cgroupDriver: cgroupfs`,无须改 Docker 配置。网络设备接口名称及 IP 地址,会运行上述命令时自动检测获取,无须修改。

#### 3.2.3 运行
接上,运行边缘端核心:

./edgecore // 建议先如此,方便观察日志

也可以:

nohup ./edgecore > edgecore.log 2>&1 &

1
2
3

如果使用系统服务方式,启动脚本为`build/tools/edgecore.service`,需修改`ExecStart`为真实值。
示例如下:

[Unit]
Description=edgecore.service

[Service]
Type=simple
Restart=always
ExecStart=/etc/kubeedge/edgecore

[Install]
WantedBy=multi-user.target

1
添加服务:

cp build/tools/edgecore.service /etc/systemd/system/edgecore.service
sudo systemctl daemon-reload
sudo systemctl start edgecore

1
2

这里再强调一次 mqtt,另起终端,运行命令:

/usr/sbin/mosquitto -d -c /etc/mosquitto/mosquitto.conf

1
2
3
4

### 3.3 验证

在云端查看状态:

kubectl get nodes

NAME STATUS ROLES AGE VERSION
latelee-master Ready master 49m v1.17.3
latelee-node Ready edge 4m8s v1.17.1-kubeedge-v0.0.0-master+$Format:%h$

1
2
3
云端和边缘端均为 Ready 状态。  

尝试部署官方的 deployment:

kubectl apply -f $GOPATH/src/github.com/kubeedge/kubeedge/build/deployment.yaml

1
输出示例:

kubectl get pod -owide

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-77698bff7d-t4pkg 1/1 Running 0 3m11s latelee-node

1
扩容测试:

kubectl scale deployment nginx-deployment –replicas=4

1
2
3
预期效果:有4个pod出现,但只有1个正常运行,因为该 deployment 导出了节点端口,前面的 pod 已经占用,无法再分配。理论上,如果有4个节点,则会自动将 deployment 调度到4个节点上。  

删除:

kubectl delete -f $GOPATH/src/github.com/kubeedge/kubeedge/build/deployment.yaml

1
2
3
4
5
6

注:截至2020年3月中下旬,KubeEdge 环境中,是不支持`kubectl logs`和`kubectl exec`命令的,官方说法未来会支持。

## 四、ARM部署
ARM的部署十分简单,将 edgecore 交叉编译即可,其它与 X86 环境是一致的,这里再列一次:创建对应的目录,分发证书,启动mqtt,运行。
安装交叉编译器:

sudo apt-get install gcc-arm-linux-gnueabihf

1
设置环境变量并编译:

export GOARCH=arm
export GOOS=”linux”
export GOARM=7
export CGO_ENABLED=1
export CC=arm-linux-gnueabihf-gcc
export GO111MODULE=off
make all WHAT=edgecore

1
2
3
4
5
6
7
8
9
10
11
12
13
14
注:KubeEdge 已经将依赖包纳入代码仓库,直接编译即可,不需要下载额外的包,为安全,可暂时禁止 GO111MODULE。  

## 五、清除
kubeedge运行文件:
1、/etc/kubeedge/: 证书、配置文件(云边均有)。
2、/var/lib/kubeedge/: 云端有socket文件kubeedge.sock ,边缘端有数据库文件edgecore.db。

如果要完全清理kubeedge环境,上述目录需要删除。

## 六、问题
在测试时发现的问题及解决方法。

1、
云端运行时出现:

./cloudcore

[address: Invalid value: “unix:///var/lib/kubeedge/kubeedge.sock”: unixSocketAddress unix:///var/lib/kubeedge/kubeedge.sock dir /var/lib/kubeedge not exist , need create it]

1
解决:此目录保存socket文件,需要手动创建目录

mkdir -p /var/lib/kubeedge

1
2
2、  
云端无法获取请求的资源:

./cloudcore

github.com/kubeedge/kubeedge/cloud/pkg/synccontroller/synccontroller.go:162: Failed to list *v1alpha1.ObjectSync: the server could not find the requested resource (get objectsyncs.reliablesyncs.kubeedge.io)

1
2
3
4
没有执行`$GOPATH/src/github.com/kubeedge/kubeedge/build/crds/reliablesyncs`目录的yaml文件,参见 2.4 小节。  

3、
Cgroup 驱动不匹配:

[CGroupDriver: Invalid value: “groupfs”: CGroupDriver value error]

1
2
3
4
5
6
7
如果 Docker 使用的驱动方式为 systemd,则需要修改 yaml 文件为 systemd,如使用 cgroupfs,Docker 也要保持一致。  

4、
边缘端机器的配置文件的主机名称、IP,必须与真实主机一致。否则会注册不成功。

5、
节点注册失败:

create node LATE-LEE error: Node “LATE-LEE” is invalid: metadata.name: Invalid value: “LATE-LEE”: a DNS-1123 subdomain must consist of lower case alphanumeric characters, ‘-‘ or ‘.’, and must start and end with an alphanumeric character (e.g. ‘example.com’, regex used for validation is ‘a-z0-9?(.a-z0-9?)*’) , register node failed

1
2
3
4
主机名称不合法,必须是小写字母、数字,其它字符只能是`-`或`.`(下划线也不行),而且名称的开头和结尾必须是小写字母。(注:这是k8s dns命名的一个规范)。  

6、
清理相关。

Failed to check the running environment: Kubelet should not running on edge node when running edgecore

1
一般出现于k8s和kubeedge混用情况,需要完全清理k8s方可。相似问题有:

Orphan pod: Orphaned pod “8685b805-a1c7-4687-8ce8-c77d24af5828” found, but volume paths are still present on disk


如果要重新运行edgecore,需要删除`/var/lib/kubeedge/edgecore.db`。

## 七、小结
KubeEdge 在2020年2月10日(即本文发表前9天)发布了1.2.0。笔者在春节期间看了几天源码,略有所得,还用 visio 画了流程图并记录结构体参数,不料通网后更新代码,发现代码大变样,又得重新阅读一次。CHANGELOG 还没有细看,为了继续研究代码,于是先部署运行,再通过打印信息来跟踪,此为笔者研读代码习惯之一。  
KubeEdge 的 beehive 框架目录使用了符号链接方式,不能在 Windows 文件系统存储。  

## 参考
* 官方源码仓库: https://github.com/kubeedge/kubeedge 
* 官方镜像: https://hub.docker.com/u/kubeedge
* 压缩包: https://github.com/kubeedge/kubeedge/releases 
* 官方安装文档:https://docs.kubeedge.io/en/latest/setup/setup.html  
* KubeEdge環境を構築してみた by AWS EC2: https://qiita.com/S-dwinter/items/f1e92f21d4b23fbbba80  
* KubeEdge 部署:  https://www.latelee.org/kubeedge/kubeedge-deploy.html