K8S部署MERN栈容器时如何正确定义环境变量?
问题根因
环境变量读取失败、功能不生效是三个核心问题导致的:
- 代码中未通过Node.js标准的
process.env对象读取容器注入的环境变量,直接写${MONGO_URL}属于引用未定义的JS变量,运行时会直接报错 - 你在K8s中配置了
FRONT_URL,但后端CORS中间件完全没有使用该配置,跨域校验不通过时前端请求会被浏览器拦截 - K8s中配置的
FRONT_URL缺少协议前缀,不符合跨域校验的origin格式要求,同时代码中MongoDB连接串的&是HTML转义字符,实际运行时会导致连接参数解析失败
修正步骤
1. 修改后端业务代码
将原有服务代码替换为以下版本,正确读取环境变量、配置CORS规则:
import express, { Express } from 'express' import mongoose from 'mongoose' import cors from 'cors' import todoRoutes from './routes' const app: Express = express() // 正确从process.env读取容器注入的环境变量,设置兜底默认值 const PORT: string | number = process.env.PORT || 4000 const FRONT_URL: string = process.env.FRONT_URL || "http://localhost:3000" const MONGO_URL: string = process.env.MONGO_URL || "localhost:27017" // 配置CORS允许前端地址访问 app.use(cors({ origin: FRONT_URL, credentials: true })) app.use(express.json()) // 原代码缺少JSON body解析,POST类请求会异常 app.use(todoRoutes) // 注意连接串里用&而非HTML转义的& const uri: string = `mongodb://${MONGO_URL}?retryWrites=true&w=majority` const options = { useNewUrlParser: true, useUnifiedTopology: true } mongoose.set('useFindAndModify', false) mongoose .connect(uri, options) .then(() => // 监听0.0.0.0确保容器内端口可被K8s集群访问,日志里的localhost不影响外部访问 app.listen(Number(PORT), "0.0.0.0", () => console.log(`Server running on port ${PORT}, allowed frontend origin: ${FRONT_URL}`) ) ) .catch((error) => { throw error })
2. 修正K8s Deployment配置
调整环境变量格式,补全协议前缀,显式声明PORT变量避免默认值偏差:
apiVersion: apps/v1 kind: Deployment metadata: name: todo-server-app-deploy spec: replicas: 1 selector: matchLabels: app: todo-server-app template: metadata: labels: app: todo-server-app spec: containers: - image: repo/todo-server-app:24 name: container1 ports: - containerPort: 4000 env: - name: FRONT_URL # 补全http协议前缀,跨域校验要求origin必须带协议 value: "http://a1ecab155236d4c7fba8b0c6a1b6ad2b-549550669.us-east-1.elb.amazonaws.com" - name: MONGO_URL value: "todo-mongo-service:27017" # 显式声明PORT,和containerPort保持一致 - name: PORT value: "4000" imagePullPolicy: IfNotPresent
3. 验证方法
重新构建镜像、更新Deployment后,执行以下命令验证环境变量注入正常:
# 替换为你的实际Pod名称 kubectl exec -it $(kubectl get pod -l app=todo-server-app -o jsonpath='{.items[0].metadata.name}') -- printenv | grep -E "FRONT_URL|MONGO_URL|PORT"
如果输出的三个变量值和你配置的一致,说明环境变量注入成功,服务即可正常运行。
注意:如果你的ELB是HTTPS协议,需要把
FRONT_URL的前缀改为https://,否则跨域校验依然会失败。
内容的提问来源于stack exchange,提问作者Temo Hatna
相关产品推荐
相关产品推荐

