Featured image of post Kubernetes 1.x 部署实战:Debian/Ubuntu Kubeadm 初始化与集群规划

Kubernetes 1.x 部署实战:Debian/Ubuntu Kubeadm 初始化与集群规划

apt 源配置、kubelet/kubeadm/kubectl 安装与版本锁定、kubeadm config images list 拉镜像、bash-completion 自动补全、集群规模选型 3/5/7 节点

背景

Kubernetes(K8s)2014-06 由 Google 开源,2015-07 推出 1.0 版本,如今已是容器编排领域的事实标准。

K8s 解决了什么

  • 跨机器调度容器(哪台机器跑哪个 Pod)
  • 自愈(容器挂了自动重启)
  • 滚动升级(无停机发布)
  • 服务发现 + 负载均衡
  • 配置管理(ConfigMap / Secret)
  • 存储编排(PV / PVC)

部署 K8s 集群的几种方式

方式难度适用
kubeadm官方推荐、学习首选
kubespray裸金属/混合云,Ansible 自动化
KopsAWS 专用
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-103 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 GBSSD ≥ 50 GB

生产 master 建议

  • 4 核 8 GB 起
  • SSD(etcd 写延迟敏感

2.2 系统要求

  • OS:Ubuntu 20.04+ / Debian 11+
  • 内核:≥ 4.19(Ubuntu 20.04 / Debian 11 默认)
  • 网络:所有节点互通
  • 关闭 swapswapoff -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 initkubeadm 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-addressmaster 节点 IP(worker 连这个)
--image-repository镜像仓库(国内用阿里云)
--kubernetes-versionK8s 版本(必须与 apt 装的 kubeadm 一致)
--service-cidrService IP 段
--pod-network-cidrPod 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>

升级顺序

  1. 先 master(一台一台滚)
  2. 再 worker(kubectl drain → upgrade → uncordon)
  3. 不要跨大版本(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 部署的核心三件套

  1. kubeadm(init/join 工具)
  2. kubelet(节点代理,每台都装)
  3. 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 节点规模选型)
使用 Hugo 构建
主题 StackJimmy 设计