Pod设置中文

Pod为什么乱码?

简单说,Linux程序显示中文依赖三个东西:

  1. 语言环境变量LANGLC_ALL
  2. locale数据包/usr/lib/locale/下的二进制文件)
  3. 字符集支持(通常是zh_CN.UTF-8

K8S默认不注入任何语言环境,Pod继承的是镜像的默认值 。多数官方镜像(比如nginx:alpine、node:16-slim)把LANG设成了C或干脆没设,结果就是程序按ASCII解析中文。

坑爹的是:你改了Dockerfile的ENV LANG=zh_CN.UTF-8,本地docker run正常,一上K8S又乱码——因为K8S的env会覆盖镜像里的环境变量(如果没显式声明的话)。我在这卡了半天,后来发现是Helm模板里有个全局env配置把值冲掉了。

2步根治方案

第1步:镜像里装好locale并生成中文包

Dockerfile(基于Debian/Ubuntu)

FROM ubuntu:22.04
 
# 安装locales包(Ubuntu最小镜像经常没有)
RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/*
 
# 生成中文locale(这一步很多人漏了)
RUN locale-gen zh_CN.UTF-8
 
# 设置默认语言环境
ENV LANG=zh_CN.UTF-8 \
    LANGUAGE=zh_CN:zh \
    LC_ALL=zh_CN.UTF-8

Dockerfile(CentOS/RockyLinux)

FROM rockylinux:9
 
RUN dnf install -y glibc-langpack-zh && dnf clean all
ENV LANG=zh_CN.UTF-8 \
    LC_ALL=zh_CN.UTF-8

验证镜像是否成功(构建后本地跑一下):

docker run --rm your-image locale
# 看到LANG=zh_CN.UTF-8就是对了

第2步:Pod配置里显式声明环境变量(关键!)

Deployment YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-chinese
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: main
        image: your-registry/app:latest
        env:
        # 这里必须写,防止被K8S默认值覆盖
        - name: LANG
          value: zh_CN.UTF-8
        - name: LC_ALL
          value: zh_CN.UTF-8
        - name: LANGUAGE
          value: zh_CN:zh

为什么一定要写这三行?
K8S启动容器时,环境变量的优先级是:Pod定义 > 镜像ENV > 基础镜像默认值。如果不显式声明,有些CI/CD系统或运维平台会偷偷注入LANG=C

Alpine镜像的特殊方式

Alpine用musl libc而不是glibc,默认连locale命令都没有。如果你非得用Alpine(比如为了体积),有两个办法:

方案1:装musl-locales(推荐,体积增加约5MB)

FROM alpine:3.19
 
RUN apk add --no-cache musl-locales musl-locales-lang
ENV LANG=zh_CN.UTF-8 \
    LC_ALL=zh_CN.UTF-8

方案2:不改镜像,用C.UTF-8兜底(不完美但省事)

env:
- name: LANG
  value: C.UTF-8  # Alpine自支持,但中文排序可能会怪

注意:Alpine 3.17以下版本连C.UTF-8都没有,老老实实升级或用Debian基础镜像。

总结

  1. 镜像里必须locale-gen zh_CN.UTF-8,光设环境变量没用。
  2. Pod的YAML里显式写env: LANG=zh_CN.UTF-8,防止被覆盖。
  3. Alpine单独处理,用musl-locales或至少C.UTF-8
  4. 验证用datelocale -a,比瞎猜快十倍。