本章将从云、边、端协同的边缘计算系统的整体架构切入,罗列云、边、端各部分包含的组件的技术栈,然后分别对云、边、端各部分的部署方式和注意事项进行系统梳理和详细说明。
本节将对云、边、端协同的边缘计算系统的整体架构进行梳理和分析。边缘计算系统整体分为云、边、端三部分,具体如图2-1所示。
1)云: CPU支持X86和ARM架构;操作系统支持Linux、Windows和MacOS;容器运行时支持docker、containerd和cri-o;集群编排使用Kubernetes,包括控制节点、计算节点和集群存储。控制节点核心组件包括kube-apiserver、kube-controller-manager和kube-scheduler,计算节点组件包括Kubelet和kube-proxy,集群存储组件包括etcd。云上的负载以pod形式运行,pod是container组,container是基于操作系统namespace和cgroup隔离出来的独立空间。
2)边:CPU支持X86和ARM架构;操作系统支持Linux;容器运行时支持docker;边缘集群编排使用KubeEdge,包括云部分的CloudCore、边缘部分的EdgeCore和边缘集群存储sqlite。边缘的负载以pod形式运行。
3)端:由运行在边缘集群上的管理端设备的服务框架EdgeX Foundry和端设备组成,EdgeX Foundry从下向上依次为设备服务层、核心服务层、支持服务层、开放服务层,这也是物理域到信息域的数据处理顺序。设备服务层负责与南向设备交互;核心服务层介于北向与南向之间作为消息管道和负责数据存储;支持服务层包含广泛的微服务,主要提供边缘分析服务和智能分析服务;开放服务层整个EdgeX Foundry服务框架的网关层。
图 2-1边缘计算整体架构
Kubernetes是一个全新的基于容器技术的分布式架构的云部署方案,是Google开源的容器集群管理系,为部署容器化的应用提供资源调度、服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的便捷性。本书将Kubernetes作为边缘计算系统的云部分解决方案。
本节会对Kubernetes的部署方式进行梳理,主要从Kubernetes相关的容器运行时部署、Kubernetes的学习环境部署、Kubernetes的生产环境部署三方面进行梳理。
Kubernetes通过容器运行时在pod里运行容器,官方默认支持docker容器运行时。除此之外,Kubernetes支持的容器运行时还包括CRI-O、Containerd、Frakti等,具体如表2-1所示。
表2-1 Kubernetes支持的容器运行时
容器运行时 |
原理说明 |
备注 |
docker |
基于Linux Namespace、Control Groups和Union filesystem的一种容器运行时实现方式 |
同时支持Linux和Windows操作系统,目前是Kubernetes默认的容器运行时 |
Containerd |
与docker相比减少了dockerd这一层富功能组件,其底层实现原理与docker相同 |
Containerd的可配制性比较强,可以通过插件的方式替换具体实现 |
CRI-O |
RedHat发布的容器运行时, 在同时满足 CRI 标准和 OCI 标准的前提下,将CRI和OCI的实现都进行了轻量化 |
还没有在大规模运行环境的验证,稳定性没有保障 |
Frakti |
基于Hypervisors的容器运行时,具有独立kernel,比基于Linux Namespace的容器运行时的隔离性要好 |
还没有在大规模运行环境的验证,稳定性没有保障 |
从Kubernetes支持的容器运行时列表,我们可知:
1)docker和Containerd在实现原理上是相同的,只是Containerd裁剪了docker原有的一些富功能;
3)Frakti的目的是实现容器运行时的强隔离性,基于Hypervisors实现容器运行时,使每个容器具有独立的kernel。
目前,业界普遍使用的容器运行时是docker。本节详细说明一下部署docker的相关步骤和注意事项。
本书环境使用的操作系统都是CentOS7+,所以部署docker的步骤也是针对CentOS7+操作环境。
# yum install yum-utils device-Mapper-persistent-data lvm2
# yum-config-manager --add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# yum update && yum install containerd.io-1.2.10 docker-ce-19.03.4 docker-ce-cli-19.03.4,命令如下:
# yum update && yum install containerd.io-1.2.10 docker-ce-19.03.4 docker-ce-cli-19.03.4
创建配置文件目录:#mkdir /etc/docker
设置docker配置文件:# cat > /etc/docker/daemon.json < { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ] } EOF # mkdir -p /etc/systemd/system/docker.service.d # systemctl daemon-reload # systemctl restart docker 至此,docker容器运行时就安装成功了。接下来,分析docker配置相关的注意事项。 docker的相关配置在/etc/docker/daemon.json文件中进行设置,在daemon.json文件可以设置私有仓库、DNS解析服务器、docker运行时使用的路径、镜像加速地址、日志输出、Cgroup Driver、docker主机的标签等。本节重点介绍Cgroup Driver的设置。 在Linux操作系统发行版本中使用 systemd 作为其初始化系统,初始化进程生成并使用一个 root 控制组件 (cgroup),并将其当作 cgroup 管理器。systemd 与 cgroup 集成紧密,为每个进程分配 cgroup。docker容器运行时默认的cgroup 管理器是cgroupfs,也就是 Kubelet 使用 cgroupfs来管理cgroup。这样就造成在同一台主机上同时使用 systemd和cgroupfs两种cgroup 管理器来对cgroup 进行管理。 cgroup用来约束分配给进程的资源。单个 cgroup 管理器能够简化分配资源的视图,并且默认情况下在管理可用资源和使用中的资源时使用一致的视图。当有两个cgroup管理器时,最终产生两种视图。我们已经看到某些案例中的节点配置让使Kubelet 和 docker 使用 cgroupfs管理器,而节点上运行的其余进程则使用 systemd,这类节点在资源压力下会变得不稳定。 更改设置,令容器运行时和 Kubelet 使用 systemd 作为 cgroup 驱动,以便系统更稳定。 请注意在/etc/docker/daemon.json文件中设置 native.cgroupdriver=systemd 选项。具体如下: # vi /etc/docker/daemon.json { ... "exec-opts": ["native.cgroupdriver=systemd"], ... } 本节对部署Kubernetes学习环境的相关工具进行梳理,并对不同工具从安装方法、使用方法、相应原理的维度进行横向和纵向对比,如表2-2所示。 表2-2 搭建Kubernetes学习环境的工具 部署工具 依赖 原理 备注 Minikube 操作系统对虚拟化的支持、一款Hypervisor KVM/VirtualBox、安装并配置了kubectl 创建一台虚拟机,在虚拟机里运行Kubernetes集群 只适用于学习和测试Kubernete的场景 Kind(Kubernetes in docker) docker容器运行时、在容器里运行Kubernetes集群的基础镜像node image 创建一个docker容器,并在该容器里运行一个Kubernetes集群 只适用于学习和测试Kubernete的场景 从搭建Kubernetes学习环境的工具列表可知,Minikube、Kind(Kubernetes in docker)都可以搭建Kubernetes的学习环境,但两者所需要的依赖和原理各不相同。由于Minikube和Kind(Kubernetes in docker)都是用于搭建Kubernetes学习环境的工具,所以两者的安装步骤和使用方法相对比较简单。接下来,笔者对两者的安装步骤和使用方法进行详细说明。 Minikube是一种可以轻松在本地运行Kubernetes的工具。其首先通过在物理服务器或计算机上创建虚拟机,然后在虚拟机(VM)内运行一个单节点Kubernetes集群。该Kubernetes集群可以用于开发和测试Kubernetes的最新版本。 下面对Minikube的安装和使用进行说明。本书使用的操作系统都是CentOS7+,所以本节安装Minikube的步骤也是针对CentOS7+操作环境。 (1)安装Minikube 1)检查对虚拟化的支持,命令如下: # grep -E --color 'vmx|svm' /proc/cpuinf 2)安装kubectl。 因为网络问题,使用操作系统原生包管理工具安装会遇到很多问题,所以推荐在Kubernetes的GitHub 仓库上的release下载pre-built的binary进行安装。 进入Kubernetes的GitHub 仓库上的release主页,找到需要下载的Kubernetes版本,比如本节要下载的版本是v1.16.6,如图2-2所示。 图 2-2 Kubernetes release版本 点击CHANGELOG-1.16.md进入binary下载列表,复制server binary下载地址,使用wget下载server binary压缩包,命令如下: # wget https://dl.k8s.io/v1.16.6/Kubernetes-server-linux-amd64.tar.gz 下载Kubernetes具体如图2-3所示。 图2-3 下载Kubernetes 如图2-4所示,解压Kubernetes-server-linux-amd64.tar.gz,命令如下: # tar -zxvf Kubernetes-server-linux-amd64.tar.gz 图 2-4 解压Kubernetes 由图2-4可知,kubectl在Kubernetes/server/bin下,只需将其放入/usr/bin下即可: #cp Kubernetes/server/bin/kubectl /usr/bin 3)安装KVM。 在确认所在的操作系统支持虚拟的前提下,通过如下步骤安装KVM及相关依赖。 更新安装KVM所需的源,命令如下: #yum -y update && # yum install epel-release 安装KVM及其所需的依赖包,命令如下: # yum install qemu-kvm libvirt libvirt-python libguestfs-tools virt-install 设置libvirtd开机自启动并将其启动,命令如下: # systemctl enable libvirtd && systemctl start libvirtd 4)安装Minikube。 # curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-1.6.2.rpm \ && rpm -ivh minikube-1.6.2.rpm (2)使用Minikube 1)启动一个本地单节点集群,命令如下: # minikube start --vm-driver= 2)检查集群状态,命令如下: # minikube status 3)使用集群部署应用,命令如下: # kubectl create deployment hello-minikube --image={image-name} 至此,我们已经成功安装了Minikube,并通过Minikube创建了一个本地单节点的Kubernetes集群。 Kind(Kubernetes in docker)是一种使用docker容器节点(该容器可用于运行嵌套容器,在该容器里可以使用systemd运行、管理Kubernetes的组件)运行本地Kubernetes集群的工具。Kind主要是为了测试Kubernetes本身而设计的,也可用于本地开发或持续集成。 下面对Kind的安装和使用进行说明。本书环境使用的操作系统都是CentOS7+,所以本节安装Kind的步骤也是针对CentOS7+操作环境。 (1)安装Kind 由于安装Kind需要Golang语言环境,使用Kind运行本地Kubernetes集群需要docker容器运行时,因此在安装Kind之前需要先安装Golang和docker。 1)安装Golang和docker,命令如下: # yum -y install Golang 参考“部署docker”步骤来部署docker容器运行时。 2)安装kind,命令如下: #GO111MODULE="on" go get sigs.k8s.io/[email protected] 上述步骤会将kind安装到GOPATH/bin目录下。为了使用方便,建议将其在/etc/profile中进行追加设置,命令如下: # vi /etc/profile export PATH=$GOPATH/bin:$PATH 使在/etc/profile中设置的环境变量立即生效,命令如下: #source /etc/profile (2)使用Kind 1)使用Kind创建Kubernetes集群(如图2-5所示),命令如下: # kind create cluster。 图2-5 使用Kind创建集群 2)检查、使用Kind部署的集群(如图2-6所示),命令如下: #kubectl get pods --all-namespaces 图2-6 检查使用Kind部署的集群状态 至此,我们已经成功安装了Kind,并通过Kind创建了一个本地单节点的Kubernetes集群。 本节对部署Kubernetes生产环境的相关工具进行梳理,并对不同工具从安装方法、使用方法、相应原理的维度进行横向和纵向对比,具体如表2-3所示。 表2-3 搭建Kubernetes生产环境的工具 部署工具 依赖 原理 备注 kubeadm docker容器运行时、Kubelet 将安装Kubernetes过程的环境检查、下载镜像、生成证书、配置Kubelet、准备yaml文件等步骤自动化 Kubeadm所需的镜像默认以k8s.gcr.io开头,而且是硬编码的,国内无法直接下载,需要提前准备好 kops Kubectl 在kubeadm的基础上,使搭建Kubernetes集群更方便 主要在AWS上进行自动化部署Kubernetes集群 KRIB Golang Digital Rebar Provision专有的在裸机上搭建Kubernetes集群的工具 Digital Rebar Provision还可以调用Kubespray Kubespray ansible 用ansible playbooks、inventory自动化部署Kubernetes集群 从表2-3可知,kops、KRIB有明显局限性,因为kops主要在AWS上进行自动化部署Kubernetes集群;KRIB主要在裸机上进行自动化部署Kubernetes集群。kubeadm和Kubespray可以在多种平台上搭建Kubernetes的生产环境,kubespray从v2.3开始支持kubeadm,也就意味着kubespray最终还是通过kubeadm进行自动化部署Kubernetes集群。 基于上述原因,本节将只对kubeadm进行自动化部署Kubernetes集群的步骤进行说明。 本节将对使用kubeadm的注意事项以及安装、使用kubeadm进行梳理和分析。kubeadm支持的平台和资源要求如表2-4所示。 表2-4 kubeadm支持的平台和资源要求 kubeadm 支持的平台 Ubuntu 16.04+、Debian 9+ CentOS 7、Red Hat Enterprise Linux (RHEL) 7、Fedora 25+、HyprIoTOS v1.0.1+、Container Linux (tested with 1800.6.0) 资源要求 至少2CPUs、2GB内存 注意事项 集群中主机之间的网络必须是相互可达的,在集群中每台主机的hostname、MAC address和product_uuid必须是唯一的,iptables后端不用nftable,在集群中每台主机上Kubernetes需要的一些端口必须是打开的,而且swap要关闭 接下来介绍对kubeadm的注意事项注意说明。 1)确保集群中所有主机之间网络可达。 在集群中不同主机间通过ping命令进行检测,命令如下: # ping {被检测主机ip} 2)确保集群中所有主机的hostname、MAC address和product_uuid唯一。 查看主机hostname命令:#hostname 查看MAC address命令:#ip link 或者 #ifconfig -a 查看product_uuid命令:#/sys/class/dmi/id/product_uuid 3)iptables后端不用nftable,命令如下: # update-alternatives --set iptables /usr/sbin/iptables-legacy 4)Kubernetes集群中主机需要打开的端口,如表2-5所示。 表2-5 Kubernetes集群中主机需要打开的端口 节点 协议 流量方向 端口 用途 使用组件 控制节点 TCP 进入集群 6443 Kubernetes-api-server 集群中所有组件都会使用这个端口 2379、2380 etcd server client API kube-api、etcd 10250 Kubelet API Kubelet、控制平面 10251 kube-scheduler kube-scheduler 10252 kube-controller-manager kube-controller-manager 计算节点 TCP 进入集群 10250 Kubelet API Kubelet、控制平面 30000-32767 NodePort Services 集群中所有组件都会使用这个端口 由表2-5可知,上述需要打开的端口都是Kubernetes默认需要打开的端口。我们也可以根据需要对一些端口进行单独指定,比如Kubernetes-api-server默认打开的端口是6443,也可以指定打开其他与现有端口不冲突的端口。 5)在Kubernetes集群中所有节点上关闭swap,命令如下: #swapoff -a (2)安装kubeadm 安装kubeadm有两种方式,即通过操作系统的包管理工具进行安装和从Kubernetes GitHub仓库的release上下载pre-build的binary进行安装。下面对这两种安装方式进行详细说明。 1)通过操作系统的包管理工具安装kubeadm。 在需要安装kubeadm的节点上设置安装kubeadm需要的仓库,命令如下: #cat < [Kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/Kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF 将SELinux设置为permissive,命令如下: #setenforce 0 #sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config 安装kubeadm、Kubelet、kubectl,命令如下: #yum install -y Kubelet kubeadm kubectl --disableexcludes=Kubernetes 将Kubelet设置为开机自启动,命令如下: #systemctl enable --now Kubelet 注意:由于网络问题,通过操作系统包管理工具安装kubeadm很可能会失败。 2)通过在Kubernetes GitHub仓库的release上下载pre-build的binary安装kubeadm。 进入Kubernetes的GitHub 仓库上的release主页,找到需要下载的Kubernetes版本,比如要下载的版本是v1.16.6,如图2-7所示。 图 2-7 Kubernetes release版本 点击CHANGELOG-1.16.md进入binary下载列表,复制server binary下载地址,使用wget下载server binary压缩包,命令如下: # wget https://dl.k8s.io/v1.16.6/Kubernetes-server-linux-amd64.tar.gz 下载Kubernetes binary具体如图2-8所示。 图2-8 下载Kubernetes binary 解压Kubernetes-server-linux-amd64.tar.gz,命令如下: # tar -zxvf Kubernetes-server-linux-amd64.tar.gz 解压Kubernetes binary,具体如图2-9所示。 图2-9 解压Kubernetes binary 由图2-9可知,kubeadm在Kubernetes/server/bin只需将其放入/usr/bin下即可,命令如下:#cp Kubernetes/server/bin/kubeadm /usr/bin (3)使用kubeadm 使用kubeadm可以部署Kubernetes单节点集群、Kubernetes单控制节点集群和Kubernetes高可用集群。下面将详细说明部署3种集群的具体步骤和注意事项。 1)部署Kubernetes单节点集群。 使用kubeadm部署Kubernetes单节点集群,其实是在一个节点使用kubeadm部署Kubernetes的控制平面,然后对该节点进行设置,使其能够运行应用负载。 查看使用kubeadm部署Kubernetes集群时所需的镜像,命令如下: #kubeadm config images list 所需镜像如图2-10所示。 图 2-10 kubeadm 所需镜像 由于这些镜像都是以k8s.gcr.io*开头,一般情况下,kubeadm无法正常下载这些镜像,需要提前准备好。获取这些镜像的方法不止一种,笔者建议通过dockerhub获得。 使用kubeadm创建Kubernetes集群,在创建集群的过程中会用到图2-10中列出的所有镜像,命令为#kubeadm init {args}。 在args中一般只需指定--control-plane-endpoint、--pod-network-cidr、--cri-socket、--apiserver-advertise-address参数。这些参数的具体作用如下。 1)--control-plane-endpoint:在搭建高可用Kubernetes集群时,为多个控制平面共用的域名或负载均衡IP; 2)--pod-network-cidr Kubernetes:集群中pod所用的IP池; 3)--cri-socket :指定Kubernetes集群使用的容器运行时; 4)--apiserver-advertise-address :指定kube-api-server绑定的IP地址,既可以是IPv4也可以是IPv6 。 我们可以根据具体情况具体指定以上参数。 根据non-root用户和root用户,设置kubectl使用的配置文件。 non-root用户设置命令入如下: $mkdir -p $HOME/.kube $sudo cp -i /etc/Kubernetes/admin.conf $HOME/.kube/config $sudo chown $(id -u):$(id -g) $HOME/.kube/config root用户设置命令如下: export KUBECONFIG=/etc/Kubernetes/admin.conf 为了方便,也可以将KUBECONFIG设置成自动生效的系统环境变量,命令如下: # vim /etc/profile export KUBECONFIG=/etc/Kubernetes/admin.conf 安装pod network所需的网络插件,命令如下: # kubectl apply -f https://docs.projectCalico.org/v3.8/manifests/Calico.yaml 本节使用的网络插件是Calico,我们也可以根据具体需求选择其他的网络插件,比如flannel、Weave Net、kube-router等。 至此,一个完整的Kubernetes控制节点就搭建完成了,但还不能算一个完整单节点集群,因为该控制节点默认不接受负载调度。要使其能够接受负载调度,需要进行如下设置: # kubectl taint nodes --all node-role.Kubernetes.io/master- 2)部署Kubernetes单控制节点集群。 Kubernetes的单控制节点集群,是指该Kubernetes集群只有一个控制节点,但可以有不止一个的计算节点。部署该集群只需在部署Kubernetes单节点集群中安装pod network所需的网络插件之后,计算节点加入该控制节点即可,具体命令如下: ubeadm join 使用kubeadm join可以将多个计算节点加入到已经部署成功的控制节点,与控制节点组成一个单控制节点的Kubernetes集群。 3)部署Kubernetes高可用集群。 kubeadm除了可以部署单节点Kubernetes集群和单控制节点Kubernetes集群外,还可以部署高可用Kubernetes集群。Kubeadm部署Kubernetes高可用集群的架构包含两种,即ectd集群与Kubernetes控制节点集群一起部署的Kubernetes高可用集群,以及ectd集群与Kubernetes控制节点集群分开部署的Kubernetes高可用集群,具体架构如图2-11和图2-12所示。 图2-11 ectd集群与Kubernetes控制节点集群一起部署 图2-12 ectd集群与Kubernetes控制节点集群分开部署 由图2-11和图2-12可知,Kubernetes集群高可用即Kubernetes集群中master节点和etcd集群的高可用。etcd集群又有两种高可用部署方式,即ectd集群与Kubernetes控制节点集群一起部署和ectd集群与Kubernetes控制节点集群分开部署。 部署Kubernetes高可用集群是面向生产环境的,需要的资源比较多,部署步骤也相对比较复杂,限于篇幅本书就不展开说明了,感兴趣的读者可以参考Kubernetes官网进行实践。 KubeEdge是一个基于Kubernetes构建的开放平台,能够将Kubernetes拥有的编排容器化应用的能力扩展到边缘的节点和设备,并为云和边缘之间的网络、应用部署和元数据同步提供基础架构支持。本书将KubeEdge作为边缘计算系统边部分的解决方案。 本节会对KubeEdge的部署方式进行梳理。KubeEdge可以通过系统进程的方式、容器化的方式和使用工具进行部署。 以系统进程的方式部署KubeEdge,即以系统进程的方式部署KubeEdge的云组件和边缘组件。下面将对部署过程中需要的依赖、配置等进行详细说明。 获取KubeEdge云组件的方法有两种,即通过编译KubeEdge的云组件源码和从KubeEdge GitHub仓库的release下载。本节只说明通过编译KubeEdge的云组件源码获得KubeEdge云组件可执行文件的方式。 1)编译KubeEdge的云组件源码。 下载KubeEdge源码命令如下: #git clone https://GitHub.com/KubeEdge/KubeEdge.git KubeEdge 在编译之前确保gcc已经安装,命令如下: #gcc --version 通过编译源码,获得KubeEdge云组件,命令如下: #cd KubeEdge #make all WHAT=CloudCore 编译成功之后,会在./cloud下生成可执行文件CloudCore,将其复制到/usr/bin下即可。 2)创建device model和device CRDs,命令如下: #cd ../KubeEdge/build/crds/devices #kubectl create -f devices_v1alpha1_devicemodel.yaml #kubectl create -f devices_v1alpha1_device.yaml 3)生成Certificates,命令如下: #cd KubeEdge/build/tools #./certgen.sh genCertAndKey edge 执行上述命令后,会在/etc/KubeEdge/ca下生成rootCA.crt,在etc/KubeEdge/certs 下生成edge.crt 、edge.key。生成的这些证书在KubeEdge的云组件和边缘组件中共用。 4)生成和设置KubeEdge云组件的配置文件。 使用CloudCore可以生成最小化配置文件和默认配置文件。 创建配置文件目录命令如下: #mkdir -p /etc/KubeEdge/config/ 生成最小化配置文件命令如下: #CloudCore –minconfig > /etc/KubeEdge/config/CloudCore.yaml 生成默认配置文件命令如下: # CloudCore –defaultconfig > /etc/KubeEdge/config/CloudCore.yaml 执行上述命令后,会在/etc/KubeEdge/config下生成CloudCore.yaml。下面对执行CloudCore生成的默认配置文件CloudCore.yaml进行说明,具体如下所示。 apiVersion: CloudCore.config.KubeEdge.io/v1alpha1 kind: CloudCore kubeAPIConfig: kubeConfig: /root/.kube/config # kubeconfig 文件的绝对路径 master: "" # kube-apiserver address (比如:http://localhost:8080) modules: cloudhub: nodeLimit: 10 tlsCAFile: /etc/KubeEdge/ca/rootCA.crt tlsCertFile: /etc/KubeEdge/certs/edge.crt tlsPrivateKeyFile: /etc/KubeEdge/certs/edge.key unixsocket: address: unix:///var/lib/KubeEdge/KubeEdge.sock # unix domain socket address enable: true # enable unix domain socket protocol websocket: address: 0.0.0.0 enable: true # enable websocket protocol port: 10000 # open port for websocket server 5)运行KubeEdge云组件,命令如下: #nohup ./CloudCore & 除了上述形式,还可以通过systemd以后台进程的形式运行KubeEdge云组件,命令如下: #ln KubeEdge/build/tools/CloudCore.service /etc/systemd/system/CloudCore.service # systemctl daemon-reload # systemctl start CloudCore 将KubeEdge云组件设置为开机自启动,命令如下: #systemctl enable CloudCore (2)安装KubeEdge的边缘组件 1)编译KubeEdge的边缘组件源码。 下载KubeEdge源码,命令如下: #git clone https://GitHub.com/KubeEdge/KubeEdge.git KubeEdge 在编译之前确保gcc已经安装,命令如下: #gcc --version 通过编译源码获得KubeEdge的边缘组件,命令如下: #cd KubeEdge #make all WHAT=EdgeCore 编译成功之后,会在./edge下生成可执行文件EdgeCore,将其复制到/usr/bin下即可。 2)从KubeEdge的云组件节点复制Certificates,命令如下: #scp -r /etc/KubeEdge root@{KubeEdge edge节点IP}:/etc/KubeEdge 3)在KubeEdge的云组件节点为边缘节点创建node对象资源,命令如下: #kubectl create -f KubeEdge/build/node.json node.json具体内容如下所示。 { "kind": "Node", "apiVersion": "v1", "metadata": { "name": "edge-node", "labels": { "name": "edge-node", "node-role.Kubernetes.io/edge": "" } } } 4)生成和设置KubeEdge边缘组件的配置文件。 使用EdgeCore可以生成最小化配置文件和默认配置文件。 创建配置文件目录,命令如下: #mkdir -p /etc/KubeEdge/config/ 生成最小化配置文件,命令如下: #EdgeCore –minconfig > /etc/KubeEdge/config/EdgeCore.yaml 生成默认配置文件,命令如下: # EdgeCore –defaultconfig > /etc/KubeEdge/config/EdgeCore.yaml 执行上述命令后,会在/etc/KubeEdge/config下生成EdgeCore.yaml文件。下面对执行EdgeCore生成的默认配置文件EdgeCore.yaml进行说明,具体如下所示。 apiVersion: EdgeCore.config.KubeEdge.io/v1alpha1 database: dataSource: /var/lib/KubeEdge/EdgeCore.db kind: EdgeCore modules: edged: cgroupDriver: cgroupfs clusterDNS: "" clusterDomain: "" devicePluginEnabled: false dockerAddress: unix:///var/run/docker.sock gpuPluginEnabled: false hostnameOverride: $your_hostname interfaceName: eth0 nodeIP: $your_ip_address podSandboxImage: KubeEdge/pause:3.1 # KubeEdge/pause:3.1 for x86 arch , KubeEdge/pause-arm:3.1 for arm arch, KubeEdge/pause-arm64 for arm64 arch remoteImageEndpoint: unix:///var/run/dockershim.sock remoteRuntimeEndpoint: unix:///var/run/dockershim.sock runtimeType: docker edgehub: heartbeat: 15 # second tlsCaFile: /etc/KubeEdge/ca/rootCA.crt tlsCertFile: /etc/KubeEdge/certs/edge.crt tlsPrivateKeyFile: /etc/KubeEdge/certs/edge.key websocket: enable: true handshakeTimeout: 30 # second readDeadline: 15 # second server: 127.0.0.1:10000 # CloudCore address writeDeadline: 15 # second eventbus: mqttMode: 2 # 0: internal mqtt broker enable only. 1: internal and external mqtt broker enable. 2: external mqtt broker mqttQOS: 0 # 0: QOSAtMostOnce, 1: QOSAtLeastOnce, 2: QOSExactlyOnce. mqttRetain: false # if the flag set true, server will store the message and can be delivered to future subscribers. mqttServerExternal: tcp://127.0.0.1:1883 # external mqtt broker url. mqttServerInternal: tcp://127.0.0.1:1884 # internal mqtt broker url. 其中,Modules.edged.hostnameOverride与node.json里的metadata.name保持一致;Modules.edged.nodeIP是KubeEdge边缘节点的IP; Modules.edgehub.websocket.server是KubeEdge云节点的IP。 5)运行KubeEdge云组件,命令如下: #nohup ./EdgeCore & 除了上述形式,我们还可以通过systemd以后台进程的形式运行KubeEdge云组件,命令如下: #ln KubeEdge/build/tools/EdgeCore.service /etc/systemd/system/EdgeCore.service # systemctl daemon-reload # systemctl start EdgeCore 将KubeEdge云组件设置为开机自启动,命令如下: #systemctl enable EdgeCore 至此,以系统进程的方式部署KubeEdge的云组件和边缘组件都已经完成了,接下来检查KubeEdge的状态,并基于KubeEdge部署应用。 (3)检查KubeEdge节点状态 在KubeEdge云节点执行如下命令,检查KubeEdge边缘节点的状态,命令如下: #kubectl get nodes (4)基于KubeEdge部署应用 基于KubeEdge部署应用的命令如下: #kubectl apply -f KubeEdge/build/deployment.yaml 本节以容器的方式部署KubeEdge,即以容器的方式部署KubeEdge的云组件和边缘组件。下面将对部署过程的步骤和相关配置等进行详细说明。 (1)以容器的方式部署KubeEdge的云组件 1)下载部署KubeEdge的云组件所需的资源文件,命令如下: #git clone https://GitHub.com/KubeEdge/KubeEdge.git KubeEdge 2)构建部署KubeEdge的云组件所需的镜像,命令如下: #cd KubeEdge # make cloudimage 3)生成部署KubeEdge的云组件所需的06-secret.yaml,命令如下: #cd build/cloud #../tools/certgen.sh buildSecret | tee ./06-secret.yaml 4)以容器的方式部署KubeEdge的云组件,命令如下: #for resource in $(ls *.yaml); do kubectl create -f $resource; done (2)以容器的方式部署KubeEdge的边缘组件 1)下载部署KubeEdge的边缘组件所需的资源文件,命令如下: #git clone https://GitHub.com/KubeEdge/KubeEdge.git KubeEdge 2)检查container runtime环境,命令如下: # cd ./KubeEdge/build/edge/run_daemon.sh prepare 3)设置容器参数,命令如下: # ./KubeEdge/build/edge /run_daemon.sh set \ cloudhub=0.0.0.0:10000 \ edgename=edge-node \ EdgeCore_image="KubeEdge/EdgeCore:latest" \ arch=amd64 \ qemu_arch=x86_64 \ certpath=/etc/KubeEdge/certs \ certfile=/etc/KubeEdge/certs/edge.crt \ keyfile=/etc/KubeEdge/certs/edge.key 4)构建部署KubeEdge的边缘组件所需的镜像,命令如下: #./KubeEdge/build/edge /run_daemon.sh build 5)启动KubeEdge的边缘组件容器,命令如下: #./KubeEdge/build/edge /run_daemon.sh up 至此,以容器的方式部署KubeEdge的云组件和边缘组件都已经完成了。关于KubeEdge的状态查看以及基于KubeEdge部署应用部分,读者可以参考“以系统进程的方式部署KubeEdge部分”。 EdgeX Foundry是一个由Linux Foundation托管的、供应商中立的开源项目,用于为IoT边缘计算系统构建通用的开放框架。该项目的核心是一个互操作性框架。该框架可以托管在与硬件和操作系统无关的平台上,以实现即插即用组件的生态系统,从而加速IoT解决方案的部署。本节将对EdgeX Foundry的部署方式进行系统梳理,并对部署方式中的相关注意事项进行详细说明,具体如表2-9所示。 表2-9 KubeEdge的部署方式和注意事项 部署方式 部署平台 部署原理 备注 容器化部署 docker-compose 将EdgeX Foundry的各组件容器化,并通过docker-compose对其进行部署、编排 目前,该部署方式是官方提供的部署方式之一 Kubernetes 将EdgeX Foundry的各组件容器化,并通过Kubernetes对其进行部署、编排 目前,官方不提供该部署方式的相关说明 KubeEdge 将EdgeX Foundry的各组件容器化,并通过KubeEdge对其进行部署、编排 目前,官方不提供该部署方式的相关说明 系统进程部署 支持EdgeX Foundry运行的各种操作系统 将EdgeX Foundry的各组件以系统进程的方式进行部署 目前,该部署方式是官方提供的部署方式之一 需要说明的是,在本书云、边、端协同的边缘计算系统中,作为端解决方案的EdgeX Foundry是通过KubeEdge对其进行容器化部署的。但是,目前官方没有提供通过KubeEdge对其进行容器化部署的相关说明,所以笔者根据本书的部署环境针对KubeEdge开发了一套yaml文件。 1)该yaml文件托管在GitHub 上(https://GitHub.com/WormOn/edgecomputing/tree/master/end),可作为读者学习参考资料。 2)通过Kubernetes对EdgeX Foundry进行容器化部署,与通过KubeEdge对其进行容器化部署原理相同,读者也可以参考该yaml文件完成通过Kubernetes对EdgeX Foundry的部署。 以系统进程部署EdgeX Foundry,即将EdgeX Foundry的各组件以系统进程的方式进行部署。本节对该方式进行展开说明。 #git clone https://GitHub.com/EdgeX Foundry/edgex-go.git 进入edgex-go源码根目录,命令如下: #cd edgex-go 源码编译edgex-go,命令如下: #make build 构建EdgeX Foundry各组件的binary,具体如图2-13所示。 图2-13 构建EdgeX Foundry各组件的binary 由图2-13可知,会在./cmd下各组件子目录里生成相应的可执行文件,比如config-seed的可执行文件会在./cmd/config-seed目录下,具体如图2-14所示。 图 2-14 源码编译edgex-go生成的可执行文件 (3)运行EdgeX Foundry的各组件 通过make一键运行edgex,命令如下: #make run edgex-go 一键启动命令和输出结果如图2-15所示。 图2-15 edgex-go 一键启动 由2-15可知,make run是通过执行#cd bin && ./edgex-launch.sh将EdgeX Foundry的各组件以系统进程的方式运行起来的。下面看一下edgex-launch.sh的具体内容。 打开edgex-launch.sh:#vim edgex-go/bin/edgex-launch.sh,具体如下所示。 #!/bin/bash edgex-launch.sh主要做了3件事。 以容器化方式部署EdgeX Foundry,即使用docker-compose、Kubernetes和KubeEdge对EdgeX Foundry进行容器化部署。本节对使用docker-compose部署EdgeX Foundry的步骤和注意事项进行详细说明。 #git clone https://GitHub.com/EdgeX Foundry/edgex-go.git 进入edgex-go源码根目录,命令如下: #cd edgex-go 源码编译edgex-go命令如下: #make build 源码编译edgex-go具体如图2-16所示。 图2-16 源码编译edgex-go 由图2-16可知,会在./cmd下各组件子目录里生成相应的可执行文件,比如config-seed的可执行文件会在./cmd/config-seed目录下,具体如图2-17所示。 图 2-17 edgex-go源码编译结果 使用docker容器对edgex-go进行源码编译的命令如下: # make docker 使用docker容器对edgex-go进行源码编译具体如图2-18所示。 图2-18 使用docker容器对edgex-go进行源码编译 4)获取运行EdgeX Foundry各组件的docker-compose.yml文件,命令如下: #curl -s -o docker-compose.yml https://raw.GitHubusercontent.com/EdgeX Foundry/developer-scripts/master/releases/edinburgh/compose-files//docker-compose-edinburgh-no-secty-1.0.1.yml 将 docker-compose.yml文件的相关镜像替换为构建的最新镜像,命令如下: # vim docker-compose.yml 替换镜像具体如图2-19所示。 图2-19 替换镜像 5)运行EdgeX Foundry。 使用docker-compose启动edgex,命令如下: # docker-compose up -d 使用docker-compose启动edgex-go具体如图2-20所示。 图 2-20 使用docker-compose启动edgex-go 至此,通过docker-compose以容器的方式运行EdgeX Foundry的相关步骤和注意事项也就结束了。 本章小结 本章梳理了云、边、端协同的边缘计算系统的整体架构,对云、边、端各部分包含的组件的技术栈进行了罗列,还分别对云、边、端各部分的部署方式和注意事项进行了系统梳理和详细说明。下一章将对整个边缘计算系统的逻辑架构及云、边、端之间的逻辑关系进行系统梳理。
1.Minikube的安装与使用
2.Kind的安装与使用
2.3.1以系统进程的方式部署KubeEdge
2.4.1系统进程部署EdgeX Foundry
#
# Copyright (c) 2018
# Mainflux
#
# SPDX-License-Identifier: Apache-2.0
#
###
# Launches all EdgeX Go binaries (must be previously built).
#
# Expects that Consul and MongoDB are already installed and running.
#
###
DIR=$PWD
CMD=../cmd
# Kill all edgex-* stuff
function cleanup {
pkill edgex
}
# disable secret-store integration
export EDGEX_SECURITY_SECRET_STORE=false
###
# Support logging
###
cd $CMD/support-logging
# Add `edgex-` prefix on start, so we can find the process family
exec -a edgex-support-logging ./support-logging &
cd $DIR
###
# Core Command
###
cd $CMD/core-command
# Add `edgex-` prefix on start, so we can find the process family
exec -a edgex-core-command ./core-command &
cd $DIR
###
# Core Data
###
cd $CMD/core-data
exec -a edgex-core-data ./core-data &
cd $DIR
###
# Core Meta Data
###
cd $CMD/core-metadata
exec -a edgex-core-metadata ./core-metadata &
cd $DIR
###
# Support Notifications
###
cd $CMD/support-notifications
# Add `edgex-` prefix on start, so we can find the process family
exec -a edgex-support-notifications ./support-notifications &
cd $DIR
###
# System Management Agent
###
cd $CMD/sys-mgmt-agent
# Add `edgex-` prefix on start, so we can find the process family
exec -a edgex-sys-mgmt-agent ./sys-mgmt-agent &
cd $DIR
# Support Scheduler
###
cd $CMD/support-scheduler
# Add `edgex-` prefix on start, so we can find the process family
exec -a edgex-support-scheduler ./support-scheduler &
cd $DIR
trap cleanup EXIT
while : ; do sleep 1 ; done