1. 为什么需要自己搭建Kubernetes集群
在云原生时代,Kubernetes已经成为容器编排的事实标准。虽然各大云厂商都提供了托管版Kubernetes服务,但自己动手搭建集群仍然是每个DevOps工程师和云原生开发者的必修课。通过手动搭建,你能够:
- 深入理解Kubernetes的架构原理和组件交互
- 掌握集群网络、存储等核心配置的底层细节
- 为后续的故障排查和性能优化打下坚实基础
- 在本地开发环境或私有云中灵活部署应用
我见过太多团队直接使用托管服务,遇到问题就束手无策。这份指南将带你从零开始,用最少的硬件资源(3台2核4G的虚拟机就足够)搭建一个生产可用的集群。过程中我会分享5年来在金融、电商等多个行业落地Kubernetes的实战经验。
2. 环境准备与系统配置
2.1 硬件与操作系统要求
建议使用以下最小化配置:
- 控制平面节点:2核CPU/4GB内存/50GB磁盘
- 工作节点:2核CPU/4GB内存/100GB磁盘
- 操作系统:Ubuntu 20.04 LTS或CentOS 7/8
注意:生产环境建议至少3个控制平面节点实现高可用,本文为简化演示使用单控制平面。
2.2 系统基础配置
在所有节点执行以下操作:
bash复制# 关闭swap
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 设置主机名
sudo hostnamectl set-hostname k8s-master # 在master节点
sudo hostnamectl set-hostname k8s-node1 # 在worker节点
# 将主机名写入hosts
cat <<EOF | sudo tee -a /etc/hosts
192.168.1.100 k8s-master
192.168.1.101 k8s-node1
EOF
# 加载内核模块
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
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
2.3 容器运行时安装
Kubernetes 1.24+默认不再支持Docker,我们选择containerd:
bash复制# 安装依赖
sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
# 添加Docker仓库(containerd由Docker提供)
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# 安装containerd
sudo apt-get update && sudo apt-get install -y containerd.io
# 配置containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
3. Kubernetes组件安装与集群初始化
3.1 安装kubeadm、kubelet和kubectl
在所有节点执行:
bash复制# 添加Kubernetes仓库
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
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
sudo apt-get install -y kubelet=1.25.0-00 kubeadm=1.25.0-00 kubectl=1.25.0-00
sudo apt-mark hold kubelet kubeadm kubectl
3.2 初始化控制平面
在master节点执行:
bash复制sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=192.168.1.100 \
--kubernetes-version=1.25.0
成功后会输出join命令,类似:
bash复制kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
配置kubectl:
bash复制mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
3.3 安装网络插件
选择Flannel作为CNI插件:
bash复制kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
验证核心组件状态:
bash复制kubectl get pods -n kube-system
应该看到coredns、kube-proxy等组件处于Running状态。
3.4 加入工作节点
在每个worker节点执行前面输出的join命令:
bash复制sudo kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
在master节点验证节点状态:
bash复制kubectl get nodes
几分钟后应该看到所有节点状态变为Ready。
4. 关键配置与生产级优化
4.1 证书管理与自动续期
默认证书有效期只有1年,配置自动续期:
bash复制# 检查证书有效期
kubeadm certs check-expiration
# 更新所有证书
sudo kubeadm certs renew all
# 配置自动续期
sudo apt-get install -y cron
echo "0 0 1 * * root kubeadm certs renew all && systemctl restart kubelet" | sudo tee /etc/cron.d/k8s-cert-renew
4.2 控制平面高可用(可选)
生产环境建议至少3个控制平面节点:
- 在第一台master初始化时添加--control-plane-endpoint参数:
bash复制sudo kubeadm init --control-plane-endpoint "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT" ...
- 在其他控制平面节点执行:
bash复制sudo kubeadm join LOAD_BALANCER_DNS:LOAD_BALANCER_PORT --token ... \
--discovery-token-ca-cert-hash ... \
--control-plane --certificate-key ...
4.3 节点资源预留
防止系统进程资源不足:
bash复制# 在/var/lib/kubelet/config.yaml添加
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
evictionHard:
memory.available: "500Mi"
nodefs.available: "10%"
systemReserved:
cpu: "500m"
memory: "500Mi"
然后重启kubelet:
bash复制sudo systemctl daemon-reload
sudo systemctl restart kubelet
5. 常见问题排查指南
5.1 节点NotReady状态排查
- 检查kubelet日志:
bash复制journalctl -u kubelet -f
- 常见原因:
- 网络插件未正确安装:重新应用CNI manifest
- 容器运行时异常:
systemctl status containerd - 资源不足:检查内存/磁盘空间
5.2 Pod一直处于Pending状态
- 查看事件详情:
bash复制kubectl describe pod <pod-name>
- 常见原因:
- 资源请求超过节点可用资源
- 没有满足节点选择器/亲和性规则
- PV/PVC问题(如果使用存储卷)
5.3 网络连通性问题
- 检查基础连通性:
bash复制# 从pod内测试
kubectl run -it --rm --image=alpine test -- sh
ping <另一个pod的IP>
- 检查CNI插件:
bash复制# 查看CNI插件pod日志
kubectl logs -n kube-system <flannel-pod-name>
6. 下一步学习建议
集群搭建只是Kubernetes之旅的第一步,建议后续重点学习:
- 工作负载管理:Deployment、StatefulSet、DaemonSet的区别与使用场景
- 服务暴露:Service的ClusterIP、NodePort、LoadBalancer类型
- 存储管理:PV/PVC原理与常用存储插件
- 安全加固:RBAC配置、NetworkPolicy、Pod安全策略
- 监控告警:Prometheus+Grafana监控体系搭建
我在生产环境中发现,90%的Kubernetes问题都源于对基础原理理解不深。建议定期执行kubeadm reset然后重新搭建集群,直到整个过程完全不需要查阅文档。这种肌肉记忆式的练习,能让你在真正遇到问题时快速定位原因。