首页 » K8s » 第7章 配置与密钥

第7章 配置与密钥

 

本章目录(点击跳转):

本章目标:掌握 ConfigMap 和 Secret 的三种使用方式(环境变量、命令行参数、文件挂载),并学会镜像仓库认证等实战技巧。

7.1 为什么要配置分离

同一个应用镜像,在开发/测试/生产环境数据库地址、开关不同。如果把配置写死在镜像里:

  • 每个环境要构建不同镜像;
  • 改个配置就要重新发版;
  • 密码进了镜像仓库,泄露风险极大。

K8s 的解法:ConfigMap 放普通配置,Secret 放敏感配置,都注入到 Pod 里,镜像保持一份。

7.2 ConfigMap 详解

7.2.1 创建 ConfigMap 的几种方式

# 方式一:字面量(演示用)
kubectl create configmap app-config \
  --from-literal=db-host=mysql.default.svc \
  --from-literal=db-port=3306 \
  --from-literal=log-level=info

# 方式二:从文件(生产常用,一个文件 = 一个 key,内容是 value)
echo "server.port=8080" > app.properties
kubectl create configmap app-config --from-file=app.properties

# 方式三:从目录(目录下所有文件都进来)
kubectl create configmap nginx-conf --from-file=./conf/

# 方式四:YAML(推荐,可进版本管理)
# app-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  db-host: "mysql.default.svc"
  db-port: "3306"              # 注意:value 都是字符串
  log-level: "info"
  app.properties: |            # 整个文件作为一个 key
    server.port=8080
    spring.datasource.url=jdbc:mysql://mysql:3306/mydb
kubectl apply -f app-config.yaml
kubectl get configmap app-config -o yaml
kubectl create configmap app-config --from-file=app.properties --dry-run=client -o yaml
# 最后一句:用 kubectl 生成 YAML,保存下来进 git,很实用

7.2.2 使用方式一:环境变量

apiVersion: v1
kind: Pod
metadata:
  name: cm-env-demo
spec:
  containers:
    - name: app
      image: busybox:1.36
      command: ["sh", "-c", "echo db=$DB_HOST port=$DB_PORT; sleep 3600"]
      env:
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: db-host
        - name: DB_PORT
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: db-port
        # 一次性引入整个 ConfigMap(每个 key 变一个环境变量)
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: log-level
      envFrom:                   # 或者整体引入
        - configMapRef:
            name: app-config
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: cm-env-demo
spec:
  containers:
    - name: app
      image: busybox:1.36
      command: ["sh", "-c", "env | sort; sleep 3600"]
      envFrom:
        - configMapRef:
            name: app-config
EOF
kubectl logs cm-env-demo
kubectl delete pod cm-env-demo

7.2.3 使用方式二:命令行参数

      command: ["python", "app.py"]
      args:
        - "--db=$(DB_HOST):$(DB_PORT)"   # 容器内支持 $(VAR) 插值(需先定义 env)

7.2.4 使用方式三:挂载为文件(配置文件整体更新场景)

apiVersion: v1
kind: Pod
metadata:
  name: cm-file-demo
spec:
  containers:
    - name: app
      image: busybox:1.36
      command: ["sh", "-c", "cat /etc/app/app.properties; sleep 3600"]
      volumeMounts:
        - name: config
          mountPath: /etc/app
  volumes:
    - name: config
      configMap:
        name: app-config
# 应用后查看
kubectl logs cm-file-demo
# 只挂单个 key 为单个文件:
#   volumes:
#     - name: config
#       configMap:
#         name: app-config
#         items:
#           - key: app.properties
#             path: app.properties

7.2.5 修改配置后会发生什么(小白高频疑问)

  • env 方式:ConfigMap 改了,Pod 里的环境变量不会自动变,需要重启 Pod 才生效(kubectl rollout restart deployment xxx)。
  • 文件挂载方式:K8s 会定期同步(默认 1 分钟内)更新文件内容,但应用自己要监听文件变化才会生效(比如 Spring Cloud、Nginx 的 reload 机制)。
# 修改 ConfigMap
kubectl edit configmap app-config
# 让 env 方式生效:重启工作负载
kubectl rollout restart deployment web

7.3 Secret 详解

7.3.1 类型

类型 用途
Opaque(默认) 任意键值对
kubernetes.io/dockerconfigjson 私有镜像仓库认证
kubernetes.io/tls TLS 证书(第 5 章用过)
kubernetes.io/basic-auth / ssh-auth 基础认证/SSH

⚠️ Secret 默认只是 base64 编码,不是加密!base64 是编码不是加密,任何人拿到都能解码。生产要开启 etcd 静态加密(Encryption at Rest)并严格 RBAC。

7.3.2 创建与使用

# 创建
kubectl create secret generic db-secret \
  --from-literal=username=root \
  --from-literal=password='P@ssw0rd'

# 从文件
kubectl create secret generic tls-secret --from-file=ca.crt=./ca.crt

# 查看(注意输出是 base64)
kubectl get secret db-secret -o yaml
# 解码看明文
kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d
# 使用(与 ConfigMap 几乎一样,只是 secretKeyRef)
apiVersion: v1
kind: Pod
metadata:
  name: secret-demo
spec:
  containers:
    - name: app
      image: busybox:1.36
      command: ["sh", "-c", "echo user=$DB_USER pass=$DB_PASS; sleep 3600"]
      env:
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: username
        - name: DB_PASS
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password
kubectl apply -f secret-demo.yaml   # 上面 YAML 存为 secret-demo.yaml
kubectl logs secret-demo
# 输出:user=root pass=P@ssw0rd
kubectl delete pod secret-demo

7.3.3 实战:私有镜像仓库认证

私有镜像拉不下来(ImagePullBackOff)时,多半要配 registry 凭证:

# 创建 dockerconfigjson 类型的 Secret
kubectl create secret docker-registry regcred \
  --docker-server=registry.example.com \
  --docker-username=admin \
  --docker-password=secret \
  --docker-email=admin@example.com

Pod 里引用:

spec:
  imagePullSecrets:
    - name: regcred
  containers:
    - name: app
      image: registry.example.com/myapp:1.0

也可以把 imagePullSecret 写到 ServiceAccount 上,该 SA 的所有 Pod 自动带上。

7.3.4 Secret 使用注意事项

  • Secret 只能被同命名空间的 Pod 引用(跨命名空间要复制或用工具同步)。
  • 不要把 Secret 写进 git;YAML 里只引用名字,不写明文。
  • 审计:kubectl get secret -A 能列出所有,RBAC 要管住(第 8 章)。

7.4 最佳实践清单

  1. 配置进 ConfigMap,敏感进 Secret,镜像里一个不留。
  2. 配置随应用一起进 git(ConfigMap 的 YAML 可以进 git;Secret 用 SealedSecret / SOPS / 云 KMS 等方案加密后管理)。
  3. 用 --dry-run=client -o yaml 把 kubectl 生成的对象落成文件。
  4. 应用做好"配置变更"处理:文件挂载 + 监听变化 > 环境变量(改配置不用重启)。
  5. 每个环境一个 ConfigMap(app-config-dev / app-config-prod),用不同的 Deployment 模板引用。

7.5 本章小结

  • ConfigMap/Secret 三种注入方式:env、args 插值、文件挂载。
  • env 方式改配置必须重启 Pod;文件方式有同步延迟且应用需支持热加载。
  • Secret 是 base64 不是加密,生产要 etcd 加密 + 严格 RBAC。
  • 私有镜像拉不动先查 imagePullSecrets。

下一章:命名空间与权限(RBAC)。

原文链接:第7章 配置与密钥,转载请注明来源!

赞 0