本文介绍了如何在两台 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 依赖
依赖组件(含工具、编译器)及版本:
- golang
版本 1.12.14,到 https://studygolang.com/dl 下载。编译源码需要,如果不编译,则无须安装。需要指出的是,KubeEdge 对 golang 版本有兼容性,当前官方源码的 master 分支已经支持 1.13 版本 golang,但本文依旧使用 1.12。 - k8s 版本
1.17,具体部署参考其它文章。根据当前官方文档,已经支持 1.17 版本了。 - mosquitto
1.6.8, 到 https://mosquitto.org/download/ 下载。 - KubeEdge 相关的(云端、边缘端)
最新发布版本为 v1.2.0, 到 https://github.com/kubeedge/kubeedge/releases/tag/v1.2.0 下载。代码仓库为 https://github.com/kubeedge/kubeedge/ 。
注意,github并不是一直都十分稳定,所以下载可能会较耗时。
本文部署时间约为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 | # mkdir ~/tools |
在 ~/.bashrc 文件最后添加:
1 | export PATH=$PATH:/home/ubuntu/tools/go/bin |
执行 source ~/.bashrc 生效。验证:
1 | # ubuntu@ubuntu:~/kubeedge$ go version |
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 | # gcc --version |
如果没有安装 gcc,则自行安装。
编译云端:
1 | # cd $GOPATH/src/github.com/kubeedge/kubeedge/ |
编译边缘端:
1 | # cd $GOPATH/src/github.com/kubeedge/kubeedge |
生成的二进制位于_output/local/bin/
目录下。
2.3 生成证书
1 | # $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 | # cd $GOPATH/src/github.com/kubeedge/kubeedge/build/crds/devices |
注:新版本的 yaml 文件有两类,在 devices 和 reliablesyncs 目录。可用kubectl get crds
查看。
2.6 配置云端节点
新版本配置文件由 cloudcore 程序生成,执行:
1 | # cd $GOPATH/src/github.com/kubeedge/kubeedge/cloud |
注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 | # add-apt-repository ppa:mosquitto-dev/mosquitto-ppa // 添加源 |
另外也可以使用源码编译。
在 ubuntu 系统,安装 mosquitto 成功后会自动启动服务。由于 KubeEdge 使用多个端口,故需用配置文件。服务端添加多端口:
1 | vim /etc/mosquitto/conf.d/port.conf |
/etc/init.d/mosquitto restart
1 |
|
/usr/sbin/mosquitto -d -c /etc/mosquitto/mosquitto.conf
1 | 建议使用系统级别服务,预防漏掉此步骤,导致 KubeEdge 测试失败。 |
mosquitto_pub -h <mqtt服务IP> -p 1884 -t “hello” -m “this is hello world”
1 | 如果出现`Error: Connection refused`表示服务(及对应的端口)未启动。 |
systemctl restart mosquitto // 重启
systemctl stop mosquitto // 停止
1 |
|
kubectl get node
NAME STATUS ROLES AGE VERSION
latelee-master Ready master 2m v1.17.0
1 | 此刻只有云端节点就绪。 |
cd $GOPATH/src/github.com/kubeedge/kubeedge/cloud
./cloudcore // 建议先如此,方便观察日志
也可以:
nohup ./cloudcore > cloudcore.log 2>&1 &
1 | 如果使用系统服务方式,启动脚本为`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 |
|
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 | 注1:此操作在边缘端机器上,非云端。假设部署工程目录为`~/kubeedge`。 |
./edgecore –minconfig > /etc/kubeedge/config/edgecore.yaml
1 | 修改配置文件: |
vim /etc/kubeedge/config/edgecore.yaml
1 | 注意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`。 |
./edgecore // 建议先如此,方便观察日志
也可以:
nohup ./edgecore > edgecore.log 2>&1 &
1 |
|
[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 |
|
/usr/sbin/mosquitto -d -c /etc/mosquitto/mosquitto.conf
1 |
|
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 | 云端和边缘端均为 Ready 状态。 |
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
1 | 扩容测试: |
kubectl scale deployment nginx-deployment –replicas=4
1 | 预期效果:有4个pod出现,但只有1个正常运行,因为该 deployment 导出了节点端口,前面的 pod 已经占用,无法再分配。理论上,如果有4个节点,则会自动将 deployment 调度到4个节点上。 |
kubectl delete -f $GOPATH/src/github.com/kubeedge/kubeedge/build/deployment.yaml
1 |
|
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 | 注:KubeEdge 已经将依赖包纳入代码仓库,直接编译即可,不需要下载额外的包,为安全,可暂时禁止 GO111MODULE。 |
./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、 |
./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 | 没有执行`$GOPATH/src/github.com/kubeedge/kubeedge/build/crds/reliablesyncs`目录的yaml文件,参见 2.4 小节。 |
[CGroupDriver: Invalid value: “groupfs”: CGroupDriver value error]
1 | 如果 Docker 使用的驱动方式为 systemd,则需要修改 yaml 文件为 systemd,如使用 cgroupfs,Docker 也要保持一致。 |
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 | 主机名称不合法,必须是小写字母、数字,其它字符只能是`-`或`.`(下划线也不行),而且名称的开头和结尾必须是小写字母。(注:这是k8s dns命名的一个规范)。 |
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