在云计算和容器化技术普及的今天,Kubernetes(简称K8s)已成为容器编排领域的事实标准。作为一名长期从事基础设施运维的工程师,我经常需要在CentOS环境下部署生产级Kubernetes集群。与Ubuntu等发行版相比,CentOS因其稳定性和企业级支持特性,成为许多传统企业首选的部署平台。本文将详细记录我在CentOS 7/8系统上部署高可用Kubernetes集群的完整过程,重点分享那些官方文档中不会提及的实战技巧和避坑经验。
这个部署方案适用于需要构建本地开发环境或生产环境的技术团队,特别是那些受限于监管要求必须使用CentOS的金融机构、政府单位等传统行业用户。通过本文,您将获得一个经过实战检验的、可直接复用的部署方案,包含网络插件选型建议、系统参数调优、证书管理策略等关键内容。
对于测试环境,我建议至少准备:
生产环境则需要根据实际负载评估,但有几个黄金法则:
重要提示:CentOS 8已停止维护,建议使用CentOS Stream或迁移至兼容的RHEL替代方案。本文示例基于CentOS 7.9,但核心步骤同样适配其他RHEL系发行版。
在所有节点执行以下初始化操作:
bash复制# 关闭SELinux(生产环境需评估安全需求)
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
# 关闭防火墙(或按需开放端口)
systemctl stop firewalld
systemctl disable firewalld
# 加载内核模块
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
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
vm.swappiness = 0
EOF
sysctl --system
我推荐使用containerd而非Docker作为运行时,因其更轻量且CNCF原生支持:
bash复制# 安装containerd
yum install -y containerd.io
mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
systemctl enable --now containerd
# 配置crictl(kubeadm依赖)
cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
在所有节点执行:
bash复制cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
# 安装指定版本(示例使用1.25.x稳定版)
yum install -y kubelet-1.25.5 kubeadm-1.25.5 kubectl-1.25.5 --disableexcludes=kubernetes
systemctl enable --now kubelet
选择一台作为首个Master节点执行:
bash复制kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=<MASTER_IP> \
--control-plane-endpoint=<LOAD_BALANCER_IP>:6443 \
--upload-certs \
--image-repository registry.aliyuncs.com/google_containers
关键参数说明:
--control-plane-endpoint:高可用集群必填,指向负载均衡器IP--image-repository:使用国内镜像源加速下载--upload-certs:自动生成并分发证书初始化成功后,记下输出的kubeadm join命令,后续节点需要用到。
Flannel是最简单稳定的选择:
bash复制kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
对于需要更高性能的场景,建议Calico:
bash复制kubectl create -f https://projectcalico.docs.tigera.io/manifests/tigera-operator.yaml
kubectl create -f https://projectcalico.docs.tigera.io/manifests/custom-resources.yaml
在每个Worker节点执行Master初始化时输出的join命令:
bash复制kubeadm join <LOAD_BALANCER_IP>:6443 \
--token <TOKEN> \
--discovery-token-ca-cert-hash sha256:<HASH>
bash复制# 查看节点状态
kubectl get nodes -o wide
# 检查核心组件状态
kubectl get pods -n kube-system
# 测试DNS解析
kubectl run -it --rm --restart=Never busybox --image=busybox -- nslookup kubernetes.default
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| kubelet不断重启 | 系统资源不足/配置错误 | 检查/var/log/messages,确保内存swap关闭 |
| Pod网络不通 | 网络插件未正确安装 | 重新应用网络插件manifest,检查iptables规则 |
| 镜像拉取失败 | 国内网络限制 | 配置国内镜像仓库或使用代理 |
kubelet配置:
bash复制# 在/var/lib/kubelet/config.yaml增加:
evictionHard:
memory.available: "500Mi"
nodefs.available: "10%"
maxPods: 150
API Server参数:
bash复制# 修改/etc/kubernetes/manifests/kube-apiserver.yaml
- --default-not-ready-toleration-seconds=30
- --default-unreachable-toleration-seconds=30
ETCD调优:
bash复制# 在/etc/kubernetes/manifests/etcd.yaml增加:
- --auto-compaction-retention=8h
- --quota-backend-bytes=8589934592
K8s默认证书有效期为1年,配置自动续期:
bash复制# 修改kube-controller-manager配置
- --experimental-cluster-signing-duration=87600h
- --feature-gates=RotateKubeletServerCertificate=true
创建/etc/kubernetes/audit-policy.yaml:
yaml复制apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
resources:
- group: ""
resources: ["secrets", "configmaps"]
然后在kube-apiserver配置中添加:
bash复制- --audit-policy-file=/etc/kubernetes/audit-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit.log
为Master节点添加污点防止调度工作负载:
bash复制kubectl taint nodes <master-node> node-role.kubernetes.io/master:NoSchedule
对于特殊硬件节点(如GPU):
bash复制kubectl label nodes <node-name> accelerator=nvidia-tesla-v100
kubectl taint nodes <node-name> special=true:NoSchedule
在部署应用时,可以通过affinity配置实现智能调度:
yaml复制affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: accelerator
operator: In
values:
- nvidia-tesla-v100
升级kubeadm:
bash复制yum install -y kubeadm-1.26.0 --disableexcludes=kubernetes
kubeadm upgrade plan
kubeadm upgrade apply v1.26.0
升级节点组件:
bash复制# 逐个节点执行
kubectl drain <node> --ignore-daemonsets
yum install -y kubelet-1.26.0 kubectl-1.26.0
systemctl restart kubelet
kubectl uncordon <node>
使用etcdctl备份集群状态:
bash复制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 snapshot.db
恢复时:
bash复制kubeadm reset
ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \
--data-dir /var/lib/etcd-from-backup
# 修改/etc/kubernetes/manifests/etcd.yaml指向新数据目录
经过数十次集群部署实践,我总结出几个关键经验点:
网络方案选择:
存储方案:
监控体系:
安全加固:
最后特别提醒:CentOS 7默认的3.10内核对K8s支持有限,建议升级到4.x以上内核以获得更好的容器性能:
bash复制yum install -y kernel-lt
grub2-set-default 0
reboot