K8s-配置管理

目录

什么是ConfigMap

核心特性

[基于文件创建 ConfigMap](#基于文件创建 ConfigMap)

单个文件创建

多个文件创建

从目录创建

在Pod中使用ConfigMap

[通过 env 注入环境变量(直接引用键值)](#通过 env 注入环境变量(直接引用键值))

[通过 envFrom 批量注入(适用于多个键值对)](#通过 envFrom 批量注入(适用于多个键值对))

以文件形式挂载(适合完整配置文件)

[自定义 ConfigMap 键值对](#自定义 ConfigMap 键值对)

ConfigMap限制

大小限制

命名空间隔离

引用顺序要求

挂载路径限制

数据类型限制

动态更新限制

[静态 Pod 限制](#静态 Pod 限制)

[RBAC 权限控制](#RBAC 权限控制)

加密数据管理Secret

核心特性

使用方式

[创建 Secret](#创建 Secret)

[在 Pod 中使用](#在 Pod 中使用)

安全增强措施

[与 ConfigMap 的对比](#与 ConfigMap 的对比)


什么是ConfigMap

ConfigMap 是 Kubernetes 中的一种 API 对象,用于将非机密性的配置数据(如配置文件、环境变量、命令行参数等)与容器镜像解耦,从而更灵活地管理应用的配置。它通过键值对的形式存储数据,并可以被 Pod 以多种方式引用,使得应用的配置可以独立于代码进行修改和更新。

核心特性

  1. 解耦配置与镜像
    • 将配置数据(如数据库连接字符串、日志级别等)从容器镜像中分离,避免因配置变更而重新构建镜像。
    • 支持动态更新配置(需配合滚动重启或热加载机制)。
  2. 多用途支持
    • 可作为环境变量、命令行参数、配置文件挂载到 Pod 中。
    • 支持存储单个值或整个文件内容。
  3. 非机密性数据
    • ConfigMap 仅用于存储非敏感配置。敏感数据(如密码、密钥)应使用 Secret 对象。

创建 ConfigMap

ConfigMap可以使用目录、单个文件或字符值的方式创建,使用kubectl创建一个ConfigMap的命令格式

复制代码
kubectl create configmap <map-name> <data-source>
  • map-name:ConfigMap的名称。
  • data-sourece:数据源,可以是数据的目录、文件或字符值。

ConfigMap中数据是以键值对的形式保存的,其中:

  • key:文件名或密钥
  • value:文件内容或字符值

基于文件创建 ConfigMap

将本地文件的内容直接存储到 ConfigMap 中,适合配置文件(如 nginx.conf``application.properties)或键值对文件(如 .env)。

单个文件创建

复制代码
# 将文件内容作为 ConfigMap 的一个键(键名为文件名)
kubectl create configmap my-config --from-file=./config.yaml

生成的ConfigMap(yaml)

复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  config.yaml: |
    apiVersion: v1
    database:
      host: db.example.com
      port: 5432

多个文件创建

复制代码
# 将多个文件存储为不同的键
kubectl create configmap my-config \
  --from-file=./config.yaml \
  --from-file=./settings.json

生成的ConfigMap(yaml)

复制代码
data:
  config.yaml: |
    apiVersion: v1
    database: ...
  settings.json: |
    { "logLevel": "debug" }

从目录创建

复制代码
# 将目录下所有文件存储为 ConfigMap(键名为文件名)
kubectl create configmap my-config --from-file=./config-dir/

在Pod中使用ConfigMap

通过 env 注入环境变量(直接引用键值)

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: env-pod
spec:
  containers:
    - name: my-container
      image: nginx
      env:
        - name: DB_HOST  # 环境变量名
          valueFrom:
            configMapKeyRef:
              name: my-config  # ConfigMap 名称
              key: database.host  # ConfigMap 中的键

通过 envFrom 批量注入(适用于多个键值对)

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: envfrom-pod
spec:
  containers:
    - name: my-container
      image: nginx
      envFrom:
        - prefix: APP_  # 可选:为所有环境变量添加前缀
          configMapRef:
            name: my-config

以文件形式 挂载(适合完整配置文件**)**

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: volume-pod
spec:
  containers:
    - name: my-container
      image: nginx
      volumeMounts:
        - name: config-volume
          mountPath: /etc/app/config.yaml  # 容器内路径
          subPath: config.yaml  # 可选:仅挂载 ConfigMap 中的 config.yaml 键
  volumes:
    - name: config-volume
      configMap:
        name: my-config  # ConfigMap 名称

自定义 ConfigMap 键值对

如果不想从文件创建,可以直接在 YAML 中定义 ConfigMap 的键值对:

复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: custom-config
data:
  # 简单键值对
  database.host: "db.example.com"
  database.port: "5432"

  # 多行文本(如配置文件)
  nginx.conf: |
    user nginx;
    events {
        worker_connections 1024;
    }
    http {
        server {
            listen 80;
            server_name example.com;
        }
    }

ConfigMap限制

ConfigMap 在 Kubernetes 中虽能高效管理配置,但存在以下关键限制,需在设计和使用时重点关注:

大小限制

  • 默认上限 :单个 ConfigMap 的数据大小不能超过 1MB(具体限制可能因 Kubernetes 版本或集群配置略有差异)。
  • 应对策略
    • 将大型配置拆分为多个 ConfigMap(如按功能模块划分)。
    • 使用其他存储方案(如数据库、独立文件服务或持久化卷 PV)。
    • 对于敏感数据,优先使用 Secret(同样有 1MB 限制,但更适合加密存储)。

命名空间隔离

  • 作用域限制:ConfigMap 仅在创建它的命名空间(Namespace)内可见,不同命名空间的 Pod 无法互相引用。
  • 示例 :若 ConfigMap my-config 位于 dev 命名空间,则 prod 命名空间的 Pod 无法使用它。

引用顺序要求

  • 依赖关系:Pod 必须在 ConfigMap 创建后才能引用它。若 ConfigMap 不存在,Pod 会启动失败并报错。
  • 解决方式
    • 通过 kubectl apply -f 先创建 ConfigMap,再部署 Pod。
    • 使用 Helm 或 Kustomize 等工具管理资源依赖关系。

挂载路径限制

  • 目录挂载 :通过 volumeMounts 挂载 ConfigMap 时,mountPath 必须是目录路径,不能直接挂载为单个文件。

  • 文件覆盖 :挂载后,容器内目标目录下的原有文件会被 ConfigMap 的内容覆盖(除非使用 subPath 指定单个文件)。

  • 示例:

    volumes:
    - name: config-volume
    configMap:
    name: my-config
    items: # 可选:仅挂载特定键
    - key: "config.yaml"
    path: "config.yaml" # 挂载为目录下的单个文件
    volumeMounts:
    - name: config-volume
    mountPath: "/etc/app" # 必须是目录
    readOnly: true

数据类型限制

  • 仅支持字符串:ConfigMap 的所有数据(键和值)必须为字符串类型。若需存储非字符串数据(如数字、布尔值),需手动转换为字符串格式。

  • 多行文本 :可通过 |> 符号存储多行内容(如配置文件):

    data:
    nginx.conf: |
    server {
    listen 80;
    server_name example.com;
    }

动态更新限制

  • 更新不自动生效:修改 ConfigMap 后,已挂载的 Pod 不会自动感知变化(除非应用支持热加载或重启 Pod)。
  • 触发更新方式
    • 手动重启 Pod(如通过 kubectl rollout restart)。
    • 使用第三方工具(如 Argo Rollouts)实现自动滚动更新。

静态 Pod 限制

  • 无法引用 :通过 --manifest-url--config 自动创建的静态 Pod(由 kubelet 直接管理)无法引用 ConfigMap。
  • 替代方案:将静态 Pod 转换为常规 Pod(通过 Deployment 或 DaemonSet 管理)。

RBAC 权限控制

  • 需显式授权 :若集群启用了 RBAC,需确保服务账号(ServiceAccount)有权限读取 ConfigMap(通过 RoleClusterRole 绑定 configmaps 资源)。

  • 示例 RBAC 规则

    rules:
    - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "watch"]

加密数据管理Secret

在 Kubernetes 中,Secret 是一种用于存储和管理敏感信息的核心资源对象,专门用于解决密码、令牌、密钥等敏感数据的配置问题,避免将这些数据直接暴露在镜像或 Pod 规约中

核心特性

  1. 敏感数据保护
    • 存储密码、OAuth 令牌、SSH 密钥、TLS 证书等敏感信息,防止硬编码在镜像或配置文件中。
    • 默认以 Base64 编码存储(非加密),但可通过集群级加密增强安全性。
  2. 灵活访问控制
    • 支持通过 RBAC(基于角色的访问控制) 限制访问权限,确保只有授权的 Pod 或用户能读取 Secret。
  3. 动态更新能力
    • 修改 Secret 后,挂载为 Volume 的 Pod 可自动同步更新(默认 1 分钟同步周期),但通过 环境变量 引用的需重启 Pod 生效。
  4. 类型化支持

使用方式

创建 Secret
  • 命令行创建

    从键值对创建 Opaque Secret

    kubectl create secret generic my-secret --from-literal=username=admin --from-literal=password=1f2d1e2e67df

    从文件创建 TLS Secret

    kubectl create secret tls tls-secret --cert=path/to/cert.pem --key=path/to/key.pem

  • YAML定义:

    apiVersion: v1
    kind: Secret
    metadata:
    name: db-secret
    type: Opaque
    data:
    username: YWRtaW4= # Base64 编码的 "admin"
    password: MWYyZDFlMmU2N2Rm # Base64 编码的 "1f2d1e2e67df"

在 Pod 中使用
  • 作为环境变量

    apiVersion: v1
    kind: Pod
    metadata:
    name: secret-env-pod
    spec:
    containers:
    - name: my-container
    image: nginx
    env:
    - name: DB_USERNAME
    valueFrom:
    secretKeyRef:
    name: db-secret
    key: username
    - name: DB_PASSWORD
    valueFrom:
    secretKeyRef:
    name: db-secret
    key: password

  • 挂载为 Volume

    apiVersion: v1
    kind: Pod
    metadata:
    name: secret-volume-pod
    spec:
    containers:
    - name: my-container
    image: nginx
    volumeMounts:
    - name: secret-volume
    mountPath: "/etc/secrets"
    readOnly: true
    volumes:
    - name: secret-volume
    secret:
    secretName: db-secret

  • 用于 Docker 镜像拉取

    apiVersion: v1
    kind: Pod
    metadata:
    name: private-reg-pod
    spec:
    containers:
    - name: my-container
    image: myprivateregistry.com/myapp:latest
    imagePullSecrets:
    - name: my-reg-secret # 引用预先创建的 Docker 仓库认证 Secret

安全增强措施

  1. 启用静态加密
  • 使用 EncryptionConfigEncryptionProvider 插件(如 AES-CBC、KMS)对存储在 etcd 中的 Secret 数据加密:

    apiVersion: apiserver.config.k8s.io/v1
    kind: EncryptionConfiguration
    resources:
    - resources: ["secrets"]
    providers:
    - aescbc:
    keys:
    - name: key1
    secret: <base64-encoded-32-byte-key>

  • 更新 API Server 配置并重启以应用加密:

    --encryption-provider-config=/path/to/encryption-config.yaml

最小权限原则

  • 通过 RBAC 限制 Secret 的访问权限,例如:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
    namespace: default
    name: secret-reader
    rules:
    - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "list", "watch"]

  1. 定期轮换与审计
    • 定期更新 Secret 内容(如密码、证书),并审计使用情况以降低泄露风险。
  2. 集成外部密钥管理
    • 使用 HashiCorp VaultAWS Secrets Manager 等外部工具管理 Secret,通过 CSI 驱动或初始化容器动态注入。

与 ConfigMap 的对比

特性 Secret ConfigMap
数据类型 敏感数据(密码、密钥、证书) 非敏感配置(环境变量、配置文件)
存储方式 Base64 编码(默认)或加密存储 明文存储
更新生效 Volume 挂载自动同步,环境变量需重启 需应用支持热加载或重启
典型场景 数据库凭证、TLS 证书、API 令牌 Nginx 配置、应用属性文件