文档版本:v1.0 适用系统:CentOS 7.9+ / Rocky Linux 8+ / Ubuntu 20.04+ K8s 版本:v1.28+ 部署方式:kubeadm 容器运行时:containerd 编写日期:2026-05-14
1. K8s 架构概览
![图片[1]-Kubernetes 集群部署手册-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/96bd88fd6c20260514164607-1024x701.png)
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 集群部署手册-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/e050fe157e20260514164617-701x1024.png)
| 步骤 | 操作 | 执行节点 |
|---|---|---|
| Step 1 | 环境规划与准备 | 所有节点 |
| Step 2 | 系统初始化配置 | 所有节点 |
| Step 3 | 安装 containerd | 所有节点 |
| Step 4 | 安装 kubeadm/kubelet/kubectl | 所有节点 |
| Step 5 | 初始化 Master | Master 节点 |
| Step 6 | 部署网络插件 | Master 节点 |
| Step 7 | Worker 加入集群 | Worker 节点 |
| Step 8 | 验证集群 | Master 节点 |
3. 环境规划与准备
3.1 集群节点规划
| 角色 | 主机名 | IP 地址 | 配置要求 |
|---|---|---|---|
| Master | k8s-master | 192.168.1.100 | 2C4G+ / 50GB 磁盘 |
| Worker1 | k8s-worker1 | 192.168.1.101 | 2C4G+ / 50GB 磁盘 |
| Worker2 | k8s-worker2 | 192.168.1.102 | 2C4G+ / 50GB 磁盘 |
⚠️ 最低配置:Master 至少 2核4G,Worker 至少 2核2G。生产环境建议 Master 4核8G 以上。
3.2 软件版本
| 软件 | 版本 |
|---|---|
| 操作系统 | CentOS 7.9 / Rocky Linux 8 / Ubuntu 20.04 |
| Kubernetes | v1.28.x |
| containerd | 1.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 集群部署手册-小程博客](https://www.zenly.ink/wp-content/uploads/2026/05/d7308b574520260514164835-1024x701.png)
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 管理
| 操作 | 命令 |
|---|---|
| 查看 Pod | kubectl get pods -A |
| 查看 Pod 详情 | kubectl describe pod <name> -n <ns> |
| 查看 Pod 日志 | kubectl logs <name> -n <ns> |
| 进入 Pod | kubectl exec -it <name> -n <ns> -- sh |
| 删除 Pod | kubectl delete pod <name> -n <ns> |
Deployment 管理
| 操作 | 命令 |
|---|---|
| 创建 Deployment | kubectl 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 管理
| 操作 | 命令 |
|---|---|
| 查看 Service | kubectl get svc -A |
| 暴露服务 | kubectl expose deploy <name> --port=<p> --target-port=<tp> --type=NodePort |
| 查看端点 | kubectl get endpoints <name> |
配置与密钥
| 操作 | 命令 |
|---|---|
| 查看 ConfigMap | kubectl get cm -A |
| 查看 Secret | kubectl 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
附录
附录一:端口规划
| 节点 | 端口 | 协议 | 用途 |
|---|---|---|---|
| Master | 6443 | TCP | kube-apiserver |
| Master | 2379-2380 | TCP | etcd |
| Master | 10250 | TCP | kubelet API |
| Master | 10259 | TCP | kube-scheduler |
| Master | 10257 | TCP | kube-controller-manager |
| Worker | 10250 | TCP | kubelet API |
| Worker | 30000-32767 | TCP | NodePort 服务范围 |
| Worker | 10256 | TCP | kube-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)。














暂无评论内容