TKE与ACK生产级运维实战:从节点池规划到集群升级排障指南

发布时间:2026/9/30 3:14:13
TKE与ACK生产级运维实战:从节点池规划到集群升级排障指南 接手过不少公有云上跑的Kubernetes集群腾讯云的TKE和阿里云的ACK占了大多数。前两天翻自己的运维笔记正好到第12章第2节写的就是这两个托管平台的生产级运维。网上聊自建kubeadm的教程一抓一把但真正在TKE、ACK上把集群玩明白、把线上事故摁下去的实战经验反而散得很。这篇就把我这些年攒下的选型思路、建集群时埋过的雷、排障链路、升级胆量训练一次性倒出来。正在用或者准备上TKE、ACK做生产环境的同学这套东西基本可以直接照着抄。先搞清楚自己用的是什么托管TKE与ACK的形态差异很多人一听托管集群就觉得万事大吉这是第一个误区。TKE和ACK的托管是分档位的选错了形态后面运维姿势完全是两码事。1.1 托管版、自管版与自建集群的取舍先看一张对比表形态 | 控制面Master谁运维 | 能否SSH到Master | 自定义组件参数 | 适合场景 自建kubeadm | 自己 | 可以 | 完全自由 | 想彻底掌控、愿意投入人力 TKE 独立集群 | 自己 | 可以 | 完全自由 | 需要自定义kube-apiserver参数 TKE 托管集群 | 腾讯云 | 不可以 | 受限 | 绝大多数生产业务 ACK Pro 托管 | 阿里云 | 不可以 | 受限 | 绝大多数生产业务 ACK 专有版 | 自己 | 可以 | 完全自由 | 合规要求必须自管Master生产环境我几乎无脑推荐托管版原因很简单控制面的高可用、etcd备份、apiserver异常恢复这些脏活云平台替你扛了。托管版出问题工单一发平台侧能直接查控制面组件状态比自己半夜爬Master节点强太多。但代价也得知道托管之后你上不了Master像自定义apiserver的审计策略、改controller-manager的某些启动参数平台控制台不开放就不行。所以如果你的团队有强烈的Control Plane定制需求或者等保合规明确要求运维人员可登录Master那就选自管版或干脆自建。提到自建我多说一句。网上搜kubeadm教程时常见这么一段输出[init] using kubernetes version: v1.26.0 [preflight] running pre-flight checks ... kubeadm join 192.168.1.10:6443 --token xxx \ --discovery-token-ca-cert-hash sha256:xxx很多人以为init跑完集群就自动完好实际上控制面初始化成功之后还需要手动把这些 join 命令复制到每个Worker节点上执行Worker才会加进来。这个环节漏了kubectl get node永远只有Master一个节点。托管集群没有这一步控制台添加节点就行但底层逻辑一样——节点加入是独立动作别把创建集群和节点就绪划等号。1.2 网络模型差异决定了你的排障姿势TKE和ACK在网络模型上的选择直接决定了以后排查问题的手段。TKE主要两种模式GlobalRouter基于VPC路由的容器网络Pod IP和Node IP同在一个VPC平面通过路由表转发性能和传统虚拟机网络接近排查时可以在VPC路由表里看到容器网段的路由条目。VPC-CNI含Cilium弹性网卡直连每个Pod一张ENI网络延迟最低安全组可以精细到Pod但可分配的Pod数量受节点规格和可用子网IP数量限制。ACK主要也是两种Flannel经典overlay网络VXLAN封装Pod网段与VPC网段隔离排查时容易遇到跨节点通信走隧道抓包要进隧道口看。Terway阿里云自研CNI基于ENI直连性能强支持Trunk弹性网卡同样存在IP资源上限问题。从运维视角看这两家有个共同规律网络模型 | Pod IP是否VPC内直接路由 | 排障关注点 Flannel/GlobalRouter路由表模式 | 部分隔离/路由可达 | 路由表、iptables规则、conntrack表 VPC-CNI/Terway ENI直连 | 直接可达 | 弹性网卡配额、安全组规则、子网IP余量我建议生产环境优先选ENI直连模式VPC-CNI或Terway性能好Pod IP和云资源互通方便安全组能直接管理Pod粒度。代价就是IP规划要精细很多搞不定的人工裁减问题实际是子网IP不够。选Flannel类overlay虽然IP压力小但排查网络问题时要多查一层封装conntrack满载、iptables规则膨胀这类坑够你喝一壶。1.3 节点的选择实例规格、系统盘、数据盘分开看节点选型不是越大越好。我见过有人一台64C256G裸奔跑所有业务最后单点爆炸。生产建议业务节点每台规格控制在8C16G到32C64G之间太大故障爆炸半径大太小Pod密度上不去浪费资源。系统盘和数据盘必须分开。系统盘用50GB左右的高效云盘起步数据盘挂独立的SSD/ESSD给容器运行时和镜像存储。默认40G系统盘跑生产一周爆满是常事。如果有GPU业务GPU节点单独建池不要和CPU业务混部。另外ACK的节点池和TKE的节点池逻辑类似都是一组配置相同的节点。我后面单独讲节点池设计但选型阶段的铁律是不同付费模式包年包月、按量、Spot、不同机型、不同标签用途的节点一定分开池子。建集群阶段就埋下的雷网络规划、节点池与权限集群创建只是半天的事但创建时填错的每个选项都会在半年后的某个凌晨变成事故。这个阶段最值得花时间的就三件事CIDR规划、节点池设计、权限边界。2.1 网段规划一段CIDR规划示例容器网段和VPC网段重叠是最低级的错误但真有人踩。Kubernetes里Service网段和Pod网段一旦定下来后期几乎不可能改只能重建集群。我常用的生产规划示例对象 | 网段 | 说明 VPC主网段 | 10.10.0.0/16 | 承载节点、SLB/NLB、数据库等云资源 Pod网段TKE GlobalRouter/ACK Flannel | 172.16.0.0/16 | 独立大网段和VPC不重叠 Service网段 | 172.16.128.0/17 | 从Pod网段中单独划出或云平台默认分配 节点子网 | 10.10.0.0/19、10.10.32.0/19 | 按可用区划分方便多AZ容灾给TKE的VPC-CNI或ACK的Terway设计时Pod子网要从VPC主网段里划比如10.10.128.0/18和10.10.192.0/18分别放在不同可用区。这时候有个容易被忽略的约束Terway/VPC-CNI创建Pod要占用VPC IP一个节点最大Pod数取决于弹性网卡能挂的辅助IP数量而不是你想跑多少跑多少。实例规格越大、单卡辅助IP越多Pod密度才越高。还有一点Service网段不要和VPC内任何网段重叠否则kube-proxy的ClusterIP会和云上资源IP冲突表现就是Pod里访问某个内网地址时通不通全看运气。2.2 节点池是生产集群的骨架节点池建得好扩缩容、升级、故障隔离都是点几个按钮的事。我通常按三个维度拆分维度 | 节点池划分 | 典型配置 业务维度 | 核心交易、通用业务、离线任务 | 不同规格核心业务独占池 付费维度 | 包年包月池、按量池、Spot池 | Spot池跑无状态可重放任务 调度维度 | 带污点池、无污点池 | 关键应用容忍度控制以ACK为例一个金融客户生产集群我会拆成core-production节点池包年包月c7系列8C32Gtaint专用、common-online节点池按量g7系列4C16G、spot-offline节点池抢占式实例跑批量计算、gpu-inference节点池GPU节点带NVIDIA污点。这样拆的好处Spot节点被回收只影响离线池不会把核心业务带走包年包月池打底按量池弹性兜底成本可控。TKE的节点池玩法一样腾讯云叫弹性伸缩节点池抢占式实例就叫竞价实例原理相通。创建节点池时的两个坑一定要给节点池打标签比如poolspot部署时通过nodeSelector指定调度目标否则调度器把关键Pod扔到Spot池就悲剧了。节点池的扩缩容阈值要结合集群剩余可分配量看别只盯着CPU。内存接近耗尽但CPU还有余量的情况非常普遍HPA和节点扩缩容都容易失灵。2.3 权限与安全组的最小化配置权限问题是最容易拖后腿的。TKE走CAMACK走RAM一开始就按最小权限建模后面省无数事。我的落地经验创建独立的服务角色TKE的QCloudTKE/ACK的AliyunCSDefaultRole不要让集群使用主账号默认角色。开启RAM Roles for PodsACK、OIDC联邦TKE让Pod通过云平台临时凭证访问OSS/COS等云资源而不是在代码里硬编码AccessKey。AK泄露调MFA、轮换密钥的痛真不想再经历第二次。RBAC按命名空间收敛给每个业务团队建独立Namespace和ServiceAccount绑定只对该Namespace的RoleClusterRole资源如节点查看权收紧到运维组。安全组方面节点安全组不要为了省事直接放通0.0.0.0/0的所有端口。至少要做到管控端口22、10250只对运维跳板机网段开放Pod网段的互访规则在VPC-CNI/Terway模式下通过Pod安全组控制节点连接SLB/NLB的健康检查端口要放通。TKE默认的安全组规则比较保守ACK的Terway模式对安全组依赖更强加白名单时一定要把Pod网段覆盖进去而不是只加节点IP。节点NotReady与Pod Pending一条能复现的排障链路集群出问题的前两大信号就是节点NotReady和Pod Pending。很多人一上来就重启节点治标不治本。我从告警触发开始讲完整的排查链路这部分可以当作标准作业程序直接收藏。3.1 Node NotReady从告警到根因的递进式排查生产环境我收到过无数次节点NotReady告警90%的根因集中在几个地方。按下面顺序排查基本不会漏先看云平台控制台的节点信息。TKE/ACK的节点列表里会显示NotReady的状态时间如果整批节点同时NotReady优先怀疑网络组件Terway/GlobalRouter/Cilium或集群升级操作单个节点异常优先怀疑节点自身。SSH登录节点第一件事看kubelet状态和服务日志systemctl status kubelet journalctl -u kubelet -f --since 10 minutes agokubelet的常见错误有几种证书过期、连接apiserver超时、容器运行时不可用。日志里说话很直白。 3. 检查容器运行时。现在默认都是containerdcrictl ps -a crictl images如果crictl执行卡住或报错基本就是容器运行时G了和kubelet本身无关。 4. 看磁盘和inodedf -h df -i注意看/var/lib/containerd和/var/lib/kubelet所在分区镜像堆积和数据盘写满是最常被忽视的元凶。df -h看着还有空间但inode满了也一样会挂。 5. 看内核和网络组件。Terway/GlobalRouter这类CNI如果有单独的Agent进程也要检查它们的日志。节点长时间NotReady还要看一眼内核日志里有无oom、panic。根因对照表症状特征 | 大概率根因 | 首次处理 kubelet日志大量node xxx not found | kubelet证书过期 | 过期时间确认后重签发证书或更新节点 crictl ps卡死docker进程异常 | containerd故障/镜像堆积 | 清理镜像必要时重启containerd df -h显示100%分区 | 数据盘满 | 清理/var/lib/containerd设置镜像GC策略 某安全组规则改动后集体NotReady | 安全组阻止kubelet连apiserver | 检查10250端口放通 节点实例被释放/抢占 | Spot节点回收 | 节点池自动扩容补位3.2 Pod Pendingkubectl describe里的信息怎么读Pod Pending的第一现场永远是describekubectl describe pod pod-name -n namespaceEvents字段里会直接告诉你调度失败原因。最常见的几类信息我翻译一下0/1 nodes are available: 1 Insufficient cpu。CPU不足看该节点是否被别的Pod打满或者请求值是否过大。0/1 nodes are available: 1 node(s) had untolerated taint。节点有污点Pod没配容忍。要问一句这个Pod真的不该跑在那台节点上吗还是忘了给容忍0/1 nodes are available: 1 node(s) didnt match Pods node affinity/selector。nodeSelector和节点标签不匹配。这是配节点池后最容易踩的坑标签打错或selector写错都是常事。no PersistentVolumes available for this claim。PV调度失败常见于云盘类型与可用区不匹配比如Pod调度到可用区A但静态PV的云盘在可用区B隔区就用不了。注意describe看Event但Event会滚动被顶掉就看不到了。我习惯先跑一遍kubectl describe pod xxx -n xxx | tail -30再叠加kubectl get events --sort-by.lastTimestamp -n xxx两条命令对着看基本能把Pending原因钉死。3.3 一次CPU Limit引发的雪崩复盘讲个真实事故。有个无状态网关服务YAML里写了resources.limits.cpu500m但业务高峰期单个Pod实际能跑到1.2核。Kubernetes对CPU Limit的压制导致Pod反复重启每次重启都有几十秒冷启动流量在Pod间抖来抖去节点CPU被反复打高触发了节点压力驱逐最后集群里一大片Pod变成Evicted。排查链条是这样的先是告警爆CrashLoopBackOffdescribe看到Liveness探针失败但log里业务日志又没异常只有OOMKilled字样然后看节点监控发现CPU使用率曲线是锯齿状最后翻到ResourceQuota和limit配置才发现是limit设得太死。这类坑的根本解法不是调大limit而是无状态服务尽量不设CPU limit靠HPA按CPU使用率扩缩容来兜底如果团队规范强制要limit那就用requests和limits分离限制值至少是稳定峰值的1.5倍配上PodDisruptionBudget防止节点排空时Pod被一波清掉。可观测性建设监控、日志与告警的实战配置生产集群没有可观测性等于裸奔。很多团队只依赖控制台自带的基础监控这是不够的。4.1 双轨监控云监控保底Prometheus做深度TKE和ACK控制台都自带云监控节点CPU、内存、负载均衡流量等这些是保底项零成本必须都开。但深度可观测性一定要上Prometheus。腾讯云有托管的Prometheus监控服务阿里云有ARMS Prometheus直接和TKE/ACK打通省去自己维护Thanos的麻烦。开好后至少要盯下面这些指标节点层CPU利用率、内存利用率、磁盘I/O、网络重传率容器层Pod内存RSS、CPU usage、restart次数集群层APIServer请求错误率、etcd磁盘延迟、ControllerManager队列深度业务层工作负载RPS、P99延迟、错误率、HPA当前副本数有一个容易被忽略的指标HPA的currentReplicas与desiredReplicas。扩不起来和缩不下去都是事故前兆。Prometheus探活Kubernetes组件时注意托管版的etcd和apiserver指标暴露点要按云平台文档配置不要照搬自建集群的serviceMonitor写法。TKE和ACK各自有对应的组件指标接入配置控制台上勾选即可。4.2 日志采集容器标准输出、文件日志与审计日志日志采集上TKE默认对接CLS日志服务ACK默认对接SLS。方案上比自建ELK省心不少但有几个配置细节标准输出日志用default采集配置就行正则按json_lines或single_line选好。应用写文件日志的场景容器里用emptyDir或hostPath挂载后采集路径要写到宿主机真实路径别写成容器内路径。CLS/SLS的日志采集Agent跑在节点上读不到容器内路径。多行日志比如Java堆栈一定要开多行处理正则否则一行异常堆栈会被拆成几十条日志。审计日志强烈建议开启。TKE控制台里有审计相关开关ACK也有集群审计功能把apiserver的审计日志接到日志服务安全合规和排障都能用。出过一次恶意操作后回头翻审计日志才知道是谁在什么时候改了关键Deployment——这种后悔药不是每次都买的到。4.3 告警规则设计与告警噪音治理告警规则设计有一条铁律每条告警都必须能对应一个可执行的处置动作。无法执行的告警不如不建。我通常把告警分三级级别 | 示例 | 响应方式 P0 | 节点NotReady超过5分钟、APIServer不可用、业务错误率突增 | 立即on-call15分钟内介入 P1 | PVC使用率超过85%、Pod反复重启、HPA扩缩容异常 | 工作时间内响应2小时内处理 P2 | 节点CPU持续超过75%、镜像堆积 | 记录跟踪日常优化告警渠道用Webhook接钉钉/企业微信/飞书分不同群。P0群永远有人值班P2只进日报群。TKE的监控告警和ACK的ARMS告警都支持配置分组、静默策略和通知周期一定要把非工作时间只发P0这种规则配上不然告警疲劳是必然的。集群升级与节点维护生产环境最考验人的操作升级是生产集群运维里最刺激的操作没有之一。控制面托管已经是云平台给你兜底但节点升级、业务Pod迁移仍是高危动作。5.1 升级前的检查清单无论TKE还是ACK升级前我必做这几件事查Kubernetes版本变更里的API弃用列表。不同版本会有API移除比如旧版本里CronJob用的batch/v1beta1、PodDisruptionBudget用的policy/v1beta1在新版本里直接不可用。升级前跑一下kubectl get --raw /openapi/v3 2/dev/null | head更直观的是用第三方工具比如pluto扫描集群里的API资源把已弃用和即将移除的API列出来逐个排查YAML。 2. 确认集群里的自定义Controller和Webhook与新版本兼容。特别是ValidatingWebhookConfiguration版本升级导致的webhook故障会直接阻塞Pod创建。 3. 备份关键YAML和PV数据。托管版不好直接备份etcd至少把Deployment、ConfigMap、Secret、ServiceAccount等核心资源用Velero或kubectl备份导出。有PV的数据库类服务升级前打好快照。 4. 提前阅读云平台升级文档中关于升级顺序和回滚入口的部分。TKE和ACK都要求先升级控制面再升级节点顺序反了会出兼容性问题。5.2 节点池滚动升级的实操步骤节点池滚动升级逻辑上就是三步隔离旧节点、排空Pod、替换新节点。具体操作在节点池配置里设好升级策略TKE可以设置最大不可用节点数ACK的节点池升级也有类似参数。我一般设maxUnavailable1一次只动一个节点。手动执行时按三条命令走kubectl cordon node-name kubectl drain node-name --ignore-daemonsets --delete-emptydir-datacordon是给节点打禁止调度标记drain是排空Pod。注意尽量加--ignore-daemonsetsDaemonSet的Pod会被重新调度不用强赶。 3. 云平台会重置或替换节点新节点起来后确认节点状态Ready、业务Pod迁移成功后再处理下一个。坑点提醒drain时遇到PodDisruptionBudget不允许驱逐命令会卡住。这是保护机制在工作别硬删Pod先看PDB配置是否过严。有状态应用StatefulSet的Pod排空时要注意PVC会不会因为节点迁移而失联。跨可用区的节点池升级云盘类型PVC会有问题。原地升级的节点不是替换drain后要等节点上的Pod完全终止再让平台触发升级动作。有些平台在节点未排空时会直接拒绝升级态度很明确。5.3 升级失败的回滚与自救节点升级失败的表现通常有两类新节点启动后NotReady或者业务Pod迁移后状态异常。先说预防每升级完一个节点池观察15到30分钟看节点Ready状态、业务错误率、Pod重启次数。没问题再动下一个池子。很多事故就是一口气把所有节点升完出了问题连回滚的立足之地都没有。回滚策略分两层云平台回滚TKE节点池有回滚操作能把节点池恢复到升级前版本。ACK的节点池也支持回滚到原先的Kubelet版本。前提是节点池还在、旧版本的节点模板没被删。手动自救如果平台回滚不了最稳的办法是用旧版本的节点池模板重新扩容节点把业务引到旧节点池再把新节点池缩容到零。前提是你在升级前没有把旧节点池模板删掉。升级之后etcd版本提升一般不可逆。所以升级前的备份不止是预防也是认赔的依据——真到了无法回滚的地步至少业务数据还在。网络与存储进阶Ingress、负载均衡与PV/PVC最后聊日常业务接触最多、也最容易出问题的网络入口和存储。6.1 入口流量选型CLB/ALB/NLB/Nginx Ingress很多团队创建完集群就把Service指名成LoadBalancer然后任由它堆满一堆公网SLB实例既不统一也不经济。生产入口流量我建议这样分层场景 | 推荐方案 | 说明 公网七层路由 | Nginx Ingress Controller 云负载均衡 | 路径路由、灰度发布、限流都靠Ingress规则 高性能七层网关 | ALBACK/ CLB IngressTKE | 托管网关性能好、免运维 四层高性能TCP/UDP | NLBACK/ CLB四层TKE | 数据库、RPC等不需要七层路由的场景 多集群统一入口 | 各自Ingress 上层GSLB/云DNS | 做流量调度、故障转移TKE上我把Nginx Ingress挂在CLB后面CLB只做流量引入真正的路由规则全部收敛到Ingress Controller。ACK上通常直接用ALB Ingress Controller省掉Nginx层配置也简单。注意Ingress Controller的副本数至少2个并开启反亲和跨可用区部署。另一个常被忽略的是Service的externalTrafficPolicy。想保留客户端真实IP要设置externalTrafficPolicy: Local但会让负载均衡只调度到有Pod的节点流量可能不均。Cluster模式下SNAT会让后端拿不到真实源IP。这个取舍要根据业务类型提前确定。6.2 存储方案选型与挂载避坑存储选型表存储类型 | 适用场景 | 注意点 云盘CBS/ESSD | 单Pod读写数据库 | 单可用区限制不能跨区挂载 NASCFS/NAS | 多Pod共享读写 | 性能受吞吐上限影响注意协议差异 对象存储COS/OSS | 静态文件、大数据分析 | 走内网endpoint公网流量贵且慢 本地盘 | 高吞吐缓存 | 节点故障数据丢仅限无状态三个高频坑同一块云盘挂多个Pod。常见于把PVC做成静态多个副本的Deployment都指定同一个PV结果第二个Pod起来就发现VolumeAlreadyInUse。云盘本质是块存储只支持单节点读写多副本场景老老实实换NAS或者用ReadWriteMany的云存储。PVC的storageClassName没配对。集群里有多套存储类ssd、essd、nfsPod不指定或指定错调度时PVC都是Pending。检查一下kubectl get sc把默认storageClass设置好。NAS挂载用错协议。TKE的CFS和ACK的NAS都有NFS和SMB协议Linux容器只能用NFS在StorageClass里配好协议即可。挂载后若出现文件锁问题检查nfsvers参数通常建议nfsvers4.0。6.3 备份与容灾Velero与跨集群迁移TKE和ACK都能用Velero做集群维度的备份。Velero可以把Namespace下的所有资源连同PV快照备份到对象存储恢复时一键拉起来。我的做法每天早上定时备份关键命名空间到COS/OSS数据库类Pod不依赖Velero的PV快照而是走业务层备份比如MySQL定时备份每个月做一次完整的恢复演练不只是备份成功就完事要真恢复出一个环境验证数据可读。跨集群迁移场景也一样TKE迁ACK或反过来Velero的备份文件格式统一资源定义可以平移。但要注意存储类映射TKE的CBS对应ACK的ESSD恢复时需要在Velero的StorageClass映射配置里指过去否则PVC起不来。最后说点不太中听的大实话托管集群不是买了保险它只是把你亲自运维Master换成了云平台帮你运维Master但节点、Pod、网络、存储、业务安全这些责任永远在自己手里。我见过太多人把TKE/ACK当黑盒出问题只会提单连describe都不跑最后明明是业务配置问题硬拖成P0事故。把这篇文章里提到的网段规划、节点池拆分、排障链路、升级清单落到自己的环境里比什么都强。这套东西不敢说让你从此零事故但至少能让事故来了的时候你手里有家伙、心里有底。