云原生转型经验:容器化部署的坑与解决

先说容器网络这块。刚开始用默认的bridge网络模式,发现微服务之间经常出现调用超时。通过tcpdump抓包分析,发现容器跨节点通信时存在明显的丢包现象。后来改成macvlan模式,又遇到交换机ARP表爆炸的问题,直接把物理网络搞出广播风暴。最后被迫上了Calico方案,配合BGP协议实现容器网络与物理网络互通。这里有个细节:记得调整iptables规则,避免kube-proxy和Docker自带的iptables规则冲突。我们当时就因为没清理历史规则,导致NodePort服务始终无法正常访问。

存储方案的选择更是让人头大。最初直接挂载宿主机的目录到容器里,结果发现并发写文件时经常出现权限混乱。后来改用CephFS,又遇到小文件读写性能差的问题。经过测试发现,当单个Pod同时读写超过200个小文件时,IO延迟会从20ms飙升到800ms。最终方案是分级存储:热点数据用本地SSD盘做hostPath,冷数据放到CephFS,重要数据再通过Velero做定期快照到对象存储。特别要注意的是,在K8s里挂载CephFS时必须设置mountOptions中的noatime参数,否则inode缓存会快速耗尽。

配置管理这块也踩过坑。最初把应用配置直接打包进镜像,每次改配置都要重新构建镜像。后来改用ConfigMap,又发现中文配置项经常出现乱码。最后摸索出的最佳实践是:基础环境变量用ConfigMap,敏感信息用Secret,动态配置通过Apollo配置中心管理。特别提醒:ConfigMap挂载为volume时,要设置subPath避免覆盖整个目录,否则容器内其他文件会神秘消失。

监控诊断方面,传统的那套监控体系基本报废。我们最初尝试在容器里安装Agent,结果发现容器重启后监控数据就丢了。后来改用DaemonSet方式部署监控采集器,又遇到资源竞争问题。最终方案是:业务容器通过sidecar模式输出日志和指标,由Prometheus统一采集,再通过Grafana展示。关键是要给每个容器设置合理的resource.limits,否则某个容器内存泄漏时会把整个节点拖垮。我们就遇到过因为JVM堆内存设置过大,导致节点OOM被系统kill的情况。

健康检查的配置看似简单,实则暗藏玄机。刚开始只配置了存活探针,结果应用假死时探针始终返回成功。后来补上了就绪探针,又因为检测间隔设置太短,导致Pod在启动过程中就被重启了七八次。血泪教训:livenessProbe的initialDelaySeconds一定要大于应用真实启动时间,readinessProbe的failureThreshold要适当放宽,特别是对Java应用这种启动慢的类型。

镜像仓库的维护也是痛点多发区。自建Harbor仓库时没做垃圾回收,半年时间500G的磁盘就被僵尸镜像占满了。后来设置自动清理策略时又误删了生产环境正在使用的历史镜像,导致部署失败。现在我们的策略是:主分支镜像保留30天,特性分支镜像保留7天,所有镜像都打上CI流水线编号作为标签。

最后给几个关键建议:第一,容器化改造前必须先做好日志规范,所有应用必须输出结构化日志;第二,网络策略要提前规划,用NetworkPolicy做好微服务间的访问控制;第三,一定要搭建镜像安全扫描流程,我们曾发现基础镜像里有高危漏洞;第四,资源限制必须配置,这是保证集群稳定的生命线。

经过半年折腾,现在我们的容器平台总算稳定了。最大体会是:容器化不是简单地把应用塞进Docker,而是要从架构设计、开发流程到运维体系都做出相应调整。下次有机会再和大家聊聊我们在服务网格落地时踩的新坑。

相关推荐
阿里云云原生1 天前
Higress v2.2.3 发布:正式入驻 CNCF Sandbox,AI Gateway 与 Ingress 迁移能力双向加固
云原生
阿里云云原生2 天前
香港站【企业 AI Agent 工程化实战专场】来啦,邀您7月9日见!
云原生·agent
阿里云云原生2 天前
研发域与运维域的“数字握手”:通过 Agentic Skills 实现 DevOps 全链路自动化
云原生
阿里云云原生6 天前
AI 开发新常态:当 Cursor、Claude、Codex 并行,如何统一管理散落的 Skill 资产?
云原生·ai编程
探索云原生6 天前
K8s 1.36 这个 GA 特性,把 initContainer 拉模型的 hack 干掉了
ai·云原生·kubernetes
Java之美6 天前
从edge-trigger到level-trigger,谈谈 Kubernetes controller 的开发范式
云原生
阿里云云原生7 天前
深度解构:当 Append-only 的 SLS 遇上 Update/Delete,是如何实现设计权衡的?
云原生
Java之美7 天前
一次k8s升级引发的DevicePlugin注册失败
云原生·kubernetes
秋播7 天前
nerdctl推送rancher本地镜像到harbor
云原生
阿里云云原生8 天前
告别冗长链路!Kafka × Table Bucket 实现开放表格式零 ETL 实时入湖
云原生·kafka