在云原生时代,Kubernetes(简称 K8s)作为容器编排平台的事实标准,其集群部署是运维和开发人员的核心技能。本文基于 Ubuntu 22.04 LTS 系统,详细讲解两种主流部署方案:单 Master 集群(快速测试) 和 多 Master 高可用集群(生产环境) ,采用官方推荐的kubeadm工具,搭配containerd容器运行时,全程步骤可复现,新手也能顺利完成部署。
一、部署前核心准备:环境要求与基础配置
1. 系统与硬件要求
| 节点类型 | 硬件配置建议 | 系统要求 |
|---|---|---|
| Master 节点 | 2 核 4G 以上内存,20G + 硬盘 | Ubuntu 22.04 LTS(64 位) |
| Node 节点 | 2 核 2G 以上内存,20G + 硬盘 | Ubuntu 22.04 LTS(64 位) |
| 高可用 Master 节点 | 3 个节点,每节点 2 核 4G 以上 | 同单 Master 系统要求 |
| 网络要求 | 所有节点互通,外网可访问(拉取镜像) | 关闭防火墙 / 开放必要端口 |
2. 基础环境配置(所有节点执行)
(1)关闭防火墙与 SELinux
K8s 集群内部需要大量端口通信,新手建议直接关闭防火墙(生产环境可按需开放端口):
bash
\ 关闭Ubuntu防火墙(UFW)
sudo ufw disable
\ 验证防火墙状态(输出inactive即为关闭)
sudo ufw status
\ 关闭SELinux(Ubuntu默认未安装,可跳过;CentOS需执行)
\ sudo setenforce 0
\ sudo sed -i 's/^SELINUX=enforcing\$/SELINUX=permissive/' /etc/selinux/config
(2)禁用 Swap 分区(K8s 强制要求)
Swap 分区会影响 K8s 的调度和性能,必须禁用:
bash
\ 临时禁用Swap
sudo swapoff -a
\ 永久禁用Swap(注释/etc/fstab中的Swap配置)
sudo sed -i '/swap/s/^/#/' /etc/fstab
\ 验证Swap是否禁用(输出均为0即为成功)
free -h
(3)配置内核参数(开启 IP 转发与模块)
K8s 需要内核支持 IP 转发和容器网络相关模块:
ini
\ 创建内核配置文件
sudo cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip\_forward = 1
net.ipv4.tcp\_tw\_recycle = 0
vm.swappiness = 0
EOF
\ 加载内核模块
sudo modprobe br\_netfilter
sudo modprobe overlay
\ 生效内核配置
sudo sysctl --system
\ 验证参数(输出1即为成功)
sysctl net.bridge.bridge-nf-call-iptables net.ipv4.ip\_forward
(4)配置主机名与 Hosts 解析
确保所有节点的主机名唯一,且能通过主机名互通:
bash
\ 配置主机名(Master节点执行)
sudo hostnamectl set-hostname k8s-master-01
\ 配置主机名(Node节点1执行)
sudo hostnamectl set-hostname k8s-node-01
\ 配置主机名(Node节点2执行,如需多Node)
sudo hostnamectl set-hostname k8s-node-02
\ 配置Hosts解析(所有节点,替换为实际IP)
sudo cat >> /etc/hosts << EOF
192.168.1.100 k8s-master-01 单Master节点IP/高可用Master节点1IP
192.168.1.101 k8s-master-02 高可用Master节点2IP(单Master忽略)
192.168.1.102 k8s-master-03 高可用Master节点3IP(单Master忽略)
192.168.1.110 k8s-node-01 Node节点1IP
192.168.1.111 k8s-node-02 Node节点2IP(可选)
192.168.1.200 k8s-vip 高可用虚拟IP(单Master忽略)
EOF
\ 验证Hosts解析(能ping通所有节点主机名即为成功)
ping k8s-master-01 -c 2
ping k8s-node-01 -c 2
(5)安装依赖工具
sql
sudo apt update && sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
二、安装容器运行时:containerd(K8s 1.24 + 推荐)
K8s 从 1.24 版本开始不再默认依赖 Docker,containerd是 CNCF 认证的容器运行时,轻量且稳定,以下是详细安装步骤:
1. 安装 containerd
bash
\ 添加Docker官方源(containerd包含在Docker源中)
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb \[arch=\$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \$(lsb\_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
\ 安装containerd(指定版本,避免自动更新)
sudo apt update && sudo apt install -y containerd.io=1.6.28-1
2. 配置 containerd(关键步骤)
arduino
\ 生成默认配置文件
sudo containerd config default | sudo tee /etc/containerd/config.toml
\ 修改配置文件(3个核心修改点)
sudo sed -i 's/SystemdCgroup \\= false/SystemdCgroup \\= true/g' /etc/containerd/config.toml 开启SystemdCgroup
sudo sed -i 's#sandbox\_image \\= "k8s.gcr.io/pause:3.6"#sandbox\_image \\= "registry.aliyuncs.com/google\_containers/pause:3.9"#g' /etc/containerd/config.toml 替换pause镜像为阿里云源
sudo sed -i 's#config\_path \\= ""#config\_path \\= "/etc/containerd/certs.d"#g' /etc/containerd/config.toml 配置镜像仓库证书路径
\ 重启containerd并设置开机自启
sudo systemctl restart containerd
sudo systemctl enable containerd
\ 验证containerd状态(输出active即为成功)
sudo systemctl status containerd
三、安装 K8s 核心组件:kubeadm、kubelet、kubectl
kubeadm是集群部署工具,kubelet是节点上的核心组件,kubectl是集群命令行工具,三者版本必须一致。
1. 添加 K8s 官方源(国内优化)
bash
\ 添加K8s官方GPG密钥
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-apt-keyring.gpg
\ 添加K8s源(国内可访问)
echo 'deb \[signed-by=/etc/apt/trusted.gpg.d/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
2. 安装组件并锁定版本
sql
\ 安装指定版本(1.29.0为稳定版,可替换为其他稳定版)
sudo apt update && sudo apt install -y kubeadm=1.29.0-1.1 kubelet=1.29.0-1.1 kubectl=1.29.0-1.1
\ 锁定版本,避免自动更新导致版本不一致
sudo apt-mark hold kubeadm kubelet kubectl
\ 验证安装(输出版本号即为成功)
kubeadm version
kubectl version --client
四、方案一:单 Master 集群部署(快速测试)
适合新手入门、测试环境,部署 1 个 Master 节点 + N 个 Node 节点,步骤简单高效。
1. 初始化 Master 节点(仅 Master 执行)
css
\ 初始化集群(关键参数说明)
\ --apiserver-advertise-address:Master节点IP
\ --pod-network-cidr:Pod网络网段(需与后续网络插件一致,Calico默认10.244.0.0/16)
\ --image-repository:国内镜像仓库(避免k8s.gcr.io无法访问)
\ --kubernetes-version:指定K8s版本(与安装的kubeadm版本一致)
sudo kubeadm init \\
  \--apiserver-advertise-address=192.168.1.100 \\
  \--pod-network-cidr=10.244.0.0/16 \\
  \--image-repository=registry.aliyuncs.com/google\_containers \\
  \--kubernetes-version=v1.29.0
初始化成功后,执行以下操作(普通用户执行)
bash
\ 配置kubectl权限(让普通用户能操作集群)
mkdir -p \$HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf \$HOME/.kube/config
sudo chown \$(id -u):\$(id -g) \$HOME/.kube/config
\ 验证Master节点状态(输出Ready即为成功)
kubectl get nodes
重要:初始化成功后,终端会输出
Node 节点加入集群的命令
(形如
kubeadm join
192.168.1.100:6443
--token xxx --discovery-token-ca-cert-hash sha256:xxx),复制保存,后续 Node 节点需使用。若忘记,可在 Master 节点执行
kubeadm token create --print-join-command重新生成。
2. 安装网络插件:Calico(必装)
K8s 集群需网络插件实现 Pod 间通信,Calico 是轻量、稳定的选择,支持网络策略:
sql
\ 下载Calico配置文件(国内加速地址)
curl -O https://docs.projectcalico.org/v3.27/manifests/calico.yaml
\ (可选)修改Pod网络网段(若初始化时修改了--pod-network-cidr,需同步修改此处)
\ sed -i 's/10.244.0.0\\/16/你的网段/g' calico.yaml
\ 安装Calico
kubectl apply -f calico.yaml
\ 查看Calico Pod状态(所有Pod为Running即为成功,约1-2分钟)
kubectl get pods -n kube-system -l k8s-app=calico-node
3. Node 节点加入集群(仅 Node 执行)
在所有 Node 节点执行之前保存的kubeadm join命令:
sql
sudo kubeadm join 192.168.1.100:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx
验证 Node 节点加入状态(Master 节点执行)
arduino
\ 查看所有节点(状态均为Ready即为成功)
kubectl get nodes
\ 查看集群组件状态(所有组件为Healthy即为成功)
kubectl get cs
五、方案二:多 Master 高可用集群部署(生产环境)
生产环境需避免单点故障,采用 "3 个 Master 节点 + N 个 Node 节点 + 负载均衡(HAProxy+Keepalived)" 架构,以下是关键步骤(基于单 Master 基础,补充高可用相关配置)。
1. 部署负载均衡(HAProxy+Keepalived)
在 2 个独立节点(或 Master 节点上,不推荐生产环境)部署负载均衡,提供虚拟 IP(VIP)访问 Master 节点的 apiserver(6443 端口)。
(1)安装 HAProxy 与 Keepalived(所有负载均衡节点执行)
sql
sudo apt update && sudo apt install -y haproxy keepalived
(2)配置 HAProxy(负载均衡节点执行)
ruby
sudo cat > /etc/haproxy/haproxy.cfg << EOF
global
  log /dev/log local0 warning
  chroot /var/lib/haproxy
  stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
  stats timeout 30s
  user haproxy
  group haproxy
  daemon
defaults
  log global
  mode tcp
  option tcplog
  option dontlognull
  timeout connect 5000
  timeout client 50000
  timeout server 50000
\ K8s apiserver负载均衡配置
frontend k8s-apiserver
  bind \*:6443
  mode tcp
  option tcplog
  default\_backend k8s-apiserver-backend
backend k8s-apiserver-backend
  mode tcp
  option tcplog
  option tcp-check
  balance roundrobin 轮询负载均衡
  server k8s-master-01 192.168.1.100:6443 check fall 3 rise 2
  server k8s-master-02 192.168.1.101:6443 check fall 3 rise 2
  server k8s-master-03 192.168.1.102:6443 check fall 3 rise 2
EOF
\ 重启HAProxy并设置开机自启
sudo systemctl restart haproxy
sudo systemctl enable haproxy
\ 验证HAProxy状态
sudo systemctl status haproxy
(3)配置 Keepalived(负载均衡节点执行)
主负载均衡节点(如 192.168.1.150)配置:
csharp
sudo cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived
global\_defs {
  router\_id LVS\_DEVEL
}
vrrp\_instance VI\_1 {
  state MASTER 主节点为MASTER,备节点为BACKUP
  interface ens33 网卡名称(通过ip addr查看)
  virtual\_router\_id 51
  priority 100 主节点优先级高于备节点(如备节点设为90)
  advert\_int 1
  authentication {
  auth\_type PASS
  auth\_pass 1111
  }
  virtual\_ipaddress {
  192.168.1.200/24 虚拟IP(K8s-VIP)
  }
}
EOF
备负载均衡节点(如 192.168.1.151)配置:
csharp
sudo cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived
global\_defs {
  router\_id LVS\_DEVEL
}
vrrp\_instance VI\_1 {
  state BACKUP
  interface ens33
  virtual\_router\_id 51
  priority 90
  advert\_int 1
  authentication {
  auth\_type PASS
  auth\_pass 1111
  }
  virtual\_ipaddress {
  192.168.1.200/24
  }
}
EOF
(4)启动 Keepalived 并验证 VIP
bash
\ 所有负载均衡节点执行
sudo systemctl restart keepalived
sudo systemctl enable keepalived
sudo systemctl status keepalived
\ 验证VIP是否生效(主节点执行,能看到192.168.1.200即为成功)
ip addr
2. 初始化第一个 Master 节点(192.168.1.100 执行)
csharp
sudo kubeadm init \\
  \--apiserver-advertise-address=192.168.1.100 \\
  \--apiserver-cert-extra-sans=192.168.1.200 \ 添加虚拟IP(VIP)到证书信任列表
  \--pod-network-cidr=10.244.0.0/16 \\
  \--image-repository=registry.aliyuncs.com/google\_containers \\
  \--kubernetes-version=v1.29.0
配置 kubectl 权限(同单 Master 步骤)
bash
mkdir -p \$HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf \$HOME/.kube/config
sudo chown \$(id -u):\$(id -g) \$HOME/.kube/config
3. 加入其他 Master 节点(192.168.1.101、192.168.1.102 执行)
首先在第一个 Master 节点生成加入命令:
lua
\ 生成Master节点加入命令(复制输出结果)
kubeadm token create --print-join-command
在其他 Master 节点执行加入命令,并添加--control-plane参数(表示加入为 Master 节点):
sql
sudo kubeadm join 192.168.1.200:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx \\
  \--control-plane \\
  \--certificate-key \$(kubeadm init phase upload-certs --upload-certs | grep -v 'certificate-key' | tail -n1)
4. 安装 Calico 网络插件(第一个 Master 节点执行)
同单 Master 步骤,安装 Calico 后,所有 Master 节点状态会变为 Ready。
5. Node 节点加入高可用集群(Node 节点执行)
通过 VIP 加入集群(而非单个 Master 节点 IP):
sql
sudo kubeadm join 192.168.1.200:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx
6. 验证高可用集群状态(任意 Master 节点执行)
sql
\ 查看所有节点(3个Master+N个Node均为Ready)
kubectl get nodes
\ 查看apiserver Pod(3个Master节点各1个,均为Running)
kubectl get pods -n kube-system -l component=kube-apiserver
六、集群验证:部署测试应用
无论单 Master 还是高可用集群,部署 Nginx 应用验证集群可用性:
sql
\ 创建Deployment(2个副本)
kubectl create deployment nginx-test --image=nginx:1.25-alpine --replicas=2
\ 创建NodePort类型Service(外部可访问)
kubectl expose deployment nginx-test --type=NodePort --port=80
\ 查看Pod和Service状态
kubectl get pods
kubectl get svc nginx-test
\ 访问测试(浏览器访问http://节点IP:NodePort,如30xxx端口)
七、常见问题排查(新手必看)
1. 节点状态为 NotReady
-
原因:网络插件未安装或运行失败,或 containerd 未正常启动。
-
解决方案:
perl
\ 查看Calico Pod日志
kubectl logs -n kube-system calico-node-xxx
\ 重启Calico
kubectl delete pods -n kube-system -l k8s-app=calico-node
\ 重启containerd
sudo systemctl restart containerd
2. 镜像拉取失败(如 pause、calico 镜像)
-
原因:国外镜像仓库无法访问。
-
解决方案:替换为阿里云镜像源,参考 containerd 配置步骤中的
sandbox_image修改,或手动拉取镜像并打标签。
3. kubeadm init 失败,提示 "port 6443 is in use"
-
原因:6443 端口(apiserver)被占用。
-
解决方案:查找占用进程并杀死:
bash
sudo lsof -i :6443
sudo kill -9 进程ID
4. Node 节点加入失败,提示 "connection refused"
-
原因:Master 节点 6443 端口未开放,或网络不通。
-
解决方案:关闭 Master 节点防火墙,或开放 6443 端口:
bash
sudo ufw allow 6443/tcp
5. 高可用集群 apiserver Pod 启动失败
-
原因:VIP 未生效,或证书未包含 VIP。
-
解决方案:验证 Keepalived 的 VIP 是否存在(
ip addr),重新初始化 Master 节点时添加--apiserver-cert-extra-sans=VIP参数。