前后端并行开发时,前端常常依赖尚未完成的后端接口。为了不让联调阻塞,很多团队会创建Mock服务,但本地Mock很难在测试环境复用。本文介绍一种Mock2Image思路:使用Node.js编写轻量Mock API,通过Google Cloud Build自动构建容器镜像,并部署到Kubernetes集群。这样既保证Mock行为一致,又能利用云端构建能力,开发机无需安装Docker。

接下来从Mock服务实现、Cloud Build配置、Kubernetes部署以及优化四个层面展开。
一、用Node.js编写可容器化的Mock服务
Mock服务的核心职责是模拟后端接口的返回数据。Node.js配合Express框架可以在几十行代码内完成一个稳定可扩展的HTTP服务。为了保证服务能够运行在容器中,有几个关键点需要提前处理。首先是监听地址,必须绑定到0.0.0.0而不是127.0.0.1,因为容器内网络命名空间与宿主机不同,绑定到回环地址会导致Kubernetes无法访问。其次,端口需要通过环境变量注入,避免写死。
下面是一个典型的Express Mock服务示例。它提供了健康检查端点/healthz和用户列表接口/api/users,返回固定的JSON数据。健康检查端点对于Kubernetes探针非常重要,后文会用到。
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
app.get('/healthz', (req, res) => {
res.status(200).json({ status: 'ok' });
});
app.get('/api/users', (req, res) => {
res.json([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]);
});
app.listen(port, '0.0.0.0', () => {
console.log(`Mock server running on port ${port}`);
});
上述代码中使用了JavaScript模板字符串,注意反引号内的变量会正常展开。为了让Mock服务更贴近真实后端,可以进一步拆分路由模块、添加请求日志和延迟模拟。延迟模拟对于前端测试加载状态很有帮助,可以在响应前使用setTimeout等待一段时间。
另外,建议在package.json中明确start脚本为node server.js,并锁定依赖版本。容器构建时使用npm ci命令会根据package-lock.json精确安装依赖,避免版本漂移。
二、配置Dockerfile与cloudbuild.yaml
Dockerfile采用多阶段构建,构建阶段安装生产依赖,运行阶段只复制node_modules和源码。这样最终镜像中不包含npm缓存和开发依赖,体积更小。这里选择node:18-alpine基础镜像,因为它体积小且兼容Express。
FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --only=production FROM node:18-alpine WORKDIR /app COPY --from=builder /app/node_modules ./node_modules COPY . . ENV PORT=3000 EXPOSE 3000 CMD ["node", "server.js"]
Google Cloud Build的配置写在cloudbuild.yaml中。构建步骤分为两步:第一步使用docker builder构建镜像并打上带有提交哈希的标签;第二步将镜像推送到Google Container Registry或Artifact Registry。使用提交哈希作为标签可以方便追踪每次构建对应的代码版本。
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/mock-api:$COMMIT_SHA', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/mock-api:$COMMIT_SHA']
images:
- 'gcr.io/$PROJECT_ID/mock-api:$COMMIT_SHA'
在实际使用中,可以将代码仓库关联到Cloud Build触发器,当推送到指定分支时自动执行构建。Cloud Build会为每次构建分配一个临时虚拟机,所有步骤都在该环境中运行,因此开发机不需要安装Docker。触发器还支持替换变量,例如在控制台配置_COMMIT_SHA或使用内置的$COMMIT_SHA。
值得注意的是,cloudbuild.yaml中的$PROJECT_ID和$COMMIT_SHA是Cloud Build提供的内置替换变量。如果使用自定义变量,需要在触发器中声明。构建超时时间也可以通过timeout字段调整,对于首次构建安装依赖较多的情况,建议适当延长。
三、部署到Kubernetes并验证
构建完成的镜像可以通过Kubernetes Deployment进行部署。下面的清单创建了两个副本的Mock服务,并配置了readinessProbe和livenessProbe。这两个探针会请求/healthz端点,确保Pod只有在服务就绪时才接收流量,并且在异常时自动重启。
apiVersion: apps/v1
kind: Deployment
metadata:
name: mock-api
spec:
replicas: 2
selector:
matchLabels:
app: mock-api
template:
metadata:
labels:
app: mock-api
spec:
containers:
- name: mock-api
image: gcr.io/PROJECT_ID/mock-api:COMMIT_SHA
ports:
- containerPort: 3000
readinessProbe:
httpGet:
path: /healthz
port: 3000
livenessProbe:
httpGet:
path: /healthz
port: 3000
---
apiVersion: v1
kind: Service
metadata:
name: mock-api
spec:
selector:
app: mock-api
ports:
- port: 80
targetPort: 3000
type: LoadBalancer
执行kubectl apply -f deployment.yaml后,可以通过kubectl get pods观察Pod状态。如果探针配置正确,Pod会显示Running且READY列为1/1。Service类型设置为LoadBalancer适合云环境,GKE会自动创建外部负载均衡器,分配公网IP。若在本地Minikube环境,可以改用NodePort或使用kubectl port-forward进行访问。
Mock2Image的收益在于环境一致性。开发、测试、预发布使用同一套Mock镜像,避免了本地代码与集群中行为不一致的问题。同时,镜像版本可追溯,配合回滚机制可以快速切换到上一个稳定版本。
四、构建优化与注意事项
使用Docker构建虽然直观,但在Cloud Build中默认的Docker daemon并非始终安全。生产环境推荐使用Kaniko,它能够在无守护进程的情况下构建镜像,并且支持缓存层,显著加快构建速度。下面的cloudbuild.yaml片段展示了Kaniko的用法。
steps:
- name: 'gcr.io/kaniko-project/executor:latest'
args:
- '--destination=gcr.io/$PROJECT_ID/mock-api:$COMMIT_SHA'
- '--cache=true'
- '--cache-ttl=24h'
除了构建工具,镜像大小也值得关注。虽然node:18-alpine已经很小,但可以进一步使用distroless镜像作为运行阶段,只包含Node.js运行时。不过这会让调试变得困难,需要根据团队情况权衡。若Mock服务只提供静态JSON,甚至可以脱离Express,使用原生的http模块,进一步减少依赖。
Kubernetes中的Mock服务通常需要区分不同环境的数据。建议使用ConfigMap挂载JSON数据文件或通过环境变量传递配置。敏感信息如API密钥不应硬编码在镜像中,应使用Secret并挂载为文件或环境变量。此外,不要使用latest标签作为生产部署标签,因为它无法明确版本,回滚和审计都会遇到问题。
Node.jsGoogle Cloud BuildKubernetes Mock修改时间:2026-08-22 05:25:37