一、准备环境

角色

IP

master

10.1.1.101

node1

10.1.1.102

node2

10.1.1.103

在三台主机执行

设置主机名

[root@localhost ~]# hostnamectl set-hostname master
[root@localhost ~]# su
[root@master ~]#

[root@localhost ~]# hostnamectl set-hostname node1
[root@localhost ~]# su
[root@node1 ~]#

[root@localhost ~]# hostnamectl set-hostname node2
[root@localhost ~]# su
[root@node2 ~]#

改/etc/hosts文件(添加以下内容)

# vim /etc/hosts
127.0.0.1 localhost
10.1.1.101 master
10.1.1.102 node1
10.1.1.103 node2

配默认yum源(我这里配腾讯源)

# 打包服务器上原本存在的yum源作备份
cd /etc/yum.repos.d/
tar -zcf repo.tar.gz *.repo
rm -rf *.repo
# 拉取腾讯源
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.tencent.com/repo/centos7_base.repo
# 重新生成缓存
yum clean all
yum makecache
# 打开yum源文件,将所有http改为https
yum update

配免密

# 生成公钥与私钥
ssh-keygen
# 把id_rsa.pub文件,scp到目标服务器端
scp ~/.ssh/id_rsa.pub root@10.1.1.102:/root/
# 在目标服务器端,把id_rsa.pub文件中的内容追加到~/.ssh/authorized_keys文件中
mkdir -p ~/.ssh
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
# 确保文件权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# 测试免密是否成功
ssh root@10.1.1.102

所有节点关闭selinux

sudo setenforce 0
# 修改配置文件
sudo sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
# 验证修改
grep ^SELINUX= /etc/selinux/config
# 应该显示:SELINUX=disabled
getenforce
# 应该显示:Disabled 或 Permissive

所有节点关闭firewalld,安装iptables服务,并保存为空规则

# systemctl stop firewalld
# systemctl disable firewalld
# yum install iptables-services -y
# systemctl restart iptables
# systemctl enable iptables
# iptables -F
# iptables -F -t nat
# iptables -F -t mangle
# iptables -F -t raw
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
# service iptables save
iptables: Saving firewall rules to 
/etc/sysconfig/iptables:[  OK  ]

所有节点时间同步

# 安装ntpd服务
yum install ntpdate -y
# 时间同步
ntpdate cn.ntp.org.cn

所有节点准备yum源(在centos默认源的基础上再加上以下两个yum源)

# vim /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

# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo

所有节点关闭swap(kubernetes1.8开始不关闭swap无法启动)

注释swap 所在的行

# swapoff -a
打开fstab文件将swap那一行注释保存
# vim /etc/fstab
UUID=38182b36-9be4-45f8-9b3f-f9b3605fcdf0 /               
        xfs     defaults        0 0
UUID=6b69e04f-4a85-4612-b1c0-24939fd84962 /boot           
        xfs     defaults        0 0
#UUID=9ba6a188-d8e1-4983-9abe-ba4a29b1d138 swap           
        swap   defaults       0 0

RHEL7和CentOS7有由于iptables被绕过而导致流量路由不正确的问题, 需要所有节点做如下操作:

# cat > /etc/sysctl.d/k8s.conf <<EOF
net.ipv4.ip_forward = 1
vm.swappiness = 0
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 使配置生效
# sysctl -p /etc/sysctl.d/k8s.conf
# modprobe br_netfilter
# lsmod |grep br_netfilter
# sudo sysctl --system
# reboot

所有节点设置kube-proxy开启ipvs的前置条件(由于ipvs已经加入到了内核的主干,所以为kube-proxy开启ipvs的前提需要加载以下的内核模块)

# cat > /etc/sysconfig/modules/ipvs.modules <<EOF
modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh
modprobe nf_conntrack_ipv4
EOF
# chmod 755 /etc/sysconfig/modules/ipvs.modules
# sh /etc/sysconfig/modules/ipvs.modules
# lsmod |egrep 'ip_vs|nf_conntrack'

二、安装软件

安装 Docker

# 安装 docker-ce
yum -y install docker-ce

# 开启 docker 服务
systemctl enable docker && systemctl start docker

#查看 docker 状态
systemctl status docker

Docker 安装完成之后,配置阿里云提供的镜像库来加速镜像下载。

# 配置镜像下载加速器,国内使用阿里云镜像库会更快
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://registry.cn-hangzhou.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  }
}
EOF

# 重启 docker 服务
systemctl restart docker

安装 cri-dockerd

cri-dockerd 用于为 Docker 提供一个能够支持 K8s 容器运行时标准的工具,从而能够让 Docker 作为 K8s 容器引擎。通过 wget 下载 cri-dockerd 安装包,然后通过 rpm 命令进行安装。

# 通过 wget 命令获取 cri-dockerd软件
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.12/cri-dockerd-0.3.12-3.el7.x86_64.rpm

# 通过 rpm 命令执行安装包
rpm -ivh cri-dockerd-0.3.12-3.el7.x86_64.rpm

如果官方地址下载太慢,可以使用离线安装包(下载地址

安装完成后修改配置文件(/usr/lib/systemd/system/cri-docker.service),在 “ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd://” 这一行增加 “–pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9”

# 打开 cri-docker.service 配置文件
vim /usr/lib/systemd/system/cri-docker.service

# 修改对应的配置项
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9

配置文件修改后,重新加载配置并开启 cri-dockerd 服务。

# 加载配置并开启服务
systemctl daemon-reload
systemctl enable cri-docker && systemctl start cri-docker

安装 kubeadm、kubelet 和 kubectl

# 指定了安装的版本是 1.28.0
yum install -y kubelet-1.28.0 kubeadm-1.28.0 kubectl-1.28.0

# 开机启动 kubelet 服务
systemctl enable kubelet

Master 节点初始化 K8s

统一镜像仓库
# 创建 kubeadm 配置文件
cat <<EOF > kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
nodeRegistration:
  criSocket: unix:///var/run/cri-dockerd.sock
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.15
imageRepository: registry.aliyuncs.com/google_containers
networking:
  podSubnet: 10.244.0.0/16
EOF

# 预拉取镜像
sudo kubeadm config images pull --config kubeadm-config.yaml
# 明确指定所有镜像使用阿里云仓库
sudo kubeadm init --config kubeadm-config.yaml \
  --ignore-preflight-errors=all \
  --v=5

在 Master 节点重新生成 token

# 查看现有token列表
kubeadm token list

# 若token过期,创建新token并打印join命令
kubeadm token create --print-join-command
# 输出示例:kubeadm join 118.145.184.209:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:xxxx...

在 Master 节点执行:

watch kubectl get nodes
# 新节点应出现在列表中(状态可能为NotReady,等待网络插件安装)

三、启动集群

在master节点上操作(其它节点不操作)

执行export KUBECONFIG=/etc/kubernetes/admin.conf 就可以启动集群(加到/etc/profile里实现开机自动启动)

确认kubelet服务启动了
[root@master ~]# systemctl status kubelet.service
[root@master ~]# vim /etc/profile
export KUBECONFIG=/etc/kubernetes/admin.conf
[root@master ~]# source /etc/profile

查看集群状态

[root@master ~]# kubectl get cs

[root@master ~]# kubectl get node

四、创建flannel网络

在master节点上操作(其它节点不操作)

1,下载kube-flannel.yml

[root@master ~]# mkdir /root/k8s
[root@master ~]# cd /root/k8s/
[root@master k8s]# curl -O https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

2, 应用kube-flannel.yml创建pod(这一步非常慢,因为要下载镜像,可以使用共享的镜像先导入)

[root@master k8s]# kubectl apply -f kube-flannel.yml
namespace/kube-flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created

3, 要确认所有的pod为running状态

[root@master k8s]# kubectl get pods -n kube-system
NAME                             READY   STATUS    RESTARTS       AGE
coredns-66f779496c-dq5qt         1/1     Running   0              152m
coredns-66f779496c-v88zl         1/1     Running   0              152m
etcd-master                      1/1     Running   0              152m
kube-apiserver-master            1/1     Running   0              152m
kube-controller-manager-master   1/1     Running   1 (112m ago)   152m
kube-proxy-srknv                 1/1     Running   0              149m
kube-proxy-tg8cl                 1/1     Running   0              150m
kube-proxy-tvpsh                 1/1     Running   0              152m
kube-scheduler-master            1/1     Running   1 (112m ago)   152m

验证master节点OK

[root@master k8s]# kubectl get nodes
NAME     STATUS   ROLES           AGE    VERSION
master   Ready    control-plane   154m   v1.28.0

加入其它节点

1, node1上join集群

在 node 节点:

# 执行从Master获取的完整join命令
# 指定使用docker套接字
kubeadm join 10.1.1.101:6443 \
  --token 9blb07.h17zi6wyja73xm7m \
  --discovery-token-ca-cert-hash sha256:b53639b5a0b14f08cd0798a4ca56937b66adad8cdf4d7b560c74fcd8f3d37c98 \
  --cri-socket unix:///var/run/cri-dockerd.sock \
  --v=5
# 检查状态
sudo systemctl status kubelet
验证节点加入
kubectl get nodes


移除节点的做法(假设移除node2)

1, 在master节点上执行

[root@master ~]# kubectl drain node2 --delete-local-data --force --ignore-daemonsets

2, 在node2节点上执行

[root@node2 ~]# kubeadm reset
[root@node2 ~]# ifconfig cni0 down
[root@node2 ~]# ip link delete cni0
[root@node2 ~]# ifconfig flannel.1 down
[root@node2 ~]# ip link delete flannel.1
[root@node2 ~]# rm -rf /var/lib/cni/

3,在node1上执行

[root@node1 ~]# kubectl delete node node2

如果master节点需要重新初始化,步骤如下:

1. 彻底清理环境

# 停止所有容器
sudo docker rm -f $(sudo docker ps -aq)

# 彻底重置kubeadm
sudo kubeadm reset -f

# 清理网络配置
sudo ipvsadm --clear
sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X

# 删除所有残留文件
sudo rm -rf \
  /etc/kubernetes/ \
  /var/lib/etcd/ \
  /var/lib/kubelet/ \
  /etc/cni/net.d/ \
  $HOME/.kube/config

# 确保所有k8s相关进程已停止
sudo systemctl stop kubelet
sudo pkill -f 'kube|etcd'

2. 检查端口占用情况

sudo ss -tulnp | grep -E '6443|10259|10257|10250|2379|2380'

3.重新初始化

[root@master ~]# sudo kubeadm init \
>   --apiserver-advertise-address=10.1.1.101 \
>   --pod-network-cidr=10.244.0.0/16 \
>   --upload-certs \
>   --ignore-preflight-errors=all \
>   --v=5

五、报错处理

[ERROR CRI]: container runtime is not running: 
validate service connection: CRI v1 runtime API is not implemented for endpoint "unix:///var/run/containerd/containerd.sock"

这表明:

  1. containerd 安装了但未启用 CRI 插件
  2. Kubernetes 无法通过 containerd 的默认 socket 路径通信

修复步骤:

1.修正 containerd 配置

# 生成默认配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# 启用CRI插件(关键步骤)
sudo sed -i 's/disabled_plugins = $$"cri"$$/# disabled_plugins = ["cri"]/' /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

# 重启containerd
sudo systemctl restart containerd

2.验证 containerd CRI 状态

sudo crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock info

正常应返回类似:

{
  "status": {
    "conditions": [
      {
        "type": "RuntimeReady", 
        "status": true
      }
    ]
  }
}

六、参考博客

实战Kubernetes之快速部署 K8s 集群 v1.28.0-云社区-华为云

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐