Kubernetes笔记(8) - ConfigMap和Secret

<!-- /code_chunk_output -->mysql

ConfigMap和Secret是Kubernetes系统上两种特殊类型的存储卷,ConfigMap对象用于为容器中的应用提供配置数据,Secret对象则用于提供密钥、证书等敏感的配置信息。它们将相应的配置信息保存于对象中,然后在Pod资源上以存储卷的形式将其挂载并获取相关的配置,以实现配置与镜像文件的解耦。nginx

ConfigMap

配置自己源于代码,是为了提升代码的灵活性而提取出来的一些常常变化的或须要定制的内容。已有一些开源的分布式系统配置管理系统如Apollo、Diamond、Disconf等。ConfigMap则是Kubernetes提供的统一配置管理方案,一个ConfigMap对象就是一系列配置数据的集合,这些数据可“注入”到Pod对象中,并为容器应用所使用,注入方式有两种redis

  • 挂载为存储卷
  • 传递为环境变量

建立ConfigMap对象

ConfigMap对象将配置数据以键值对的形式进行存储,能够使用kubectl create命令建立sql

kubectl create configmap <map-name> <data-source>

map-name为ConfigMap对象的名称,而data-source是数据源,它能够经过这几种方式来获取docker

  • 字面值
  • 文件
  • 目录
  • 配置清单

不管采用哪种方式,都要被转换为ConfigMap对象中的Key-Value数据。json

基于字面值建立

使用--from-literal选项可在命令行直接提供键值对:api

kubectl create configmap literal-config --from-literal=key1=value1

建立后能够使用kubectl get configmaps dir-config -o yaml命令查看。app

基于文件建立

基于文件建立时要使用--from-file选项:分布式

kubectl create configmap file-config --from-file=8_config_file.txt

这种方式建立的ConfigMap对象,其数据存储的键为文件名,值为文件内容学习

apiVersion: v1
data:
  8_config_file.txt: |-
    test
    config
    from
    file
kind: ConfigMap

自定义键名的方式:

kubectl create configmap file-config --from-file=file-key1=8_config_file.txt

基于目录建立

使用--from-file选项时,若是指定的是文件目录,kubectl会将目录下的文件分别建立为键值数据。

kubectl create configmap dir-config --from-file=.

使用配置清单建立

配置清单须要指定apiVersion、kind、metadata、data字段,data字段用于存储键值数据:

apiVersion: v1
kind: ConfigMap
metadata:
  name: yaml-config
data:
  key1: value1
  key2: value2

经过环境变量传递ConfigMap数据

ConfigMap是名称空间级别的资源,它必须与引用它的Pod资源在同一空间中; 经过环境变量传递ConfigMap的格式为:

env:
- name: <env-name>
  valueFrom:
    configMapKeyRef: 
      name: <configmap-name>
      key: <key-name>
      optional: <bool>

若是optional指定为false,则建立引用了ConfigMap资源的Pod对象时,被引用的资源必须事先存在,不然将没法启动容器,直到被依赖的资源建立完成为止。 示例:

apiVersion: v1
kind: Pod
metadata:
  name: env-test-pod
  labels:
    app: label-env-test-pod
spec:
  containers:
  - name: env-test-container
    image: busybox
    command: ["/bin/sh", "-c", "env"]
    env:
    - name: MY_KEY1
      valueFrom:
        configMapKeyRef: 
          name: yaml-config
          key: key3
          optional: true
    - name: MY_KEY2
      valueFrom:
        configMapKeyRef: 
          name: yaml-config
          key: key4
          optional: true

envFrom

有时容器须要引用不少ConfigMap资源中的键值数据,这种状况下若是为容器逐一配置环境变量会很是繁琐,并且很差维护。使用envFrom字段能够直接将ConfigMap资源中的全部键值一次性导入。格式为:

envFrom:
- prefix: <prefix>
  configMapRef:
    name: <configmap-name>
    optional: <bool>

经过ConfigMap存储卷传递数据

若是在ConfigMap中的值体积较大,好比存放的是给容器应用提供的配置文件,那么使用环境变量将其导入会使得变量值占据过多的内存空间并且不易处理。这时建议经过ConfigMap存储卷的方式能够将内容直接做为文件进行引用。

挂载整个存储卷

关联为Pod资源的存储卷时,ConfigMap对象中的每一个键都对应地表现为一个文件,键名为文件名

apiVersion: v1
kind: Pod
metadata:
  name: configmap-vol
  labels:
    app: configmap-vol
spec:
  containers:
  - name: configmap-vol
    image: busybox
    command: ["/bin/sh", "-c", "sleep 3600"]
    volumeMounts:
    - name: config-vol
      mountPath: /etc/test
      readOnly: true
  volumes:
  - name: config-vol
    configMap:
      name: file-config

挂载后能够将键名做为文件名来查看内容:

kubectl exec configmap-vol -- cat /etc/test/file-key1

挂载存储卷中的部分键值

有时并不但愿挂载ConfigMap中的全部内容,能够只挂载存储卷中的部分键值。 格式为:

volumes:
- name: config-vol
  configMap:
    name: file-config
    items:
    - key: file-key1
      path: file-key1

Secret

Secret资源的功能相似于ConfigMap,但它专用于存放敏感数据,例如密码、数字证书、私钥、令牌和SSH key等。 与ConfigMap相似,Secret以键值方式存储数据,在Pod资源中经过环境变量或存储卷进行数据访问。 Secret对象的数据的存储及打印格式为Base64编码的字符串,在容器中以环境变量或存储卷的方式访问时,它们会被自动解码为明文格式。 Secret对象主要有两种用途:

  • 做为存储卷注入到Pod上由容器应用程序所使用
  • 用于kubelet为Pod里的容器拉取镜像时向私有仓库提供认证信息

Secret资源分为四种类型:

  • Opaque:自定义数据内容;base64编码,用来存储密码、密钥、信息、证书等数据,类型标识符为generic。‰
  • kubernetes.io/service-account-token:Service Account的认证信息,可在建立Service Accout时由Kubernetes自动建立。‰
  • kubernetes.io/dockerconfigjson:用来存储Docker镜像仓库的认证信息,类型标识为docker-registry。‰
  • kubernetes.io/tls:用于为SSL通讯模式存储证书和私钥文件,命令式建立时类型标识为tls。

建立Secret资源

命令式建立

直接使用字面值建立:

kubectl create secret generic mysql-auth --from-literal=username=root --from-literal=password=password1

查看base64编码后的内容:

✗ kubectl get secret mysql-auth -o yaml
apiVersion: v1
data:
  password: cGFzc3dvcmQx
  username: cm9vdA==

使用generic标识建立的Secret为Opaque类型。下面的示例使用了tls标识来建立tls类型的Secret:

kubectl create secret tls nginx-ssl --key=./nginx.key --cert=./nginx.crt

建立成功后名称固定为tls.key和tls.crt,不受证书和私钥文件的名称的影响。

基于配置清单建立

基于配置清单建立的示例:

apiVersion: v1
kind: Secret
metadata:
  name: yaml-secret
stringData:
  username: redis
  password: password1
type: Opaqu

这里使用了stringData,能够用明文的形式设置secret数据,而后在建立为Secret对象时会自动进行Base64编码并保存于data字段中;stringData字段中的明文不会被API Server输出,但若是使用“kubectl apply”命令进行的建立,那么注解信息中仍是能够看到明文信息的。若是用data字段,则必须直接提供Base64编码后的数据。

Secret存储卷

虽然Secret数据也能够痛殴环境变量注入,但并不推荐这样作,由于容器应用一般会在发生错误时将全部环境变量保存于日志信息中,甚至有些应用在启动时即会将运行环境打印到日志中;另外,容器应用调用第三方程序为子进程时,这些子进程可以继承并使用父进程的全部环境变量。 因此建议使用Secret存储卷来传递数据,使用方式与configMap基本相同,但字段为secret和secretName:

volumes:
- name: secret-vol
  secret:
    secretName: yaml-secret
    items:
    - key: username
      path: username
    - key: password
      path: password

imagePullSecret资源对象

imagePullSecret资源可用于将Secret提供的密码传递给kubelet从而在拉取镜像前完成认证。 建立imagePullSecret的标识为docker-registry,有两种使用方式:

  • 在定义Pod资源时经过“imagePullSecrets”字段指定
  • 将其添加到某特定的ServiceAccount对象中

采用第一张方式,建立docker-registry:

kubectl create secret docker-registry local-registry --docker-username=user1 --docker-password=password1

而后在建立Pod的配置清单中,经过spec.imagePullSecrets字段为kubelet提供Secret信息:

spec:
  imagePullSecrets:
  - name: local-registry

但这种方式须要为每一个Pod资源显式定义imagePullSecrets,基于ServiceAccount的的方式能够避免这个问题,后续再作详细了解。

学习资料

《Kubernetes实战进阶》 马永亮著