3、Kubernetes集群搭建:kubeadm部署、高可用架构、网络插件选择(Calico vs Flannel)、集群验证

说实话,Kubernetes集群搭建这件事,我见过太多人栽跟头了。

有人照着官方文档一步步来,结果网络不通;有人用kubeadm一键部署,结果etcd挂了;还有人高可用搭好了,一压测就脑裂。嗯,这些坑我都踩过。

今天咱们就聊聊,怎么用kubeadm搭一个生产可用的集群。我会把那些文档里没写的、踩过的坑,一并告诉你。

3.1 环境准备:别在起跑线上翻车

先说说节点规划。我个人习惯,至少准备3台机器。为什么是3台?因为etcd需要奇数节点才能保证选举。

配置方面,2核4G是底线。我建议4核8G起步,不然跑几个Pod就卡得不行。

注意: 所有节点的主机名不能重复,而且必须能互相解析。我见过有人用localhost当主机名,结果集群死活起不来。

操作系统我推荐Ubuntu 20.04或CentOS 7.9。内核版本最好在4.15以上,不然有些网络功能不支持。

嗯,这里有个小技巧:提前把swap关掉。kubelet默认要求swap关闭,不然会报错。

# 临时关闭
swapoff -a
# 永久关闭,注释掉/etc/fstab中的swap行
sed -i '/swap/d' /etc/fstab

3.2 kubeadm部署:三步走,稳得很

kubeadm是官方推荐的部署工具。说白了,它就是把Kubernetes的组件打包成容器,然后用静态Pod的方式跑起来。

第一步,安装容器运行时。我推荐containerd,比Docker轻量,而且Kubernetes 1.24之后已经弃用Docker了。

# 安装containerd
cat <

第二步,安装kubeadm、kubelet和kubectl。版本要一致,不然会出兼容性问题。

apt-get update
apt-get install -y kubelet=1.27.0-00 kubeadm=1.27.0-00 kubectl=1.27.0-00
apt-mark hold kubelet kubeadm kubectl

第三步,初始化控制平面。这里有个坑:一定要指定Pod网络CIDR,不然后面网络插件装不上。

kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.1.10
我的经验: 初始化完成后,记得把kubeconfig复制到~/.kube目录。不然kubectl用不了。

3.3 高可用架构:别让单点搞垮你

单Master节点?生产环境千万别这么干。我经历过一次Master节点宕机,整个集群都瘫痪了,那叫一个惨。

高可用的核心思路:多个Master节点 + 负载均衡器。

架构是这样的:

组件 数量 说明
Master节点 3 奇数,etcd选举需要
Worker节点 ≥2 根据业务需求扩展
负载均衡器 1 可以是HAProxy或Nginx

具体怎么搭?我习惯用HAProxy做负载均衡,Keepalived做VIP漂移。

# HAProxy配置示例
frontend kubernetes
    bind *:6443
    option tcplog
    mode tcp
    default_backend kubernetes-master

backend kubernetes-master
    mode tcp
    balance roundrobin
    server master1 192.168.1.10:6443 check
    server master2 192.168.1.11:6443 check
    server master3 192.168.1.12:6443 check

初始化时,用VIP地址代替单个Master地址:

kubeadm init --control-plane-endpoint "192.168.1.100:6443" --upload-certs
注意: 高可用模式下,etcd的存储路径要放在共享存储上,不然Master挂了数据就丢了。

3.4 网络插件选择:Calico vs Flannel

网络插件是Kubernetes里最容易出问题的地方。我见过有人因为选错插件,折腾了一周。

先说说Flannel。它简单,真的简单。部署就一条命令:

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

Flannel用的是VXLAN或host-gw模式。说白了,它就是在宿主机之间搭了个隧道。优点是配置少,缺点是性能一般,而且不支持网络策略。

再说Calico。它用的是BGP协议,直接在三层转发。性能比Flannel好,而且支持网络策略。

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25/manifests/tigera-operator.yaml

怎么选?我建议:

  • 小规模集群(<50节点),Flannel够用
  • 生产环境,必须上Calico
  • 需要网络隔离的,选Calico
  • 对性能敏感的,选Calico
我的经验: 如果用了Calico,记得把IPIP模式改成BGP直连。IPIP封装会降低性能,BGP直连能跑满线速。

3.5 集群验证:别信"看起来正常"

集群搭好了,怎么验证?我见过有人只看kubectl get nodes就以为没问题了。结果一跑业务就崩。

我的验证流程是这样的:

  1. 检查节点状态:kubectl get nodes,所有节点都应该是Ready
  2. 检查Pod状态:kubectl get pods -n kube-system,所有系统组件都Running
  3. 部署测试应用:kubectl create deployment nginx --image=nginx
  4. 暴露服务:kubectl expose deployment nginx --port=80 --type=NodePort
  5. 访问测试:curl http://任意节点IP:NodePort

嗯,这里有个坑:如果NodePort访问不了,先检查防火墙。我遇到过好几次,防火墙把端口封了。

还有一个验证点:DNS解析。Kubernetes的CoreDNS经常出问题。

# 创建一个测试Pod
kubectl run test --image=busybox -- sleep 3600
# 进入Pod测试DNS
kubectl exec -it test -- nslookup kubernetes.default.svc.cluster.local

如果DNS解析失败,八成是CoreDNS的配置有问题。检查一下ConfigMap:

kubectl get configmap coredns -n kube-system -o yaml
最后说一句: 集群验证不是一次性的。每次升级、改配置后,都要重新验证一遍。我吃过这个亏,升级后没验证,结果线上出了故障。

好了,Kubernetes集群搭建就聊到这儿。下一章咱们聊聊Pod的调度策略,那又是一个大坑。

专注资料整理