参考链接:
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.227 | k8s-master |
| 192.168.2.228 | k8s-node01 |
| 192.168.2.229 | k8s-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 网络,则需要启用此参数。
| 步骤 | 作用 |
|---|---|
加载 overlay和 br_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. 下载
也可以通过脚本来下载,如下:
# 下载 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
错误排查官方文档:
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
-------------------------------------