Kubernetes 配置管理

目录

前言:为什么需要 K8s 配置管理?

一、为什么需要 ConfigMap 和 Secret?

二、ConfigMap:非敏感配置的管理工具

1. 什么是 ConfigMap?

2. 实战:创建 ConfigMap 的 4 种方式

① 基于目录创建(多文件批量导入)

② 基于单个文件创建(指定 key 名)

③ 基于 ENV 文件创建(key=value 格式)

④ 基于命令行键值对创建(少量配置)

3. 实战:在 Pod 中使用 ConfigMap

① 作为环境变量注入

② 作为文件挂载

③ 高级技巧:自定义文件名和权限

④ 解决挂载覆盖问题:SubPath

4. ConfigMap 的使用限制

三、Secret:敏感信息的安全管理

1. 实战:创建 Secret 的 2 种方式

① 用命令行从文件创建

② 用 YAML 文件创建(手动编码)

2. 在 Pod 中使用 Secret

① 作为文件挂载(推荐,支持动态更新)

② 作为环境变量

3. 解码 Secret

四、总结


前言:为什么需要 K8s 配置管理?

在传统应用中,配置文件常存在本地或代码仓库,容器化后因节点不固定、镜像与配置耦合,修改配置需重新构建镜像,十分繁琐。
Kubernetes 通过ConfigMap(非敏感配置)和Secret(敏感配置)解决这一问题,实现配置与镜像解耦,提升灵活性与安全性。

一、为什么需要 ConfigMap 和 Secret?

在容器化部署中,配置文件如果打包进镜像,改配置就得重新构建镜像,非常麻烦;而且密码、令牌等敏感信息明文存放也存在安全风险。

Kubernetes 的ConfigMapSecret就是为解决这些问题而生的:

  • ConfigMap:存储非敏感配置(如 Nginx 配置、环境变量),实现配置与镜像解耦,改配置不用重打包。
  • Secret:存储敏感信息(如密码、API 密钥),通过编码方式保护数据,比明文更安全。
  • 两者都能灵活注入到 Pod 中,支持环境变量、文件挂载等方式,适配各种应用场景

二、ConfigMap:非敏感配置的管理工具

1. 什么是 ConfigMap?

ConfigMap 是 Kubernetes 中用于存储非加密配置数据的键值对资源,数据存在 etcd 中,可作为环境变量、命令行参数或文件挂载到 Pod。

核心优势

  • 配置与 Pod 解耦,改配置不用重新构建镜像。
  • 支持多种创建方式,适配不同配置格式(单个文件、目录、键值对等)。
  • 限制:数据大小不超过 1MiB,不适合存大量数据。

2. 实战:创建 ConfigMap 的 4 种方式

① 基于目录创建(多文件批量导入)

适合有多个配置文件的场景,比如应用的多个环境配置。

# 1. 创建测试目录和文件
mkdir /conf
echo "This is file01" > /conf/file01.conf
echo "This is file02" > /conf/file02.conf

# 2. 从目录创建ConfigMap
kubectl create configmap game-config-1 --from-file=/conf/

# 3. 查看结果(key默认是文件名)
kubectl get cm game-config-1 -o yaml

输出解析

data:
  file01.conf: "This is file01"
  file02.conf: "This is file02"

目录下的每个文件会成为 ConfigMap 的一个键值对,文件名是 key,文件内容是 value。

代码解释

  • 先创建一个/conf目录,并在其中生成两个配置文件file01.conf和file02.conf。​
  • 使用kubectl create configmap命令,通过--from-file=/conf/指定从目录创建,K8s 会将目录下所有文件以 “文件名:文件内容” 的键值对形式存入 ConfigMap。​
  • 最后用kubectl get cm命令查看创建的 ConfigMap 详情,-o yaml表示以 YAML 格式输出。
② 基于单个文件创建(指定 key 名)

如果想自定义 key 名称,而非使用默认文件名,可以用--from-file=<自定义key>=<文件路径>

# 1. 创建测试文件
echo "This is game config" > /conf/game.cfg

# 2. 自定义key创建ConfigMap
kubectl create configmap game-config-2 --from-file=app.conf=/conf/game.cfg

# 3. 查看结果
kubectl get cm game-config-2 -o yaml

代码解释:​

  • 先创建一个game.cfg文件并写入内容。​

  • 创建 ConfigMap 时,通过--from-file=app.conf=/conf/game.cfg自定义 key 为app.conf,值为game.cfg的文件内容。​

  • 查看结果时,能看到 ConfigMap 中以自定义的app.conf作为 key。

输出解析

data:
  app.conf: "This is game config"  # key是自定义的app.conf
③ 基于 ENV 文件创建(key=value 格式)

适合存储环境变量配置,直接导入key=value格式的文件。

# 1. 创建ENV文件
cat << EOF > /conf/app-env.cfg
DB_HOST=mysql
DB_PORT=3306
EOF

# 2. 从ENV文件创建
kubectl create configmap app-env-config --from-env-file=/conf/app-env.cfg

# 3. 查看结果(直接解析为键值对)
kubectl get cm app-env-config -o yaml

代码解释:​

  • 用cat << EOF语法创建一个app-env.cfg文件,其中内容为key=value格式的环境变量配置。​
  • 通过--from-env-file参数从 ENV 文件创建 ConfigMap,K8s 会自动将文件中的key=value解析为 ConfigMap 的键值对。

输出解析

data:
  DB_HOST: "mysql"
  DB_PORT: "3306"
④ 基于命令行键值对创建(少量配置)

适合配置项较少的场景,直接在命令行指定key=value

# 创建包含两个键值对的ConfigMap
kubectl create configmap spec-config --from-literal=log_level=info --from-literal=max_conn=100

# 查看结果
kubectl get cm spec-config -o yaml

代码解释:​

  • 使用--from-literal参数直接在命令行定义键值对,多个键值对可多次使用该参数。这里创建了log_level=info和max_conn=100两个配置项。​
  • 这种方式适合配置项较少的情况,无需创建额外文件。

输出解析

data:
  log_level: "info"
  max_conn: "100"

3. 实战:在 Pod 中使用 ConfigMap

① 作为环境变量注入

适合需要通过环境变量读取配置的应用(如 Java 应用的spring.profiles.active)。

# env-test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: env-test-pod
spec:
  containers:
  - name: test-container
    image: busybox:v1
    command: ["sh", "-c", "env"]  # 输出环境变量
    env:
    # 单个环境变量(自定义变量名)
    - name: LOG_LEVEL  # 容器内的环境变量名
      valueFrom:
        configMapKeyRef:
          name: spec-config  # 引用的ConfigMap名称
          key: log_level     # 引用的key
    # 批量注入所有键值对
    envFrom:
    - configMapRef:
        name: app-env-config  # 引用包含DB_HOST、DB_PORT的ConfigMap
  restartPolicy: Never

部署并验证

kubectl create -f env-test-pod.yaml
kubectl logs env-test-pod  # 会输出LOG_LEVEL=info、DB_HOST=mysql等变量

配置解析

  • valueFrom:单独引用 ConfigMap 中的某个 key,可自定义环境变量名。
  • envFrom:批量导入 ConfigMap 的所有键值对,变量名与 key 一致。
② 作为文件挂载

适合需要读取配置文件的应用(如 Nginx 的nginx.conf)。

# file-mount-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: file-mount-pod
spec:
  containers:
  - name: test-container
    image: nginx:1.7.9
    volumeMounts:
    - name: config-volume  # 关联下面的卷名
      mountPath: /etc/config  # 挂载到容器的目录
  volumes:
  - name: config-volume
    configMap:
      name: game-config-1  # 引用的ConfigMap名称

部署并验证

kubectl create -f file-mount-pod.yaml
kubectl exec -ti file-mount-pod -- ls /etc/config  # 会看到file01.conf、file02.conf

配置解析

  • ConfigMap 的每个 key 会以文件形式出现在/etc/config目录下,文件内容为对应的 value3。
③ 高级技巧:自定义文件名和权限

如果需要修改挂载后的文件名或权限,可以通过items配置:

volumes:
- name: config-volume
  configMap:
    name: game-config-1
    items:
    - key: file01.conf  # ConfigMap中的key
      path: app1.cfg    # 挂载后的文件名
      mode: 0644        # 文件权限(八进制)
    - key: file02.conf
      path: app2.cfg
      mode: 0755
④ 解决挂载覆盖问题:SubPath

直接挂载 ConfigMap 会覆盖容器内的目录(原目录文件会丢失),用subPath可只挂载单个文件,不影响其他内容:

volumeMounts:
- name: config-volume
  mountPath: /etc/nginx/nginx.conf  # 容器内的目标文件
  subPath: nginx.conf  # ConfigMap中对应的key(文件名)

适用场景:修改 Nginx 配置文件时,不覆盖/etc/nginx目录下的其他文件。

4. ConfigMap 的使用限制

  • 必须先创建 ConfigMap,再创建引用它的 Pod(否则 Pod 启动失败,状态为Pending
  • 引用的key必须存在于 ConfigMap 中(否则 Pod 启动失败,状态为ContainerCreating
  • ConfigMap 和 Pod 必须在同一个命名空间(比如都在default下)
  • 数据大小不能超过 1MiB(约 100 万字符,足够存常规配置)
  • 不能存敏感信息(比如密码,敏感信息用 Secret

三、Secret:敏感信息的安全管理

Secret 用于存储密码、令牌等敏感信息,与 ConfigMap 用法类似,但数据会经过 Base64 编码(注意:编码不是加密,生产环境需配合集群加密配置)

1. 实战:创建 Secret 的 2 种方式

① 用命令行从文件创建

适合从现有密钥文件(如 SSH 密钥)创建 Secret:

# 1. 创建存储敏感信息的文件
echo -n "admin" > ./username.txt  # 用户名(-n避免换行)
echo -n "mypassword" > ./password.txt  # 密码

# 2. 从文件创建Secret
kubectl create secret generic db-creds --from-file=./username.txt --from-file=./password.txt

查看结果

kubectl get secret db-creds -o yaml  # 数据会显示为Base64编码
② 用 YAML 文件创建(手动编码)

适合直接定义敏感信息,需先手动 Base64 编码:

# 1. 对明文进行Base64编码
echo -n "admin" | base64  # 输出:YWRtaW4=
echo -n "mypassword" | base64  # 输出:bXlwYXNzd29yZA==

# 2. 创建YAML文件
cat << EOF > db-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque  # 通用类型,存储键值对
data:
  username: YWRtaW4=  # 编码后的用户名
  password: bXlwYXNzd29yZA==  # 编码后的密码
EOF

# 3. 创建Secret
kubectl create -f db-secret.yaml

2. 在 Pod 中使用 Secret

与 ConfigMap 完全一致,支持环境变量和文件挂载:

① 作为文件挂载(推荐,支持动态更新)
# secret-mount-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secret-mount-pod
spec:
  containers:
  - name: test-container
    image: nginx:1.7.9
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secret  # 挂载目录(只读)
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: db-secret  # 引用的Secret名称

验证

kubectl create -f secret-mount-pod.yaml
kubectl exec -ti secret-mount-pod -- cat /etc/secret/username  # 输出admin
② 作为环境变量
env:
- name: DB_USERNAME
  valueFrom:
    secretKeyRef:
      name: db-secret
      key: username

3. 解码 Secret

查看 Secret 时数据是编码后的,可用以下命令解码:

# 1. 获取编码后的密码
kubectl get secret db-secret -o jsonpath='{.data.password}'  # 输出bXlwYXNzd29yZA==
# 2. 解码
echo "bXlwYXNzd29yZA==" | base64 --decode  # 输出mypassword

四、总结

Kubernetes 的配置管理核心是解耦与安全

  • ConfigMap:管理非敏感配置,支持多种创建和挂载方式,灵活适配各类应用,记住避免存储大量数据(≤1MiB)。
  • Secret:管理敏感信息,通过编码保护数据,用法与 ConfigMap 一致,但需注意编码并非加密。
  • 两者都能通过环境变量或文件挂载注入 Pod,实际使用时根据数据敏感性选择合适的工具,同时遵守命名空间、创建顺序等限制。

你可能感兴趣的:(kubernetes,容器,云原生)