centos部署cri-docker、k8s和kubeedge

350 阅读14分钟

参考链接:

www.cnblogs.com/zengqinglei…

www.cnblogs.com/renshengdez…

1. 配置清单

  • 操作系统:centos9
  • k8s:1.26.3
  • 容器运行时:docker 28.0.4
  • cri:cri-docker 0.3.16
  • k8s网络插件:flannel
  • kubeedge:1.16.3
IP地址主机名
192.168.2.227k8s-master
192.168.2.228k8s-node01
192.168.2.229k8s-node02

2. 前置准备

每个节点都需要进行如下操作

2.1. 关闭防火墙

firewalld 是 Linux 系统中的一种动态防火墙管理工具,用于管理网络流量规则。

Kubernetes 的网络插件(如 Calico、Flannel 等)通常会自动配置所需的防火墙规则。

如果 firewalld 启用,可能会干扰这些规则,导致 Pod 之间的通信失败。

在测试或开发环境中,关闭 firewalld 可以减少复杂性,避免因为防火墙规则冲突而导致问题。

在高负载生产环境中,firewalld 的动态规则管理可能会增加额外的开销。

# 停止 firewalld 服务
sudo systemctl stop firewalld

# 禁用 firewalld 服务(防止开机启动)
sudo systemctl disable firewalld

# 检查状态
sudo systemctl status firewalld

2.2. 关闭selinux

SELinux(Security-Enhanced Linux)是一种强制访问控制(MAC)安全机制,用于增强操作系统的安全性。

在测试或开发环境中,关闭 SELinux 可以简化部署流程,避免因权限问题导致的错误。

某些 Kubernetes 组件或容器运行时(如 Docker、containerd)可能与 SELinux 的强制模式不完全兼容。

如果遇到无法解决的权限问题,可以尝试关闭 SELinux。

在生产环境中,SELinux 提供了额外的安全保护,可以防止恶意攻击者利用漏洞提升权限。

注意:如果您希望在生产环境中启用 SELinux,可以将其设置为 permissive 模式,这样它会记录违规行为但不会阻止操作。

# 临时关闭(重启后失效)
sudo setenforce 0

# 检查状态
getenforce

ps:后续重启后cri-docker日志提示没有权限,查看状态还是启动的,可以执行如下命令给cri-docker设置正确selinux上下文:

# 修改 SELinux 上下文
sudo chcon -t bin_t /usr/local/bin/cri-dockerd

# 重新启用 SELinux 强制模式
sudo setenforce 1

2.3. 关闭swap

2.3.1. 资源管理失效

  • Kubernetes 的调度器和节点组件(如 kubelet)主要依赖于物理内存的使用情况来分配资源。
  • 如果启用了 swap,Pod 可能会使用 swap 空间,而 Kubernetes 无法感知到 swap 的使用情况。这会导致调度器误判节点的可用资源。
2.3.1.1. 影响
  • 调度器可能会将过多的 Pod 调度到某个节点上,导致该节点的内存资源耗尽。
  • 系统性能下降,甚至可能引发节点崩溃。

2.3.2. 性能下降

  • Swap 是将部分内存数据写入磁盘,其读写速度远远低于物理内存。
  • 当系统开始使用 swap 时,应用程序的性能会显著下降。
2.3.2.1. 影响
  • 在高负载场景下,Kubernetes 集群中的 Pod 性能可能会受到严重影响,导致应用响应变慢或服务中断。

2.3.3. Pod 驱逐机制失效

  • Kubernetes 使用内存压力(Memory Pressure)来触发 Pod 的驱逐机制(Eviction)。
  • 如果启用了 swap,当内存不足时,操作系统会优先使用 swap,而不是触发内存压力事件。
2.3.3.1. 影响
  • Kubernetes 无法及时检测到内存压力,导致 Pod 驱逐机制失效。
  • 结果可能是某些关键 Pod 因内存不足而被强制终止,而非按照 Kubernetes 的策略进行优雅驱逐。

2.4. 执行命令

#临时关闭
swapoff -a
#永久关闭
sed -ri 's/.*swap.*/#&/' /etc/fstab

2.5. 将桥接的 IPv4 流量传递到 iptables 的链

目的是为 Kubernetes 集群节点配置必要的内核模块和网络参数,以确保 Kubernetes 的容器网络(CNI)能够正常工作。

  • overlay:支持容器运行时(如 containerd 或 Docker)使用的联合文件系统(Union File System)。Kubernetes 的容器镜像是基于这种技术构建的。
  • br_netfilter:允许桥接流量通过 Netfilter(Linux 的防火墙框架)处理,这是 Kubernetes 网络插件(如 Calico、Flannel 等)正确工作的关键。
  • net.bridge.bridge-nf-call-iptables = 1
    • 允许桥接流量通过 iptables 规则进行过滤。
    • 这是 Kubernetes 网络插件(如 Calico、Flannel)正常工作的基础,确保 Pod 之间的流量可以被正确处理。
  • net.ipv4.ip_forward = 1
    • 启用 IPv4 数据包转发。
    • Kubernetes 中的 Pod 通常位于不同的子网中,启用 IP 转发可以确保跨子网的流量能够正确路由。
  • net.bridge.bridge-nf-call-ip6tables = 1
    • 允许桥接流量通过 ip6tables(IPv6 防火墙规则)进行过滤。
    • 如果您的集群使用 IPv6 网络,则需要启用此参数。
步骤作用
加载 overlaybr_netfilter模块支持容器运行时和 Kubernetes 网络插件的正常工作
设置开机自动加载模块确保模块在系统重启后仍然可用
配置内核参数确保桥接流量可以通过 iptables/ip6tables 处理,并启用 IP 转发
应用配置立即生效内核参数,避免重启系统
#启用必要的模块
sudo modprobe overlay
sudo modprobe br_netfilter

cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

#配置生效
sudo sysctl --system

2.6. 安装docker

在 Kubernetes 1.24 及之后的版本中,官方移除了对 Docker 的直接支持(即弃用了 dockershim)。如果您希望继续使用 Docker 作为 Kubernetes 的容器运行时,则需要安装一个名为 cri-dockerd 的组件。cri-dockerd 是一个实现了 CRI(Container Runtime Interface)协议的适配器,它允许 Kubernetes 使用 Docker 作为容器运行时。

# 添加 Docker 官方仓库
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo

# 安装 Docker
sudo dnf update
sudo dnf install -y docker-ce docker-ce-cli containerd.io

# 启动并启用 Docker 服务
sudo systemctl start docker
sudo systemctl enable docker

# 验证 Docker 是否正常运行
docker --version
sudo docker run hello-world

2.7. 安装cri-docker

由于 Kubernetes 不再直接支持 Docker,您需要安装 cri-dockerd 来实现兼容性。

2.7.1. 下载

下载地址:github.com/Mirantis/cr…

也可以通过脚本来下载,如下:

# 下载 cri-dockerd 二进制文件
VERSION="0.3.16"  # 替换为最新版本号
wget https://github.com/Mirantis/cri-dockerd/releases/download/v${VERSION}/cri-dockerd-${VERSION}.amd64.tgz

# 解压
tar -xvf cri-dockerd-${VERSION}.amd64.tgz

# 将二进制文件移动到系统路径
sudo mv cri-dockerd/cri-dockerd /usr/local/bin/

# 验证安装
cri-dockerd --version

记得给执行权限:chmod +x cri_docker_down.sh

arm版本记得找对安装包

2.7.2. 设置 cri-dockerd 服务

创建一个 systemd 服务文件来管理 cri-dockerd

# 创建服务文件
sudo tee /etc/systemd/system/cri-docker.service <<EOF
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network.target

[Service]
ExecStart=/usr/local/bin/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9 --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

ExecStart指定所用的pause镜像用阿里的,否则默认拉取k8s.gcr.io/pause:3.6,会导致安装失败

sudo tee /etc/systemd/system/cri-docker.socket <<EOF
[Unit]
Description=CRI Docker Socket for the API
PartOf=cri-docker.service

[Socket]
ListenStream=/var/run/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker

[Install]
WantedBy=sockets.target
EOF

2.7.3. 启动并启用 cri-dockerd 服务

sudo systemctl daemon-reload
sudo systemctl enable cri-docker.socket
sudo systemctl start cri-docker.socket
sudo systemctl enable cri-docker
sudo systemctl start cri-docker
sudo systemctl status cri-docker

2.7.4. 验证 cri-dockerd 是否正常运行

sudo systemctl status cri-docker

2.8. 在 /etc/hosts 配置主机名与IP地址映射,避免将来IP变更导致k8s集群需要做大量工作适配

192.168.2.227 k8s-master
192.168.2.228 k8s-node01
192.168.2.229 k8s-node02

hostname也需要改,如果/etc/hosts如下

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

直接在后面追加就好了

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 k8s-master
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6 k8s-master

3. 部署k8s集群及网络插件(flannel)

以下步骤没有显示说明在指定节点上执行的步骤,则在所有节点上执行。

3.1. 添加kubernetes仓库

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=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

3.2. 安装 Kubernetes 组件(kubelet、kubeadm、kubectl)

kubelet 负责节点级别的容器生命周期管理,kubeadm 用于自动化地搭建和管理 Kubernetes 集群,而 kubectl 则是管理员与 Kubernetes 集群之间交互的主要工具,用于日常管理和故障排查。这三个工具共同构成了 Kubernetes 集群的基础架构和支持体系。

sudo dnf update
sudo dnf install -y kubelet-1.26.3 kubeadm-1.26.3 kubectl-1.26.3
sudo systemctl enable kubelet
sudo systemctl start kubelet

3.3. 部署kubernetes集群

3.3.1. 在k8s-master节点上初始化集群

# pod-network-cidr填写地址与后面安装的flannel插件默认的网段(10.244.0.0/16)保持一致
# 指定使用cri-docker
sudo kubeadm init \
  --apiserver-advertise-address=192.168.2.227 \
  --image-repository registry.aliyuncs.com/google_containers \
  --pod-network-cidr=10.244.0.0/16 \
  --control-plane-endpoint=k8s-master \
  --cri-socket unix:///var/run/cri-dockerd.sock

# 等待一会,成功初始化后,输出内容如下:
-------------------------------------
Your 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/config

Alternatively, 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/

You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:

  kubeadm join k8s-master:6443 --token u7bbbk.o3cx1erc4qdxg2ug \
        --discovery-token-ca-cert-hash sha256:b3ecb764868843bdb13f1ade93162a608567ffce1eed8d6a00608ca591d0e7a0 \
        --control-plane 

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join k8s-master:6443 --token u7bbbk.o3cx1erc4qdxg2ug \
        --discovery-token-ca-cert-hash sha256:b3ecb764868843bdb13f1ade93162a608567ffce1eed8d6a00608ca591d0e7a0 

说明k8s主节点初始化成功了,保存上面的token:fa6rsr.x1kyf0mpl69vx209,或者使用下面命令重新生成一个新的

sudo kubeadm token create --print-join-command

# 查看当前所有有效的令牌,默认24小时
kubeadm token list

接下来按照输出提示创建和声明目录

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

3.3.2. 将pod网络部署到集群

3.3.2.1. 部署网络插件

对于Flannel和Calico的选择,省流:

Flannel:简单、小规模
Calico:复杂,灵活,大规模

# 注意:如果flannel相关的镜像无法拉取,则wget下载yml并替换"docker.io"镜像仓库为"swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io"
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
3.3.2.2. 验证主节点现在是否准备就绪
sudo kubectl get nodes
-------------------------------------
NAME         STATUS   ROLES           AGE     VERSION
k8s-master   Ready    control-plane   2m18s   v1.26.3
-------------------------------------
3.3.2.3. 建议检查所有 Pod 是否正常运行
kubectl get pods --all-namespaces
-------------------------------------
NAMESPACE      NAME                                            READY   STATUS    RESTARTS   AGE
kube-flannel   kube-flannel-ds-9tvhf                           1/1     Running   0          10m
kube-system    coredns-5bbd96d687-92vln                        1/1     Running   0          24m
kube-system    coredns-5bbd96d687-tkxgv                        1/1     Running   0          24m
kube-system    etcd-localhost.localdomain                      1/1     Running   0          24m
kube-system    kube-apiserver-localhost.localdomain            1/1     Running   0          25m
kube-system    kube-controller-manager-localhost.localdomain   1/1     Running   0          24m
kube-system    kube-proxy-mlk4l                                1/1     Running   0          24m
kube-system    kube-scheduler-localhost.localdomain            1/1     Running   0          25m
-------------------------------------

3.3.3. 在子节点(k8s-node01、k8s-node02)按照上面的提示添加工作节点运行第1步kubeadm join的命令,将节点加入集群

sudo kubeadm join k8s-master:6443 \
  --token u7bbbk.o3cx1erc4qdxg2ug \
  --discovery-token-ca-cert-hash sha256:b3ecb764868843bdb13f1ade93162a608567ffce1eed8d6a00608ca591d0e7a0 \
  --cri-socket unix:///var/run/cri-dockerd.sock

两个节点加入完成后,在k8s-master节点上验证:

kubectl get nodes
-------------------------------------
NAME         STATUS   ROLES           AGE   VERSION
k8s-master   Ready    control-plane   39m   v1.26.3
k8s-node01   Ready    worker          34m   v1.26.3
k8s-node02   Ready    worker          34m   v1.26.3
-------------------------------------

将子节点设置为worker角色:

kubectl label node k8s-node01 node-role.kubernetes.io/worker=worker
kubectl label node k8s-node02 node-role.kubernetes.io/worker=worker

完成后,再次查看节点,可以看到ROLES变为了worker,至此,我们的集群就准备就绪了。

kubectl get nodes
-------------------------------------
NAME         STATUS   ROLES           AGE   VERSION
k8s-master   Ready    control-plane   39m   v1.26.3
k8s-node01   Ready    worker          34m   v1.26.3
k8s-node02   Ready    worker          34m   v1.26.3
-------------------------------------

3.3.4. 如果需要在子节点访问kubernetes集群

# 在子节点创建文件夹
$ mkdir -p ~/.kube
# 在主节点执行如下命令
$ scp $HOME/.kube/config root@k8s-node01:~/.kube/config
$ scp $HOME/.kube/config root@k8s-node02:~/.kube/config
# 在子节点进行验证
$ kubectl get nodes
-------------------------------------
NAME         STATUS   ROLES           AGE   VERSION
k8s-master   Ready    control-plane   39m   v1.26.3
k8s-node01   Ready    worker          34m   v1.26.3
k8s-node02   Ready    worker          34m   v1.26.3
-------------------------------------

3.3.5. k8s重置

sudo kubeadm reset --cri-socket unix:///var/run/cri-dockerd.sock
# 删除 CNI 网络配置
sudo rm -rf /etc/cni/net.d
# 重启 kubelet 服务
sudo systemctl restart kubelet

4. 安装Dashboard

dashboard提供界面化查看kubernetes集群相关资源使用情况,且可在线化编辑和操作资源。

4.1. 安装Dashboard服务

4.1.1. 下载dashborad.yaml

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

# 修改recommended.yaml,暴露端口
vim recommended.yaml
---

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30001
  type: NodePort
  selector:
    k8s-app: kubernetes-dashboard

---

# 查看dashboard需要的镜像。
# 提前在所有节点下载dashboard镜像和metrics-scraper镜像,外国的镜像下载不下来,我们下载阿里云的镜像。
grep image recommended.yaml
-------------------------------------
image: kubernetesui/dashboard:v2.7.0
imagePullPolicy: Always
image: kubernetesui/metrics-scraper:v1.0.8
-------------------------------------

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-scraper:v1.0.8
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/dashboard:v2.7.0

docker images | egrep 'dashboard|metrics-scraper'
-------------------------------------
registry.cn-hangzhou.aliyuncs.com/google_containers/dashboard         v2.7.0            07655ddf2eeb   2 years ago     246MB
registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-scraper   v1.0.8            115053965e86   2 years ago     43.8MB
-------------------------------------

# 修改yaml文件,把镜像换为我们下载好的镜像,镜像下载策略修改为imagePullPolicy: IfNotPresent。
vim recommended.yaml 

grep image recommended.yaml
-------------------------------------
#image: kubernetesui/dashboard:v2.7.0
image: registry.cn-hangzhou.aliyuncs.com/google_containers/dashboard:v2.7.0
imagePullPolicy: IfNotPresent
#image: kubernetesui/metrics-scraper:v1.0.8
image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-scraper:v1.0.8
-------------------------------------

kubectl apply -f recommended.yaml

4.1.2. 查看所有资源

kubectl get all -n kubernetes-dashboard
-------------------------------------
NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-5c49b6bb6b-4zstf   1/1     Running   0          72s
kubernetes-dashboard-68fd4584cb-dm8bc        1/1     Running   0          72s
[root@k8s-master ~]# kubectl get all -n kubernetes-dashboard
NAME                                             READY   STATUS    RESTARTS   AGE
pod/dashboard-metrics-scraper-5c49b6bb6b-4zstf   1/1     Running   0          3m32s
pod/kubernetes-dashboard-68fd4584cb-dm8bc        1/1     Running   0          3m32s

NAME                                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
service/dashboard-metrics-scraper   ClusterIP   10.109.81.75     <none>        8000/TCP        3m32s
service/kubernetes-dashboard        NodePort    10.108.152.100   <none>        443:30001/TCP   3m32s

NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/dashboard-metrics-scraper   1/1     1            1           3m32s
deployment.apps/kubernetes-dashboard        1/1     1            1           3m32s

NAME                                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/dashboard-metrics-scraper-5c49b6bb6b   1         1         1       3m32s
replicaset.apps/kubernetes-dashboard-68fd4584cb        1         1         1       3m32s
-------------------------------------

4.1.3. 查看pod

kubectl get pod -n kubernetes-dashboard
-------------------------------------
NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-5c49b6bb6b-4zstf   1/1     Running   0          4m14s
kubernetes-dashboard-68fd4584cb-dm8bc        1/1     Running   0          4m14s
-------------------------------------

4.1.4. 查看svc

kubectl get svc -n kubernetes-dashboard
-------------------------------------
NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP   10.109.81.75     <none>        8000/TCP        5m5s
kubernetes-dashboard        NodePort    10.108.152.100   <none>        443:30001/TCP   5m5s
-------------------------------------

4.2. 创建用户

kubectl apply -f https://raw.githubusercontent.com/cby-chen/Kubernetes/main/yaml/dashboard-user.yaml

4.3. 创建登录token

kubectl -n kubernetes-dashboard create token admin-user
-------------------------------------
eyJhbGciOiJSUzI1NiIsImtpZCI6IlBTdjFpMnd6Z29xa09DMkxRN1dKT3QyQ3JtUE9YTGJBWkw1STd5T203UlEifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzQzMTYxNzc1LCJpYXQiOjE3NDMxNTgxNzUsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJhZG1pbi11c2VyIiwidWlkIjoiNjJjNDRhODItMmY1NC00YmE4LWFkZjktNTYwYzkzNTRjNDJkIn19LCJuYmYiOjE3NDMxNTgxNzUsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDphZG1pbi11c2VyIn0.B_JAnJ5RnjtltbFh1dovM1Lwmyik1xrKrHf-Or69vSEOzmEyaQNa5g_l8fXao7oHcdZjEt5vDAUDX961IctEBh8GvETM9WdcHqUCPZqc1S9jnzl6Eu0i4NesrdxRSVDxSIQL8lhtVHvarE0yjgKXA3-UYCRTT0gszabk8_dGlokW5gdVRjuU0j5s9sHXTyy4igE2-A29stBpYVCBuHb3kZunfKtTt0IwmDPidYwwE6vuq_jT42jwCsKBYKjFyY6e-a_Ni8AtjeNWpmNYXLA4XPFpy8K31lpJv5HOICJIyQ4041ydZiaDqenZrvol4DnS9Buj37nAehK9sG6FhSThag
-------------------------------------

4.4. 访问Kubernetes仪表板(Dashboard)

https://192.168.2.227:30001/#/login

使用token登录,token:

eyJhbGciOiJSUzI1NiIsImtpZCI6IlBTdjFpMnd6Z29xa09DMkxRN1dKT3QyQ3JtUE9YTGJBWkw1STd5T203UlEifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzQzMTYxNzc1LCJpYXQiOjE3NDMxNTgxNzUsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJhZG1pbi11c2VyIiwidWlkIjoiNjJjNDRhODItMmY1NC00YmE4LWFkZjktNTYwYzkzNTRjNDJkIn19LCJuYmYiOjE3NDMxNTgxNzUsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDphZG1pbi11c2VyIn0.B_JAnJ5RnjtltbFh1dovM1Lwmyik1xrKrHf-Or69vSEOzmEyaQNa5g_l8fXao7oHcdZjEt5vDAUDX961IctEBh8GvETM9WdcHqUCPZqc1S9jnzl6Eu0i4NesrdxRSVDxSIQL8lhtVHvarE0yjgKXA3-UYCRTT0gszabk8_dGlokW5gdVRjuU0j5s9sHXTyy4igE2-A29stBpYVCBuHb3kZunfKtTt0IwmDPidYwwE6vuq_jT42jwCsKBYKjFyY6e-a_Ni8AtjeNWpmNYXLA4XPFpy8K31lpJv5HOICJIyQ4041ydZiaDqenZrvol4DnS9Buj37nAehK9sG6FhSThag

5. 部署kubeedge

5.1. 下载keadm

arm版本记得找对安装包

# keadm,类似kubeadm的KE部署包
wget https://github.com/kubeedge/kubeedge/releases/download/v1.16.3/keadm-v1.16.3-linux-amd64.tar.gz
tar -xvzf keadm-v1.16.3-linux-amd64.tar.gz
cd keadm-v1.16.3-linux-amd64/keadm/
sudo cp keadm /usr/local/bin/

# 验证 keadm 是否安装成功
keadm version
-------------------------------------
version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.3", GitCommit:"4f1da43e6807c127e549e5d4859ed1b66c6f5806", GitTreeState:"clean", BuildDate:"2024-07-12T03:02:51Z", GoVersion:"go1.20.10", Compiler:"gc", Platform:"linux/amd64"}
-------------------------------------

# 删除污节点
kubectl taint nodes --all node-role.kubernetes.io/control-plane-

# 提前下载kubeedge压缩包和校验文件
wget https://github.com/kubeedge/kubeedge/releases/download/v1.16.3/kubeedge-v1.16.3-linux-amd64.tar.gz
wget https://github.com/kubeedge/kubeedge/releases/download/v1.16.3/checksum_kubeedge-v1.16.3-linux-amd64.tar.gz.txt
#下载好的kubeedge压缩包和校验文件,可以先把它们存在/etc/kubeedge目录下
mkdir /etc/kubeedge/
cp kubeedge-v1.16.3-linux-amd64.tar.gz /etc/kubeedge/
cp checksum_kubeedge-v1.16.3-linux-amd64.tar.gz.txt /etc/kubeedge/

5.2. 云端组件初始化

kebeedge分为云端组件(cloudcore)和边端组件(edgecore),省流:

云端:k8s+cloudcore
边端:edgecore

# 先拉镜像
keadm config images pull \
  --kubeedge-version=v1.16.3 \
  --part=cloud \
  --remote-runtime-endpoint=unix:///var/run/cri-dockerd.sock
-------------------------------------
Pulling kubeedge/controller-manager:v1.16.3 ...
Successfully pulled kubeedge/controller-manager:v1.16.3
Pulling kubeedge/admission:v1.16.3 ...
Successfully pulled kubeedge/admission:v1.16.3
Pulling kubeedge/cloudcore:v1.16.3 ...
Successfully pulled kubeedge/cloudcore:v1.16.3
Pulling kubeedge/iptables-manager:v1.16.3 ...
Successfully pulled kubeedge/iptables-manager:v1.16.3
-------------------------------------

#cloudcore部署
keadm init \
  --advertise-address=192.168.2.227 \
  --set iptablesManager.mode="external" \
  --profile version=v1.16.3

如果初始化时报错,十有八九是负载到别的节点去了,每个节点都拉镜像再搞:context deadline exceeded

错误排查官方文档:

kubeedge.io/docs/faq/se…

5.3. 查看pod

kubectl get pod -n kubeedge
-------------------------------------
NAME                           READY   STATUS    RESTARTS   AGE
cloud-iptables-manager-ds5jj   1/1     Running   0          16m
cloud-iptables-manager-nwxdh   1/1     Running   0          16m
cloud-iptables-manager-x2qnd   1/1     Running   0          16m
cloudcore-76c9c94cb-8wqvw      1/1     Running   0          16m
-------------------------------------

kubectl get pods -n kubeedge --show-labels
-------------------------------------
NAME                           READY   STATUS    RESTARTS   AGE   LABELS
cloud-iptables-manager-ds5jj   1/1     Running   0          37h   controller-revision-hash=5c6bf65f6,k8s-app=iptables-manager,kubeedge=iptables-manager,pod-template-generation=1
cloud-iptables-manager-nwxdh   1/1     Running   0          37h   controller-revision-hash=5c6bf65f6,k8s-app=iptables-manager,kubeedge=iptables-manager,pod-template-generation=1
cloud-iptables-manager-x2qnd   1/1     Running   0          37h   controller-revision-hash=5c6bf65f6,k8s-app=iptables-manager,kubeedge=iptables-manager,pod-template-generation=1
cloudcore-76c9c94cb-8wqvw      1/1     Running   0          37h   k8s-app=kubeedge,kubeedge=cloudcore,pod-template-hash=76c9c94cb
-------------------------------------

5.4. 创建service

vim cloudcore-service.yaml
-------------------------------------
apiVersion: v1
kind: Service
metadata:
  name: cloudcore-service
  namespace: kubeedge
spec:
  selector:
    k8s-app: kubeedge
    kubeedge: cloudcore
  ports:
    - name: http-10000
      protocol: TCP
      port: 10000
      targetPort: 10000
      nodePort: 32084
    - name: http-10001
      protocol: TCP
      port: 10001
      targetPort: 10001
      nodePort: 32085
    - name: https-10002
      protocol: TCP
      port: 10002
      targetPort: 10002
      nodePort: 32086
    - name: http-10003
      protocol: TCP
      port: 10003
      targetPort: 10003
      nodePort: 32087
    - name: http-10004
      protocol: TCP
      port: 10004
      targetPort: 10004
      nodePort: 32088
  type: NodePort
-------------------------------------
protocol: 指定通信协议。这里是 TCP,表示使用 TCP 协议。
port: Service 内部暴露的端口号。
这里设置为 10000,表示 Service 在集群内部可以通过 10000 端口访问。
targetPort: 目标 Pod 内部容器监听的端口号。
这里设置为 10000,表示 Service 会将流量转发到 Pod  10000 端口。
nodePort:  Service 类型为 NodePort 时,指定节点上开放的端口号。
这里设置为 32084,表示外部客户端可以通过 <Node-IP>:32084 访问该 Service。

# 创建service
kubectl apply -f cloudcore-service.yaml

5.5. 查看service

kubectl get svc -n kubeedge
-------------------------------------
NAME                TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                           AGE
cloudcore-service   NodePort   10.111.123.163   <none>        10000:32084/TCP,10001:32085/TCP,10002:32086/TCP,10003:32087/TCP,10004:32088/TCP   5h41m
-------------------------------------

kubectl describe svc cloudcore-service -n kubeedge
-------------------------------------
Name:                     cloudcore-service
Namespace:                kubeedge
Labels:                   <none>
Annotations:              <none>
Selector:                 k8s-app=kubeedge,kubeedge=cloudcore
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.111.123.163
IPs:                      10.111.123.163
Port:                     http-10000  10000/TCP
TargetPort:               10000/TCP
NodePort:                 http-10000  32084/TCP
Endpoints:                192.168.2.228:10000
Port:                     http-10001  10001/TCP
TargetPort:               10001/TCP
NodePort:                 http-10001  32085/TCP
Endpoints:                192.168.2.228:10001
Port:                     https-10002  10002/TCP
TargetPort:               10002/TCP
NodePort:                 https-10002  32086/TCP
Endpoints:                192.168.2.228:10002
Port:                     http-10003  10003/TCP
TargetPort:               10003/TCP
NodePort:                 http-10003  32087/TCP
Endpoints:                192.168.2.228:10003
Port:                     http-10004  10004/TCP
TargetPort:               10004/TCP
NodePort:                 http-10004  32088/TCP
Endpoints:                192.168.2.228:10004
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>
-------------------------------------
1. Type: Service 的类型为 NodePort,表示外部可以通过节点的 IP 和指定端口访问该服务。
2. IP Family Policy: 当前使用的是单栈模式(SingleStack),即只支持一种 IP 协议族(IPv4  IPv6)。
3. IP Families: 支持的协议族为 IPv4。
4. IP: Service 的虚拟 ClusterIP 地址为 10.111.123.163。这是 Kubernetes 内部网络分配给 Service  IP 地址,用于集群内部访问。
5. IPs: 同样显示了分配的 ClusterIP 地址。
6. Port: Service 在集群内部暴露的端口号为 10000,协议为 TCP。
7. TargetPort: 流量会被转发到目标 Pod  10000 端口。
8. NodePort: 外部客户端可以通过节点的 IP  32084 端口访问该服务。
9. Endpoints: 列出了与该 Service 关联的 Pod  IP 地址和端口号。
这里显示了一个 Endpoint:192.168.2.228:10000。
这表示当前有一个 Pod  IP 地址为 192.168.2.228,并且它正在监听 10000 端口。
如果 Service 没有关联的 Pod,则 Endpoints 字段会显示 <none>。

5.6. 获取token

keadm gettoken
-------------------------------------
3accb685ab07da84134b4076a7f7462585bd945118ac2c1783f781046adcacce.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDM0NjY5NzR9.Dk4e3r5sevX2NyQocWE3BB6uMtYTNSOYzSqolJePz8g
-------------------------------------

5.7. kubeedge重置

keadm reset --remote-runtime-endpoint=unix:///var/run/cri-dockerd.sock

6. kubeedge边端加入云端

6.1. 加入云端

sudo keadm join --cloudcore-ipport=192.168.2.227:32084 --kubeedge-version=1.16.3 --token=3accb685ab07da84134b4076a7f7462585bd945118ac2c1783f781046adcacce.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDM0NjY5NzR9.Dk4e3r5sevX2NyQocWE3BB6uMtYTNSOYzSqolJePz8g --edgenode-name edge-01 --remote-runtime-endpoint=unix:///var/run/cri-dockerd.sock --cgroupdriver=systemd

6.2. 云端查看

kubectl get node -o wide
-------------------------------------
NAME         STATUS   ROLES           AGE     VERSION                     INTERNAL-IP     EXTERNAL-IP   OS-IMAGE           KERNEL-VERSION          CONTAINER-RUNTIME
edge-01      Ready    agent,edge      39s     v1.27.15-kubeedge-v1.16.3   192.168.0.240   <none>        Ubuntu 20.04 LTS   5.10.66                 docker://23.0.1
k8s-master   Ready    control-plane   2d23h   v1.26.3                     192.168.2.227   <none>        CentOS Stream 9    5.14.0-573.el9.x86_64   docker://28.0.4
k8s-node01   Ready    worker          2d23h   v1.26.3                     192.168.2.228   <none>        CentOS Stream 9    5.14.0-573.el9.x86_64   docker://28.0.4
k8s-node02   Ready    worker          2d23h   v1.26.3                     192.168.2.229   <none>        CentOS Stream 9    5.14.0-573.el9.x86_64   docker://28.0.4
-------------------------------------