K8s实践云端集群

KubeEdge 边缘计算实验

实验背景与目标

本实验基于三台 Ubuntu 虚拟机搭建 Kubernetes + KubeEdge 边缘计算实验环境,实现云端统一管理边缘节点,并验证云边协同能力。

实验环境

节点 主机名 IP 地址 作用
master master 192.168.139.184 Kubernetes 控制节点 / KubeEdge CloudCore
slave1 slave1 192.168.139.226 Kubernetes 工作节点
edge edge 192.168.139.105 KubeEdge 边缘节点 / EdgeCore

实验最终目标

在 master 节点执行:

1
kubectl get nodes -o wide

能够看到类似结果:

1
2
3
4
NAME     STATUS   ROLES           VERSION
master Ready control-plane v1.28.15
slave1 Ready <none> v1.28.15
edge Ready agent,edge v1.23.17-kubeedge-v1.13.4

注意事项

  • 三台虚拟机均使用 Ubuntu22.04
  • 本文档中所有 IP 为内网真实 IP
  • edge 节点 不通过 kubeadm 加入 K8s,而是通过 KubeEdge 接入

01.基础环境准备与旧环境清理

本阶段在 master、slave1、edge 三台虚拟机上都需要执行。如果环境已经配置好主机名和 hosts,可跳过 1.1、1.2。

1.1 设置主机名

master 节点执行:

1
2
sudo hostnamectl set-hostname master
sudo reboot

slave1 节点执行:

1
2
sudo hostnamectl set-hostname slave1
sudo reboot

edge 节点执行:

1
2
sudo hostnamectl set-hostname edge
sudo reboot

1.2 配置 hosts 文件

三台机器都执行,编辑 /etc/hosts,添加以下内容(若已有请核对):

1
2
3
192.168.139.184 master
192.168.139.226 slave1
192.168.139.105 edge

检查主机名解析:

1
2
3
ping master
ping slave1
ping edge

三台机器都应能 ping 通这三个主机名。

1.3 检查网络和 DNS

三台机器都执行。若域名解析失败,执行以下命令修复 DNS:

1
2
3
4
5
6
sudo rm -f /etc/resolv.conf
sudo tee /etc/resolv.conf <<EOF
nameserver 223.5.5.5
nameserver 114.114.114.114
nameserver 8.8.8.8
EOF

然后测试:

1
2
ping -c 3 mirrors.aliyun.com
ping -c 3 github.com

后续若下载失败出现 Temporary failure in name resolution,可重新执行本步。

1.4 安装基础工具

三台机器都执行:

1
2
sudo apt update
sudo apt install -y curl wget vim net-tools

1.5 关闭防火墙和 swap

三台机器都执行:

1
2
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab

检查 swap:

1
free -h

Swap 一行应为 0。

1.6 清理旧 K3s 环境(若未使用过 K3s 可跳过)

1
2
3
4
5
6
7
8
9
sudo /usr/local/bin/k3s-uninstall.sh || true
sudo /usr/local/bin/k3s-agent-uninstall.sh || true
sudo systemctl stop k3s || true
sudo systemctl stop k3s-agent || true
sudo rm -f /etc/systemd/system/k3s.service /etc/systemd/system/k3s-agent.service /etc/systemd/system/k3s-agent.service.env /etc/systemd/system/multi-user.target.wants/k3s-agent.service
sudo rm -f /usr/local/bin/k3s /usr/local/bin/kubectl /usr/local/bin/crictl /usr/local/bin/ctr
sudo rm -rf /etc/rancher /var/lib/rancher /var/lib/kubelet /etc/cni/net.d /opt/cni/bin
sudo systemctl daemon-reload
sudo systemctl reset-failed

检查是否清理干净:

1
2
3
which k3s
systemctl status k3s --no-pager
systemctl status k3s-agent --no-pager

期望无输出或显示 could not be found, 不然后续是启动不了kubeadm的

1.7 配置内核模块和网络参数

三台机器都执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sudo modprobe overlay
sudo modprobe br_netfilter

sudo tee /etc/modules-load.d/k8s.conf <<EOF
overlay
br_netfilter
EOF

sudo tee /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

sudo sysctl --system

检查:

1
ls /proc/sys/net/bridge/bridge-nf-call-iptables

看到路径即为成功。


02.安装 Kubernetes 云端集群

本阶段只在 masterslave1 上执行。edge 节点不安装 kubeadm/kubelet/kubectl

2.1 安装 containerd

在 master 和 slave1 上执行:

1
2
3
4
5
6
7
8
9
10
sudo apt update
sudo apt install -y containerd

sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

sudo systemctl restart containerd
sudo systemctl enable containerd
  • containerd 是 Kubernetes 默认的容器运行时。它支持两种 cgroup 驱动:cgroupfssystemd
  • Kubernetes 官方强烈推荐使用 systemd 作为 cgroup 驱动,因为当同一个节点上既有容器运行时又有 kubelet 时,两种不同的 cgroup 驱动会导致系统资源统计混乱、节点不稳定的问题。
  • 默认生成的 containerd 配置里 SystemdCgroup = false(即使用 cgroupfs),需要改为 true 才能与 kubelet 匹配。
    检查:
1
systemctl status containerd --no-pager

应显示 Active: active (running)

2.2 安装 kubeadm、kubelet、kubectl

在 master 和 slave1 上执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gpg

sudo mkdir -p /etc/apt/keyrings
sudo rm -f /etc/apt/keyrings/kubernetes-apt-keyring.gpg

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | \
sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | \
sudo tee /etc/apt/sources.list.d/kubernetes.list


sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

sudo systemctl enable kubelet
sudo systemctl start kubelet
  • gpg --dearmor:将这个文本格式的公钥“解装甲”为二进制格式,保存为 apt 可以直接使用的密钥文件。
  • 这个密钥用于验证后续安装的 kubeadmkubeletkubectl 包确实来自 Kubernetes 官方,防止被中间人篡改。

检查版本:

1
2
3
kubeadm version
kubectl version --client
systemctl status kubelet --no-pager

kubelet 在未加入集群前可能反复重启,属于正常现象。

2.3 补装 CNI 插件

在 master 和 slave1 上执行:

1
sudo apt install --reinstall -y kubernetes-cni

检查:

1
ls /opt/cni/bin/

应看到多个 CNI 插件文件。

2.4 初始化 master 节点

master 上执行,直接使用你的 master IP

1
MASTER_IP=192.168.139.184

拉取镜像:

1
sudo kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers

初始化集群:

1
2
3
4
5
6
sudo kubeadm init \
--apiserver-advertise-address=$MASTER_IP \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/12 \
--image-repository registry.aliyuncs.com/google_containers \
--node-name master

成功后配置 kubectl:

1
2
3
4
5
mkdir -p $HOME/.kube

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

sudo chown $(id -u):$(id -g) $HOME/.kube/config

查看节点:

1
2
3
# 刷新缓存: hash -r

kubectl get nodes

此时 master 为 NotReady(尚未安装网络插件),正常。

若初始化失败,清理后重试:

1
2
sudo kubeadm reset -f
sudo rm -rf /etc/kubernetes /var/lib/etcd /etc/cni/net.d

2.5 安装 Flannel/host-gw 网络插件

master 上执行:

1
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

等待 Pod 启动:

1
kubectl get pods -n kube-system

几分钟后查看节点:

1
kubectl get nodes

应显示 master Ready

若 kube-proxy 或 coredns 出现 ImagePullBackOff,执行:

1
2
3
4
5
6
kubectl -n kube-system set image daemonset/kube-proxy kube-proxy=registry.aliyuncs.com/google_containers/kube-proxy:v1.28.15
kubectl -n kube-system rollout restart daemonset/kube-proxy

kubectl -n kube-system set image deployment/coredns coredns=registry.aliyuncs.com/google_containers/coredns:v1.10.1
kubectl -n kube-system rollout restart deployment/coredns
kubectl -n kube-system delete pod -l k8s-app=kube-dns

修bug

这里我的proxy一直CrashLoopBackOff 排查一下是权限问题

bug修复 我去研究一下
我的obstack的虚拟机太轻量 没有内核编译出一个插件

那就:

1
2
3
kubectl -n kube-system edit configmap kube-proxy

hh
  • 修改 Flannel 为 host-gw 后端
1
2
3
4
5
6
7
8
9
10
11
12
13
kubectl -n kube-flannel edit configmap kube-flannel-cfg

net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "host-gw"
}
}

kubectl -n kube-flannel delete pod -l app=flannel

kubectl get pods -n kube-flannel -w
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


kubectl describe pod -n kube-system coredns-66f779496c-4985b
...plugin type="loopback" failed (add): failed to find plugin "loopback" in path [/opt/cni/bin]...

# 缺插件了


choco@master:~$ ls -la /opt/cni/bin/
total 2908
drwxr-xr-x 1 root root 14 May 26 15:54 .
drwxr-xr-x 1 root root 6 May 26 15:18 ..
-rwxr-xr-x 1 root root 2974518 May 26 15:54 flannel


sudo apt install --reinstall -y kubernetes-cni

ok全跑上了..

2.6 slave1 加入 Kubernetes 集群

master 上生成加入命令:

1
kubeadm token create --print-join-command

输出类似:

1
kubeadm join 192.168.139.184:6443 --token vyhvvu.m8srywcta8jdo6is --discovery-token-ca-cert-hash sha256:37d9687e898ecd4aed6699f52d23580a411f89fb16250dee3b1702395a830b06

复制整条命令,在 slave1 上以 sudo 执行(前面加 sudo):

1
sudo kubeadm join 192.168.139.184:6443 --token vyhvvu.m8srywcta8jdo6is --discovery-token-ca-cert-hash sha256:37d9687e898ecd4aed6699f52d23580a411f89fb16250dee3b1702395a830b06

回到 master 检查:

1
kubectl get nodes

应看到 master Readyslave1 Ready

这里挺慢的..大概5-15min
下面是正常情况 因为 slave1 上没有 API Server,也没有配置 kubeconfig。所有集群管理操作必须在 master 上执行。

1
2
3
4
5
6
7
8
kubectl describe node slave1 | grep -A 10 Conditions

E0526 16:08:55.677888 7492 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0526 16:08:55.678154 7492 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0526 16:08:55.679597 7492 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0526 16:08:55.679706 7492 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0526 16:08:55.681727 7492 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
The connection to the server localhost:8080 was refused - did you specify the right host or port?

若 slave1 加入失败,在 slave1 上执行清理后重试:

1
2
sudo kubeadm reset -f
sudo rm -rf /etc/kubernetes /etc/cni/net.d /var/lib/kubelet/pki

若 slave1 长时间 NotReady,两台机器都执行:

1
2
sudo systemctl restart containerd
sudo systemctl restart kubelet

03.安装 KubeEdge CloudCore

本阶段主要在 master 节点上执行。

3.1 master 下载并安装 keadm

master 上执行:我这里是arm64架构

1
2
3
4
5
6
7
8
9
10
11
cd /tmp

VERSION="v1.13.4"

wget https://github.com/kubeedge/kubeedge/releases/download/${VERSION}/keadm-${VERSION}-linux-arm64.tar.gz

tar -xzf keadm-${VERSION}-linux-arm64.tar.gz

sudo mv keadm-${VERSION}-linux-arm64/keadm/keadm /usr/local/bin/keadm
sudo chmod +x /usr/local/bin/keadm
keadm version

若下载缓慢,可使用代理:

1
wget -O keadm-v1.13.4-linux-amd64.tar.gz https://gh-proxy.com/https://github.com/kubeedge/kubeedge/releases/download/v1.13.4/keadm-v1.13.4-linux-amd64.tar.gz

3.2 初始化 CloudCore

确认 Kubernetes 正常运行:

1
2
kubectl get nodes -o wide
kubectl get pods -A

初始化 CloudCore:

1
2
3
4
5
6
7
MASTER_IP=192.168.139.184

keadm init \
--kube-config=$HOME/.kube/config \
--advertise-address=$MASTER_IP \
--set iptablesManager.mode="external" \
--profile version=v1.13.4

若出现超时错误但 cloudcore pod 已 Running,可继续后续步骤。

3.3 将 CloudCore 服务改为 NodePort

在 master 上执行:

1
kubectl edit svc cloudcore -n kubeedge

找到 type: ClusterIP,改为 type: NodePort,保存退出。

查看端口映射:

1
kubectl get svc cloudcore -n kubeedge

示例输出(你的实际端口可能不同):

1
2
3
kubectl get svc cloudcore -n kubeedge
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cloudcore NodePort 10.105.82.23 <none> 10000:32739/TCP,10001:31413/TCP,10002:32301/TCP,10003:30418/TCP,10004:30527/TCP 2m3s

请记录端口映射,后续 edge 加入时需要用到。

为便于说明,本文档假设端口映射如下(你必须替换成自己查到的真实端口):

  • PORT_10000=32739
  • PORT_10001=31413
  • PORT_10002=32301
  • PORT_10003=30418
  • PORT_10004=30527

edge 加入时需要的是 10000 对应的 NodePort,即 192.168.139.184:32739

3.4 为 kube-system 组件添加节点亲和性

防止系统组件调度到 edge 节点:

1
kubectl get daemonset -n kube-system | grep -v NAME | awk '{print $1}' | xargs -n 1 kubectl patch daemonset -n kube-system --type='json' -p='[{"op": "replace","path":"/spec/template/spec/affinity","value":{"nodeAffinity": {"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"node-role.kubernetes.io/edge","operator":"DoesNotExist"}]}]}}}}]'

3.5 获取 edge 加入 token

在 master 上执行:

1
2
3
keadm gettoken --kube-config=$HOME/.kube/config

2b56e292d2e9f2fba406e4e252219647a7ba1f276e505eb1ce81822025a062a3.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Nzk4Njk5OTh9.rioP2qVs7zyEWdJODGmPEZkUXrp2kfCRLaIsKUHhBKo

输出一长串 token,完整复制保存,后续 edge 加入时需要。


04.配置 edge 节点并加入 KubeEdge

本阶段在 edge 节点上执行。

4.1 检查 Docker 状态

在 edge 上执行:

1
2
3
4
hostname
docker --version
sudo systemctl status docker --no-pager
sudo docker info

正常情况下 docker info 能显示 Server 信息,服务状态为 active (running)

若 Docker 未安装或异常,执行以下命令重装:

1
2
3
sudo apt update
sudo apt install -y docker.io
sudo systemctl enable --now docker

若提示权限不足,sudo docker info 正常即可继续。

4.2 edge 下载并安装 keadm

在 edge 上执行:

1
2
3
4
5
6
7
8
9
10
11
cd /tmp

VERSION="v1.13.4"

wget https://github.com/kubeedge/kubeedge/releases/download/${VERSION}/keadm-${VERSION}-linux-arm64.tar.gz

tar -xzf keadm-${VERSION}-linux-arm64.tar.gz

sudo mv keadm-${VERSION}-linux-arm64/keadm/keadm /usr/local/bin/keadm
sudo chmod +x /usr/local/bin/keadm
keadm version

4.3 edge 加入 KubeEdge

替换以下变量为你自己的值

  • <TOKEN> :3.5 步获取的完整 token
  • <10000对应的NodePort> :你自己的 10000 NodePort,例如 32261

在 edge 上执行:

1
2
TOKEN="<你的TOKEN>"
SERVER="192.168.139.184:<10000对应的NodePort>"

例如我本地

1
2
TOKEN="2b56e292d2e9f2fba406e4e252219647a7ba1f276e505eb1ce81822025a062a3.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3Nzk4Njk5OTh9.rioP2qVs7zyEWdJODGmPEZkUXrp2kfCRLaIsKUHhBKo"
SERVER=192.168.139.184:32739

然后执行加入命令:

1
2
3
4
sudo keadm join --token=$TOKEN \
--cloudcore-ipport=$SERVER \
--kubeedge-version=v1.13.4 \
--edgenode-name=edge

这里不行的话可能是/etc/kubeedge/config/edgecore.yaml没有改 继续后面一步去修(4.4修改 edgecore 中的 CloudCore NodePort 地址)

bugfix

我这报错cni plugin not initialized

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 1. 安装依赖
sudo apt install -y apt-transport-https ca-certificates curl gpg

# 2. 添加 Kubernetes 官方仓库(以 v1.30 为例,可替换版本)
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | \
sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \
https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" | \
sudo tee /etc/apt/sources.list.d/kubernetes.list

# 3. 更新并安装
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl


# 安装CNI插件
# 通过 apt 安装(推荐)
sudo apt update
sudo apt install -y kubernetes-cni

# 如果 apt 不可用,手动下载 arm64 版本(OrbStack 为 aarch64)
CNI_VERSION="v1.3.0"
wget https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-arm64-${CNI_VERSION}.tgz
sudo mkdir -p /opt/cni/bin
sudo tar -xzf cni-plugins-linux-arm64-${CNI_VERSION}.tgz -C /opt/cni/bin/
rm cni-plugins-linux-arm64-${CNI_VERSION}.tgz


# 配置CNI
sudo mkdir -p /etc/cni/net.d
sudo tee /etc/cni/net.d/10-containerd-net.conflist <<EOF
{
"cniVersion": "0.4.0",
"name": "containerd-net",
"plugins": [
{
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"routes": [
{ "dst": "0.0.0.0/0" }
],
"ranges": [
[{ "subnet": "10.88.0.0/16" }]
]
}
},
{
"type": "portmap",
"capabilities": {"portMappings": true}
}
]
}
EOF

若报 client version 1.41 is too old,先执行:

1
2
3
4
5
6
export DOCKER_API_VERSION=1.44
sudo -E keadm join --token=$TOKEN \
--cloudcore-ipport=$SERVER \
--kubeedge-version=v1.13.4 \
--runtime-type=docker \
--edgenode-name=edge

若报 edge node already exists,先执行清理:

1
sudo keadm reset

确认 /etc/kubeedge/ 目录已删除,再重新 join。

4.4 修改 edgecore 中的 CloudCore NodePort 地址

CloudCore 已改为 NodePort,需要确保 edgecore 使用正确的 NodePort 而非原始端口 10000/10002/10004。

首先在 edge 上备份配置:

1
sudo cp /etc/kubeedge/config/edgecore.yaml /etc/kubeedge/config/edgecore.yaml.bak

务必替换为你自己查到的真实端口(此处为示例):

1
2
3
4
5
6
MASTER_IP=192.168.139.184
PORT_10000=32739
PORT_10001=31413
PORT_10002=32301
PORT_10003=30418
PORT_10004=30527

执行替换:

1
2
3
4
5
sudo sed -i "s#${MASTER_IP}:10000#${MASTER_IP}:${PORT_10000}#g" /etc/kubeedge/config/edgecore.yaml
sudo sed -i "s#${MASTER_IP}:10001#${MASTER_IP}:${PORT_10001}#g" /etc/kubeedge/config/edgecore.yaml
sudo sed -i "s#${MASTER_IP}:10002#${MASTER_IP}:${PORT_10002}#g" /etc/kubeedge/config/edgecore.yaml
sudo sed -i "s#${MASTER_IP}:10003#${MASTER_IP}:${PORT_10003}#g" /etc/kubeedge/config/edgecore.yaml
sudo sed -i "s#${MASTER_IP}:10004#${MASTER_IP}:${PORT_10004}#g" /etc/kubeedge/config/edgecore.yaml

检查修改结果:

1
sudo grep -nE "httpServer|websocket|server:|edgeStream" /etc/kubeedge/config/edgecore.yaml

应看到地址为 https://192.168.139.184:<PORT_10002> 等。

master上kubectl get nodes 三个running即可

4.5 将 Docker API 环境变量写入 edgecore 服务

如果之前使用了 DOCKER_API_VERSION=1.44,需写入 systemd 服务:

1
2
3
4
5
6
7
sudo mkdir -p /etc/systemd/system/edgecore.service.d
sudo tee /etc/systemd/system/edgecore.service.d/override.conf <<EOF
[Service]
Environment="DOCKER_API_VERSION=1.44"
EOF

sudo systemctl daemon-reload

4.6 修复 cgroup driver 不一致问题

检查 Docker cgroup driver:

1
sudo docker info | grep -i "Cgroup Driver"

若为 systemd,而 edgecore 配置中为 cgroupfs,则需修改:

1
sudo sed -i 's/cgroupDriver: cgroupfs/cgroupDriver: systemd/' /etc/kubeedge/config/edgecore.yaml

确认:

1
sudo grep -n "cgroupDriver" /etc/kubeedge/config/edgecore.yaml

应显示 cgroupDriver: systemd

4.7 重启 edgecore 并检查状态

1
2
3
sudo systemctl restart edgecore
sleep 10
sudo systemctl status edgecore --no-pager -l

期望 Active: active (running),日志中可见 Successfully registered node

若反复重启,查看日志:

1
sudo journalctl -u edgecore.service -n 120 --no-pager -l

常见问题对应处理:

  • 10002 connect refused → 执行 4.4
  • client version too old → 执行 4.5
  • cgroupfs is different → 执行 4.6

05.验证

本阶段在 master 节点上执行。

1
kubectl get nodes -o wide

预期输出:

1
2
3
4
NAME     STATUS   ROLES           VERSION
master Ready control-plane v1.28.15
slave1 Ready <none> v1.28.15
edge Ready agent,edge v1.23.17-kubeedge-v1.13.4

若 edge 未出现,在 edge 上检查 sudo systemctl status edgecore
若 edge 为 NotReady,稍等 30 秒再查看,若仍异常则查看 edgecore 日志。


06.Temperature-demo 示例实验(选做)

本进阶实验模拟边缘温度传感器数据采集,通过 MQTT 将数据传输到云端。在 master 节点执行以下操作。

6.1 克隆代码并修改

1
2
git clone https://github.com/kubeedge/examples.git
cd examples/temperature-demo

修改 temperature-mapper/main.go,内容如下(已直接提供,可覆盖原文件):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package main

import (
"context"
"encoding/json"
"fmt"
"log"
"time"

mqtt "github.com/eclipse/paho.mqtt.golang"
)

type TempData struct {
Temperature float64 `json:"temperature"`
Timestamp string `json:"timestamp"`
}

func main() {
brokerURL := "tcp://127.0.0.1:1883"
clientID := "temperature-mapper"
topic := "temperature"

opts := mqtt.NewClientOptions()
opts.AddBroker(brokerURL)
opts.SetClientID(clientID)
opts.SetCleanSession(true)

client := mqtt.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
log.Fatalf("Failed to connect to MQTT broker: %v", token.Error())
}
fmt.Println("Connected to MQTT broker")

baseTemp := 20.0
increment := 0.5

for {
currentTemp := baseTemp + (float64(time.Now().Unix()%120) * increment)
tempData := TempData{
Temperature: currentTemp,
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
}
jsonData, _ := json.Marshal(tempData)
token := client.Publish(topic, 0, false, jsonData)
token.Wait()
fmt.Printf("Published temperature data: %s\n", jsonData)
time.Sleep(5 * time.Second)
}
}

6.2 构建 Docker 镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cat > temperature-mapper/Dockerfile <<EOF
FROM golang:1.19-alpine AS builder
WORKDIR /app
COPY . .
RUN go mod init temperature-mapper
RUN go mod tidy
RUN go build -o temperature-mapper main.go

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/temperature-mapper .
EOF

cd temperature-mapper
sudo docker build -t temperature-mapper:v1.0 .

6.3 创建 Kubernetes 资源文件

创建设备模型与实例、MQTT Broker、温度数据生成器、云端消费者。由于篇幅限制,此处给出关键部署命令,完整 YAML 可参照原始实验资料。

1
2
3
4
5
6
7
8
9
10
11
12
# 部署设备模型和实例
kubectl apply -f device-model.yaml
kubectl apply -f device-instance.yaml

# 部署 MQTT Broker(注意需指定 nodeName: edge)
kubectl apply -f mqtt-deployment.yaml

# 部署温度生成器(指定 nodeName: edge)
kubectl apply -f temperature-mapper-deployment.yaml

# 部署云端消费者(指定 nodeName: master)
kubectl apply -f temperature-consumer-deployment.yaml

6.4 验证

1
2
3
kubectl get pods -o wide
kubectl logs -f deployment/temperature-mapper
kubectl logs -f deployment/temperature-consumer

云端消费者应能持续收到边缘上报的温度数据。


实验提交

  1. 在 master 节点执行 kubectl get nodes,显示 master 和 slave1 均为 Ready

  2. 在 master 节点执行 kubectl get nodes -o wide,显示 edge 节点通过 KubeEdge 加入成功。