从docker到kubeedge
一、理论
技术背景
首先,云计算发展史其实就是虚拟化技术的发展史,技术逐渐成熟,并开始被应用到社会各个方面,成为全社会通用的技术基础,并开 始全面改变传统的产业结构。如下图所示,我们从中需要重点关注的是与我们今天所讲的主题息息相关的三种技术:Docker, Kubernetes,以及Kubeedge。那么我们今天就从这三者开始。

Why Docker ?
2013年的云计算服务,比的就是谁能更好地模拟本地服务器环境,能带来更好的“上云”体验。而 PaaS 开源项目的出现,就是当时解决这个问题的一个最佳方案。PaaS 项目被大家接纳的一个主要原因,就是它提供了一种名叫“应用托管”的能力。 在当时,虚拟机和云计算已经是比较普遍的技术和服务了,那时主流用户的普遍用法,就是租一批 AWS 或者 OpenStack 的虚拟机,然后像以前管理物理服务器那样,用脚本或者手工的方式在这些机器上部署应用。Docker 项目确实与 Cloud Foundry 的容器在大部分功能和实现原理上都是一样的,可偏偏就是这剩下的一小部分不一样的功能,成了 Docker 项目接下来“呼风唤雨”的不二法宝。这个功能,就是 Docker 镜像。Docker 项目通过“容器镜像”,解决了应用打包这个根本性难题。而docker容器镜像使用的是Linux的rootfs。它只是一个操作系统的所有文件和目录,并不包含内核,最多也就几百兆。而相比之下,传统虚拟机的镜像大多是一个磁盘的“快照”,磁盘有多大,镜像就至少有多大。
Why Kubernetes?
1. 没办法管理“有状态”的容器
2. 如何处理多个容器之间的依赖关系
过去很多的集群管理项目(比如 Yarn、Mesos,以及 Swarm)所擅长的,都是把一个容器,按照某种规则,放置在某个最佳节点上运行起来。这种功能,我们称为“调度”。而 Kubernetes 项目所擅长的,是按照用户的意愿和整个系统的规则,完全自动化地处理好容器之间的各种关系。这种功能,就是我们经常听到的一个概念:编排。所以说,Kubernetes 项目的本质,是为用户提供一个具有普遍意义的容器编排工具。不过,更重要的是,Kubernetes 项目为用户提供的不仅限于一个工具。它真正的价值,乃在于提供了一套基于容器构建分布式系统的基础依赖。现在,k8s已经逐渐演进为云原生下的”操作系统”。操作系统一般有存储,网络,进程管理,进程调度,系统调用api等功能。类似的k8s也提供了云原生下的存储,调度,网络,声明式api。而且还带有一些运维能力,比如备份,扩缩容,负载均衡等。实现这种能力的的核心就是k8s定义的下图中的的API对象。

Why Kubeedge?
从云端走向边缘场景:
-
低延时要求。AR/VR的时延要求是ms级,工业控制的时延更是在us级。
-
高可靠性。具体表现为:>99.999%的可用性,响应时间可预测,响应结果可重复等。
-
本地自治。要求边缘侧可适应偶尔断网,或者直接本地自治。
-
海量数据和有限带宽的矛盾。设备侧将产生海量数据,而以目前的带宽还无法承载这数据量。另外一个事实就是,很多数据没有全局价值,没有必要浪费带宽上传到云端。
-
信息安全。考虑到商业密码和个人隐私,很多机构和个人并不愿意把数据传输到云端。
云计算/Kubernetes的问题:
-
云中心存算压力大 云-端二元模式,数据集中存算,在业务高峰 时,中心计算带宽、传输带宽快速消耗殆尽, 数据大量积压而无法及时处理、有效利用
-
端-云网络链路不可控 一旦网络抖动、链路故障甚至前端断网,业务数据无法及时上传中心,中心指令无法及时下 达路口,导致路口智能程度显著降级
-
业务迭代升级慢 创新型的云端业务需在实战中反复打磨。传统稳态IT架构难以承载快速迭代带来的维护调试 工作量
-
优化效果难评价 欠缺对业务优化效果的评价依据和手段,建设 成效难以进行客观量化评估
Kubeedge特点以及优势
-
KubeEdge构建在Kubernetes之上,100%兼容K8S API,可以使用K8S API原语管理边缘节点和设备;
-
为了让K8S应用能够跑在边缘上,深度定制和优化了runtime;
-
为了应对边缘侧的网络不稳定因素,设计了可靠的消息通道;
-
边缘适应本地自治;
-
丰富的应用和协议支持;
-
大大简化了设备的接入复杂度;
章鱼式边缘计算模型

基本概念
官网架构

cloudcore
-
CloudHub:云中的通信接口模块。 - EdgeController:管理Edge节点。 - devicecontroller 负责设备管理。
-
edgecore: - Edged:在边缘管理容器化的应用程序。 - EdgeHub:Edge上的通信接口模块。 - EventBus:使用MQTT处理内部边缘通信。 - DeviceTwin:它是用于处理设备元数据的设备的软件镜像。 - MetaManager:它管理边缘节点上的元数据。 - ServiceBus: 接收云上服务请求和边缘应用进行http交互
edged
-
EdgeD是管理节点生命周期的边缘节点模块。它可以帮助用户在边缘节点上部署容器化的工作负载或应用程序。 这些工作负载可以执行任何操作,从简单的遥测数据操作到分析或ML推理等。使用kubectl云端的命令行界面,用户可以发出命令来启动工作负载。Docker容器运行时当前受容器和镜像管理支持。将来应添加其他运行时支持,例如containerd等。有许多模块协同工作以实现edged的功能。

-
pod管理 用于pod的添加删除修改,它还使用pod status manager和pleg跟踪pod的运行状况。其主要工作如下:
-
从metamanager接收和处理pod添加/删除/修改消息
-
处理单独的工作队列以添加和删除容器。
-
处理工作程序例程以检查工作程序队列以执行pod操作。
-
分别为config map 和 secrets保留单独的的缓存。
-
定期清理孤立的pod
-
Pod生命周期事件生成器
-
CRI边缘化
-
secret管理
-
Probe Management
-
ConfigMap Management
-
Container GC
-
Image GC
-
Status Manager
-
卷管理
-
MetaClient
eventbus
Eventbus充当用于发送/接收有关mqtt主题的消息的接口
它支持三种模式:
-
internalMqttMode
-
externalMqttMode
-
bothMqttMode
metamanager
MetaManager是edged和edgehub之间的消息处理器。它还负责将元数据存储到轻量级数据库(SQLite)或从中检索元数据。
Metamanager根据以下列出的操作接收不同类型的消息:
-
Insert
-
Update
-
Delete
-
Query
-
Response
-
NodeConnection
-
MetaSync
Edgehub
Edge Hub负责与云中存在的CloudHub组件进行交互。它可以使用Web套接字连接或QUIC协议连接到CloudHub 。它支持同步云端资源更新,报告边缘端主机和设备状态更改等功能。
它充当边缘与云之间的通信链接。它将从云接收的消息转发到边缘的相应模块,反之亦然。
edgehub执行的主要功能是:
-
Keep Alive
-
Publish Client Info
-
Route to Cloud
-
Route to Edge
DeviceTwin
DeviceTwin模块负责存储设备状态,处理设备属性,处理设备孪生操作,在边缘设备和边缘节点之间创建成员资格, 将设备状态同步到云以及在边缘和云之间同步设备孪生信息。它还为应用程序提供查询接口。 DeviceTwin由四个子模块(即membership,communication,device和device twin)组成,以执行device twin模块的职责。
Edge Controller
EdgeController是Kubernetes Api服务器和Edgecore之间的桥梁
CloudHub
CloudHub是cloudcore的一个模块,是Controller和Edge端之间的中介。它同时支持基于Web套接字的连接以及QUIC协议访问。Edgehub可以选择一种协议来访问cloudhub。CloudHub的功能是启用边缘与控制器之间的通信。
Device Controller
通过k8s CRD来描述设备metadata/status ,devicecontroller在云和边缘之间同步,有两个goroutines: upstream controller/downstream controller
二、部署
Centos部署Kubernetes
1. 环境配置
-
关闭swapoff交换分区
# 将 /etc/fstab 中的swap相关信息注释掉
sudo sed -i 's/.*swap.*/#&/' /etc/fstab
-
禁用selinux
# 注释掉/etc/selinux/config中的相关信息
sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
-
关闭防火墙
sudo systemctl stop firewalld.service
sudo systemctl disable firewalld.service
-
编辑网络配置(非必须)
vim /etc/sysconfig/network-scripts/ifcfg-ens32
**DEVICE=eth0 #描述网卡对应的设备别名**
**BOOTPROTO=static #设置网卡获得ip地址的方式,选项可以为为static,dhcp或bootp**
**BROADCAST=192.168.1.255 #对应的子网广播地址**
**HWADDR=00:07:E9:05:E8:B4 #对应的网卡物理地址**
**IPADDR=12.168.1.80 #只有网卡设置成static时,才需要此字段**
**NETMASK=255.255.255.0 #网卡对应的网络掩码**
**NETWORK=192.168.1.0 #网卡对应的网络地址,也就是所属的网段**
**ONBOOT=yes #系统启动时是否设置此网络接口,设置为yes时,系统启动时激活此设备**
-
安装doker的虚拟网络环境
# 安装docker所需的工具
yum install -y yum-utils device-mapper-persistent-data lvm2
# 配置阿里云的docker源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 指定安装这个版本的docker-ce
yum install -y docker-ce-18.09.9-3.el7
# 启动docker
systemctl enable docker && systemctl start docker
# 配置docker的cgroup
vim/etc/docker/daemon.json
# 添加如下配置
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
# 查看docker的信息保证cgroup是需要的设置的
docker info
# 附:查看kubelet的cgroup信息
cat /var/lib/kubelet/config.yaml |grep group
-
设置ipv4流量桥接
# /etc/sysctl.d/k8s.conf这个文件是不存在的,所以如果用vim的方式的话则直接创建这个文件并编辑
cat <<EOF > /etc/sysctl.d/k8s.conf
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
EOF
# 重新加载
sysctl --system
2. 安装部署
-
添加kubernetes的镜像源
# 执行配置k8s阿里云源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
# 安装kubeadm、kubectl、kubelet
yum install -y kubectl-1.18.8 kubeadm-1.18.8 kubelet-1.18.8
# 启动kubelet服务
systemctl enable kubelet && systemctl start kubelet
-
初始化master节点
# 下载管理节点中用到的6个docker镜像,你可以使用docker images查看到
# 这里需要大概两分钟等待,会卡在[preflight] You can also perform this action in beforehand using ''kubeadm config images pull
kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.16.0 --apiserver-advertise-address 192.168.137.246 --pod-network-cidr=10.244.0.0/16 --token-ttl 0
-
成功标志
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
# 初始化配置kubectl的环境
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
# 使用该命令将工作节点加入此master之中
kubeadm join 192.168.137.246:6443 --token j4sv99.plfbibaqxh6lrqbq \
--discovery-token-ca-cert-hash sha256:4b77992d15386d9bb97ce6e97ce8d4b9891689b56ca87bc84a967d60dc48cbbf
# token有效期为24小时,如果过期使用命令
kubeadm token create --ttl 0
kubeadm token list
-
节点的网桥设置
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 1 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
-
master安装网络插件flannel,国内flannel的镜像源可能找不到,改成以下的配置
略
Centos部署Kubeedge
1. 配置环境
-
安装golang的环境
# 下载解压
wget https://golang.google.cn/dl/go1.14.4.linux-amd64.tar.gz
tar -zxvf go1.14.4.linux-amd64.tar.gz -C /usr/local
# 配置环境变量
vim /etc/profile
# golang env
export GOROOT=/usr/local
export GOPATH=/data/gopath
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
# 生效
source /etc/profile
-
keadm需要使用wget获取设备表的yaml文件
yum -y install wget
-
解析github下载镜像需要的dns
vim /etc/sysconfig/network-scripts/ifcfg-ens32
# 加入百度的dns服务器和阿里的dns服务器地址
DNS1=180.76.76.76
DNS2=223.5.5.5
DNS3=8.8.8.8
# 配置已经启动的dns
vim /etc/resolv.conf
namespace 223.5.5.5
namespace 8.8.8.8
namespace 180.76.76.76
# 重启网络服务
service network restart
2. 部署cloudcore
-
下载keadm并初始化cloudcore部分
./keadm-v1.8.2-linux-amd64/keadm/keadm init --advertise-address="192.168.137.246" --kubeedge-version="1.8.2"
-
查看cloudcore的日志
tail -f /var/log/kubeedge/cloudcore.log
-
获取token
keadm gettoken
-
配置使用的cgroup和k8s保持一致
# 编辑cloudcore的配置
vim /etc/kubeedge/config/cloudcore.yaml
# 1. 修改dynamicController支持edgecore的listwatch监听
dynamicController:
- enable: false
+ enable: true # 开启dynamicController以支持edgecore的listwatch功能
# 云侧cloudcore可以直接通过systemd管理
# 拷贝cloudcore.service到/usr/lib/systemd/system
$ cp /etc/kubeedge/cloudcore.service /usr/lib/systemd/system
# 杀掉当前cloudcore进程
$ pkill -9 cloudcore
$ systemctl restart cloudcore
# 查看cloudcore是否运行
$ systemctl status cloudcore
3. 部署edgecore
-
下载keadm加入cloud,同样需要网络下载
./keadm-v1.8.2-linux-amd64/keadm/keadm join --cloudcore-ipport=192.168.137.246:10000 --token=14b135ddf60b79568acbccda3d10f7143498d628ec67abdf40c13835afe9d853.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzU1MTk4MjV9.qV-NeeTtKQdthAWdAAuYwxXSFIqzLuY6nFzKPMfrkHs
-
查看节点日志
journalctl -u edgecore.service -b
-
修改edge端的cgroup
# 修改配置
vim /etc/kubeedge/config/edgecore.yaml
# 1. 开启listwatch机制
modules:
enable: true
metaServer:
debug: false-
enable: false+
enable: true # 开启listwatch
# 2.修改cgroup edged:
cgroupDriver: systemd # 修改为和cloud一致的cgroup
# 杀掉当前edgecore进程
pkill edgecore
# 重启edgecore
systemctl restart edgecore

浙公网安备 33010602011771号