2、集群安装与配置:kubeadm部署高可用集群、kubectl配置、集群节点管理

好,咱们直接进入正题。集群安装这件事,说白了就是给Kubernetes搭骨架。骨架搭得正不正,直接决定了后面运维是喝茶还是救火。我个人习惯用kubeadm,它把很多底层细节封装好了,但又不是黑盒——出了问题你能顺着日志摸到根儿。

2.1 环境准备:别在起跑线上摔跤

先说说硬件。我见过太多人一上来就敲命令,结果卡在某个依赖上半天。嗯,这里有几个硬性条件你得先过一遍:

  • 操作系统:Ubuntu 20.04+ 或 CentOS 7.9+。我个人偏爱Ubuntu,包管理省心。
  • 资源规格:Master节点至少2核4G,Worker节点2核2G。别问我为什么,我在项目中遇到过2核2G的Master跑着跑着etcd就OOM了。
  • 网络互通:所有节点之间要能ping通,并且SSH免密登录配好。你想想看,如果节点间网络不通,集群就是个摆设。
  • 关闭交换分区swapoff -a 并且注释掉 /etc/fstab 里的swap行。Kubernetes要求必须关,否则kubelet会罢工。
⚠️ 我曾经踩过的坑:有次部署完集群,Pod调度总失败。查了半天,发现是某个Worker节点没关swap。kubelet日志里明确写着"running with swap on is not supported"。所以,先检查再动手

2.2 使用kubeadm部署高可用集群

高可用集群,说白了就是多个Master节点,一个挂了另一个顶上。这里我用三台Master、三台Worker来演示。你跟着做就行。

2.2.1 安装容器运行时

Kubernetes从1.24版本开始,默认用containerd。我建议你也用这个,别折腾Docker了。

# 所有节点执行
cat <
💡 小技巧:配置containerd时,记得把 SystemdCgroup 设为 true。否则kubelet和containerd的cgroup驱动不一致,Pod会一直处于ContainerCreating状态。

2.2.2 安装kubeadm、kubelet、kubectl

这三个工具版本必须一致。我习惯用最新稳定版,但生产环境建议锁定版本。

# 所有节点执行
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet=1.28.0-1.1 kubeadm=1.28.0-1.1 kubectl=1.28.0-1.1
sudo apt-mark hold kubelet kubeadm kubectl

2.2.3 初始化第一个Master节点

这里要注意,高可用集群需要先有一个"领头羊"。我习惯用 --control-plane-endpoint 指定一个负载均衡地址,比如用keepalived+HAProxy搭一个VIP。

# 在第一个Master节点执行
sudo kubeadm init \
  --control-plane-endpoint "192.168.1.100:6443" \
  --upload-certs \
  --pod-network-cidr=10.244.0.0/16

# 初始化成功后,会输出类似下面的信息:
# You can now join any number of the control-plane node running the following command:
#   kubeadm join 192.168.1.100:6443 --token xxxxx --discovery-token-ca-cert-hash sha256:xxxxx --control-plane --certificate-key xxxxx

🔑 关键点--upload-certs 参数会把证书上传到集群中,这样后续加入的Master节点能自动拉取证书。否则你得手动拷贝,麻烦得很。

2.2.4 加入其他Master节点

把上面init输出的join命令,在另外两台Master上执行就行。注意,如果token过期了,可以用 kubeadm token create --print-join-command 重新生成。

# 在第二、第三个Master节点执行
kubeadm join 192.168.1.100:6443 --token xxxxx \
  --discovery-token-ca-cert-hash sha256:xxxxx \
  --control-plane --certificate-key xxxxx

2.2.5 加入Worker节点

Worker节点不需要 --control-plane 参数,去掉就行。

# 在所有Worker节点执行
kubeadm join 192.168.1.100:6443 --token xxxxx \
  --discovery-token-ca-cert-hash sha256:xxxxx

2.3 kubectl配置:你的指挥棒

kubectl是操作集群的入口。初始化完成后,kubeadm会在Master节点生成 /etc/kubernetes/admin.conf。你需要把它拷贝到本地。

# 在Master节点执行
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 验证
kubectl get nodes
# 应该能看到所有节点,但状态是NotReady——因为还没装网络插件
💡 我个人的习惯:我会把 KUBECONFIG 环境变量设成多个路径,方便切换集群。比如 export KUBECONFIG=$HOME/.kube/config:$HOME/.kube/prod-config。这样用 kubectl config use-context 就能快速切换。

2.4 集群节点管理:日常操作三板斧

节点管理是运维的日常。我总结了三板斧:查看、隔离、恢复。

2.4.1 查看节点状态

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

# 查看节点详细信息
kubectl describe node node1

# 查看节点资源使用情况
kubectl top node

输出示例:

NAME STATUS ROLES AGE VERSION
master1 Ready control-plane 2d v1.28.0
worker1 Ready <none> 2d v1.28.0
worker2 NotReady <none> 1h v1.28.0

2.4.2 节点维护:排水与恢复

当你要重启或升级节点时,得先把上面的Pod赶走。这就是排水(drain)。

# 排水:驱逐Pod,并标记为不可调度
kubectl drain worker1 --ignore-daemonsets --delete-emptydir-data

# 维护完成后,恢复调度
kubectl uncordon worker1
⚠️ 注意--ignore-daemonsets 是必须的,因为DaemonSet类型的Pod(比如网络插件)是绑在节点上的,驱逐不掉。不加这个参数,drain会卡住。我曾经因为这个在凌晨被电话叫醒过。

2.4.3 节点标签与污点

标签用来分组,污点用来限制调度。比如把GPU节点打上标签,然后加上污点,只有特定Pod才能调度上去。

# 打标签
kubectl label node worker1 gpu=true

# 加污点
kubectl taint nodes worker1 gpu=true:NoSchedule

# 查看污点
kubectl describe node worker1 | grep Taints

2.5 安装网络插件:让Pod能互相通信

集群初始化后,Pod之间是ping不通的。你需要装一个CNI插件。我推荐Calico,功能全、性能好。

# 安装Calico
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/custom-resources.yaml

# 等待Pod启动
kubectl get pods -n calico-system -w

装完后,再执行 kubectl get nodes,所有节点应该都变成Ready了。

🎯 验证集群:创建一个测试Pod,看看能不能跨节点通信。

kubectl run test-pod --image=busybox -- sleep 3600
kubectl exec test-pod -- ping <另一个Pod的IP>

2.6 避坑指南:我踩过的那些雷

  • 证书过期:kubeadm生成的证书默认一年有效。我建议用 kubeadm certs renew 定期续期,或者直接改 /etc/kubernetes/kubelet.conf 里的证书路径。
  • etcd集群脑裂:高可用集群中,etcd节点数必须是奇数。3个节点最多挂1个,5个节点最多挂2个。否则会出现脑裂,整个集群不可用。
  • kubelet日志太多:默认日志级别是2,生产环境建议调到3或4。用 --v=3 启动kubelet,能拿到更多调试信息。

好了,这一章的内容就到这儿。集群装好了,后面咱们才能聊运维和排障。下一章我会讲Pod的生命周期管理,包括怎么优雅地处理Pod的启动、停止和重启。到时候见。

专注资料整理