✨ 06-kubeadm部署单Master K8s测试集群
一、集群整体规划
1. 网段规划
-
Pod 网段(podSubnet):
10.244.0.0/16 -
Service 网段(serviceSubnet):
10.96.0.0/12 -
物理机网段:
192.168.40.0/24
2. 节点角色规划
| 角色 | 主机名 | IP 地址 | 核心组件 |
|---|---|---|---|
| 控制节点 Master | zhappymaster1 | (192.168.40.180) | apiserver、controller-manager、scheduler、etcd、kube-proxy、docker、calico |
| 工作节点 Node1 | zhappynode1 | (192.168.40.181) | kubelet、kube-proxy、docker、calico、coredns |
| 工作节点 Node2 | zhappynode2 | (192.168.40.182) | kubelet、kube-proxy、docker、calico、coredns |
3. 系统环境要求
-
操作系统:CentOS 7.9
-
硬件配置:4GiB 内存 / 4vCPU / 60G 硬盘
-
网络:NAT 模式,虚拟机开启 CPU 虚拟化支持
二、集群环境初始化(所有节点执行)
1. 配置静态 IP
修改网卡配置(网卡名以实际为准,示例为ens33):
vim /etc/sysconfig/network-scripts/ifcfg-ens33
核心配置项:
BOOTPROTO=static
IPADDR=192.168.40.180 # 替换为对应节点IP
NETMASK=255.255.255.0
GATEWAY=192.168.40.2
DNS1=192.168.40.2
ONBOOT=yes
NAME=ens33
DEVICE=ens33
重启网络生效:
service network restart
2. 关闭 SELinux
# 临时关闭
setenforce 0
# 永久关闭,重启后生效
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
# 重启机器
reboot -f
# 验证状态
getenforce
3. 设置主机名
分别在对应节点执行:
# Master执行
hostnamectl set-hostname zhappymaster1 && bash
# Node1执行
hostnamectl set-hostname zhappynode1 && bash
# Node2执行
hostnamectl set-hostname zhappynode2 && bash
可选操作:执行
yum update -y升级系统至最新 CentOS7 版本。
4. 配置主机名解析
所有节点的/etc/hosts添加节点映射:
cat >> /etc/hosts <<EOF
192.168.40.180 zhappymaster1
192.168.40.181 zhappynode1
192.168.40.182 zhappynode2
EOF
5. 配置节点间 SSH 免密登录
分别在三个节点生成密钥并分发至所有节点:
# 生成密钥,一路回车即可
ssh-keygen
# 分发公钥
ssh-copy-id zhappymaster1
ssh-copy-id zhappynode1
ssh-copy-id zhappynode2
6. 关闭 Swap 交换分区
K8s 默认禁用 Swap 以保证性能,未关闭会导致初始化失败。
# 临时关闭
swapoff -a
# 永久关闭:注释fstab中swap挂载行
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
说明:若必须保留 Swap,可在 kubeadm 命令后追加
--ignore-preflight-errors=Swap跳过检测。
7. 配置内核网络参数
加载桥接模块,开启 IP 转发与网桥 iptables 支持:
# 加载br_netfilter内核模块
modprobe br_netfilter
echo "modprobe br_netfilter" >> /etc/profile
# 写入内核配置
cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
# 生效配置
sysctl -p /etc/sysctl.d/k8s.conf
8. 关闭 firewalld 防火墙
systemctl stop firewalld
systemctl disable firewalld
9. 配置软件源与基础依赖
- 添加 Docker 阿里云 YUM 源:
yum install yum-utils -y
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 安装基础依赖包:
yum install -y yum-utils device-mapper-persistent-data lvm2 wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel vim ncurses-devel autoconf automake zlib-devel python-devel epel-release openssh-server socat ipvsadm conntrack ntpdate telnet ipvsadm
10. 配置 K8s 阿里云 YUM 源
在 Master 创建源文件,再分发到其他节点:
cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
EOF
# 分发至工作节点
scp /etc/yum.repos.d/kubernetes.repo zhappynode1:/etc/yum.repos.d/
scp /etc/yum.repos.d/kubernetes.repo zhappynode2:/etc/yum.repos.d/
11. 配置时间同步
# 安装同步工具
yum install ntpdate -y
# 立即同步时间
ntpdate cn.pool.ntp.org
# 添加定时任务,每小时同步一次
crontab -e
* */1 * * * /usr/sbin/ntpdate cn.pool.ntp.org
# 重启定时任务
service crond restart
三、安装 Docker 服务(所有节点执行)
1. 安装指定版本 Docker
yum install docker-ce-20.10.6 -y
2. 配置镜像加速器与 Cgroup 驱动
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors":["https://rsbud4vc.mirror.aliyuncs.com","https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn","http://hub-mirror.c.163.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
重要:Kubelet 默认使用
systemd作为 cgroup 驱动,Docker 默认为cgroupfs,两者必须一致,否则集群启动失败。
3. 启动并设置开机自启
systemctl daemon-reload
systemctl start docker
systemctl enable docker.service
systemctl status docker
四、安装 K8s 核心组件(所有节点执行)
1. 安装指定版本组件
yum install -y kubelet-1.20.6 kubeadm-1.20.6 kubectl-1.20.6
2. 设置 kubelet 开机自启
systemctl enable kubelet
组件说明:
kubeadm:K8s 集群自动化初始化工具
kubelet:运行在所有节点,负责 Pod 生命周期管理、与 APIServer 通信
kubectl:K8s 命令行客户端,用于集群资源管理与操作
五、kubeadm 初始化 Master 节点(Master 执行)
1. 导入离线镜像(所有节点)
提前将k8simage-1-20-6.tar.gz上传至所有节点,导入镜像:
docker load -i k8simage-1-20-6.tar.gz
2. 生成并修改初始化配置文件
# 生成默认配置模板
kubeadm config print init-defaults > kubeadm.yaml
修改kubeadm.yaml,完整配置如下:
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.40.180 # Master节点IP
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: zhappymaster1 # Master主机名
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers # 国内镜像源
kind: ClusterConfiguration
kubernetesVersion: v1.20.6
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16 # Pod网段
scheduler: {}
---
# kube-proxy启用IPVS模式
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
---
# kubelet cgroup驱动与docker保持一致
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
3. 执行集群初始化
kubeadm init --config=kubeadm.yaml --ignore-preflight-errors=SystemVerification
初始化成功后会输出 Worker 节点加入命令,请保存好 token 和 hash 值。
4. 配置 kubectl 管理员权限
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
5. 查看初始节点状态
kubectl get nodes
此时节点状态为NotReady属于正常现象,原因是尚未安装网络插件。
扩展:kubeadm init 执行流程详解
-
配置初始化:加载默认配置与用户自定义配置,转换为内部参数格式
-
安装预检:检查 root 权限、版本兼容性、防火墙、端口占用、容器运行时、内核参数、Swap 状态等
-
镜像拉取:拉取 apiserver、controller-manager、scheduler、etcd、coredns 等组件镜像
-
配置 kubelet:写入 kubelet 配置文件并重启服务
-
生成证书:生成 CA 根证书及各组件证书、kubeconfig 配置文件
-
生成静态 Pod 清单:在
/etc/kubernetes/manifests下生成控制平面组件的 Pod 配置,由 kubelet 启动 -
等待控制平面启动:等待 APIServer 等组件就绪
-
集群后置配置:创建 ConfigMap、RBAC 权限、标记 Master 节点、部署 CoreDNS 与 kube-proxy
-
输出加入命令:打印 Worker 节点加入集群的命令
扩展:Kubeadm 证书体系说明
K8s 证书分为两大目录:/etc/kubernetes/pki、/etc/kubernetes/pki/etcd
-
K8s 集群根证书 CA
ca.crt / ca.key:签发 APIServer、kubelet 客户端等组件证书
-
APIServer 相关证书
-
apiserver.crt / apiserver.key:APIServer 服务端证书 -
apiserver-kubelet-client.crt / apiserver-kubelet-client.key:APIServer 访问 kubelet 的客户端证书
-
-
前端代理根证书
-
front-proxy-ca.crt / front-proxy-ca.key:用于聚合层 API 代理认证 -
front-proxy-client.crt / front-proxy-client.key:代理客户端证书
-
-
Etcd 证书体系
-
etcd/ca.crt / etcd/ca.key:Etcd 集群根证书 -
etcd/server.crt / etcd/server.key:Etcd 服务端证书 -
etcd/peer.crt / etcd/peer.key:Etcd 节点间通信证书 -
etcd/healthcheck-client.crt / etcd/healthcheck-client.key:Etcd 健康检查客户端证书 -
apiserver-etcd-client.crt / apiserver-etcd-client.key:APIServer 访问 Etcd 的客户端证书
-
六、扩容 Worker 工作节点
1. 生成节点加入命令(Master 执行)
kubeadm token create --print-join-command
2. Node1 加入集群
在 Node1 节点执行输出的 join 命令:
kubeadm join 192.168.40.180:6443 --token 你的token值 \
--discovery-token-ca-cert-hash sha256:你的hash值 \
--ignore-preflight-errors=SystemVerification
3. Node2 加入集群
同样执行 join 命令加入集群。
4. 给 Worker 节点打角色标签
kubectl label node zhappynode1 node-role.kubernetes.io/worker=worker
kubectl label node zhappynode2 node-role.kubernetes.io/worker=worker
5. 查看节点状态
kubectl get nodes
所有节点均为NotReady,等待安装网络插件后恢复正常。
七、安装 Calico 网络插件(Master 执行)
1. 部署 Calico
上传calico.yaml文件,或在线下载:
# 在线下载(可选)
# wget https://docs.projectcalico.org/manifests/calico.yaml
kubectl apply -f calico.yaml
2. 验证 Pod 与节点状态
# 查看系统Pod状态
kubectl get pods -n kube-system
# 查看节点状态
kubectl get nodes
等待 calico 相关 Pod 全部 Running,节点状态变为Ready,CoreDNS 也会从 Pending 转为正常运行。
3. Calico 核心组件
-
Felix:运行在每个节点的 Agent,负责路由、ARP、ACL 规则管理,保障容器网络互通
-
Etcd:分布式存储,保存 Calico 网络元数据,保证状态一致性
-
BGP Client(BIRD):每个节点部署一个,将内核路由信息分发到整个 Calico 网络
-
BGP Route Reflector:大规模集群使用,替代全网状互联,集中分发路由,降低节点连接数
4. IPIP 与 BGP 模式对比
| 模式 | 原理 | 特点 | 适用场景 |
|---|---|---|---|
| IPIP | IP 包外层再封装一层 IP 头,通过 tunl0 隧道转发,属于 Overlay 网络 | 不要求节点二层互通,有额外封装开销 | 跨网段、三层不通的复杂网络环境 |
| BGP | 节点作为虚拟路由器,直接通过路由转发,无额外隧道 | 性能高,无封装开销,要求节点二层互通 | 同机房、同网段的物理机集群 |
Calico 默认开启 IPIP 模式,通过环境变量
CALICO_IPV4POOL_IPIP控制,Always为开启,Off为关闭并使用 BGP 模式。
多网卡节点可通过IP_AUTODETECTION_METHOD指定网卡,例如interface=ens33。
八、集群功能验证
1. Pod 外网连通性测试
- 所有 Node 节点导入 busybox 镜像:
docker load -i busybox-1-28.tar.gz
- 启动临时测试 Pod:
kubectl run busybox --image busybox:1.28 --image-pull-policy=IfNotPresent --restart=Never --rm -it -- sh
- 容器内 ping 公网测试:
ping www.baidu.com
能正常连通说明容器外网与 Calico 网络正常。
2. CoreDNS 域名解析测试
在 busybox 容器内执行:
nslookup kubernetes.default.svc.cluster.local
能正常解析出 Service IP([10.96.0.1](10.96.0.1))则集群 DNS 服务正常。
注意:必须使用 busybox 1.28 版本,高版本存在 nslookup 解析异常问题。
九、K8s 证书有效期续期
kubeadm 默认签发的组件证书有效期为 1 年,CA 根证书为 10 年,可通过脚本将组件证书延长至 10 年。
1. 查看证书有效期
# 查看CA根证书有效期
openssl x509 -in /etc/kubernetes/pki/ca.crt -noout -text | grep Not
# 查看APIServer证书有效期
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | grep Not
2. 执行续期脚本(Master 执行)
上传update-kubeadm-cert.sh脚本:
# 授权可执行
chmod +x update-kubeadm-cert.sh
# 全量续期所有证书
./update-kubeadm-cert.sh all
3. 验证续期结果
# 验证组件证书已延长至10年
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | grep Not
# 验证系统Pod运行正常
kubectl get pods -n kube-system