刚入职的阿明是一家互联网公司的后端程序员,上周接手一个用户反馈系统的开发 —— 要做个能收集 App 用户吐槽、自动生成统计报表的小服务。本以为是个 “CRUD 小能手” 就能搞定的活儿,没成想从写代码到上线,一路踩的坑都和 “怎么让程序稳定跑起来” 有关,也让他摸清了容器、镜像、K8s 那些事儿。

第一天:本地跑通了,同事电脑却 “崩了”—— 镜像的诞生
阿明用Java写了服务核心逻辑,本地调试时跑得顺风顺水:接收用户反馈存入数据库,定时生成 Excel 报表,日志也打得整整齐齐。可当他把代码压缩包发给测试同事小夏时,麻烦来了。
“阿明,你这代码跑不起来啊!” 小夏的消息弹了出来,附带一串报错截图,“我本地 Java 是 11 版本,你用的是8吧?还有你依赖的那个Excel工具包,我这边少了个jar包。”

阿明一拍脑袋 —— 忘了环境不一致的坑。(环境可以理解为代码运行基于的操作系统以及依赖库和各种配置)

他只好远程帮小夏装 Java 8,手动传 jar 包,又改了数据库配置路径,折腾半小时才让服务跑起来。“要是每个同事都要这么调,太浪费时间了”,阿明琢磨着,“有没有办法把‘代码 + 环境’打包成一个‘成品’,谁拿过去都能直接用?”

组长听见了他的吐槽,扔过来一个词:“试试容器镜像。” 阿明查了资料才明白,镜像就像个 “密封好的电脑”—— 把 Java 8 运行时、所有依赖包、他写的代码,甚至数据库连接配置都装进去,打包成一个只读的文件包。别人拿到这个镜像,不用装任何东西,直接 “启动镜像” 就能运行服务,环境一模一样。

于是他写了个 Dockerfile(打包镜像的 “说明书”),执行命令后生成了一个叫 “user-feedback:v1” 的镜像。这次发给小夏,小夏只输了一行命令,服务就起来了,连一句 “报错” 都没提。阿明第一次觉得:“原来镜像就是解决‘在我这能跑,在你那不行’的神器啊!”

这天晚上睡前,阿明在他的日记博客中写下他对容器的镜像的思考:“镜像是代码和环境的打包,针对代码在不一致环境无法运行的问题,把代码、依赖、运行时打包成静态模板,解决环境一致问题。”

第三天:镜像跑起来了,可 “临时文件去哪了”—— 容器的真相

镜像解决了环境问题,阿明又遇到了新情况:服务运行时会生成临时日志文件,可每次重启后,日志就不见了。

他跑去问运维老周,老周笑着说:“你把镜像当容器用了吧?镜像只是个静态模板,真正跑起来的是容器。” 阿明这才搞懂两者的区别:
镜像就像手机里的 “App 安装包”—— 你下载的微信安装包是静态的,不能直接聊天;而容器就是 “安装后打开的微信”—— 是安装包的 “运行实例”,能发消息、存聊天记录,但如果把微信卸载重装(容器删除重启),之前的临时聊天记录(容器里的临时文件)就没了。

老周接着说:“容器启动时会在镜像上面加一层‘可写层’,你生成的日志、临时文件都存在这层里。要是想让数据持久化,得给容器挂个‘存储卷’,就像给手机插内存卡,数据存在卡里,换手机也能接着用。”

阿明照着做,给容器挂载了存储卷,再重启服务时,日志果然保留下来了。他还发现一个细节:同一个 “user-feedback:v1” 镜像,他能同时启动 3 个容器 —— 就像一个微信安装包,能在手机、平板、电脑上分别登录,每个设备里的聊天记录(容器可写层数据)互不干扰。

一周后:服务要上线,10 个容器怎么管 ——K8s 的救场

项目要上线了,运维老周说:“线上得跑 10 个容器,分担用户流量;还得保证万一某个容器崩了,能自动补一个新的。”

阿明一听就懵了:10 个容器要分别启动?每个容器的状态要盯着?崩了还要手动重启?这也太麻烦了。

老周指了指屏幕上的 K8s 控制台:“别慌,有 K8s 呢。你先把这 10 个容器‘分组’—— 咱们的服务每个容器都要配个‘日志收集容器’,俩容器得绑在一起跑,这一组就是一个 Pod。”

阿明这才明白,Pod 是 K8s 里最小的管理单位,就像 “打包好的套餐”—— 比如汉堡和可乐必须一起卖,服务容器和日志容器必须一起跑,Pod 就把它们捆在一起,确保它们在同一台服务器上,共享网络和存储。

“然后你告诉 K8s,‘我要 5 个这样的 Pod’(每个 Pod 含 2 个容器,共 10 个容器),K8s 会自动把这些 Pod 分配到集群的服务器上。” 老周边操作边说,“要是某个 Pod 崩了,K8s 会自动重启;要是某台服务器断电了,K8s 会把那台机器上的 Pod 移到其他服务器上,你啥都不用管。”

阿明看着 K8s 控制台里的 Pod 状态:5 个 Pod 全部 “Running”,有一个 Pod 意外崩溃后,几秒钟内就自动弹出一个新的。他突然觉得,之前觉得复杂的 “集群管理”,其实就是让 K8s 当 “智能管家”,把重复的、麻烦的活儿都替人干了。

上线成功后,阿明在笔记本上画了张图,把这些天搞懂的概念串了起来:
镜像:解决 “环境一致”—— 把代码、依赖、运行时打包成静态模板,像 “微信安装包”;
容器:镜像的 “运行实例”—— 像 “打开的微信”,有临时可写层,能跑服务但数据不持久;
Pod:K8s 里的 “最小单位”—— 把关联容器捆在一起,像 “汉堡 + 可乐的套餐”;
K8s 集群:管理大规模 Pod的 “智能管家”—— 自动分配、监控、修复,让服务稳定跑在线上。
他终于明白,这些技术不是孤立的 “术语”,而是为了解决实际问题一步步出现的:**先有镜像解决环境问题,再有容器实现动态运行,最后有 K8s 搞定大规模管理。**就像他写代码时,先解决单个功能,再考虑复用,最后优化性能 —— 技术的逻辑,其实和程序员解决问题的逻辑,是相通的。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐