资讯动态

Day59-阿里云ACK实战:生产级K8s集群部署与运维

发布时间:2026/8/26 18:59:54 来源:尧图企业网站定制
一、为什么不是自建 K8s而是 ACK前两篇文章我们用kind和minikube在本地跑通了 K8s也用kubectl apply部署了 Spring Boot 应用。但真正上生产你面临一个选择自建 K8s 还是用云厂商托管我先把结论放这儿除非你有特殊合规要求或极端成本敏感否则选托管。维度自建 K8sACK 托管版Master 节点自己搭 3 台 etcd kube-apiserver挂了自己修阿里云托管SLA 99.95%版本升级自己 drain、升级、回滚一个周末没了控制台一键升级自动兼容检查证书轮换手动生成 kubelet 证书过期了集群直接挂自动轮换无感知安全补丁自己跟踪 CVE手动打补丁云安全中心自动告警修复建议运维人力至少 2 个专职 SRE1 个兼职 DevOps 搞定自建 K8s 的隐藏成本极高。一个 3 Master 的集群光是 etcd 备份策略、证书过期监控、apiserver 调优这些活儿就能吃掉一个 SRE 大半精力。ACK 托管版把这些全包了你只管 Worker 节点。ACK 目前有三种形态ACK 托管版Pro/Pro 版Master 免费托管按 Worker 节点付费。绝大多数团队选这个。ACK Serverless连 Worker 都不用管按 Pod 付费。适合突发流量场景冷启动稍慢。ACK 专有版Master 也自己管但用阿里云的 IaaS。极端合规需求才用。下面以ACK Pro 托管版为主线讲生产级集群的落地流程。二、集群创建那些控制台不会告诉你的坑2.1 网络规划——最容易被忽略的前置工作创建集群前先规划 VPC 和交换机。这是最容易被忽略的一步但一旦搞错后期迁移成本极高。# 用 aliyun CLI 创建 VPC 和交换机也可在控制台操作 # 创建 VPC aliyun vpc CreateVpc \ --RegionId cn-hangzhou \ --CidrBlock 10.0.0.0/8 \ --VpcName k8s-prod-vpc ​ # 拿到 VpcId 后创建两个交换机跨可用区高可用 aliyun vpc CreateVSwitch \ --RegionId cn-hangzhou \ --ZoneId cn-hangzhou-h \ --CidrBlock 10.0.1.0/24 \ --VpcId vpc-xxx \ --VSwitchName k8s-prod-sw-h ​ aliyun vpc CreateVSwitch \ --RegionId cn-hangzhou \ --ZoneId cn-hangzhou-i \ --CidrBlock 10.0.2.0/24 \ --VpcId vpc-xxx \ --VSwitchName k8s-prod-sw-i三条铁律Pod 网段和 Service 网段不能跟 VPC 网段重叠。ACK 默认 Pod 用192.168.0.0/16Service 用172.21.0.0/20如果跟你的 VPC 冲突一定要改。至少两个可用区的交换机。单可用区一旦机房故障整个集群直接没了。交换机网段留足余量。一个/24只有 254 个 IP中型集群很快耗尽建议/20起步。2.2 集群参数配置创建集群时有几个参数必须按生产标准配# ACK 集群创建关键参数控制台 / Terraform 均可配置 # 这里用 Terraform 示例方便版本化管理 resource alicloud_cs_managed_kubernetes prod { name k8s-prod cluster_spec ack.pro.small # Pro 版控制面规格 worker_vswitch_ids [vsw-h, vsw-i] # 双可用区 pod_cidr 192.168.0.0/16 service_cidr 172.21.0.0/20 new_nat_gateway true # 自动创建 NAT 网关拉镜像要用 proxy_mode ipvs # 生产用 IPVS不用 iptables delete_options [delete-resourcegroups] # 删集群时清理关联资源 kube_config_path ~/.kube/config-prod # 安全组配置 security_group_id alicloud_security_group.k8s_sg.id # 日志服务集成SLS log_config { type SLS project alicloud_log_project.k8s_log.name } # 监控插件 addons { name arms-prometheus config jsonencode({ enable true }) } }几个关键点proxy_mode: ipvsiptables 模式在节点 Pod 数超过 1000 后性能急剧下降。IPVS 用哈希表查找O(1) 复杂度生产集群必须切。log_config创建时就关联 SLS后面再补配置很麻烦。arms-prometheusARMS 监控插件在集群创建时就装好省去后期手动安装的麻烦。2.3 存储插件选择ACK 默认安装 CSI 插件。如果你要用云盘做持久化存储确保 StorageClass 配置正确# storageclass-disk.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: alicloud-disk-essd provisioner: diskplugin.csi.alibabacloud.com parameters: type: cloud_essd # ESSD 云盘性能最好 performanceLevel: PL1 # PL1/PL2/PL3按 IOPS 需求选 fsType: ext4 reclaimPolicy: Retain # 生产用 Retain别用 Delete volumeBindingMode: WaitForFirstConsumer # 延迟绑定等 Pod 调度到节点再建盘 allowVolumeExpansion: true # 允许在线扩容血泪经验reclaimPolicy一定要设Retain。默认是DeletePVC 删了云盘跟着删数据直接蒸发。我见过好几个团队在这上面翻车。三、节点池管理弹性伸缩的正确姿势3.1 节点池概念节点池NodePool是 ACK 对一组相同配置的 Worker 节点的抽象。你可以按业务维度划分系统节点池跑 kube-system、日志 Agent、监控 Agent 等基础设施 Pod。用稳定机型不弹。业务节点池跑你的业务应用。用弹性伸缩按需扩缩。AI 节点池带 GPU 的节点池专门跑推理服务。贵但可以按需弹。# 节点池配置示例通过 ACK 控制台或 OpenAPI 创建 # 这里展示一个业务节点池的 Terraform 配置 resource alicloud_cs_kubernetes_node_pool business { cluster_id alicloud_cs_managed_kubernetes.prod.id name business-pool vswitch_ids [vsw-h, vsw-i] instance_types [ecs.g7.xlarge] # 4C16G 通用型 instance_charge_type PostPaid # 按量付费弹性场景 desired_size 3 # 期望节点数 min_size 2 # 最小节点数 max_size 10 # 最大节点数 # 弹性伸缩配置 scaling_policy { type proactive # 主动预测型伸缩 proactive { scale_down_debounce 300 # 缩容冷却 5 分钟防止抖动 } } # 节点标签和污点 labels { node-pool business workload java-service } taints { key dedicated value business effect NoSchedule # 只允许声明 toleration 的 Pod 调度上来 } # 系统盘配置 system_disk_category cloud_essd system_disk_size 120 # 登录密钥 key_name k8s-prod-key }3.2 弹性伸缩的核心原则原则一扩容快缩容慢。缩容太快会导致正在处理的请求被中断。scale_down_debounce设 5~10 分钟让系统有缓冲。扩容则要快——ACK 的弹性节点池从触发到节点 Ready 通常需要 1~2 分钟对于突发流量这已经很慢了。应对方案是预留 BufferHPA 的目标 CPU 设 60% 而不是 80%给扩容留反应时间。原则二别让系统 Pod 和业务 Pod 抢资源。# 给系统 Pod 加亲和性只调度到系统节点池 # nginx-ingress-controller 的 deployment 示例 spec: template: spec: nodeSelector: node-pool: system # 只跑在系统节点池上 tolerations: - key: dedicated value: system effect: NoSchedule containers: - name: ingress resources: requests: cpu: 1 memory: 2Gi limits: cpu: 2 memory: 4Gi系统组件不设 resources limits 是另一个大坑。日志 Agent、监控 Agent 如果不限制资源在流量高峰时会跟业务 Pod 抢 CPU导致业务响应变慢。原则三GPU 节点池单独管。AI 推理服务需要 GPU而 GPU 实例贵得多一台ecs.gn7i-c8g1.2xlarge带一张 A10按量约 15 元/小时。GPU 节点池建议min_size: 0没任务时缩到 0 节省成本用cluster-autoscaler 自定义扩容策略GPU Pod 加nvidia.com/gpu资源请求确保调度到 GPU 节点四、日志采集SLS 让 Pod 日志自动汇聚4.1 SLS 日志服务集成ACK 集群创建时如果关联了 SLS会自动在每个节点安装 Logtail Agent。Logtail 以 DaemonSet 形式运行采集节点上所有 Pod 的 stdout/stderr 日志发到 SLS。但默认配置只是「能用」离「好用」还有几步。4.2 为 Spring Boot 应用配置结构化日志第一步让应用输出 JSON 格式日志。Logback 配置!-- logback-spring.xml -- configuration appender nameSTDOUT classch.qos.logback.core.ConsoleAppender encoder classnet.logstash.logback.encoder.LogstashEncoder customFields {app:ai-service,env:prod,version:${project.version}}/customFields fieldNames timestamptimestamp/timestamp version[ignore]/version levelValue[ignore]/levelValue /fieldNames /encoder /appender root levelINFO appender-ref refSTDOUT/ /root /configuration用 JSON 日志的好处SLS 可以直接做字段索引查询时不用写正则提取。例如查所有 ERROR 级别且包含特定 traceId 的日志直接level: ERROR AND traceId: abc123。第二步在 SLS 侧创建 Logstore 和采集配置// SLS 采集配置通过 API 或控制台配置 { configName: ai-service-stdout, inputType: container_stdout, inputDetail: { Stdout: { IncludeLabel: { app: ai-service // 只采集带这个 label 的 Pod }, ExcludeLabel: {} } }, outputType: LogService, outputDetail: { logstoreName: ai-service-log } }4.3 日志查询与告警日志进 SLS 后可以配告警规则。比如「5 分钟内 ERROR 日志超过 50 条就告警」-- SLS 告警 SQL * and level: ERROR | SELECT count(*) as error_count, max(timestamp) as last_error_time FROM ai-service-log WHERE __time__ to_unixtime(now() - 300) GROUP BY app HAVING error_count 50配告警通知到钉钉机器人// 告警通知配置 { actionName: 钉钉告警, type: dingding, service: { webhook: https://oapi.dingtalk.com/robot/send?access_tokenxxx, content: 告警${results[0].app} ERROR 日志 ${results[0].error_count} 条请检查 } }五、监控告警ARMS 实现 JVM 级别可观测5.1 ARMS 是什么ARMSApplication Real-Time Monitoring Service是阿里云的应用监控服务。跟 Prometheus Grafana 自己搭相比ARMS 的优势是零侵入——你不用改代码不用加 JMX exporterACK 会自动给 Java 应用注入探针。在 ACK 控制台给命名空间开启 ARMS 监控后所有新启动的 Java Pod 会自动被注入 ARMS Agent通过 init-container JVM-javaagent参数实现。5.2 关键监控指标ARMS 采集到的 JVM 级别指标包括指标含义告警阈值建议jvm_thread_countJVM 线程数 500 告警jvm_heap_used堆内存使用量 85% 持续 3 分钟告警jvm_gc_countGC 次数Full GC 5 次/分钟告警jvm_gc_timeGC 耗时单次 GC 500ms 告警http_request_countHTTP 请求量按业务基线配http_response_timeHTTP 响应时间P99 2s 告警http_error_countHTTP 5xx 10 次/分钟告警5.3 配置自定义业务指标ARMS 支持通过ArmsMethod注解或 Micrometer 上报自定义指标。如果你的 Spring Boot 已经用了 Micrometer直接配 ARMS 的 Prometheus Remote Write# application.yml — Micrometer 对接 ARMS management: endpoints: web: exposure: include: health,info,prometheus,metrics metrics: tags: application: ai-service env: prod export: prometheus: enabled: true # ARMS 会自动抓取 /actuator/prometheus 端点自定义业务指标示例——统计 AI 调用的 Token 消耗// AI 调用 Token 计量器 Component public class AiUsageMetrics { private final MeterRegistry meterRegistry; private final Counter inputTokenCounter; private final Counter outputTokenCounter; private final Counter requestCounter; public AiUsageMetrics(MeterRegistry meterRegistry) { this.meterRegistry meterRegistry; this.inputTokenCounter Counter.builder(ai_tokens_total) .tag(type, input) .tag(model, qwen-turbo) .description(AI input tokens consumed) .register(meterRegistry); this.outputTokenCounter Counter.builder(ai_tokens_total) .tag(type, output) .tag(model, qwen-turbo) .description(AI output tokens consumed) .register(meterRegistry); this.requestCounter Counter.builder(ai_requests_total) .tag(model, qwen-turbo) .description(Total AI API requests) .register(meterRegistry); } public void recordUsage(int inputTokens, int outputTokens) { // Counter 只增不减适合累计统计 inputTokenCounter.increment(inputTokens); outputTokenCounter.increment(outputTokens); requestCounter.increment(); } }这段代码执行后ARMS 的 Prometheus 端点会暴露三个时序指标ai_tokens_total{typeinput,modelqwen-turbo}、ai_tokens_total{typeoutput,modelqwen-turbo}和ai_requests_total{modelqwen-turbo}。在 ARMS 控制台可以直接用 PromQL 查询并配告警。5.4 告警最佳实践生产环境的告警要遵循「少而准」原则。我见过太多团队配了上百条告警结果每天收到几十条通知最后全部静音——告警失去了意义。建议只配三类告警可用性告警Pod 重启次数 3 次/5分钟、HPA 扩到上限、节点 NotReady性能告警HTTP P99 2s、Full GC 频繁、堆内存 85%业务告警AI 调用 5xx 率 5%、Token 消耗异常飙升可能被刷每条告警必须配可执行的 Runbook——告警里带上排查链接告诉值班人第一步干什么、第二步干什么。没 Runbook 的告警等于没告警。六、三条建议1. 集群创建用 Terraform 管理别在控制台点。控制台创建的集群没有版本记录出问题时无法回溯配置。把 VPC、交换机、ACK 集群、节点池、SLS、ARMS 全部写成 Terraform 代码放 Git 仓库。改配置走 PR Review有审计有回滚。2. 日志和监控在集群创建时就配好别等上线后补。见过太多团队先上线业务、后补日志和监控结果第一周出问题完全是裸奔状态。log_config和arms-prometheus在创建集群时就带上应用一部署日志就在 SLS 里了监控大盘自动生成。3. GPU 节点池的 min_size 设为 0用模型预热池解决冷启动。AI 推理服务用 GPU 节点池空闲时缩到 0 是省钱利器。但冷启动 1~2 分钟的延迟可能让用户体验很差。解法是部署一个轻量的「预热 Pod」始终占用 1 个 GPU用 Deployment replicas1真正的推理 Pod 按需弹。预热 Pod 只加载模型到显存不接流量等新节点起来后推理 Pod 能快速调度上去。自建 K8s 是技术能力的体现但生产环境从不为「炫技」买单——稳定、可观测、可回滚才是运维的唯一标准。下篇预告Day 60Serverless 开发入门——函数计算改写传统 Spring Boot。K8s 是当前主流但 Serverless 正在蚕食低流量场景。下一篇我们看阿里云函数计算FC怎么跑 Spring Boot冷启动到底有多慢以及什么场景该上 Serverless。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价