1. 为什么需要Kubernetes集群?
在当今云原生时代,Kubernetes(简称K8s)已经成为容器编排的事实标准。我最初接触Kubernetes是在2017年,当时我们团队正在将单体应用迁移到微服务架构。随着服务数量增加,手动管理Docker容器变得异常困难,这才意识到我们需要一个可靠的编排系统。
Kubernetes集群的核心价值在于:
- 自动化部署与扩展:只需一个命令或配置文件,就能完成应用的部署、回滚和水平扩展
- 资源高效利用:通过调度算法将容器合理分配到集群节点,提高硬件资源利用率
- 服务自愈能力:自动重启失败的容器、替换不可用的节点,保证服务持续可用
- 负载均衡与服务发现:内置DNS和负载均衡机制,简化微服务间的通信
提示:对于中小型企业,建议从3节点集群开始。生产环境至少需要3个master节点保证高可用,而开发环境可以只用1个master节省资源。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与前置条件
2.1 硬件需求
根据我的实践经验,不同规模的集群对硬件要求差异很大。以下是建议配置:
| 节点类型 | CPU | 内存 | 存储 | 网络 | 数量 |
|---|---|---|---|---|---|
| Master | 2核+ | 4GB+ | 20GB | 千兆 | 奇数个(≥3) |
| Worker | 4核+ | 8GB+ | 50GB | 千兆 | 按需 |
注意:etcd对磁盘I/O敏感,建议master节点使用SSD。我曾在一个机械硬盘的测试环境遇到etcd性能问题,导致集群频繁超时。
2.2 操作系统配置
在所有节点上执行以下操作:
bash复制# 关闭swap(Kubernetes 1.8+要求)
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 设置主机名解析
sudo tee -a /etc/hosts <<EOF
192.168.1.10 master1
192.168.1.11 worker1
192.168.1.12 worker2
EOF
# 加载内核模块
sudo tee /etc/modules-load.d/k8s.conf <<EOF
br_netfilter
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF
# 设置内核参数
sudo tee /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
3. 容器运行时安装与配置
Kubernetes支持多种容器运行时,我最常用的是containerd:
bash复制# 安装containerd
sudo apt-get update && sudo apt-get install -y containerd
# 生成默认配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# 修改配置启用systemd cgroup
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
# 重启服务
sudo systemctl restart containerd
sudo systemctl enable containerd
经验:我曾遇到containerd与特定Docker版本冲突的问题。如果之前安装过Docker,建议完全卸载(
sudo apt-get remove --purge docker-ce docker-ce-cli)后再安装containerd。
4. Kubernetes组件安装
4.1 安装kubeadm、kubelet和kubectl
bash复制# 添加apt仓库
sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
# 安装指定版本(这里以1.28为例)
sudo apt-get update && sudo apt-get install -y kubelet=1.28.0-00 kubeadm=1.28.0-00 kubectl=1.28.0-00
sudo apt-mark hold kubelet kubeadm kubectl
4.2 初始化Master节点
bash复制sudo kubeadm init \
--apiserver-advertise-address=192.168.1.10 \
--pod-network-cidr=10.244.0.0/16 \
--control-plane-endpoint=master1:6443 \
--upload-certs
初始化完成后会输出join命令,类似:
bash复制kubeadm join master1:6443 --token xxxx.xxxxxxxxxxxx \
--discovery-token-ca-cert-hash sha256:xxxxxxxx...
重要:务必保存这个join命令!我在一次生产部署时不小心关闭了终端,不得不重新初始化集群。
4.3 配置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
验证集群状态:
bash复制kubectl get nodes
# 应该看到master节点状态为NotReady(因为还没装网络插件)
5. 网络插件安装
我推荐使用Calico,它在性能和功能上都有不错的表现:
bash复制kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
等待几分钟后检查:
bash复制kubectl get pods -n kube-system
# 应该看到calico相关的pod都Running
kubectl get nodes
# 节点状态应该变为Ready
踩坑记录:我曾在一个金融项目中使用Flannel,但遇到与某些安全策略冲突的问题。Calico支持更细粒度的网络策略,适合安全要求高的环境。
6. Worker节点加入集群
在每个worker节点上执行之前保存的join命令:
bash复制sudo kubeadm join master1:6443 --token xxxx.xxxxxxxxxxxx \
--discovery-token-ca-cert-hash sha256:xxxxxxxx...
验证节点加入:
bash复制kubectl get nodes -w
# 应该看到所有节点状态都是Ready
7. 集群验证与测试
7.1 部署测试应用
bash复制kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get svc nginx
访问测试:
bash复制curl http://<任意节点IP>:<NodePort>
# 应该看到nginx欢迎页
7.2 检查核心组件
bash复制kubectl get pods -n kube-system
# 应该看到以下关键组件运行正常:
# - coredns
# - kube-apiserver
# - kube-controller-manager
# - kube-proxy
# - kube-scheduler
# - calico/etcd(如果使用Calico)
8. 生产环境增强配置
8.1 证书自动续期
Kubernetes证书默认1年有效期,配置自动续期:
bash复制sudo sed -i 's|KUBELET_KUBECONFIG_ARGS=.*|KUBELET_KUBECONFIG_ARGS="--kubeconfig=/etc/kubernetes/kubelet.conf --rotate-certificates=true"|g' /var/lib/kubelet/kubeadm-flags.env
sudo systemctl restart kubelet
8.2 监控与日志
安装Prometheus Operator:
bash复制kubectl create namespace monitoring
kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/main/bundle.yaml
8.3 存储配置
安装CSI驱动(以NFS为例):
bash复制git clone https://github.com/kubernetes-csi/csi-driver-nfs.git
cd csi-driver-nfs
kubectl apply -f deploy/example/nfs-provisioner/
9. 常见问题排查
9.1 节点NotReady
检查步骤:
bash复制# 查看节点详情
kubectl describe node <节点名>
# 常见原因:
# 1. 网络插件未正常运行
# 2. kubelet服务异常
# 3. 节点资源不足
# 查看kubelet日志
journalctl -u kubelet -f
9.2 Pod一直Pending
bash复制kubectl describe pod <pod名>
# 常见原因:
# 1. 资源不足
# 2. 没有满足条件的节点(如节点selector不匹配)
# 3. PV/PVC问题
9.3 网络不通
检查Calico:
bash复制kubectl get felixconfiguration -o yaml
kubectl logs -n kube-system <calico-pod名>
我在实际运维中发现,90%的网络问题都与防火墙或安全组配置有关。建议检查:
- 节点间的6443、2379-2380、10250等端口是否开放
- 是否允许Pod CIDR和Service CIDR的通信
10. 集群维护最佳实践
- 定期备份etcd:
bash复制sudo ETCDCTL_API=3 etcdctl \
--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 \
snapshot save /opt/etcd-backup-$(date +%F).db
- 节点维护:
bash复制# 安全驱逐节点上的pod
kubectl drain <节点名> --ignore-daemonsets --delete-emptydir-data
# 维护完成后重新调度
kubectl uncordon <节点名>
- 版本升级策略:
- 先升级kubectl,再升级kubeadm
- 逐个升级master节点(确保etcd集群健康)
- 最后升级worker节点
- 每次只升级一个次要版本(如1.26→1.27)
我在过去三年管理过十几个Kubernetes集群,最大的经验是:文档和自动化是关键。建议:
- 使用Git管理所有k8s manifest
- 用Terraform或Ansible自动化集群部署
- 详细记录每次变更和问题处理过程
