Skip to content

kubeadm快速搭建K8s-v1.29集群-1主2从

一、kubeadm工具介绍

kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。

二、K8s 集群安装要求

2.1 前置条件

在开始之前,部署Kubernetes集群机器需要满足以下几个前置条件:

  • 3台或多台机器,操作系统为 Openeuler22.03 LTS SP4
  • 硬件配置:2GB或更多RAM,2个CPU或更多CPU,系统盘(80G)+数据盘(100G)
  • 集群中所有机器之间网络互通
  • 可以访问互联网,需要拉取镜像

2.2 部署K8s

2.2.1 一主二从拓扑图

2.2.2 角色信息

角色IP组件
k8s-master172.22.33.220kubeadm、kubectl、kubelet、kube-apiserver,kube-scheduler,kube-controller-manager、docker、cri-docker、coredns、calico
k8s-node1172.22.33.221kubeadm、kubectl、kubelet、kube-proxy、docker、cri-docker、coredns、calico
k8s-node2172.22.33.222kubeadm、kubectl、kubelet、kube-proxy、docker、cri-docker、coredns、calico

2.2.3 环境初始化

WARNING

需要在所有节点上安装

2.2.3.1 关闭防火墙
bash
$ systemctl stop firewalld
$ systemctl disable firewalld
2.2.3.2 关闭selinux
bash
# 临时关闭
$ setenforce 0

#永久关闭selinux
$ sed -i 's/enforcing/disabled/' /etc/selinux/config
2.2.3.3 关闭swap
bash
#临时关闭
$ swapoff -a

#永久关闭
$ sed -ri 's/.*swap.*/#&/' /etc/fstab
2.2.3.4 安装 ipvs,并加载IPVS 所需内核模块

WARNING

  • 内核版本升级:从 Linux 内核 4.19+ 开始,nf_conntrack_ipv4被废弃,功能整合到 nf_conntrack模块中,新内核统一使用 nf_conntrack管理所有 IP 版本的连接跟踪(IPv4/IPv6)
bash
#安装 ipvs 软件
$ yum install -y ipvsadm

#临时加载IPVS 所需内核模块
modprobe nf_conntrack
modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh

#查看IPVS模块加载情况,能看到ip_vs ip_vs_rr ip_vs_wrr  ip_vs_sh nf_conntrack说明加载成功
$ lsmod | grep -E 'ip_vs|nf_conntrack'


#永久加载,开机自动加载内核模块
$ cat > /etc/modules-load.d/ipvs.conf <<'EOF'
nf_conntrack
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
EOF
2.2.3.5 安装bridge-utils,并加载 br_netfilter 所需内核模块
bash
#bridge-utils是一个专门用于管理 Linux 网桥(Bridge)的工具集,提供 brctl等命令(例如创建/删除网桥、绑定物理网卡到网桥等)
$ yum install -y bridge-utils

#br_netfilter是一个关键内核模块,它的功能让网桥(Bridge)支持 netfilter(Linux 内置的防火墙框架)简单说,只有加载了这个模块,网桥转发网络流量时,才能被 iptables/ip6tables 等防火墙规则过滤或处理

#手动加载br_netfilter内核模块
modprobe br_netfilter

#永久加载,开机自动加载内核模块
$ cat > /etc/modules-load.d/bridge.conf <<'EOF'
br_netfilter
EOF
2.2.3.6 配置内核参数
bash
#开启内核路由转发
sed -i 's/net.ipv4.ip_forward=0/net.ipv4.ip_forward=1/g' /etc/sysctl.conf


#将桥接的IPv4,IPV6流量传递到iptables的链处理:
$ cat > /etc/sysctl.d/k8s.conf << 'EOF'
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness = 0
EOF

# 生效
$ sysctl --system
2.2.3.7 配置时间同步
bash
$ yum install ntpdate -y
$ ntpdate ntp.ntsc.ac.cn
$ date
2025年 08月 25日 星期一 22:57:10 CST

2.2.4 部署 docker

2.2.4.1 下载二进制包,解压并拷贝至/usr/bin 下
bash
#使用南大docker镜像下载地址
$ wget https://mirrors.nju.edu.cn/docker-ce/linux/static/stable/x86_64/docker-20.10.24.tgz
$ tar -xf docker-20.10.24.tgz
$ cp docker/* /usr/bin
$ which docker
2.2.4.2 使用 systemd 管理 docker,并编写docker.service文件
bash
$ cat > /etc/systemd/system/docker.service <<'EOF'

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=65535
LimitNPROC=65535
LimitCORE=65535
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target

EOF

#添加可执行权限
$ chmod +x /etc/systemd/system/docker.service
2.2.4.3 [可选] 单独挂载 docker 工作目录

TIP

docker的默认工作路径在/var/lib/docker ,可单独挂载一块数据盘,作为 docker存储路径,并做软链接。

bash
#建立工作目录
$ mkdir /home/application/

#格式化磁盘
$ mkfs.ext4 /dev/sdb

#磁盘永久挂载
$ vim /etc/fstab
/dev/sdb  /home/application  ext4 defaults 0 0

#使挂载生效
$ mount -a


# 创建docker 工作目录
$ mkdir /home/application/docker


#创建软链接
$ ln -s /home/application/docker /var/lib/
2.2.4.4 配置docker 配置文件
bash
cat > /etc/docker/daemon.json <<'EOF'
{
  "registry-mirrors": ["https://docker.xuanyuan.me"],  #加速可能随时失效,仅供参考。
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
EOF
2.2.4.5 启动 docker并设置开机自启动
bash
$ systemctl daemon-reload
$ systemctl start docker.service
$ systemctl enable docker.service

2.2.5 部署 cri-docker

img

Kubernetes1.24 之后, 在k8s中使用docker,除了安装docker 以外,还需要安装cri-dockerd 组件; 不然就要使用Containerd。

img

img

2.2.5.1 下载二进制包,解压并拷贝至/usr/bin 下
bash
$ wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.14/cri-dockerd-0.3.14.amd64.tgz
$ tar -xf cri-dockerd-0.3.14.amd64.tgz
$ cp cri-dockerd/cri-dockerd /usr/bin/
$ chmod +x /usr/bin/cri-dockerd
2.2.5.2 使用 systemd 管理 cri-docker,并编写cri-docker.service文件
bash
$ cat <<"EOF" > /usr/lib/systemd/system/cri-docker.service
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-docker.socket

[Service]
Type=notify

ExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9

ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

StartLimitBurst=3

StartLimitInterval=60s

LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

TasksMax=infinity
Delegate=yes
KillMode=process

[Install]
WantedBy=multi-user.target
EOF
2.2.5.3 配置 socket 文件
bahs
$ cat <<"EOF" > /usr/lib/systemd/system/cri-docker.socket
[Unit]
Description=CRI Docker Socket for the API
PartOf=cri-docker.service

[Socket]
ListenStream=%t/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=root

[Install]
WantedBy=sockets.target
EOF
2.2.5.4 启动 cri-docker并设置开机自启动
bash
systemctl daemon-reload
systemctl start cri-docker
systemctl enable cri-docker
systemctl is-active cri-docker

2.2.6 安装kubelet、kubeadm、kubectl 组件

WARNING

需要在所有节点上安装

2.2.6.1 配置阿里云YUM软件源

TIP

从 1.28 版本之后,kubernetes官方变更了仓库的存储路径以及使用方式,新版本k8s 的 yum 源中,需要手动定义k8s的版本。

bash
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.29/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
2.2.6.2 部署kubelet、kubeadm、kubectl 组件
bash
#安装
 yum install kubelet kubeadm kubectl
 
#启动并配置开机自启动
systemctl enable kubelet && systemctl start kubelet
2.2.6.3 设置主机名,配置 hosts

TIP

上面的那些操作/步骤 都可以做成虚拟机模板,master 和 node 节点可直接使用;但是从这一步骤开始,都是有差异化的安装配置。

bash
#设置主机名:
$ hostnamectl set-hostname k8s-master

#配置 hosts
$ cat >> /etc/hosts << 'EOF'
172.22.33.220 k8s-master
172.22.33.221 k8s-node01
172.22.33.222 k8s-node02
EOF
bash
#设置主机名:
$ hostnamectl set-hostname k8s-node01

#配置 hosts
$ cat >> /etc/hosts << 'EOF'
172.22.33.220 k8s-master
172.22.33.221 k8s-node01
172.22.33.222 k8s-node02
EOF
bash
#设置主机名:
$ hostnamectl set-hostname k8s-node02

#配置 hosts
$ cat >> /etc/hosts << 'EOF'
172.22.33.220 k8s-master
172.22.33.221 k8s-node01
172.22.33.222 k8s-node02
EOF

2.2.7 使用 kubeadm 初始化集群

2.2.7.1 部署Kubernetes Master

WARNING

此操作仅在master 节点:k8s-master 节点上运行

2.2.7.2 使用 kubeadm 命令行方式初始化
bash
$ kubeadm init \
  --apiserver-advertise-address=172.22.33.220 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.29.15 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16 \
  --ignore-preflight-errors=all \
  --apiserver-cert-extra-sans=2.1.2.1,172.22.33.0/24,k8s.srebro.cn \
  --cri-socket unix:///var/run/cri-dockerd.sock

参数说明:

  • --apiserver-advertise-address 集群通告地址,API Server 对外广播的 IP 地址,其他节点通过此地址访问控制平面。
  • --image-repository  由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址
  • --kubernetes-version K8s版本,与上面kubelet kubeadm kubectl安装的保持一致
  • --service-cidr 集群内部虚拟网络m,Pod统一访问入口
  • --pod-network-cidr Pod网络,与下面部署的CNI网络组件yaml中保持一致
  • --apiserver-cert-extra-sans 为 API Server 证书添加额外 SAN(Subject Alternative Names),支持通过 DNS 或 IP 访问 API Server。多个值用逗号分隔或多次指定,需包含所有可能访问 API Server 的地址。如负载均衡器域名、外部 IP。
  • --ignore-preflight-errors=all 忽略所有预检错误,强制初始化集群。
  • --cri-socket unix:///var/run/cri-dockerd.sock 指定容器运行时(CRI)的 Socket 路径,用于与容器运行时(如 Docker、containerd)通信。
2.2.7.3 👍 使用 kubeadm yaml 配置文件初始化
bash
$ cat > kubeadm-init.yaml <<'EOF'
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef  # 替换为实际token
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 172.22.33.220  # 修改为实际IP
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/cri-dockerd.sock
  imagePullPolicy: IfNotPresent
  name: k8s-master  # 修改为实际节点名
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  timeoutForControlPlane: 4m0s
  certSANs:  # 添加证书SAN
  - "kubernetes"
  - "kubernetes.default"
  - "kubernetes.default.svc"
  - "kubernetes.default.svc.cluster.local"
  - 2.1.2.1
  - 172.22.33.0/24
  - k8s.srebro.cn
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers  # 修改为阿里云镜像
kind: ClusterConfiguration
kubernetesVersion: v1.29.15  # 版本号
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
  podSubnet: 10.244.0.0/16
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"  #设置代理模式为 IPVS
EOF




#指定kubeadm.conf完成k8s-master初始化
$ kubeadm init --config kubeadm-init.yaml --ignore-preflight-errors=all
bash
#初始化输出内容
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/

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

kubeadm join 172.22.33.220:6443 --token 81466z.qxuot7eveyya02cb \
        --discovery-token-ca-cert-hash sha256:763a230f73b990ba63491f0181b43002174d0adc1fe40beb3be7723a5fc7e889
2.2.7.4 拷贝kubectl使用的连接k8s认证文件到默认路径
bash
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

$ export KUBECONFIG=/etc/kubernetes/admin.conf
2.2.7.5 加入Kubernetes Node 节点

WARNING

此操作只在node 节点:k8s-node1/k8s-node2 上运行

bash
#使用刚刚k8s-master节点上kubeadm init输出的kubeadm join命令:
kubeadm join 172.22.33.220:6443 --token 81466z.qxuot7eveyya02cb \
        --discovery-token-ca-cert-hash sha256:763a230f73b990ba63491f0181b43002174d0adc1fe40beb3be7723a5fc7e889

TIP

默认token有效期为24小时,当过期之后,该token就不可用了。这时就需要重新创建token,可以直接在master 节点上,使用命令快捷生成:

bash
#重新创建token
$ kubeadm token create --print-join-command
2.2.7.6 查看集群节点状态
bash
$ kubectl get node
NAME         STATUS   ROLES           AGE   VERSION
k8s-master   NotReady    control-plane   10h   v1.29.15
k8s-node01   NotReady    <none>          10h   v1.29.15
k8s-node02   NotReady    <none>          10h   v1.29.15

可以看到,所有的节点都已经加入到集群中了,NotReady是需要等待CNI网络插件安装好。

2.2.8 部署容器网络组件(Calico)

2.2.8.1 calico 介绍
  • Calico是一个纯三层的数据中心网络方案,Calico支持广泛的平台,包括Kubernetes、OpenStack等。
  • Calico 在每一个计算节点利用 Linux Kernel 实现了一个高效的虚拟路由器( vRouter) 来负责数据转发,而每个 vRouter 通过 BGP 协议负责把自己上运行的 workload 的路由信息向整个 Calico 网络内传播。此外,Calico  项目还实现了 Kubernetes 网络策略,提供ACL功能。
2.2.8.2 下载calico.yaml

TIP

官方的 caloco.yaml 中的 image 镜像地址,需要自行替换加速。

bash
$ wget https://projectcalico.docs.tigera.io/archive/v3.21/manifests/calico.yaml
2.2.8.3 修改calico.yaml 定义Pod网络

TIP

下载完后还需要修改里面定义Pod网络CALICO_IPV4POOL_CIDR,与前面kubeadm init指定的--pod-network-cidr=10.244.0.0/16 保持一致。

yaml
- name: CALICO_IPV4POOL_CIDR
  value: "10.244.0.0/16"

2.2.8.4 部署 calico 组件
bash
$ kubectl apply -f calico.yaml
$ kubectl get pods -n kube-system

image-20250826002418379

2.2.9 测试kubernetes集群

  • 验证Pod工作
  • 验证Pod网络通信
  • 验证DNS解析

TIP

在Kubernetes集群中创建一个pod,验证是否正常运行

bash
$ kubectl create deployment nginx --image=nginx
$ kubectl expose deployment nginx --port=80 --type=NodePort
$ kubectl get pod,svc

image-20250826002554627

访问地址:http://NodeIP:Nodeport

image-20250826002705772

三、部署 kubernetes-Dashboard

3.1 kubernetes-Dashboard介绍

  • Kubernetes Dashboard 是 Kubernetes 官方提供的 图形化集群管理工具,通过 Web 界面简化集群监控、资源管理和故障排查。
  • 项目地址: https://github.com/kubernetes/dashboard

3.2 下载kubernetes-dashboard.yaml 文件

TIP

从版本 7.0.0 开始,现在仅支持基于 Helm 的安装部署方式,本文采用的是v2.6.1 版本可通过 yaml 文件进行部署;仅供参考。

bash
$ wget https://raw.githubusercontent.com/kubernetes/dashbard/v2.6.1/aio/deploy/recommended.yaml -O kubernetes-dashboard.yaml

3.3 修改kubernetes-dashboard.yaml文件

TIP

1、官方的 kubernetes-dashboard.yaml 中的 image 镜像地址,需要自行替换加速。

2、默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部访问。

bash
$ vim kubernetes-dashboard.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
  selector:
    k8s-app: kubernetes-dashboard
  type: NodePort
...

#执行配置文件
$ kubectl apply -f kubernetes-dashboard.yaml


# 查看pod
$ kubectl get pods -n kubernetes-dashboard
NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-6b4884c9d5-gl8nr   1/1     Running   0          13m
kubernetes-dashboard-7f99b75bf4-89cds        1/1     Running   0          13m

image-20250826003734685

image-20250826003639101

3.4 获取token

INFO

新建一个 rbac.yaml 配置文件,创建service account并绑定默认cluster-admin管理员集群角色

bash
$ cat > rbac.yaml <<'EOF'
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dashboard-admin
  namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1      
metadata:
  name: dashboard-admin
subjects:
  - kind: ServiceAccount
    name: dashboard-admin
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
EOF


#执行配置文件
$ kubectl apply -f rbac.yaml


#获取token
$ kubectl create token dashboard-admin  --namespace kube-system


#查看 pod,svc
$ kubectl get pod,svc -n kubernetes-dashboard

image-20250826004036812

image-20250826004400760

3.5 登录kubernetes-dashboard

将上述获取到的token复制到下方界面中,点击登录

访问地址:http://NodeIP:Nodeport

image-20250826004243271

image-20250826004503542

四、补充:

4.1 kubectl 命令tab补齐

bash
yum install bash-completion -y
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
kubectl completion bash >/etc/bash_completion.d/kubectl

4.2 资源获取

  • 本篇所涉及的 yaml 文件,见: https://xx.xx.com; 均已配置镜像加速,可直接使用。
最近更新

采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 运维小弟