目录
--master和edge安装golang(k8s是由go语言写的)
——使用keadm将边缘节点加入K8s集群(Kubeedge)
——前言
为什么要使用KubeEdge呢,这是因为Kubernetes不支持ARM架构的CPU,这就导致我们的板子无法通过k8s加入集群(k8s集群是为AMD架构的服务器服务的)。为了实现边云协同,边缘计算,KubeEdge的部署是必不可少的。(当然也可以采用k3s,虽然效率上远不如Kubeedge,但是安装相较而言比较方便)
附k3s和KubeEdge对比图:
从图上可以看出KubeEdge agent 内存消耗和CPU消耗要远比K3S agent和server都要少很多。
如果你是新手,那么我推荐你使用本文下面的Kubesphere进行一键式部署k8s集群以及KubeEdge。
本文还提供了从命令行暴力部署k8s的方法,推荐老手食用,不过本人用下来发现还是KubeSphere比较方便。(虽然KubeSphere的社会生态环境比较一半,很多问题放着都没人解决,官方文档也有很多问题,但是本文能够帮你解决大部分的问题,而且毕竟KubeSphere是可视化界面,就算环境一般也比命令行上的k8s集群友好很多了。)
那么我们正式进入部署:
使用KubeSphere部署K8s集群、KubeEdge
——什么是KubeSphere?
KubeSphere 是在 Kubernetes 之上构建的面向云原生应用的分布式操作系统,完全开源,支持多云与多集群管理,提供全栈的 IT 自动化运维能力,简化企业的 DevOps 工作流。它的架构可以非常方便地使第三方应用与云原生生态组件进行即插即用 (plug-and-play) 的集成。
简单来说,他就是一个融合怪,方便用户进行云原生开发的融合怪,把许多的复杂的功能整理到了一起,让用户可以在他的这个平台上通过简单的操作就能完成许许多多命令行上复杂的操作。
附KubeSphere官网:面向云原生应用的容器混合云,支持 Kubernetes 多集群管理的 PaaS 容器云平台解决方案 | KubeSphere
接下来我们将在Linux上使用All-in-One模式安装KubeSphere和部署k8s集群:
——先决条件
注:本文章对应KubeSphere版本为3.2.x,据说3.3.x版本就要更新了,届时将会解决kubeedge版本过低和k8s版本过高的v1beta1和v1beta2不兼容问题...当然这些都是后话了。主要是还请各位读者注意,由于KubeSphere官网明确提出不对旧版本的文档进行维护,所以如果更新了新版本的文档,还请以官方文档为主参考。
--硬件推荐配置
操作系统 | 最低配置 |
---|---|
Ubuntu 16.04, 18.04 | 2 核 CPU,4 GB 内存,40 GB 磁盘空间 |
Debian Buster, Stretch | 2 核 CPU,4 GB 内存,40 GB 磁盘空间 |
CentOS 7.x | 2 核 CPU,4 GB 内存,40 GB 磁盘空间 |
Red Hat Enterprise Linux 7 | 2 核 CPU,4 GB 内存,40 GB 磁盘空间 |
SUSE Linux Enterprise Server 15/openSUSE Leap 15.2 | 2 核 CPU,4 GB 内存,40 GB 磁盘空间 |
虽然这是官方文档的推荐配置,但本人推荐的配置是至少4核CPU,8GB内存,40GB磁盘空间,在后续的应用场景中,无论是在kk初始化还是开启可插拔软件启用Kubeedge,本笔者实测如果你的服务器只有2核4G那么将很容易发生服务器卡死、崩溃。
如果你的服务器能够有8核16G了,那么恭喜你,你可以在KubeSphere上“平步青云”了,甚至可以启动所有的KubeSphere上的可插拔软件(监控、应用商店、事件、日志等)
--修改主节点名称
修改主节点名称并不只是为了辨识方便,如果不进行修改,在使用kubesphere安装k8s集群的时候会报错,且这个错误原因比较含糊,本人最终确定是因为没有修改主节点名称导致的,原因暂且未知。不管怎么样,强烈建议修改主节点名称:
在你的终端输入如下指令查看当前主节点名称:
hostname
输入如下指令修改主节点名称:
hostnamectl set-hostname <主节点名称,例如master>
--容器运行时
你的集群必须有一个可用的容器运行时。如果您使用 KubeKey 搭建集群,KubeKey 会默认安装最新版本的 Docker。或者,您也可以在创建集群前手动安装 Docker 或其他容器运行时。
本人推荐使用Docker作为容器运行时。
支持的容器运行时 | 版本 |
---|---|
Docker | 19.3.8 + |
containerd | 最新版 |
CRI-O(试验版,未经充分测试) | 最新版 |
iSula(试验版,未经充分测试) | 最新版 |
附手动安装docker操作(可选):
安装必要的系统工具:
sudo apt-get -y update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
安装GPG证书,如果不安装则没有权限从软件源下载Docker:
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
写入软件源信息(通过这个软件源下载Docker):
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
开始下载Docker:
sudo apt-get -y update
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
curl后会自动进行安装脚本,这一步的时间可能比较久(3-10分钟),请耐心等待。
安装完之后会弹出docker的版本信息,后续可以再次通过下面这个命令查看:
docker version
或者如果只需要查看版本信息,可以输入:
docker -v
--依赖项要求
KubeKey 可以将 Kubernetes 和 KubeSphere 一同安装。针对不同的 Kubernetes 版本,需要安装的依赖项可能有所不同。您可以参考以下列表,查看是否需要提前在节点上安装相关的依赖项。
依赖项 | Kubernetes 版本 ≥ 1.18 | Kubernetes 版本 < 1.18 |
---|---|---|
socat |
必须 | 可选但建议 |
conntrack |
必须 | 可选但建议 |
ebtables |
可选但建议 | 可选但建议 |
ipset |
可选但建议 | 可选但建议 |
我的建议是:能装的全装。
sudo apt-get -y socat conntrack ebtables ipset
--网络和 DNS 要求
- 请确保
/etc/resolv.conf
中的 DNS 地址可用,否则,可能会导致集群中的 DNS 出现问题。 - 如果您的网络配置使用防火墙规则或安全组,请务必确保基础设施组件可以通过特定端口相互通信。建议您关闭防火墙。有关更多信息,请参见端口要求。(在服务器安全组里把这些要求的端口全部放行,在边缘端上确保防火墙放行这些端口)
- 支持的 CNI 插件:Calico 和 Flannel。其他插件也适用(例如 Cilium 和 Kube-OVN 等),但请注意它们未经充分测试。(咱们暂时用不到,不用考虑)
官方建议您的操作系统处于干净状态(不安装任何其他软件),否则可能会发生冲突。即将服务器更换操作系统,从零开始。(仅供参考)
——下载KubeKey(kk)并开始安装
先执行以下命令以确保您从正确的区域下载 KubeKey。
export KKZONE=cn
执行以下命令下载 KubeKey。
curl -sfL https://get-kk.kubesphere.io | VERSION=v2.0.0 sh -
为 kk
添加可执行权限:
chmod +x kk
通过一个指令进行快速安装:
./kk create cluster --with-kubernetes v1.21.5 --with-kubesphere v3.2.1
注:
- 此处的k8s和kubesphere版本可以更改成你希望下载的版本,建议默认。
安装 KubeSphere 3.2.1 的建议 Kubernetes 版本:1.19.x、1.20.x、1.21.x 或 1.22.x(实验性支持)。如果不指定 Kubernetes 版本,KubeKey 将默认安装 Kubernetes v1.21.5。有关受支持的 Kubernetes 版本的更多信息,请参见支持矩阵。
执行该命令后,KubeKey 将检查您的安装环境,结果显示在一张表格中,输入 yes
继续安装流程。
当看到以下输出的时候,证明我们的安装完成了:
#####################################################
### Welcome to KubeSphere! ###
#####################################################
Console: http://192.168.0.2:30880
Account: admin
Password: P@88w0rd
NOTES:
1. After you log into the console, please check the
monitoring status of service components in
"Cluster Management". If any service is not
ready, please wait patiently until all components
are up and running.
2. Please change the default password after login.
#####################################################
https://kubesphere.io 20xx-xx-xx xx:xx:xx
#####################################################
输出信息会显示 Web 控制台的 IP 地址和端口号,默认的 NodePort 是 30880
。现在,您可以使用默认的帐户和密码 (admin/P@88w0rd
) 通过 <你的服务器外网IP>:30880
访问控制台,进入后会自动要求你更改密码。
可以再次通过命令行输入下面的指令以查看安装结果:
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f
到这一步,我们已经通过kk完成了k8s集群和KubeSphere的部署,接下来我将告诉你如何在KubeSphere上部署KubeEdge(官方文档有坑!)
附:我的KubeSphere Web控制台截图,可能跟你的有地方不一样,因为我已经进行了后续的操作
——在KubeSphere部署KubeEdge
在命令行上暴力部署k8s和KubeEdge
——部署前的准备
对象 | 主机名称 | CPU架构 | IP地址 |
阿里云ECS云服务器 | master | AMD64 | 59.110.4.200 |
Jetson Nano B02板子 | edge | ARM64 | 192.168.123.13 |
登录到root模式,这样后续可以避免很多权限问题。
sudo passwd root
#然后输入密码
su root
#输入之前输入的密码进入root模式
或者使用:
sudo su
#输入当前用户密码
也可以不输入root密码进入root模式。
分别在master和edge上修改主机名称:
hostnamectl set-hostname master
hostnamectl set-hostname edge
更改完成之后可能终端不会马上进行反馈(@后面可能还是旧的hostname)
hostname
#只要输入这个指令返回的hostname变成了我们想要的就可以
分别在master和edge上准备环境:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install wget vim ssh ufw
#一些必要的工具
查看防火墙状态(active为激活,inactive为不激活)
sudo ufw status
关闭防火墙:
sudo ufw disable
关闭交换分区,k8s官方文档要求,否则将无法进行集群初始化,虽然初始化的时候加上--ingore参数也可以避免,但是后续可能会产生不可预知的后果。(如果是服务器貌似交换分区会默认关闭,而且edge端不需要关闭swap,因为k8s集群是在master端初始化的,实际上需要关闭swap的貌似是虚拟机的情况(?)我的服务器貌似无法启动swap,故此处我采用edge端进行演示操作)
输入该指令查看是否开启了交换分区:
sudo free -m
如图所示,Swap后面的total列不为0即为开启了交换分区,执行下面的操作进行关闭:
sudo swapoff -a
#临时关闭交换分区
或者使用下面这个永久关闭交换分区:
sudo vim /etc/fstab
在打开的文件里面找到类似于我图上带swap的若干行,把这两行注释掉(在前头加上#),如图所示,设置完需要重启(不推荐,因为只需要确保本次初始化的时候关闭swap即可):
如果后续需要打开交换分区则输入:
sudo swapon -a
更改后的结果图:
--master和edge安装docker
安装必要的系统工具:
sudo apt-get -y update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
安装GPG证书,如果不安装则没有权限从软件源下载Docker:
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
写入软件源信息(通过这个软件源下载Docker):
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
开始下载Docker:
sudo apt-get -y update
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
curl后会自动进行安装脚本,这一步的时间可能比较久(3-10分钟),请耐心等待。
附安装之后弹出的docker安装成功信息和docker的具体信息:
后续可以再次通过下面这个命令查看docker的具体信息:
docker version
或者如果只需要查看版本信息,可以输入:
docker -v
修改镜像源:
sudo vim /etc/docker/daemon.json
添加以下内容:
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://reg-mirror.qiniu.com",
"https://quay-mirror.qiniu.com"
],
"exec-opts": ["native.cgroupdriver=systemd"]
}
参数解释:
registry-mirrors为镜像源,后续docker拉取镜像的时候,会通过这个镜像源进行拉取,解决国内无法访问外网镜像站的问题
exec-opts设定执行选项,设定docker为systemd技术(k8s集群需要)
重新载入daemon:
sudo systemctl daemon-reload
重启docker:
sudo systemctl restart docker
查看修改后的docker Cgroup的参数,为systemd即修改成功:
docker info | grep Cgroup
--master和edge安装golang(k8s是由go语言写的)
sudo wget https://dl.google.com/go/go1.18.3.linux-amd64.tar.gz
#1.18.3是笔者目前的最新版,后续也可以更改版本号为自己想要下载的版本
#如果下载不下来或者想要知道更多go的版本信息请访问
#https://studygolang.com/dl
将go解压并将其添加至环境变量:
sudo tar -zxvf go1.18.3.linux-amd64.tar.gz -C /usr/local/
sudo cp /usr/local/go/bin/go /usr/local/bin/go
查看go是否安装成功:
go version
#若安装成功则输出 go version go1.18.3 linux/amd64
——开始部署k8s集群
master端:
让 apt-get 支持 ssl 传输:
apt-get update && apt-get install -y apt-transport-https
下载镜像源密钥 :
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
添加 k8s 镜像源 :
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
更新apt-get列表:
apt-get update
下载 kubelet,kubeadm,kubectl:
apt-get install -y kubelet=1.21.5-00 kubeadm=1.21.5-00 kubectl=1.21.5-00
初始化指令:
--apiserver-advertise-address里填master的ip地址(需要修改成自己的master ip地址)
--image-repository里填镜像仓库地址(一般不需要修改)
--kubernetes-version里填k8s版本号(需要修改成自己的k8s version,或者不加)
--service-cidr和--pod-network-cidr也一般不需要修改,或者不加
kubeadm init \
--apiserver-advertise-address=172.29.32.29 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.21.5 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
附初始化开始到初始化成功的终端输出:
[init] Using Kubernetes version: v1.21.5
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local master] and IPs [10.96.0.1 172.29.32.29]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [localhost master] and IPs [172.29.32.29 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [localhost master] and IPs [172.29.32.29 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 12.501782 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.21" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node master as control-plane by adding the labels: [node-role.kubernetes.io/master(deprecated) node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
[mark-control-plane] Marking the node master as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: oulfd4.0gj0r1pmmpdqtpok
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxyYour Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/configAlternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
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:
kubeadm join 172.29.32.29:6443 --token oulfd4.0gj0r1pmmpdqtpok \
--discovery-token-ca-cert-hash sha256:2b62e4c6c379e217de6422e9b2bd3ea4d670fe0c3f9489d7aca3fb5fec36daf7
这时候输入kubectl get nodes会发现我们的master节点是NotReady,这是正常现象,请先别慌张,我们还没有进行网络的部署(如果无法拉取则参考下文中修改/etc/hosts的方法加上raw.githubusercontent.com的ip):
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
查看部署情况:(都变成1/1即为部署成功)
kubectl get pods -n kube-system
查看节点情况,若为Ready就成功了!
kubectl get nodes
至此,我们已经部署好了我们的k8s集群,可喜可贺!接下来我们将通过Kubeedge的keadm将边缘节点加入k8s集群实现边云协同。
——使用keadm将边缘节点加入K8s集群(Kubeedge)
强烈推荐使用keadm进行部署,这种部署方法较为简单:
云端下载keadm:
sudo mkdir -p /etc/kubeedge && wget https://github.com/kubeedge/kubeedge/releases/download/v1.10.0/keadm-v1.10.0-linux-amd64.tar.gz
边端下载keadm:
sudo mkdir -p /etc/kubeedge && wget https://github.com/kubeedge/kubeedge/releases/download/v1.10.0/keadm-v1.10.0-linux-arm64.tar.gz
如果无法进行传输的话,可以尝试在下面这个链接查询github的ip并添加到/etc/hosts中,并输入:
https://ipaddress.com/analysis/github
sudo vim /etc/hosts
下面是本人的hosts文件,仅供格式参考(ip是会变化的,所以建议随用随查询,上面那个链接的)
如果你还是嫌弃传输速率太慢或者加上host之后依然无法下载,那么我建议你使用windows科学上网下载到本地,在通过Xftp7将本地的文件传输到云端。
原下载地址:https://github.com/kubeedge/kubeedge/tree/master/build/crds
下载完之后,解压下载好的文件
云端:
tar -zxvf keadm-v1.10.0-linux-amd64.tar.gz
边端:
tar -zxvf keadm-v1.10.0-linux-arm64.tar.gz
赋予keadm文件权限,移动到用户目录,这样方便我们后续执行keadm命令的时候不需要再一次cd到下载后的目录输入./keadm <command>执行了。
指令如下:
cd keadm-v1.10.0-linux-amd64/keadm && chmod +x keadm && mv keadm /usr/local/bin
注:后续的amd64和arm64我将不再区分,请根据你的CPU架构进行选择,我的服务器就是amd架构,我的边端jetson nano板子就是arm架构。
如果不清楚你的CPU架构,可以输入下面这个指令查看:
arch
下载好keadm之后我们就可以进行初始化了,当然你还可以在原下载地址下载好对应版本的kubeedge和cloudcore并传输到云端,如果你的网络传输速度很慢的话。如果你嫌麻烦,就不需要手动下载了,后面的初始化步骤会执行脚本自动帮你下载,你只需要在执行初始化的时候把电脑放在一旁,来杯咖啡,看个剧的时间也就结束了。
——云端初始化
开始初始化,在云端执行:
keadm init --advertise-address=59.110.5.200
--advertise-address后面是master端的ip地址,这里我使用了我的服务器外网地址,不推荐使用内网地址,因为如果我们使用内网地址,那么后面初始化结束生成的密钥也将会是适用于内网地址的,但当我们使用边端的时候,我们很显然不能用内网地址去连接master端,如果我们使用公网地址去连接,又将会因为密钥是对应内网的而无法适配。
如果你的服务器能直接初始化成功那将再好不过,恭喜你跳过了一个大坑,如果没有,而是因为网络问题无法从github上拉取初始化配置文件,那么也恭喜你看到了我的文章,这个坑困惑了我当时有一段时间。
解决方法:手动从github上面拉取配置文件(需要科学上网)
首先先创建我们初始化所需要的目录(务必一模一样)
下载地址: https://github.com/kubeedge/kubeedge/tree/master/build/crds
mkdir -p /etc/kubeedge/crds/devices && mkdir -p /etc/kubeedge/crds/reliablesyncs
这里提供一个官方文档里的文件结构树,供大家参考:
kubeedge/
├── cloudcore.service
├── crds
│ ├── devices
│ │ ├── devices_v1alpha2_devicemodel.yaml
│ │ └── devices_v1alpha2_device.yaml
│ └── reliablesyncs
│ ├── cluster_objectsync_v1alpha1.yaml
│ └── objectsync_v1alpha1.yaml
└── kubeedge-v1.10.0-linux-amd64.tar.gz
把下载的文件放置在对应的位置,这样初始化脚本才能够成功进行。
如果看不懂也没有关系,跟着我敲下去就完事了!
完成下面这些步骤(无顺序),例如:我要vim devices_v1alpha2_devicemodel.yaml,则根据结构树找到github上kubeedge库里的crds下面的devices文件夹,打开devices_v1alpha2_devicemodel.yaml文件,将里面的内容赋值粘贴到vim里,保存退出,其他类似。
cd /etc/kubeedge/crds/devices/
vim devices_v1alpha2_devicemodel.yaml
cd /etc/kubeedge/crds/devices/
vim devices_v1alpha2_device.yaml
cd /etc/kubeedge/crds/reliablesyncs/
vim cluster_objectsync_v1alpha1.yaml
cd /etc/kubeedge/crds/reliablesyncs/
vim objectsync_v1alpha1.yaml
#实测cloudcore比较容易下载,这一步可以省略
cd /etc/kubeedge/
vim cloudcore.service
如果无法科学上网或者找不到文件可以参考复制我下面的yaml文件(均是从官方网站拉取下来的)
#devices_v1alpha2_devicemodel.yaml
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
name: devicemodels.devices.kubeedge.io
spec:
group: devices.kubeedge.io
names:
kind: DeviceModel
listKind: DeviceModelList
plural: devicemodels
singular: devicemodel
scope: Namespaced
versions:
- name: v1alpha2
schema:
openAPIV3Schema:
description: DeviceModel is the Schema for the device model API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: DeviceModelSpec defines the model / template for a device.It
is a blueprint which describes the device capabilities and access mechanism
via property visitors.
properties:
properties:
description: 'Required: List of device properties.'
items:
description: DeviceProperty describes an individual device property
/ attribute like temperature / humidity etc.
properties:
description:
description: The device property description.
type: string
name:
description: 'Required: The device property name.'
type: string
type:
description: 'Required: PropertyType represents the type and
data validation of the property.'
properties:
boolean:
properties:
accessMode:
description: 'Required: Access mode of property, ReadWrite
or ReadOnly.'
enum:
- ReadWrite
- ReadOnly
type: string
defaultValue:
type: boolean
type: object
bytes:
properties:
accessMode:
description: 'Required: Access mode of property, ReadWrite
or ReadOnly.'
enum:
- ReadWrite
- ReadOnly
type: string
type: object
double:
properties:
accessMode:
description: 'Required: Access mode of property, ReadWrite
or ReadOnly.'
enum:
- ReadWrite
- ReadOnly
type: string
defaultValue:
type: number
maximum:
type: number
minimum:
type: number
unit:
description: The unit of the property
type: string
type: object
float:
properties:
accessMode:
description: 'Required: Access mode of property, ReadWrite
or ReadOnly.'
enum:
- ReadWrite
- ReadOnly
type: string
defaultValue:
type: number
maximum:
type: number
minimum:
type: number
unit:
description: The unit of the property
type: string
type: object
int:
properties:
accessMode:
description: 'Required: Access mode of property, ReadWrite
or ReadOnly.'
enum:
- ReadWrite
- ReadOnly
type: string
defaultValue:
format: int64
type: integer
maximum:
format: int64
type: integer
minimum:
format: int64
type: integer
unit:
description: The unit of the property
type: string
type: object
string:
properties:
accessMode:
description: 'Required: Access mode of property, ReadWrite
or ReadOnly.'
enum:
- ReadWrite
- ReadOnly
type: string
defaultValue:
type: string
type: object
type: object
type: object
type: array
type: object
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
#devices_v1alpha2_device.yaml
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
name: devices.devices.kubeedge.io
spec:
group: devices.kubeedge.io
names:
kind: Device
listKind: DeviceList
plural: devices
singular: device
scope: Namespaced
versions:
- name: v1alpha2
schema:
openAPIV3Schema:
description: Device is the Schema for the devices API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: DeviceSpec represents a single device instance. It is an
instantation of a device model.
properties:
data:
description: Data section describe a list of time-series properties
which should be processed on edge node.
properties:
dataProperties:
description: 'Required: A list of data properties, which are not
required to be processed by edgecore'
items:
description: DataProperty represents the device property for
external use.
properties:
metadata:
additionalProperties:
type: string
description: Additional metadata like timestamp when the
value was reported etc.
type: object
propertyName:
description: 'Required: The property name for which should
be processed by external apps. This property should be
present in the device model.'
type: string
type: object
type: array
dataTopic:
description: Topic used by mapper, all data collected from dataProperties
should be published to this topic, the default value is $ke/events/device/+/data/update
type: string
type: object
deviceModelRef:
description: 'Required: DeviceModelRef is reference to the device
model used as a template to create the device instance.'
properties:
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
type: object
nodeSelector:
description: NodeSelector indicates the binding preferences between
devices and nodes. Refer to k8s.io/kubernetes/pkg/apis/core NodeSelector
for more details
properties:
nodeSelectorTerms:
description: Required. A list of node selector terms. The terms
are ORed.
items:
description: A null or empty node selector term matches no objects.
The requirements of them are ANDed. The TopologySelectorTerm
type implements a subset of the NodeSelectorTerm.
properties:
matchExpressions:
description: A list of node selector requirements by node's
labels.
items:
description: A node selector requirement is a selector
that contains values, a key, and an operator that relates
the key and values.
properties:
key:
description: The label key that the selector applies
to.
type: string
operator:
description: Represents a key's relationship to a
set of values. Valid operators are In, NotIn, Exists,
DoesNotExist. Gt, and Lt.
type: string
values:
description: An array of string values. If the operator
is In or NotIn, the values array must be non-empty.
If the operator is Exists or DoesNotExist, the values
array must be empty. If the operator is Gt or Lt,
the values array must have a single element, which
will be interpreted as an integer. This array is
replaced during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchFields:
description: A list of node selector requirements by node's
fields.
items:
description: A node selector requirement is a selector
that contains values, a key, and an operator that relates
the key and values.
properties:
key:
description: The label key that the selector applies
to.
type: string
operator:
description: Represents a key's relationship to a
set of values. Valid operators are In, NotIn, Exists,
DoesNotExist. Gt, and Lt.
type: string
values:
description: An array of string values. If the operator
is In or NotIn, the values array must be non-empty.
If the operator is Exists or DoesNotExist, the values
array must be empty. If the operator is Gt or Lt,
the values array must have a single element, which
will be interpreted as an integer. This array is
replaced during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
type: object
type: array
required:
- nodeSelectorTerms
type: object
propertyVisitors:
description: List of property visitors which describe how to access
the device properties. PropertyVisitors must unique by propertyVisitor.propertyName.
items:
description: DevicePropertyVisitor describes the specifics of accessing
a particular device property. Visitors are intended to be consumed
by device mappers which connect to devices and collect data /
perform actions on the device.
properties:
bluetooth:
description: Bluetooth represents a set of additional visitor
config fields of bluetooth protocol.
properties:
characteristicUUID:
description: 'Required: Unique ID of the corresponding operation'
type: string
dataConverter:
description: Responsible for converting the data being read
from the bluetooth device into a form that is understandable
by the platform
properties:
endIndex:
description: 'Required: Specifies the end index of incoming
byte stream to be considered to convert the data the
value specified should be inclusive for example if
3 is specified it includes the third index'
type: integer
orderOfOperations:
description: Specifies in what order the operations(which
are required to be performed to convert incoming data
into understandable form) are performed
items:
description: Specify the operation that should be
performed to convert incoming data into understandable
form
properties:
operationType:
description: 'Required: Specifies the operation
to be performed to convert incoming data'
type: string
operationValue:
description: 'Required: Specifies with what value
the operation is to be performed'
type: number
type: object
type: array
shiftLeft:
description: Refers to the number of bits to shift left,
if left-shift operation is necessary for conversion
type: integer
shiftRight:
description: Refers to the number of bits to shift right,
if right-shift operation is necessary for conversion
type: integer
startIndex:
description: 'Required: Specifies the start index of
the incoming byte stream to be considered to convert
the data. For example: start-index:2, end-index:3
concatenates the value present at second and third
index of the incoming byte stream. If we want to reverse
the order we can give it as start-index:3, end-index:2'
type: integer
type: object
dataWrite:
additionalProperties:
format: byte
type: string
description: 'Responsible for converting the data coming
from the platform into a form that is understood by the
bluetooth device For example: "ON":[1], "OFF":[0]'
type: object
type: object
collectCycle:
description: Define how frequent mapper will collect from device.
format: int64
type: integer
customizedProtocol:
description: CustomizedProtocol represents a set of visitor
config fields of bluetooth protocol.
properties:
configData:
description: 'Required: The configData of customized protocol'
type: object
x-kubernetes-preserve-unknown-fields: true
protocolName:
description: 'Required: name of customized protocol'
type: string
type: object
customizedValues:
description: Customized values for visitor of provided protocols
type: object
x-kubernetes-preserve-unknown-fields: true
modbus:
description: Modbus represents a set of additional visitor config
fields of modbus protocol.
properties:
isRegisterSwap:
description: Indicates whether the high and low register
swapped. Defaults to false.
type: boolean
isSwap:
description: Indicates whether the high and low byte swapped.
Defaults to false.
type: boolean
limit:
description: 'Required: Limit number of registers to read/write.'
format: int64
type: integer
offset:
description: 'Required: Offset indicates the starting register
number to read/write data.'
format: int64
type: integer
register:
description: 'Required: Type of register'
enum:
- CoilRegister
- DiscreteInputRegister
- InputRegister
- HoldingRegister
type: string
scale:
description: The scale to convert raw property data into
final units. Defaults to 1.0
type: number
type: object
opcua:
description: Opcua represents a set of additional visitor config
fields of opc-ua protocol.
properties:
browseName:
description: The name of opc-ua node
type: string
nodeID:
description: 'Required: The ID of opc-ua node, e.g. "ns=1,i=1005"'
type: string
type: object
propertyName:
description: 'Required: The device property name to be accessed.
This should refer to one of the device properties defined
in the device model.'
type: string
reportCycle:
description: Define how frequent mapper will report the value.
format: int64
type: integer
type: object
type: array
protocol:
description: 'Required: The protocol configuration used to connect
to the device.'
properties:
bluetooth:
description: Protocol configuration for bluetooth
properties:
macAddress:
description: Unique identifier assigned to the device.
type: string
type: object
common:
description: Configuration for protocol common part
properties:
collectRetryTimes:
description: Define retry times of mapper will collect from
device.
format: int64
type: integer
collectTimeout:
description: Define timeout of mapper collect from device.
format: int64
type: integer
collectType:
description: Define collect type, sync or async.
enum:
- sync
- async
type: string
com:
properties:
baudRate:
description: Required. BaudRate 115200|57600|38400|19200|9600|4800|2400|1800|1200|600|300|200|150|134|110|75|50
enum:
- 115200
- 57600
- 38400
- 19200
- 9600
- 4800
- 2400
- 1800
- 1200
- 600
- 300
- 200
- 150
- 134
- 110
- 75
- 50
format: int64
type: integer
dataBits:
description: Required. Valid values are 8, 7, 6, 5.
enum:
- 8
- 7
- 6
- 5
format: int64
type: integer
parity:
description: Required. Valid options are "none", "even",
"odd". Defaults to "none".
enum:
- none
- even
- odd
type: string
serialPort:
description: Required.
type: string
stopBits:
description: Required. Bit that stops 1|2
enum:
- 1
- 2
format: int64
type: integer
type: object
commType:
description: Communication type, like tcp client, tcp server
or COM
type: string
customizedValues:
description: Customized values for provided protocol
type: object
x-kubernetes-preserve-unknown-fields: true
reconnRetryTimes:
description: Reconnecting retry times
format: int64
type: integer
reconnTimeout:
description: Reconnection timeout
format: int64
type: integer
tcp:
properties:
ip:
description: Required.
type: string
port:
description: Required.
format: int64
type: integer
type: object
type: object
customizedProtocol:
description: Configuration for customized protocol
properties:
configData:
description: Any config data
type: object
x-kubernetes-preserve-unknown-fields: true
protocolName:
description: Unique protocol name Required.
type: string
type: object
modbus:
description: Protocol configuration for modbus
properties:
slaveID:
description: Required. 0-255
format: int64
type: integer
type: object
opcua:
description: Protocol configuration for opc-ua
properties:
certificate:
description: Certificate for access opc server.
type: string
password:
description: Password for access opc server.
type: string
privateKey:
description: PrivateKey for access opc server.
type: string
securityMode:
description: Defaults to "none".
type: string
securityPolicy:
description: Defaults to "none".
type: string
timeout:
description: Timeout seconds for the opc server connection.???
format: int64
type: integer
url:
description: 'Required: The URL for opc server endpoint.'
type: string
userName:
description: Username for access opc server.
type: string
type: object
type: object
type: object
status:
description: DeviceStatus reports the device state and the desired/reported
values of twin attributes.
properties:
twins:
description: 'A list of device twins containing desired/reported desired/reported
values of twin properties.. Optional: A passive device won''t have
twin properties and this list could be empty.'
items:
description: Twin provides a logical representation of control properties
(writable properties in the device model). The properties can
have a Desired state and a Reported state. The cloud configures
the `Desired`state of a device property and this configuration
update is pushed to the edge node. The mapper sends a command
to the device to change this property value as per the desired
state . It receives the `Reported` state of the property once
the previous operation is complete and sends the reported state
to the cloud. Offline device interaction in the edge is possible
via twin properties for control/command operations.
properties:
desired:
description: 'Required: the desired property value.'
properties:
metadata:
additionalProperties:
type: string
description: Additional metadata like timestamp when the
value was reported etc.
type: object
value:
description: 'Required: The value for this property.'
type: string
required:
- value
type: object
propertyName:
description: 'Required: The property name for which the desired/reported
values are specified. This property should be present in the
device model.'
type: string
reported:
description: 'Required: the reported property value.'
properties:
metadata:
additionalProperties:
type: string
description: Additional metadata like timestamp when the
value was reported etc.
type: object
value:
description: 'Required: The value for this property.'
type: string
required:
- value
type: object
type: object
type: array
type: object
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
#cluster_objectsync_v1alpha1.yaml
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
name: clusterobjectsyncs.reliablesyncs.kubeedge.io
spec:
group: reliablesyncs.kubeedge.io
names:
kind: ClusterObjectSync
listKind: ClusterObjectSyncList
plural: clusterobjectsyncs
singular: clusterobjectsync
scope: Cluster
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: ClusterObjectSync stores the state of the cluster level, nonNamespaced
object that was successfully persisted to the edge node. ClusterObjectSync
name is a concatenation of the node name which receiving the object and
the object UUID.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: ObjectSyncSpec stores the details of objects that persist
to the edge.
properties:
objectAPIVersion:
description: ObjectAPIVersion is the APIVersion of the object that
was successfully persist to the edge node.
type: string
objectKind:
description: ObjectType is the kind of the object that was successfully
persist to the edge node.
type: string
objectName:
description: ObjectName is the name of the object that was successfully
persist to the edge node.
type: string
type: object
status:
description: ObjectSyncSpec stores the resourceversion of objects that
persist to the edge.
properties:
objectResourceVersion:
description: ObjectResourceVersion is the resourceversion of the object
that was successfully persist to the edge node.
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
objectsync_v1alpha1.yaml
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
creationTimestamp: null
name: objectsyncs.reliablesyncs.kubeedge.io
spec:
group: reliablesyncs.kubeedge.io
names:
kind: ObjectSync
listKind: ObjectSyncList
plural: objectsyncs
singular: objectsync
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: ObjectSync stores the state of the namespaced object that was
successfully persisted to the edge node. ObjectSync name is a concatenation
of the node name which receiving the object and the object UUID.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: ObjectSyncSpec stores the details of objects that persist
to the edge.
properties:
objectAPIVersion:
description: ObjectAPIVersion is the APIVersion of the object that
was successfully persist to the edge node.
type: string
objectKind:
description: ObjectType is the kind of the object that was successfully
persist to the edge node.
type: string
objectName:
description: ObjectName is the name of the object that was successfully
persist to the edge node.
type: string
type: object
status:
description: ObjectSyncSpec stores the resourceversion of objects that
persist to the edge.
properties:
objectResourceVersion:
description: ObjectResourceVersion is the resourceversion of the object
that was successfully persist to the edge node.
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
手动配置完之后再一次进行初始化,操作同上:
keadm init --advertise-address=59.110.5.200
如果不出意外的话,我们这次将成功初始化kubeedge master端,成功标志如下:
看到这个CloudCore started了吗,这是我们成功的里程碑!
输入下面这个指令可以查看cloudcore的状态:
systemctl status cloudcore
输入下面这个指令可以查看cloudcore的日志,方便排查错误(如果有的话)
journalctl -u cloudcore.service -xe
如果要重启cloudcore,不推荐用systemctl restart cloudcore
建议使用官方文档推荐的指令:
pkill cloudcore
nohup cloudcore > cloudcore.log 2>&1 &
其实后续还是有很多操作没有写上来,笔者最近的时间有些不太够,如果你们遇到什么困惑欢迎私信我或者在下面的评论区留言。
我的另一篇k8s集群部署经验总结,希望能够帮到你:
Kubernetes(k8s)集群部署实战经验总结_南南南南南琦的博客-CSDN博客_k8s项目经验
END