镜像构建环节最容易埋雷。单纯用latest标签这种野蛮操作就不多说了,关键是建立分层构建的意识。基础镜像务必从可信源拉取,生产环境禁止使用未经扫描的公共镜像。我们的Dockerfile必须遵循最小化原则:
注意最后切换非root用户这个细节,太多人忽略这点导致安全漏洞。多阶段构建更要熟练掌握,特别是Go这类编译型语言,最终镜像应该只包含二进制文件而不保留编译环境。
容器编排的黄金法则是保持无状态设计。有状态服务必须通过持久化卷处理,但要注意分布式存储的性能瓶颈。在K8s里部署MySQL这类服务时,StatefulSet配合headless service才是正道:
配置管理要严格区分环境。我们采用ConfigMap+Secret的组合方案,敏感信息全部通过K8s secret加密存储,普通配置按环境划分。Spring Boot应用的bootstrap.yaml这样配置:
监控体系需要多维度建设。除了常规的CPU/内存监控,更要关注应用本身的业务指标。Prometheus+Granfana的方案现在几乎是标配,但要注意采集间隔的设置。Java应用需要在JVM参数中添加:
这样才能暴露JMX指标给Prometheus抓取。
网络策略往往决定系统稳定性。Ingress控制器推荐使用Nginx,相比Traefik在网关层功能更完善。重要服务必须配置网络隔离,比如这个禁止默认访问的策略:
持续交付流水线要把握分寸。开发环境可以自动部署,测试环境需要代码评审后触发,生产环境必须经过人工确认。Jenkinsfile里要设置超时和重试机制,镜像推送前必须完成漏洞扫描。
资源限制是稳定运行的基石。每个容器都必须设置requests和limits,特别是内存限制必须明确,防止OOM Killer误杀关键进程。我们曾经吃过亏,某个Java应用没设堆内存限制,导致整个节点崩溃。
日志收集需要统一规划。EFK栈虽然经典,但在容器场景下更推荐Loki方案,资源消耗能降低十倍。Fluentd的配置要注意日志轮转策略,避免撑爆磁盘。
安全防护必须贯穿全程。Pod安全策略要启用,比如禁止特权模式:
镜像仓库要开启漏洞扫描,高危漏洞必须阻断部署流程。
这些经验都是用真金白银换来的。记得有次线上事故,因为没设HPA冷却时间,导致服务在阈值附近震荡了半小时。后来我们在autoscaling里加了 stabilizationWindowSeconds 参数才解决问题。
容器化不是简单地把应用塞进Docker,而是对整个研发体系的升级。从代码提交到服务上线,每个环节都需要重新设计。只有把最佳实践落实到流水线的每个阶段,才能真正享受容器化带来的红利。