Kubernetes 集群部署手册

文档版本:v1.0 适用系统:CentOS 7.9+ / Rocky Linux 8+ / Ubuntu 20.04+ K8s 版本:v1.28+ 部署方式:kubeadm 容器运行时:containerd 编写日期:2026-05-14


1. K8s 架构概览

图片[1]-Kubernetes 集群部署手册-小程博客

1.1 Master 节点(控制平面)

组件说明
kube-apiserver集群入口,提供 REST API,所有操作都经过它
etcd分布式键值存储,保存集群所有数据
kube-scheduler负责将 Pod 调度到合适的 Worker 节点
kube-controller-manager运行各种控制器(副本、节点、命名空间等)

1.2 Worker 节点(数据平面)

组件说明
kubelet节点代理,负责管理 Pod 的生命周期
kube-proxy维护网络规则,实现 Service 的负载均衡
容器运行时负责运行容器(containerd / CRI-O / Docker)

2. 部署流程总览

图片[2]-Kubernetes 集群部署手册-小程博客
步骤操作执行节点
Step 1环境规划与准备所有节点
Step 2系统初始化配置所有节点
Step 3安装 containerd所有节点
Step 4安装 kubeadm/kubelet/kubectl所有节点
Step 5初始化 MasterMaster 节点
Step 6部署网络插件Master 节点
Step 7Worker 加入集群Worker 节点
Step 8验证集群Master 节点

3. 环境规划与准备

3.1 集群节点规划

角色主机名IP 地址配置要求
Masterk8s-master192.168.1.1002C4G+ / 50GB 磁盘
Worker1k8s-worker1192.168.1.1012C4G+ / 50GB 磁盘
Worker2k8s-worker2192.168.1.1022C4G+ / 50GB 磁盘

⚠️ 最低配置:Master 至少 2核4G,Worker 至少 2核2G。生产环境建议 Master 4核8G 以上。

3.2 软件版本

软件版本
操作系统CentOS 7.9 / Rocky Linux 8 / Ubuntu 20.04
Kubernetesv1.28.x
containerd1.6.x+
Calico / Flannel最新稳定版

3.3 配置 hosts 解析(所有节点)

cat >> /etc/hosts << EOF
192.168.1.100  k8s-master
192.168.1.101  k8s-worker1
192.168.1.102  k8s-worker2
EOF

4. 系统初始化配置(所有节点)

⚠️ 以下操作需在 Master 和所有 Worker 节点 上执行。

4.1 关闭 SELinux

# 临时关闭
setenforce 0

# 永久关闭
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

4.2 关闭 Swap

# 临时关闭
swapoff -a
​
# 永久关闭(注释掉 swap 行)
sed -i '/swap/s/^/#/' /etc/fstab

⚠️ K8s 强制要求:kubelet 不支持在开启 Swap 的系统上运行。

4.3 关闭防火墙

# CentOS/Rocky
systemctl stop firewalld
systemctl disable firewalld
​
# Ubuntu
ufw disable

📌 生产环境建议保留防火墙并开放必要端口,参见 附录:端口规划

4.4 配置内核参数

# 加载内核模块
cat > /etc/modules-load.d/k8s.conf << EOF
overlay
br_netfilter
EOF
​
modprobe overlay
modprobe br_netfilter
​
# 内核网络参数
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
EOF
​
# 立即生效
sysctl --system

验证内核模块:

lsmod | grep br_netfilter
lsmod | grep overlay

4.5 同步时间

# 安装 chrony
yum install -y chrony          # CentOS/Rocky
apt install -y chrony           # Ubuntu
​
# 启动并设置开机自启
systemctl enable chronyd --now
​
# 验证时间同步
chronyc sources
timedatectl

5. 安装容器运行时 containerd(所有节点)

5.1 安装 containerd

CentOS/Rocky:

# 安装依赖
yum install -y yum-utils
​
# 添加 Docker 官方源(containerd 包含在其中)
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
​
# 安装 containerd
yum install -y containerd.io

Ubuntu/Debian:

# 安装依赖
apt install -y ca-certificates curl gnupg

# 添加 Docker 官方 GPG key 和源
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 containerd
apt update
apt install -y containerd.io

5.2 生成默认配置

# 生成默认配置文件
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml

5.3 修改配置:使用 systemd 作为 cgroup 驱动

# 将 SystemdCgroup 改为 true
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

⚠️ 关键配置:K8s 官方推荐使用 systemd 作为 cgroup 驱动,与 kubelet 保持一致,否则可能出现资源管理问题。

5.4 配置镜像加速(国内环境)

编辑 /etc/containerd/config.toml,在 [plugins."io.containerd.grpc.v1.cri".registry.mirrors] 下添加:

[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
    endpoint = ["https://mirror.ccs.tencentyun.com"]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
    endpoint = ["https://registry.cn-hangzhou.aliyuncs.com"]

5.5 启动 containerd

systemctl enable containerd --now

# 验证运行状态
systemctl status containerd

6. 安装 kubeadm、kubelet、kubectl(所有节点)

6.1 添加 Kubernetes Yum/Apt 源

CentOS/Rocky:

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
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
EOF

Ubuntu/Debian:

apt install -y apt-transport-https ca-certificates curl gpg

mkdir -p /etc/apt/keyrings
curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main' | tee /etc/apt/sources.list.d/kubernetes.list

apt update

6.2 安装组件

# CentOS/Rocky
yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2

# Ubuntu/Debian
apt install -y kubelet=1.28.2-00 kubeadm=1.28.2-00 kubectl=1.28.2-00

# 锁定版本(防止自动升级)
apt-mark hold kubelet kubeadm kubectl    # Ubuntu
yum versionlock kubelet kubeadm kubectl  # CentOS(需安装 yum-plugin-versionlock)

# 设置 kubelet 开机自启
systemctl enable kubelet

📌 注意:此时 kubelet 会启动失败,属于正常现象,待 kubeadm init 后会自动恢复正常。

6.3 验证安装

kubeadm version
kubelet --version
kubectl version --client

7. 初始化 Master 节点

⚠️ 以下操作仅在 Master 节点 上执行。

7.1 预拉取镜像

# 查看所需镜像列表
kubeadm config images list --kubernetes-version=v1.28.2

# 提前拉取镜像(使用国内源)
kubeadm config images pull \
  --kubernetes-version=v1.28.2 \
  --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers

7.2 编写初始化配置文件

cat > kubeadm-init.yaml << EOF
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
nodeRegistration:
  criSocket: unix:///run/containerd/containerd.sock
  name: k8s-master
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.2
controlPlaneEndpoint: "192.168.1.100:6443"
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
networking:
  podSubnet: "10.244.0.0/16"
  serviceSubnet: "10.96.0.0/12"
  dnsDomain: "cluster.local"
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
EOF

7.3 执行初始化

kubeadm init --config=kubeadm-init.yaml --upload-certs

⏳ 等待初始化完成(通常 2~5 分钟),成功后会输出类似以下信息:

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

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

kubeadm join 192.168.1.100:6443 --token <token> \
        --discovery-token-ca-cert-hash sha256:<hash>

⚠️ 重要:将 kubeadm join 命令完整保存下来,Worker 节点加入时需要使用!

7.4 配置 kubectl

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

7.5 验证 Master 状态

kubectl get nodes
# 此时 Master 状态为 NotReady,需要部署网络插件后变为 Ready

kubectl get pods -n kube-system
# 查看核心组件是否全部 Running

8. 部署网络插件

⚠️ 以下操作在 Master 节点 上执行。

方案 A:Calico(推荐,支持网络策略)

# 下载 Calico 清单
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml

# 修改 CALICO_IPV4POOL_CIDR 与 podSubnet 保持一致
# 默认为 192.168.0.0/16,需改为初始化时配置的 10.244.0.0/16
sed -i 's/# - name: CALICO_IPV4POOL_CIDR/- name: CALICO_IPV4POOL_CIDR/' calico.yaml
sed -i 's/#   value: "192.168.0.0\/16"/  value: "10.244.0.0\/16"/' calico.yaml

# 部署
kubectl apply -f calico.yaml

方案 B:Flannel(轻量,配置简单)

# 下载 Flannel 清单
curl -O https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

# 部署
kubectl apply -f kube-flannel.yml

验证网络插件

# 等待 Pod 状态变为 Running
kubectl get pods -n kube-system

# 确认节点变为 Ready
kubectl get nodes
图片[3]-Kubernetes 集群部署手册-小程博客

9. 加入 Worker 节点

⚠️ 以下操作在 每个 Worker 节点 上执行。

9.1 执行 join 命令

使用 Master 初始化时输出的 kubeadm join 命令:

kubeadm join 192.168.1.100:6443 --token <token> \
        --discovery-token-ca-cert-hash sha256:<hash>

成功输出:

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

9.2 Token 过期处理

如果 Token 已过期(默认 24 小时有效),在 Master 节点上重新生成:

# 生成新的 join 命令
kubeadm token create --print-join-command

# 输出类似:
# kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:xxxx

9.3 在 Master 上验证节点加入

kubectl get nodes

# 期望输出:
# NAME          STATUS   ROLES           AGE   VERSION
# k8s-master    Ready    control-plane   10m   v1.28.2
# k8s-worker1   Ready    <none>          1m    v1.28.2
# k8s-worker2   Ready    <none>          30s   v1.28.2

10. 集群验证与测试

10.1 检查集群组件

# 查看所有节点状态
kubectl get nodes -o wide

# 查看所有系统 Pod
kubectl get pods -n kube-system -o wide

# 查看组件状态
kubectl get componentstatuses

10.2 部署测试应用

# 创建 Nginx 测试 Deployment
kubectl create deployment nginx-test --image=nginx:1.24 --replicas=3

# 查看 Pod 状态
kubectl get pods -o wide

# 创建 NodePort Service 暴露服务
kubectl expose deployment nginx-test --port=80 --target-port=80 --type=NodePort

# 查看 Service
kubectl get svc nginx-test

# 记录 NodePort 端口号(如 31234)
curl http://192.168.1.101:31234

10.3 测试 DNS 解析

# 启动临时 Busybox Pod
kubectl run busybox --rm -it --image=busybox:1.36 -- sh

# 在 Pod 内执行 DNS 测试
nslookup kubernetes.default.svc.cluster.local
nslookup nginx-test.default.svc.cluster.local

# 退出
exit

10.4 清理测试资源

kubectl delete deployment nginx-test
kubectl delete svc nginx-test

11. 部署 Dashboard 可视化面板

11.1 安装 Dashboard

# 下载官方推荐版本
curl -O https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

# 部署
kubectl apply -f recommended.yaml

11.2 创建管理员 ServiceAccount

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

kubectl apply -f dashboard-admin.yaml

11.3 修改 Service 为 NodePort

# 修改 Service 类型
kubectl patch svc kubernetes-dashboard -n kubernetes-dashboard \
  -p '{"spec":{"type":"NodePort"}}'

# 查看 NodePort 端口
kubectl get svc -n kubernetes-dashboard

11.4 获取登录 Token

kubectl -n kubernetes-dashboard create token admin-user

11.5 访问 Dashboard

在浏览器中访问(以 NodePort 31234 为例):

https://192.168.1.100:31234

📌 自签名证书浏览器会提示不安全,点击”高级”→”继续访问”即可。


12. 常用管理命令速查

集群管理

操作命令
查看节点kubectl get nodes
查看节点详情kubectl describe node <name>
查看集群信息kubectl cluster-info
查看组件状态kubectl get componentstatuses

Pod 管理

操作命令
查看 Podkubectl get pods -A
查看 Pod 详情kubectl describe pod <name> -n <ns>
查看 Pod 日志kubectl logs <name> -n <ns>
进入 Podkubectl exec -it <name> -n <ns> -- sh
删除 Podkubectl delete pod <name> -n <ns>

Deployment 管理

操作命令
创建 Deploymentkubectl create deploy <name> --image=<img> --replicas=<n>
扩缩容kubectl scale deploy <name> --replicas=<n>
滚动更新kubectl set image deploy/<name> <container>=<new-img>
查看更新状态kubectl rollout status deploy/<name>
回滚kubectl rollout undo deploy/<name>

Service 管理

操作命令
查看 Servicekubectl get svc -A
暴露服务kubectl expose deploy <name> --port=<p> --target-port=<tp> --type=NodePort
查看端点kubectl get endpoints <name>

配置与密钥

操作命令
查看 ConfigMapkubectl get cm -A
查看 Secretkubectl get secrets -A
应用清单kubectl apply -f <file.yaml>
删除清单kubectl delete -f <file.yaml>

13. 常见问题排查

❌ 问题一:节点状态 NotReady

# 1. 检查网络插件是否 Running
kubectl get pods -n kube-system | grep -E "calico|flannel"

# 2. 检查 kubelet 日志
journalctl -u kubelet -f

# 3. 检查容器运行时
systemctl status containerd

❌ 问题二:Pod 一直处于 ContainerCreating

# 查看 Pod 事件
kubectl describe pod <name> -n <ns>

# 常见原因:
# 1. 镜像拉取失败 → 配置镜像加速或手动拉取
# 2. 挂载卷不存在 → 检查 PV/PVC 配置
# 3. 配置映射不存在 → 检查 ConfigMap/Secret

❌ 问题三:kubeadm init 失败

# 1. 查看详细错误日志
journalctl -u kubelet | tail -50

# 2. 常见原因:Swap 未关闭
free -h
swapoff -a

# 3. 常见原因:端口被占用
ss -tlnp | grep :6443

# 4. 重置后重新初始化
kubeadm reset -f
rm -rf /etc/kubernetes/ /var/lib/kubelet/ /var/lib/etcd/
kubeadm init --config=kubeadm-init.yaml --upload-certs

❌ 问题四:CoreDNS 一直 CrashLoopBackOff

# 1. 检查 DNS Pod 日志
kubectl logs -n kube-system <coredns-pod-name>

# 2. 常见原因:resolv.conf 配置问题
# 在 Master 节点上修改
cat > /etc/resolv.conf << EOF
nameserver 8.8.8.8
nameserver 114.114.114.114
EOF

# 3. 重启 CoreDNS
kubectl rollout restart deployment coredns -n kube-system

❌ 问题五:Token 过期无法 join

# 在 Master 节点上生成新 Token
kubeadm token create --print-join-command

# 如果连 CA 证书 hash 也忘了
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | \
  openssl rsa -pubin -outform der 2>/dev/null | \
  openssl dgst -sha256 -hex | sed 's/^.* //'

❌ 问题六:kubectl 命令报 The connection to the server was refused

# 1. 检查 kubeconfig 是否存在
ls -la $HOME/.kube/config

# 2. 重新生成
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

# 3. 检查 apiserver 是否运行
kubectl get pods -n kube-system | grep apiserver

❌ 问题七:镜像拉取失败(国内网络)

# 1. 手动拉取并重新打标签
crictl pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9

# 2. 使用 kubeadm 配置指定镜像仓库
kubeadm init \
  --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
  --kubernetes-version=v1.28.2

附录

附录一:端口规划

节点端口协议用途
Master6443TCPkube-apiserver
Master2379-2380TCPetcd
Master10250TCPkubelet API
Master10259TCPkube-scheduler
Master10257TCPkube-controller-manager
Worker10250TCPkubelet API
Worker30000-32767TCPNodePort 服务范围
Worker10256TCPkube-proxy

附录二:重置集群

如需完全重置集群,在所有节点上执行:

# 重置 kubeadm
kubeadm reset -f

# 清理残留文件
rm -rf /etc/kubernetes/ /var/lib/kubelet/ /var/lib/etcd/ /var/lib/cni/ $HOME/.kube/config

# 重启 containerd
systemctl restart containerd

附录三:kubeadm-init.yaml 完整配置参考

apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
nodeRegistration:
  criSocket: unix:///run/containerd/containerd.sock
  name: k8s-master
  taints: null
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.2
controlPlaneEndpoint: "192.168.1.100:6443"
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
networking:
  podSubnet: "10.244.0.0/16"
  serviceSubnet: "10.96.0.0/12"
  dnsDomain: "cluster.local"
apiServer:
  extraArgs:
    authorization-mode: "Node,RBAC"
    enable-admission-plugins: "NodeRestriction"
  certSANs:
    - 192.168.1.100
    - k8s-master
scheduler: {}
controllerManager: {}
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
failSwapOn: true

📌 文档维护提示:本文档基于 kubeadm 方式部署,适用于学习和中小规模生产环境。大规模生产集群建议使用 kOps、Rancher 或云厂商托管 K8s 服务(EKS/GKE/AKS)。

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容