背景
Kubernetes(K8s)2014-06 由 Google 开源,2015-07 推出 1.0 版本,如今已是容器编排领域的事实标准。
K8s 解决了什么:
- 跨机器调度容器(哪台机器跑哪个 Pod)
- 自愈(容器挂了自动重启)
- 滚动升级(无停机发布)
- 服务发现 + 负载均衡
- 配置管理(ConfigMap / Secret)
- 存储编排(PV / PVC)
部署 K8s 集群的几种方式:
| 方式 | 难度 | 适用 |
|---|
| kubeadm | 中 | 官方推荐、学习首选 |
| kubespray | 中 | 裸金属/混合云,Ansible 自动化 |
| Kops | 中 | AWS 专用 |
| minikube / kind | 低 | 本地学习 |
| RKE / K3s | 低 | 轻量级、边缘 |
| 云厂商托管(EKS/AKS/ACK) | 最低 | 生产首选,免运维 |
本篇:用 kubeadm 在 Debian/Ubuntu 上手把手部署 1.x 集群,并讲清楚集群规模怎么选。
一、集群规模规划
1.1 最小集群
2 节点:1 master + 1 worker
- 不推荐生产——master 单点
- 适合个人学习、临时测试
1.2 推荐最小生产
3 节点:1 master + 2 worker
- master 单点(生产勉强)
- worker 至少 2 台做 HA 业务
1.3 标准生产
5 节点:3 master + 2 worker
- 3 master 跑
etcd 集群(容忍 1 台挂) - 2 worker 跑业务(容忍 1 台挂)
1.4 规模生产
7 节点:3 master + 4 worker
- 3 master + 4 worker(worker 可以再多)
- 7 节点是 K8s 官方文档举例的标准规模
1.5 大规模集群
20+ 节点:
- master 必须 3 台或 5 台
- worker 数量按业务量扩展
- 配合 Ingress Controller、Pod 网络 CNI、存储 CSI 等组件
1.6 选型原则
| 业务规模 | 推荐节点数 | 说明 |
|---|
| 个人/学习 | 1-2 | 跑 minikube 就够 |
| 小团队(< 50 服务) | 3-5 | 单 master 也能用 |
| 中型企业(50-200 服务) | 7-10 | 3 master + 5+ worker |
| 大型企业(200+ 服务) | 20+ | 拆多集群 |
集群不是越大越好:
- 节点越多,网络/etcd 同步成本越高
- 100 节点以上的集群,K8s 控制面性能开始下降
- 一般 30-50 节点一个集群 较优
二、环境准备
2.1 硬件要求
| 角色 | CPU | 内存 | 磁盘 |
|---|
| master | ≥ 2 核 | ≥ 2 GB | ≥ 20 GB |
| worker | ≥ 1 核 | ≥ 1 GB | ≥ 20 GB |
| etcd 专用 | ≥ 4 核 | ≥ 8 GB | SSD ≥ 50 GB |
生产 master 建议:
- 4 核 8 GB 起
- SSD(etcd 写延迟敏感)
2.2 系统要求
- OS:Ubuntu 20.04+ / Debian 11+
- 内核:≥ 4.19(Ubuntu 20.04 / Debian 11 默认)
- 网络:所有节点互通
- 关闭 swap:
swapoff -a - 关闭防火墙 或放行 K8s 端口(6443、10250、8472/UDP)
2.3 必备设置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # 1. 关闭 swap
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 2. 加载内核模块
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
# 3. 设置 hostname(每台不同)
hostnamectl set-hostname master1
# 或 worker1
|
三、安装 kubeadm / kubelet / kubectl
3.1 更新 apt 索引
1
2
| sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
|
3.2 添加 Kubernetes apt 仓库
1
2
3
4
5
6
7
8
9
10
11
| # 下载 Google Cloud 公开签名密钥
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg \
https://packages.cloud.google.com/apt/doc/apt-key.gpg
# 添加 apt 源
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] \
https://apt.kubernetes.io/ kubernetes-xenial main" | \
sudo tee /etc/apt/sources.list.d/kubernetes.list
# 更新索引
sudo apt-get update
|
3.3 安装组件并锁定版本
1
2
| sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
|
apt-mark hold 至关重要:
- K8s 组件必须保持版本一致(kubelet 1.28.2 配 kubeadm 1.28.2)
- apt 自动升级会破坏集群
- 升级必须手动用
kubeadm upgrade 流程
3.4 三个组件的关系
| 组件 | 作用 | 装在 |
|---|
| kubeadm | 初始化集群的指令 | 所有节点 |
| kubelet | 在每个节点上启动 Pod 和容器的代理 | 所有节点 |
| kubectl | 与集群通信的命令行工具 | 通常只在 master / 运维机器 |
为什么不只装一个?kubeadm 是"一次性启动器",kubelet 是"持续运行代理",kubectl 是"客户端工具",三者各司其职。
3.5 kubelet 的"死循环"问题
安装完 kubelet 后,每隔几秒就会重启——
kubelet 现在每隔几秒就会重启,因为它陷入了一个等待 kubeadm 指令的死循环。
正常现象!kubelet 启动后等 kubeadm init 或 kubeadm join 指令,没有指令就一直重启。kubeadm init 完成后就不再重启。
3.6 启用 bash 自动补全
1
2
3
4
5
6
7
8
| apt-get install bash-completion
# 临时生效
source <(kubectl completion bash)
# 永久生效
echo "source <(kubectl completion bash)" >> ~/.bashrc
source ~/.bashrc
|
按 Tab 就能补全 kubectl 子命令。
3.7 拉取 K8s 所需镜像
1
2
3
4
5
6
7
8
9
| kubeadm config images list
# 列出 kubeadm init 时要拉的所有镜像
# k8s.gcr.io/kube-apiserver:v1.28.x
# k8s.gcr.io/kube-controller-manager:v1.28.x
# k8s.gcr.io/kube-scheduler:v1.28.x
# k8s.gcr.io/kube-proxy:v1.28.x
# k8s.gcr.io/pause:3.9
# k8s.gcr.io/etcd:3.5.x
# k8s.gcr.io/coredns/coredns:v1.10.x
|
⚠️ 2024-05 之后的版本:k8s.gcr.io 改为 registry.k8s.io(Google 自有域名)。老教程里的 k8s.gcr.io 可能要改。
国内用户(gcr.io 被墙):
1
2
| # 用国内镜像
kubeadm init --image-repository registry.aliyuncs.com/google_containers
|
四、初始化 master 节点
4.1 一行命令
1
2
3
4
5
6
| sudo kubeadm init \
--apiserver-advertise-address=<master-ip> \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.28.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
|
参数说明:
| 参数 | 作用 |
|---|
--apiserver-advertise-address | master 节点 IP(worker 连这个) |
--image-repository | 镜像仓库(国内用阿里云) |
--kubernetes-version | K8s 版本(必须与 apt 装的 kubeadm 一致) |
--service-cidr | Service IP 段 |
--pod-network-cidr | Pod IP 段(必须与 CNI 插件一致) |
4.2 安装 CNI 网络插件
K8s 不自带网络,必须装一个 CNI:
Flannel(最简单):
1
| kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
|
Calico(功能强、推荐生产):
1
| kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
|
Cilium(eBPF、性能最强):
1
| kubectl create -f https://raw.githubusercontent.com/cilium/cilium/v1.14/install/kubernetes/quick-install.yaml
|
4.3 配置 kubectl
1
2
3
| mkdir -p $HOME/.kube
sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
4.4 验证 master 节点
1
2
3
4
5
6
| kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# master1 Ready control-plane 5m v1.28.0
kubectl get pods -A
# 所有系统 Pod 应该是 Running
|
五、worker 节点加入
5.1 在 master 上获取 join 命令
1
2
3
4
| kubeadm token create --print-join-command
# 输出类似:
# kubeadm join 10.0.0.10:6443 --token abcdef.0123456789abcdef \
# --discovery-token-ca-cert-hash sha256:xxxxx
|
5.2 在每个 worker 上执行
1
2
3
| sudo kubeadm join 10.0.0.10:6443 \
--token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:xxxxx
|
5.3 验证集群
1
2
3
4
5
| kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# master1 Ready control-plane 10m v1.28.0
# worker1 Ready <none> 2m v1.28.0
# worker2 Ready <none> 2m v1.28.0
|
六、常见问题
6.1 kubeadm init 失败:端口占用
1
| [ERROR Port-6443]: Port 6443 is in use
|
对策:
1
2
3
| # 找到占用进程
lsof -i :6443
# 杀掉
|
6.2 kubeadm init 失败:镜像拉不到
国内:
1
| sudo kubeadm init --image-repository registry.aliyuncs.com/google_containers ...
|
国外:
1
2
3
4
| # 看具体哪个镜像失败
kubeadm config images list
docker pull <image>
# 重试
|
6.3 kubectl get nodes 显示 NotReady
1
2
3
4
5
| # 看 kubelet 日志
journalctl -u kubelet -f
# 常见:CNI 没装
# 装 flannel/calico
|
6.4 节点加入后 5 分钟还是 NotReady
1
2
3
4
| # 在 worker 上看 kubelet 日志
journalctl -u kubelet -f
# 常见:网络不通(6443 端口)、token 过期(默认 24h)、ca hash 不对
|
6.5 重置集群(重新 init)
1
2
3
| # 在每个节点上
sudo kubeadm reset
sudo rm -rf /etc/kubernetes /var/lib/etcd
|
七、升级(必须按 kubeadm 流程)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 1. 升级 kubeadm
sudo apt-get update
sudo apt-get install -y kubeadm=1.29.x-00
sudo apt-mark hold kubeadm
# 2. drain 节点
kubectl drain <node-name> --ignore-daemonsets
# 3. 升级
sudo kubeadm upgrade apply v1.29.x
# 4. 升级 kubelet/kubectl
sudo apt-get install -y kubelet=1.29.x-00 kubectl=1.29.x-00
sudo apt-mark hold kubelet kubectl
sudo systemctl restart kubelet
# 5. uncordon
kubectl uncordon <node-name>
|
升级顺序:
- 先 master(一台一台滚)
- 再 worker(kubectl drain → upgrade → uncordon)
- 不要跨大版本(1.28 → 1.30 风险大,逐版本 1.28 → 1.29 → 1.30)
八、生产级建议
8.1 高可用 master
3 master 模式(堆叠 etcd):
1
2
3
4
5
6
| # 第一台 master
sudo kubeadm init --control-plane-endpoint "lb-vip:6443" --upload-certs
# 其他 master 用同一命令的 join 输出
sudo kubeadm join lb-vip:6443 --token xxx --discovery-token-ca-cert-hash xxx \
--control-plane --certificate-key xxx
|
前置条件:
- 3 台 master 节点
- 一个负载均衡 VIP(HAProxy / 云 LB)
- VIP 后端 3 台 master 的 6443 端口
8.2 关闭 master 上的业务 Pod
1
2
3
| kubectl taint nodes --all node-role.kubernetes.io/control-plane-
# 或反操作:加 taint 让 master 不跑业务
kubectl taint nodes master1 node-role.kubernetes.io/control-plane:NoSchedule
|
8.3 备份 etcd
1
2
3
4
5
6
7
8
9
| # 找 etcd pod
kubectl get pods -n kube-system | grep etcd
# 备份
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-$(date +%F).db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
|
8.4 监控与日志
- metrics-server:kubectl top node/pod
- Prometheus + Grafana:监控指标
- Loki + Promtail:日志聚合
- Jaeger / Tempo:链路追踪
九、卸载
1
2
3
4
5
| # 在每个节点
sudo kubeadm reset
sudo apt remove kubeadm kubelet kubectl -y
sudo apt-mark unhold kubeadm kubelet kubectl
sudo rm -rf /etc/kubernetes /var/lib/etcd ~/.kube
|
小结
K8s 1.x 部署的核心三件套:
- kubeadm(init/join 工具)
- kubelet(节点代理,每台都装)
- kubectl(客户端工具)
集群规模:
- 学习:1-2 节点(minikube / kind)
- 生产:3 master + N worker(推荐起点 5 节点)
- 超大规模:拆多集群,单集群 ≤ 50 节点
生产部署三原则:
- HA master(3 台)+ 负载均衡 VIP
- apt-mark hold 锁定版本
- 按官方 kubeadm 流程升级(不要 apt 升级破坏集群)
下一步:
- 装 Helm(K8s 包管理)
- 部署 Ingress Controller(Nginx / Traefik)
- 用 ArgoCD / Flux 做 GitOps
- 上 Istio / Linkerd 服务网格
源文档:
os/linux/第三方tools/dev/kubernetes/debian安装kubernetes.md(apt 源、版本锁定、bash-completion)os/linux/第三方tools/dev/kubernetes/k8s集群.md(2/3/5 节点规模选型)