
一、为啥 ZKmall 非得用容器化部署?
容器化技术可不是花架子,对 ZKmall 来说,它解决的都是实打实的痛点。比起传统的虚拟机和物理机部署,在环境一致性、资源利用、扩展能力这几块,优势太明显了。
环境统一,再不用扯 "在我这能跑"
做开发的都懂,最头疼的就是环境问题。开发环境跑着好好的,到了测试环境就报错,好不容易测试通过了,上生产又出岔子。之前有家公司用 ZKmall,就因为服务器的 PHP 版本比开发环境低了个小版本,结果支付模块上线当天就出了兼容问题,差点影响了促销活动。
Docker 的镜像技术把这事儿彻底解决了。它把 ZKmall 的代码、依赖的库、各种配置打包成一个镜像,不管在什么机器上跑,环境都一模一样。开发者只需要把镜像做出来一次,开发、测试、生产环境直接用,环境问题能减少 90%。而且镜像能版本管理,新版本出问题了,一秒切回上一个稳定版,损失能降到最小。
资源用得省,服务器钱能少花
电商这行,资源需求波动太大了。平时没什么人,服务器闲得慌;一到 "618"" 双 11",流量突然涨几倍,服务器又不够用。传统部署只能按最大流量配服务器,大部分时间都是浪费。
容器化部署把 ZKmall 拆成好几个容器,商品服务一个容器,订单服务一个容器,数据库一个容器,每个容器该用多少 CPU、多少内存,都能精确分配,资源利用率能提高 40% 以上。有家小电商之前用 3 台服务器,用 Docker 部署 ZKmall 后,2 台就够用了,硬件成本省了 30%。而且容器启动快,秒级就能起来,比虚拟机快多了,需要的时候赶紧启动,不用了就关掉,一点不浪费。
自动扩缩容,流量再疯也不怕
电商的流量说涨就涨,赶上大促,流量可能是平时的 10 倍。传统部署得提前好几天准备,手动加服务器、部署应用,累不说,还容易出错。
用 k8s 搞容器化部署就不一样了,它能盯着流量自动调整。比如订单服务的 CPU 用到 70% 以上了,马上多开几个容器实例;流量降下来了,又自动关掉多余的,资源刚好够用。
k8s 还能自己检查容器是不是正常工作,发现商品服务没响应了,要么自动重启,要么把它挪到别的健康服务器上。有家商城之前出故障,平均要 15 分钟才能恢复,用了 k8s 之后,3 分钟就搞定了,用户几乎没感觉。

二、Docker 单机部署:小商城快速上线的招
如果你的商城刚起步,或者规模不大,用 Docker 单机部署最划算。简单易上手,部署快,运维也不麻烦,几天就能把商城搭起来。
部署前得准备些啥
服务器配置不能太低,至少 2 核 4G,操作系统用 CentOS 7/8 或者 Ubuntu 18.04 以上都行。得把 Docker Engine 装上,建议用 20.10 以上的版本,再装个 Docker Compose,管理多个容器方便。
然后想想需要哪些容器。跑 ZKmall 代码的应用容器肯定要有,数据库容器(MySQL 或者 PostgreSQL),Redis 缓存容器(存会话和临时数据),Nginx 容器(处理网页请求和静态文件),如果商品多需要搜索功能,再加个 Elasticsearch 容器。
网络方面,让这些容器用 Docker 的桥接网络连起来,互相能通信。最重要的是数据得存好,数据库的数据、用户上传的商品图片,这些都得用数据卷(Volume)挂载到服务器本地,不然容器一删,数据就没了。
镜像怎么做才好
ZKmall 官方有基础镜像,咱们可以在这上面改。用 Dockerfile 来定制:先从官方镜像开始,加点自己需要的 PHP 扩展,改改 Nginx 的配置,装个处理图片的库什么的;然后把商城代码、配置文件拷贝进去,最后写上启动命令,比如启动 PHP-FPM 和 Nginx。
做镜像有个窍门,就是越小越好。没用的工具、多余的依赖都删掉,用多阶段构建把不需要的东西去掉。有家公司把 ZKmall 的镜像从 1.2G 减到 600M,下载速度快了一半。还有,配置文件别写到镜像里,像数据库地址、Redis 密码这些,最好用环境变量传进去,或者用数据卷挂载,这样改起来方便,也安全。
用 Docker Compose 把容器串起来
ZKmall 不是一个容器能跑的,得好几个容器配合才行,这时候就需要 Docker Compose 了。建一个 docker-compose.yml 文件,把每个容器的配置都写清楚:
- 应用容器得等数据库和 Redis 启动了才能启动,环境变量里写上数据库地址、密码这些
- 数据库容器要把 /var/lib/mysql 目录挂载到服务器本地,这样重启容器数据也不会丢
- Nginx 容器要把服务器的 80 和 443 端口映射进去,静态文件目录和 SSL 证书也得挂载进去
然后执行 docker-compose up -d,所有容器就都启动起来了。想看日志就用 docker-compose logs -f,想重启应用就用 docker-compose restart app,特别方便。有家商户用这方法部署 ZKmall,从服务器初始化到商城能访问,总共就花了 2 小时,比以前用传统方式快多了。
单机部署怎么运维
日常运维其实不复杂。用 docker ps 看看哪些容器在运行,docker stats 能看 CPU 和内存用了多少。数据库得定期备份,要么进容器里用 mysqldump 命令,要么直接备份服务器上挂载的目录。
最好在 Dockerfile 里加个健康检查,让它定期访问一下首页,看看应用是不是还活着,有问题能及时发现。
如果突然来了点流量,服务器有点扛不住了,可以用 docker update 临时给容器加点点内存;也可以再启动一个应用容器,让 Nginx 把请求分到两个容器上,简单扩一下容。

三、k8s 集群部署:大商城的高可用方案
等 ZKmall 的业务做起来了,用户越来越多,单机部署就不够用了,这时候就得上 k8s 集群。k8s 能把好几个服务器连成一个集群,自动管理容器,不管是扩缩容还是处理故障,都比单机强多了。
集群怎么搭才靠谱
k8s 集群至少得有一个主节点和两个工作节点。主节点是管事儿的,负责调度容器、监控集群状态;工作节点是干活的,上面跑 ZKmall 的容器。
主节点的配置不能太低,至少 4 核 8G;工作节点起步 2 核 4G,以后不够了再加。里面的核心组件得弄明白:API Server 是所有操作的入口,Etcd 是存数据的,Scheduler 负责安排容器跑在哪台机器上,Controller Manager 管着各种控制器,Kubelet 在每个工作节点上,确保容器按规矩运行。
ZKmall 在 k8s 里怎么安排
k8s 里有几个重要的概念得搞清楚,不然容器没法好好跑。
- Pod 是最小的部署单位,一个 Pod 里可以装一个或多个容器。比如可以把 PHP 和 Nginx 放到一个 Pod 里
- Deployment 用来定义 Pod 的数量,比如想让 3 个应用 Pod 在运行,k8s 就会保证一直有 3 个,如果哪个挂了,就再启动一个
- Service 给 Pod 们一个固定的访问地址,不管 Pod 怎么换,Service 地址不变,这样其他服务访问起来方便
- Ingress 管外部怎么访问集群,比如把 www.zk mall.com的请求转到前端服务,把 api.zk mall.com转到 API 服务
配置方面,普通的配置可以存在 ConfigMap 里,数据库密码这些敏感信息存在 Secret 里,然后挂载到 Pod 里,不用写死在代码里。
怎么保证服务不中断
做电商的,最怕服务中断。k8s 能帮我们实现高可用。
数据库可以搞主从架构,用 StatefulSet 部署,这样 Pod 的名字和存储都稳定。Redis 可以做主从加哨兵,或者用 Redis Cluster。应用呢,就用 Deployment 部署 3 个副本,让它们跑在不同的工作节点上,就算一个节点挂了,另外两个还能继续工作。
服务之间互相访问也方便,k8s 自带 CoreDNS,Pod 之间可以直接用 Service 的名字访问,不用记 IP 地址。有家电商用 k8s 部署 ZKmall 后,核心服务一年的故障时间控制在 52 分钟以内,可用性达到 99.99%。
怎么应对流量波动和管理访问
k8s 的 HPA(Horizontal Pod Autoscaler)特别好用,能根据流量自动增减 Pod 数量。比如可以设置当 CPU 利用率超过 70% 时,就多来两个 Pod;低于 30% 时,就少两个。有家商城用了这功能,"双 11" 期间应用 Pod 从 3 个自动加到 15 个,稳稳扛住了流量高峰,活动一结束,又自动减回去了,一点不浪费资源。
流量管理靠 Ingress Controller。可以配置路径路由,把 /api 开头的请求都转给 API 服务;可以配置 HTTPS 证书,让访问更安全;还能设置会话保持,保证用户在购物车操作不会跑到别的 Pod 上。如果遇到恶意请求,还能限流,保护服务不被打垮。

四、容器化部署后怎么管和优化
容器化部署不是一部署完就万事大吉了,还得好好管理,不断优化,才能发挥最大作用。
镜像管理要做好
镜像得有个命名规矩,比如用 "版本号 + 日期 + Git 提交号",像 zk mall:v1.2.0_20240520_ab123cd,这样开发版、测试版、生产版一眼就能分清。
安全也很重要,基础镜像一定要用官方的或者信得过的,定期用 Trivy 之类的工具扫扫漏洞。镜像里别放密钥、密码这些敏感信息,运行容器的时候最好用非 root 用户,减少风险。
构建镜像的时候,把依赖安装的步骤缓存起来,比如 npm install 或者 composer install 的结果缓存一下,下次构建能快很多。有家团队通过这方法,把构建时间从 15 分钟缩到了 5 分钟。
最好建个自己的镜像仓库,比如用 Harbor,谁能拉取镜像,谁能推送镜像,都有权限控制,生产环境只允许用审核过的镜像。
资源分配要合理
每个 Pod 都要设置资源请求和限制。requests 是说这个 Pod 至少需要多少资源,k8s 会保证把它调度到有足够资源的节点上;limits 是说最多能用多少资源,别影响其他 Pod。ZKmall 的应用 Pod,一般请求 0.5 核 CPU 和 512MB 内存,限制 1 核 CPU 和 1GB 内存就差不多了,数据库可以适当多给点。
调度的时候也有技巧,可以让数据库、Redis 这些对性能要求高的服务跑在配置好的节点上,应用服务就跑在普通节点上。同一个服务的多个 Pod,别让它们跑在同一个节点上,万一节点坏了,服务还能正常运行。
定期看看资源用得怎么样,用 Prometheus 加 Grafana 把监控数据可视化,哪些 Pod 资源不够了,哪些资源浪费了,一目了然。有家商城通过优化资源配置,内存利用率从 40% 提高到 65%,服务器都少买了一台。
备份和灾备不能少
数据备份一定要做好。数据库每天凌晨备份一次,同时做主从复制,实时同步数据,备份文件存在云存储上,双保险。k8s 的各种配置文件,像 Deployment、Service 这些的 YAML,都要放到 Git 里管理,丢了还能找回来。
灾备演练也得定期搞,模拟一下服务器坏了、数据丢了这些情况,看看能不能快速恢复。比如服务器坏了,k8s 能不能自动把 Pod 移到别的服务器上;数据丢了,能不能用备份恢复回来。
一般电商平台,数据丢失最好别超过 1 小时(RPO≤1 小时),故障后 30 分钟内要能恢复服务(RTO≤30 分钟)。有家商城通过几次演练,把故障恢复时间从 1 小时缩短到 20 分钟,心里踏实多了。
搞个自动部署流水线
用 Jenkins 或者 GitLab CI 这些工具,搞个自动部署流水线,能省不少事。开发者提交代码后,自动检查代码有没有问题,自动跑测试,测试通过了自动构建镜像,镜像推到仓库后,自动更新 k8s 的配置,k8s 再慢慢把旧的 Pod 换成新的,整个过程不用人工插手。
流水线可以分环境,先部署到测试环境,测试没问题了,再手动点一下部署到生产环境,或者设置在半夜没人的时候自动部署。有家团队这么做了之后,从代码提交到生产环境能用,时间从 1 天缩短到 2 小时,还没出过部署错误。

五、常见问题怎么解决
容器化部署过程中肯定会遇到各种问题,知道怎么解决能少走很多弯路。
镜像构建和启动出问题了怎么办
镜像构建失败,大多是缺依赖或者配置错了。可以一步一步调试 Dockerfile,每加一行命令就构建一次,看看在哪步出问题。用 --progress=plain 参数能看到详细日志,方便排查。如果是下载依赖太慢,换成国内的源,比如 npm 用淘宝源,Composer 用中国镜像。
容器启动不起来,先看看日志,用 kubectl logs <pod 名字>,一般能找到原因。常见的有数据库连接信息错了,端口被占用了,或者权限不够。可以进容器里手动启动试试,kubectl exec -it <pod 名字 > -- /bin/bash,进去后看看配置文件对不对,目录权限够不够(一般 755 就行)。
网络访问有问题怎么排查
Pod 之间不通,先看看网络插件(比如 Calico、Flannel)是不是正常运行,网络策略有没有禁止访问。再检查 Service 的标签选择器和 Pod 的标签对不对,用 kubectl describe service <服务名> 看看有没有关联到 Pod。
外面访问不了服务,先看看 Ingress 规则对不对,域名、路径、关联的 Service 是不是都没错,Ingress Controller 是不是在运行。如果是云服务器,看看安全组有没有开放 80 和 443 端口,负载均衡器配置对不对。之前有家用户访问不了首页,查了半天,发现是 Ingress 的路径少写了个斜杠,加上就好了。
数据丢了或者备份恢复不了怎么办
数据丢了,十有八九是没做好持久化。数据库、Redis 这些有状态的服务,一定要用 PV 和 PVC,把数据存在服务器本地或者 NFS、云存储上,别用容器自己的存储。
备份恢复不了,可能是备份文件坏了,也可能是恢复步骤错了。最好定期在测试环境恢复一下,确保备份文件能用。恢复的时候,先把应用停了,别让新数据写进来,恢复完了检查一下关键数据对不对。有家商城之前因为没配置好 PV,容器重启后数据丢了,后来用了 PVC,又定期备份,就再也没出过这问题。
性能不好或者资源不够了怎么办
容器老是重启,看看事件日志,kubectl describe pod <pod 名字>,如果看到 "OOMKilled",就是内存不够了,要么加内存限制,要么优化应用少用点内存。如果是健康检查失败,调调检查参数,比如延长点超时时间,多试几次,或者修修应用,让它响应快点。
节点资源不够了,要么加新节点,要么把一些 Pod 移到其他节点上,k8s 会自动平衡负载。有家商城促销的时候订单服务变慢,发现是 CPU 限制设低了,调大之后马上就好了。

容器化部署让 ZKmall 的部署变得简单又高效。小商城用 Docker 单机部署,快速上线,成本还低;大商城用 k8s 集群部署,高可用,能扛住大流量。从做镜像到管理集群,从自动扩缩容到备份恢复,容器化技术贯穿了 ZKmall 的整个生命周期,能省不少事,还能降低成本。
实际用的时候,要根据自己的业务规模选合适的方案,记住 "镜像做小点、资源配合理、备份要做好、尽量自动化",不断优化,就能让 ZKmall 跑得又稳又好,为业务增长打下坚实的基础。