K8s-配置管理

发布于:2025-07-09 ⋅ 阅读:(15) ⋅ 点赞:(0)

目录

什么是ConfigMap

核心特性

基于文件创建 ConfigMap

单个文件创建

多个文件创建

从目录创建

在Pod中使用ConfigMap

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

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

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

自定义 ConfigMap 键值对

ConfigMap限制

大小限制

命名空间隔离

引用顺序要求

挂载路径限制

数据类型限制

动态更新限制

静态 Pod 限制

RBAC 权限控制

加密数据管理Secret

核心特性

使用方式

创建 Secret

在 Pod 中使用

安全增强措施

与 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.confapplication.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(通过 Role 或 ClusterRole 绑定 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. 类型化支持
    • Opaque:通用类型,存储任意 Base64 编码数据(如密码、密钥)。
    • kubernetes.io/service-account-token:存储服务账号令牌,自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount
    • kubernetes.io/dockercfg / kubernetes.io/dockerconfigjson:存储私有 Docker 仓库认证信息。
    • kubernetes.io/tls:存储 TLS 证书和私钥,用于加密通信。

使用方式

创建 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. 启用静态加密
  • 使用 EncryptionConfig 和 EncryptionProvider 插件(如 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 配置、应用属性文件