Skip to content

ConfigMap 和 Secret

概述

  几乎所有应用都需要配置信息,并且这些配置数据不庆该被嵌入应用本身。一般情况下,传递配转走选项给容器化应用程序的方法是借助环境变量或配置文件。在 Kubernetes 中,用于存储配置数据的资源称为 ConfigMap。如果需要给容器传递一些敏感数据,则可以使用 Secret。

  Kubernetes 通过仅仅将 Secret 分发到需要访问 Secret 的 Pod 所在的机器节点来保障其安全性。另外,Secret 只会存储在节点的内存中,永不写入物理存储,这样从节点上删除 Secret 时就不需要擦除磁盘了。

  无论是否使用 ConfigMap、Secret 存储配置数据,以下方法均可被用作配置你的应用程序:

  • 向容器传递命令行参数
  • 为每个容器设置自定义环境变量
  • 通过特殊类型的卷将配置文件挂载到容器中

配置容器

通过命令行参数向容器传递配置

  在 Pod 声明时,可以通过以下方式覆盖容器的启动方法,从而达到通过命令行参数向容器传递配置。

yaml
kind: Pod
spec:
  containers:
  - image: some/image
    command: ["/bin/command"]
    args: ["arg1", "arg2", "arg3" ]

通过环境变量向容器传递配置

  在 Pod 声明中,通过以下方式为容器手动添加环境变量。Pod 通过读取环境变量即可完成外部控制容器的目标。

yaml
kink: Pod
spec:
  containers:
  - image: luksa/fortune:env
    env:
    - name: INTERVAL
      value: "30"
    name: html-generator
...

  在环境变量中还可以引用其他环境变量

yaml
env:
- name: FIRST_VAR
  value: "foo"
- name: SECOND_VAR
  value: "$(FIRST_VAR)bar"

ConfigMap

创建 ConfigMap

  从简单的字面量条目创建 ConfigMap。

yaml
# 通过指令创建 ConfigMap
# ConfigMap 中的键名必须是一个合法的 DNS 子域,仅包含数字、字母、破折号、下画划以及圆点
$ kubectl create configmap fortune-config --from-literal=sleep-interval=25 --from-literal=foo=bar --from-literal=bar=baz

# 查看 ConfigMap 定义
$ kubectl get configmap fortune-config -o yaml

  从配置文件创建 ConfigMap。

yaml
# 通过文件创建配置
$ kubectl create configmap my-config --from-file=customkey=config-file.conf

# 还可以直接引入某一文件夹中的所有文件
$ kubectl create configmap my-config --fromfile=/path/to/dir

给容器传递 ConfigMap 条目作为环境变量

  在 Pod 的声明中,通过 valueFrom 引用 ConfigMap 里面的值。

yaml
apiVersion: v1
kind: Pod
metadata:
  name: fortune-env-from-configmap
spec:
  containers:
  - image: luksa/fortune:env
    env:
    - name: INTERVAL
      valueFrom:
        configMapKeyRef:
          name: fortune-config
          key: sleep-interval
...

  可以通过 evnFrom 一次性传递 ConfigMap 的所有条目作为环境变量。

yaml
apiVersion: v1
kind: Pod
metadata:
  name: fortune-env-from-configmap
spec:
  containers:
  - image: some-image
    envFrom:
    - prefix: CONFIG_         # 所有引入的环境变量均包含前缀 CONFIG_
      configMapRef:           # 引用名为 my-config-map 的 ConfigMap
        name: my-config-map

传递 ConfigMap 的条目作为命令行参数

yaml
apiVersion: v1
kind: Pod
metadata:
  name: fortune-args-from-configmap
spec:
  containers:
  - image: luksa/fortune:args
    env:
    - name: INTERVAL
      valueFrom:
        configMapKeyRef:
          name: fortune-config
          key: sleep-interval
    args: ["$(INTERVAL)"]

使用 ConfigMap 卷将条目暴露为文件

  环境变量或者命令行参数值作为配置值通常用于变量值较短的场景。由于 ConfigMap 中可以包含完整的配置文件内容,当你想要将其暴露给容器时,可以借助前面章节提到过的一种称为 configMap 卷的特殊卷格式。

yaml
apiVersion: v1
kind: Pod
metadata:
  name: fortune-configmap-volume
spec:
  containers:
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: config
      mountPath: /etc/nginx/conf.d   # 挂载 configMap 卷至这个位置
      readOnly: true
  volumes:
  - name: config
    configMap:
      name: fortune-config           # 卷定义引用 fortune-config ConfigMap
      defaultMode: "6600"            # 设置所有文件的权限为 -rw-rw--
bash
# 查看 /etc/nginx/conf.d 下的内容,可以看到 ConfigMap 下两个条目都被暴露成文件
$ kubectl exec fortune-configmap-volume -c web-service ls /etc/nginx/conf.d
my-nginx-config.conf
sleep-interval
yaml
volumes:
- name: config
  configMap:
    name: fortune-config
    items:
    - key: my-nginx-config.conf       # 该键对应的条目被包含
      path: gzip.conf                 # 条目的值被存储在该文件中
yaml
spec:
  containers:
  - image: some/image
    volumeMounts:
    - name: myvolume
      mountPath: /etc/someconfig.conf   # 挂载至某一文件,而不是文件夹
      subPath: myconfig.conf            # 仅挂载指定的条目 myconfig.conf,并非完整的卷

Secret

创建 Secret

  

yaml
apiVersion: v1
kind: Secret
stringData:
  foo: plain text
data:
  https.cert: xxxxx
  https.key: yyyyy

挂载 Secret

  

yaml
apiVersion: v1
kind: Pod
metadata:
  name: fortune-https
sepc:
  containers:
  - image: luksa/fortune:env
    name: html-generator
    env:
    - name: INTERVAl
      valueFrom:
        configMapKeyRef:
          name: fortune-config
          key: sleep-interval
    - name: FOO_SECRET                  # 通过 Secret 条目设置环境
      valueFrom:
        secretKeyRef:
          name: fortune-https           # Secret 的键
          key: foo                      # Secret 的名称
    volumnMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    - name: config
      mountPath: /etc/nginx/conf.d
      readOnly: true
    - name: certs                      # 配置 Nginx 从 /etc/nginx/certs 中读取证书和密钥文件,需将 secret 卷挂载于此
      mountPath: /etc/nginx/certs
      readOnly: true
    ports:
    - containerPort: 80
    - containerPort: 443
  volumes:
  - name: html
    emptyDir: {}
  - name: config
    configMap:
      name: fortune-config
      items:
      - key: my-nginx-config.conf
        path: https.conf
  - name: certs                       # 引用 fortune-https Secret 来定义 secret 卷
    secret:
      secretName: fortune-https

Released under the MIT license.