Pod无法被Service访问的根本原因是应用监听地址为127.0.0.1而非0.0.0.0,导致kube-proxy无法转发流量;需确保app.Listen()绑定0.0.0.0:3000(如":3000"),并配置readinessProbe/livenessProbe、正确注入FIBER_ENV环境变量及ConfigMap/Secret。

app.Listen() 必须绑定 0.0.0.0,不能是 127.0.0.1
Pod 内容器默认无法被 Service 或外部访问,根本原因是 Fiber 启动时监听地址写死了 127.0.0.1:3000。Kubernetes 的网络模型要求服务必须绑定到 0.0.0.0 才能被同一 Pod 内的 kube-proxy 或其他 Pod 访问。
检查你的 main.go:
-
app.Listen(":3000")✅ 等价于0.0.0.0:3000,安全可用 -
app.Listen("127.0.0.1:3000")❌ 仅本机回环可连,Service 健康检查、curl 测试全失败 - 如果用环境变量拼接地址(如
os.Getenv("ADDR")),务必确保值为:3000或0.0.0.0:3000,而非带 127.0.0.1
验证方式:进容器执行 netstat -tuln | grep :3000,输出中应含 *:3000,不是 127.0.0.1:3000。
Dockerfile 要用多阶段构建 + CGO_ENABLED=0
Fiber 是 Go 应用,静态编译是部署前提。Alpine 镜像不带 glibc,若编译时未禁用 cgo,运行会直接报错 no such file or directory。
关键点:
- 构建阶段用
golang:1.20-alpine(匹配go.mod中的 Go 版本),别用latest - 编译命令必须加
CGO_ENABLED=0 GOOS=linux,例如:go build -a -o app . - 运行阶段推荐
alpine:3.20,不用scratch——否则 Fiber 的/debug/pprof、日志堆栈等排障能力全失效 -
COPY --from=builder只复制二进制,不复制源码、go.mod或vendor,减小镜像体积且防泄露
Deployment 必须配 readinessProbe 和 livenessProbe
Kubernetes 不靠进程是否存活判断服务就绪,而是靠探针。Fiber 启动快,但路由注册、DB 连接、中间件初始化可能有延迟。没探针,流量会打到未准备好的 Pod 上。
推荐最小可行配置(假设端口 3000):
-
readinessProbe:路径/ready,initialDelaySeconds: 5,periodSeconds: 10;在 Fiber 中加路由:app.Get("/ready", func(c *fiber.Ctx) error { return c.SendStatus(fiber.StatusOK) }) -
livenessProbe:路径/health,initialDelaySeconds: 30(留足 DB 初始化时间),periodSeconds: 15 - 两个探针都用
httpGet,别用exec——Fiber 没内置 shell,额外装curl增大攻击面
注意:containerPort 必须和 app.Listen() 端口一致,且 readinessProbe.httpGet.port 要写数字(如 3000),不能写名称。
ConfigMap 和 FIBER_ENV 必须显式注入
Fiber 不读取 .env 文件,也不自动识别 NODE_ENV。多环境配置依赖 os.Getenv("FIBER_ENV"),而 Kubernetes 中该变量不会自动存在。
必须在 Deployment 的 env 字段里声明:
-
- name: FIBER_ENVvalue: "production" - 对应配置文件命名统一为
config.production.json或config-production.toml,避免嵌套路径(如configs/prod/) - 用
viper加载时,顺序要严格:viper.SetConfigFile("./configs/config." + env + ".json")→viper.ReadInConfig()→viper.AutomaticEnv()(否则os.Setenv不生效) - ConfigMap 存非敏感配置(如端口、日志级别),Secret 存密码、密钥——别把 DB 密码写进 ConfigMap
最容易忽略的一点:K8s 中修改 ConfigMap 并不会触发 Fiber 应用重载配置。端口、路由、中间件这些启动期行为完全不变,只有运行时轮询的开关类配置才可能动态生效。


















