ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Linux集群搭建踩坑实录:3步搞定高可用完整示例

Linux集群搭建踩坑实录:3步搞定高可用完整示例 Linux集群搭建踩坑实录:3步搞定高可用完整示例 刚把K8s从v1.24升到v1.28,我盯着终端里满屏的unknown flag: --insecure-port和apiVersion v1 not found,脑子嗡的一声:版本升级后 API 全变了。 别慌,这种“升级即崩溃”的噩梦,90%是因为没理清底层依赖。今天不讲虚的,直接上我压箱底的linux集群搭建实战方案。这不是一篇泛泛而谈的教程,而是一套经过生产环境验证的完整示例,专治各种“环境不一致”疑难杂症。 项目目标与环境规划 在敲第一行命令前,先明确我们要构建什么。本次目标不是简单的“跑起来”,而是构建一个高可用、可复现、易于维护的3节点Linux集群(1 Master + 2 Worker)。 很多新手喜欢用Docker直接拉镜像,但在生产级集群搭建中,裸机或VMware虚拟机的二进制安装方式更稳定,且能深入理解组件交互。我们基于CentOS 7.9(RHEL兼容系)进行演示,因为企业存量机器中,CentOS占比依然极高。 核心指标定义:高可用:Master节点故障时,集群自动切换;Worker节点宕机,Pod自动迁移。 网络隔离:Pod网络与主机网络隔离,使用Calico CNI实现跨节点通信。 持久化存储:本地PV绑定,确保数据不随Pod重建丢失。硬件与网络规划表:节点角色 IP地址 主机名 CPU/内存 职责描述Master 192.168.10.11 k8s-master 2C/4G 控制平面:kube-apiserver, etcdWorker1 192.168.10.12 k8s-worker1 2C/4G 工作节点:运行业务PodWorker2 192.168.10.13 k8s-worker2 2C/4G 工作节点:运行业务Pod关键前提: 所有节点必须关闭防火墙和SELinux,这是集群通信的基础。如果忽略这一步,后续排查网络不通的问题会浪费你至少半天时间。 # 所有节点执行 systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config目录结构与基础依赖初始化 在开始安装K8s组件前,我们需要搭建一个标准的目录结构。良好的目录规划是后续运维的基石,避免配置文件散落在系统各处。 标准目录规划:/opt/k8s/:存放所有K8s二进制文件(kubectl, kube-apiserver, kubelet等)。 /etc/kubernetes/:存放所有YAML配置文件和证书。 /var/lib/kubelet/:kubelet的工作目录。 /var/lib/etcd/:etcd的数据存储目录(仅Master节点)。第一步:安装Container Runtime K8s 1.28已移除Docker作为默认运行时,转向Containerd。这里我们使用Containerd 1.7.x版本。 # 1. 下载Containerd二进制包 (以1.7.11为例) cd /opt wget https://github.com/containerd/containerd/releases/download/v1.7.11/containerd-1.7.11-linux-amd64.tar.gz tar -zxvf containerd-1.7.11-linux-amd64.tar.gz cp bin/containerd* /usr/local/bin/# 2. 初始化Containerd配置 containerd config default /etc/containerd/config.toml# 3. 关键修改:启用systemd cgroup driver # 编辑 /etc/containerd/config.toml # 找到 [plugins.io.containerd.grpc.v1.cri.containerd.runtimes.runc.options] # 添加或修改: SystemdCgroup = true为什么必须改SystemdCgroup? Kubelet默认使用Systemd作为cgroup driver,而Containerd默认是cgroupfs。两者不一致会导致Pod启动失败,报错failed to create shim task: OCI runtime create failed。这是我在生产环境中遇到的最高频报错之一。 第二步:安装Kubernetes二进制文件 这里我选择从官方源码仓库发布的二进制包,而不是使用yum源。原因有二:yum源中的K8s包版本更新滞后,且经常与特定Linux内核版本存在兼容性问题。 二进制安装允许我们精确控制版本,便于灰度升级和回滚。# 1. 创建K8s安装目录 mkdir -p /opt/k8s cd /opt/k8s# 2. 下载指定版本 (以1.28.3为例,需与etcd版本匹配) # 注意:请根据实际网络情况选择镜像源,此处以GitHub为例 wget https://dl.k8s.io/v1.28.3/kubernetes-server-linux-amd64.tar.gz tar -zxvf kubernetes-server-linux-amd64.tar.gz cp kubernetes/server/bin/* /opt/k8s/ chmod +x /opt/k8s/*# 3. 添加环境变量 echo 'export PATH=$PATH:/opt/k8s' /etc/profile source /etc/profile验证安装: 执行kubectl version --client,如果输出版本信息,说明二进制文件安装成功。此时不要高兴太早,这只是客户端工具,服务端还没配置。 核心代码实现:Master节点初始化 Master节点是集群的大脑,负责存储集群状态、调度Pod、处理API请求。核心组件包括kube-apiserver、kube-scheduler、kube-controller-manager和etcd。 1. 生成ETCD证书 ETCD是K8s的唯一数据源,安全性至关重要。我们需要为ETCD生成CA、Server和Client证书。 # 安装cfssl工具 wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 mv cfssl_linux-amd64 /usr/local/bin/cfssl wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 mv cfssljson_linux-amd64 /usr/local/bin/cfssljson# 创建证书目录 mkdir -p /etc/kubernetes/ssl cd /etc/kubernetes/ssl# 生成CA证书 cat ca-config.json EOF {signing: {default: {usages: [signing, key encipherment, server auth, client auth],expiry: 87600h}} } EOFcat ca-csr.json EOF {CN: k8s,key: {algo: rsa,size: 2048},names: [{C: CN,ST: Beijing,L: Beijing,O: k8s,OU: System}] } EOFcfssl gencert -ca=ca-csr.json -cakey=ca-key.pem -config=ca-config.json -profile=kubernetes ca-csr.json | cfssljson -bare ca2. 生成ETCD Server证书 # 生成Server证书,SAN需包含Master IP和主机名 cat etcd-csr.json EOF {CN: etcd,hosts: [192.168.10.11,k8s-master,127.0.0.1],key: {algo: rsa,size: 2048},names: [{C: CN,ST: Beijing,L: Beijing,O: k8s,OU: System}] } EOFcfssl gencert -ca=ca.pem -cakey=ca-key.pem -config=ca-config.json -profile=kubernetes etcd-csr.json | cfssljson -bare etcd3. 生成Kubernetes组件证书 这里有一个高频踩坑点:kube-apiserver的证书SAN中,必须包含所有可能访问API Server的IP和域名,包括Master IP、Node IP、Service CIDR网段、Pod CIDR网段。漏掉任何一个,都会导致对应的组件无法连接API Server。 # 生成kube-apiserver证书 cat kubernetes-csr.json EOF {CN: kube-apiserver,hosts: [127.0.0.1,192.168.10.11,192.168.10.12,192.168.10.13,10.0.0.1,kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,10.0.0.1],key: {algo: rsa,size: 2048},names: [{C: CN,ST: Beijing,L: Beijing,O: k8s,OU: System}] } EOFcfssl gencert -ca=ca.pem -cakey=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kube-apiserver4. 配置Kubelet Kubelet是每个节点上的代理,负责管理Pod的生命周期。我们需要为每个节点生成独立的Kubelet证书,因为Kubelet需要通过证书向API Server注册节点。 # 在Master节点上,为Worker1生成Kubelet证书 # 注意:CN必须是node,O必须是system:nodes,这是K8s内置的RBAC规则要求 cat worker1-kubelet-csr.json EOF {CN: node,hosts: [192.168.10.12],key: {algo: rsa,size: 2048},names: [{C: CN,ST: Beijing,L: Beijing,O: system:nodes,OU: System}] } EOFcfssl gencert -ca=ca.pem -cakey=ca-key.pem -config=ca-config.json -profile=kubernetes worker1-kubelet-csr.json | cfssljson -bare worker1-kubelet5. 启动ETCD ETCD是集群状态的数据源,必须确保其数据持久化且配置正确。 # 创建systemd服务文件 cat /etc/systemd/system/etcd.service EOF [Unit] Description=etcd Documentation=https://github.com/etcd-io/etcd[Service] Type=notify User=etcd ExecStart=/opt/k8s/etcd \--name k8s-master \--cert-file=/etc/kubernetes/ssl/etcd.pem \--key-file=/etc/kubernetes/ssl/etcd-key.pem \--peer-cert-file=/etc/kubernetes/ssl/etcd.pem \--peer-key-file=/etc/kubernetes/ssl/etcd-key.pem \--trusted-ca-file=/etc/kubernetes/ssl/ca.pem \--peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \--initial-advertise-peer-urls https://192.168.10.11:2380 \--listen-peer-urls https://192.168.10.11:2380 \--advertise-client-urls https://192.168.10.11:2379 \--listen-client-urls https://192.168.10.11:2379 \--initial-cluster k8s-master=https://192.168.10.11:2380 \--initial-cluster-token etcd-k8s-initial-cluster \--initial-cluster-state new \--data-dir=/var/lib/etcd Restart=on-failure RestartSec=5 LimitNOFILE=65536[Install] WantedBy=multi-user.target EOF# 创建etcd用户和目录 useradd -ms /sbin/nologin -U etcd mkdir -p /var/lib/etcd chown etcd:etcd /var/lib/etcd# 启动ETCD systemctl daemon-reload systemctl start etcd systemctl enable etcd验证ETCD状态: /opt/k8s/etcdctl --endpoints=https://127.0.0.1:2379 \--cacert=/etc/kubernetes/ssl/ca.pem \--cert=/etc/kubernetes/ssl/etcd.pem \--key=/etc/kubernetes/ssl/etcd-key.pem \endpoint health如果返回{health:true,...},说明ETCD工作正常。 运行与测试:Worker节点加入集群 Master节点配置完成后,我们需要将Worker节点加入集群。Worker节点不需要运行ETCD和调度器,只需运行kubelet和kube-proxy。 1. 分发证书 将Master节点上生成的CA证书和Worker节点专用的Kubelet证书复制到Worker节点。 # 在Master节点执行 scp /etc/kubernetes/ssl/ca.pem /etc/kubernetes/ssl/ca-key.pem \/etc/kubernetes/ssl/worker1-kubelet.pem \/etc/kubernetes/ssl/worker1-kubelet-key.pem \root@192.168.10.12:/etc/kubernetes/ssl/2. 配置Kubelet Kubelet的配置文件kubelet-config.yaml是关键。这里有一个版本升级后的重大变化:apiVersion从v1变为了v1beta1,且部分字段名称发生了改变。 # /etc/kubernetes/kubelet-config.yaml apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration address: 0.0.0.0 authentication:anonymous:enabled: falsewebhook:cacheTTL: 2m0senabled: truex509:clientCAFile: /etc/kubernetes/ssl/ca.pem authorization:mode: Webhookwebhook:cacheAuthorizedTTL: 10m0scacheUnauthorizedTTL: 2m0s cgroupDriver: systemd clusterDNS:- 10.0.0.10 clusterDomain: cluster.local evictionHard:imagefs.available: 10%memory.available: 100Minodefs.available: 10%nodefs.inodesFree: 5% maxPods: 110 rotateCertificates: true serverTLSBootstrap: true3. 启动Kubelet # 创建systemd服务文件 cat /etc/systemd/system/kubelet.service EOF [Unit] Description=Kubelet After=network.target After=docker.service[Service] WorkingDirectory=/var/lib/kubelet ExecStart=/opt/k8s/kubelet \--config=/etc/kubernetes/kubelet-config.yaml \--kubeconfig=/etc/kubernetes/kubelet-kubeconfig.yaml \--container-runtime-endpoint=unix:///run/containerd/containerd.sock Restart=on-failure RestartSec=5[Install] WantedBy=multi-user.target EOFsystemctl daemon-reload systemctl start kubelet systemctl enable kubelet4. 验证节点状态 在Master节点上执行: kubectl get nodes如果看到k8s-worker1状态为Ready,说明Worker节点成功加入集群。 常见报错排查:node.k8s.io not found:检查Kubelet证书是否正确,O字段是否为system:nodes。 failed to get node info:检查API Server证书SAN中是否包含Worker节点IP。 container runtime is down:检查Containerd服务是否启动,以及SystemdCgroup配置是否一致。优化扩展:网络与存储配置 集群节点加入后,还需要配置Pod网络(CNI)和Service网络,否则Pod之间无法通信。 1. 安装Calico CNI Calico是K8s中最流行的CNI插件之一,支持BGP路由,性能优异。 # 下载Calico配置 kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml2. 配置Service网络 K8s的Service IP范围是虚拟的,需要确保不与Pod网络冲突。我们使用10.96.0.0/12作为Service CIDR。 3. 性能优化建议Kubelet内存限制:在生产环境中,建议为Kubelet设置内存限制,防止其OOM导致节点失联。 ETCD磁盘IO:ETCD对磁盘IO敏感,建议使用SSD,并设置fsync参数为true,确保数据持久化。 日志轮转:K8s组件日志会迅速增长,建议配置Logrotate,避免磁盘写满。# /etc/logrotate.d/kubernetes /opt/k8s/*.log {dailymissingokrotate 7compressdelaycompressnotifemptycreate 0640 root rootsharedscriptspostrotate/opt/k8s/kubelet --config=/etc/kubernetes/kubelet-config.yamlendscript }4. 监控与告警 裸机集群搭建后,建议接入Prometheus + Grafana进行监控。至少监控以下指标:Node CPU/Memory/磁盘使用率 Pod重启次数 ETCD集群健康状态 API Server请求延迟小结 本文提供了一套从零开始、基于二进制安装的linux集群搭建完整示例。我们不仅完成了基础环境的初始化,还深入讲解了证书生成、Kubelet配置、CNI安装等核心环节。 关键回顾:版本一致性:Kubelet、Kube-apiserver、Kubectl版本必须一致或相差一个次版本。 cgroup驱动统一:Containerd和Kubelet必须使用相同的cgroup driver(推荐systemd)。 证书SAN配置:API Server证书的SAN必须包含所有可能的访问IP和域名,这是通信正常的关键。 官方源码仓库:在版本升级或遇到未知Bug时,查阅官方源码仓库和Release Notes是解决问题的最快路径,不要依赖过时的博客教程。集群搭建只是第一步,真正的挑战在于后续的运维、升级和故障排查。版本升级后API全变是常态,保持对官方文档的持续关注,才是避免踩坑的根本。 你在项目里踩过这个坑吗?评论区聊聊
返回列表