主题
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-master | 172.22.33.220 | kubeadm、kubectl、kubelet、kube-apiserver,kube-scheduler,kube-controller-manager、docker、cri-docker、coredns、calico |
k8s-node1 | 172.22.33.221 | kubeadm、kubectl、kubelet、kube-proxy、docker、cri-docker、coredns、calico |
k8s-node2 | 172.22.33.222 | kubeadm、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
Kubernetes1.24 之后, 在k8s中使用docker,除了安装docker 以外,还需要安装cri-dockerd 组件; 不然就要使用Containerd。
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软件源
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
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
访问地址:http://NodeIP:Nodeport
三、部署 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
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
3.5 登录kubernetes-dashboard
将上述获取到的token复制到下方界面中,点击登录
访问地址:http://NodeIP:Nodeport
四、补充:
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; 均已配置镜像加速,可直接使用。