第十章 配置容器应用:ConfigMap和Secret

  ConfigMat和Secret是Kubernetes系统上两种特殊类型的存储卷,ConfigMap对象用于为容器中的应用提供配置数据以定制程序的行为,不过敏感的配置信息,例如密钥,证书等通常由Secret对象来进行配置。他们要么被Pod资源以存储卷的形式加载,要么由容器通过envFrom字段以变量的形式加载。

1 利用环境变量(env)配置容器应用

  在Kubernetes中使用镜像启动容器时,可以在Pod资源或Pod模版资源定义中,为容器配置段使用env参数来定义所使用的环境变量。定义env包括如下字段:

  • name<string>:环境变量的名称,必须字段
  • value<string>:环境变量的值,通过$(VAR_NAME)引用,逃逸格式为$$(VAR_NAME),默认值为空
  • valueFrom<Object>:环境变量值的引用源,例如,当前Pod资源的名称、名称空间、标签等,不能与非空值的value字段同时使用,即环境变量的值要么源于value字段,要么源于valueFrom字段,二者不可同时提供数据。

  valueFrom字段可以引用的值有多种来源,包括当前Pod资源的属性值、容器相关的系统资源配置、ConfigMap对象中的Key以及Secret对象中的Key,他们应分别使用不同的嵌套字段进行定义。

  • fieldRef<Object>:当前Pod资源的指定字段,目前支持使用的字段包括metadata.name、metadata.namespace、metadata.labels、metadata.annotations、spec.nodeName、spec.serviceAccountName、status.hostIP和status.podIP
  • configMapKeyRef<Object>:ConfigMap对象中的特定Key
  • secretKeyRef<Object>:Secret对象中的特定Key
  • resourceFieldRed<Object>:当前容器的特定系统资源的最小值(配额)或最大值(限额),目前支持的引用包括limits.cpu、limits.memory、limits.ephemeral-storage、requests.cpu、requests.memory和requests.ephemeral-storage。

  如下示例:

apiVersion: v1 
kind: Pod 
metadata: 
  name: env-demo 
  labels:
    purpose: demonstrate-environment-variables 
spec :
  containers:
  - name: env-demo-container
    image: busybox 
    command: ["httpd"] 
    args: [”-f”]
    env :
    - name: HELLO_WORLD
      value: just a demo
    - name: MY_NODE_NAME
      valueFrom: 
        fieldRef:
          fieldPath: spec.nodeName
    - name: MY_NODE_IP
      valueFrom: 
        fieldRef:
          fieldPath: status.host工P
    - name: MY_POD_NAMESPACE
      valueFrom: 
        fieldRef:
          fieldPath: metadata.namespace 
  restartPolicy : OnFailure

2 应用程序配置管理ConfigMap资源

2.1 创建ConfigMap对象

  ConfigMap既可以使用kubectl create命令创建也可以使用清单创建。

  命令的语法格式

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

  其中,<map-name>即为ConfigMap对象的名称,而<data-source>是数据源,他可以通过直接值、文件或目录来获取。

2.1.1 利用直接值创建

  为“kubectl create configmap”命令使用”--from-literal“选项可在命令行直接给出键值对来创建ConfigMap对象,重复使用此选项则可以传递多个键值对。如下格式:

kubectl create configmap configmap_name --from-literal=key-name-1=value-1
2.1.2 基于文件创建

  为“kubectl create configmap”命令使用“--from-file”选项即可基于文件内容来创建ConfigMap对象,它的命令格式如下。可以重复多次使用“--from-file”选项以传递多个文件内容:

  如下命令是创建文件基名为键名,值为文件内容

kubectl create configmap <configmap_name> --from-file=<path-to-file>

    如果需要自行指定键名,则可在"--from-file"选项中直接指定自定义的键,命令格式如下:

kubectl create configmap <configmap_name> --from-file=<my-key-name>=<path-to-file>
2.1.3 基于目录创建

  如果配置文件数量较多且存储于有限的目录中时,kubectl还提供了基于目录直接将多个文件分别收纳为键值数据的ConfigMap资源创建方式。将“--from-file”选项后面所跟的路径指向一个目录路径就能将目录下的所有文件一同创建于同一ConfigMap资源中,命令格式如下

kubectl create configmap <configmap_name> --from-file=<path-to-directory>

  例如,nginx的conf.d目录下包含三个配置文件,那这三个配置文件会分别存储为三个键值数据。

2.1.4 使用清单创建

  基于配置文件创建ConfigMap资源时,他所使用的字段包括通常的apiVersion、king和metadata字段,以及用于存储数据的关键字段“data”。例如下面的示例:

apiVersion: v1 
kind: ConfigMap 
metadata:
  name: configmap-demo
  namespace: default 
data:
  log_level: INFO
  log_file: /var/log/test.log

2.2 向Pod环境变量传递ConfigMap对象键值数据

valueFrom:
  configMapKeyRef:
    key: 
    name:
    optional:

  name:要引用的ConfigMap对象的名称

  key:要引用ConfigMap对象中某键的键名

  optional:当前Pod资源此引用是否可选

apiVersion: v1 
kind: ConfigMap 
metadata:
  name: busybox-httpd-config
  namespace: default 
data:
  httpd_port: ”8080” 
  verbose_level: ”-vv”
---
apiVersion: v1 
kind: Pod 
metadata:
  name: configmap-env-demo
  namespace: default 
spec:
  containers :
  - image: busybox
    name: busybox-httpd
    command: ["/bin/httpd”]
    args: [”-f",”-p",”$(HTTPD_PORT)”,”$(HTTPD_LOG_VERBOSE)”] 
    env:
    - name: HTTPD PORT
      valueFrom: 
        configMapKeyRef:
          name: busybox-httpd-config
          key: httpd_port
    - name: HTTPD LOG VERBOSE
      valueFrom: 
        configMapKeyRef:
          name: busybox-httpd-config   
          key: verbose_level
          optional: true

  假设存在这么一种情形,某ConfigMap资源中存在较多的键值数据,而全部或大部分的这些数据都需要由容器来引用,可以使用envFrom字段直接将ConfigMap资源中的所有键值一次性的完成导入。格式如下: 

spec:
  conta工ners :
  - image: some-image
    envFrom :
    - prefix <String>
      configMapRef:
        name <string> 
      optional <boolean>

envFrom宇段值是对象列表,可用于同时从多个ConfigMap对象导人键值数据。为了避免从多个ConfigMap引用键值数据时产生键名冲突,可以在每个引用中将被导人的键使用prefix字段指定-个特定的前缀,如“ HTCFG_” 一类的字符串,于是,ConfigMap对象中的httpd_port将成为Pod资源中名为HTCFG_httpd_port的变量。

apiVersion: v1 
kind: Pod 
metadata:
  name: configmap-envfrom-demo
  namespace: default 
spec :
 containers:
 - image: busybox
   name: busybox-httpd
   command: [”/bin/httpd”]
   args : [”-f ”,”-p”,”$(HTCFG_httpd_port)”,$(HTCFG_verbose_level)”] 
   envFrom:
   - prefix: HTCFG_
     configMapRef:
       name: busybox-httpd-config 
       optional: false

2.3 ConfigMap存储卷

2.3.1 挂载整个存储卷

  如下示例,ConfigMap创建了nginx配置文件,容器nginx-server将其挂载值应用程序nginx加载配置文件模块的目录/etc/nginx/conf.d中:

apiVersion: v1 
kind: Pod 
metadata:
  name: configmap-volume-demo
  namespace: default 
spec:
  containers:
  - image: nginx:alpine
    name: nginx-server
    volumeMounts:
    - name: ngxconfig
      mountPath: /etc/nginx/conf.d/
      readOnly: true
  volumes:
  - name: ngxconfig 
    configMap:
      name: nginx-config-files
2.3.2 挂载存储卷中的部分键值

  前两种方式中,无论是装载所有文件还是部分文件,挂载点目录下原有的文件都会被隐藏。对于期望将ConfigMap对象提供的配置文件补充于挂载点目录下的需求来说,这种方法很难实现。例如,/etc/nginx/conf.d目录中原本就存在一些文件(如default.conf),用户期望将configMap中的部分文件装载进此目录中而不影响其原有的文件。

  如上需求可以使用volumeMounts字段中使用的subPath字段来解决,他可以支持用户从存储卷挂载单个文件或单个目录而非整个存储卷。

apiVersion: v1 
kind: Pod 
metadata:
  name: configmap-volume-demo-3
  namespace: default 
spec:
  containers:
  - image: nginx:alpine
    name: web-server 
    volumeMounts:
    - name: ngxconfig
      mountPath: /etc/nginx/conf.d/myserver.conf 
      subPath : myserver.conf
      readOnly : true
    - name : ngxconfig
      mountPath: /etc/nginx/conf.d/myserver-status.cfg 
      subPath: myserver-status.cfg
      readOnly: true
  volumes:
  - name: ngxconfig
    configMap :
      name: nginx-config-files

3 Secret资源

  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。

3.1 创建Secret资源

3.1.1 命令式创建
kubectl create secret generic <SECRET_NAME> --from-literal=key=value

例如,创建一个用户名密码为root/ikubernetes的secret

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

对于本身存储在文件中的数据,可以在创建generic格式Secret对象时使用“--from-file”选项从文件中直接进行加载,例如创建用于SSH认证的Secret对象时,如果尚且没有认证信息文件,则需要首先使用明亮生产一对认证文件:

ssh-keygen -t rsa -P ‘’ -f  ${HOME}/.ssh/id_rsa

然后使用“kubectl create secret generic <SECRET_NAME> --from-file[=KEY]=/PATH/TO/FILE”命令加载文件内容并生成为Secret对象。

kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=${HOME}/.ssh/id_rsa --from-file=ssh-publickey=${HOME}/.ssh/id_rsa.pub

若要需要基于私钥和数字证书文件创建用于SSL/TLS通信的Secret对象,则需要使用“kubectl create secret tls <SECRET_NAME> --cert= --key=”命令来进行。

例如,需要为Nginx测试创建SSL虚拟主机,用户首先使用了类似如下的命令生成了私钥和自签证书;

(umask 077; openssl genrsa out nginx.key 2048)
openssl req -new -x509 -key nginx.key -out nginx.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=www.ilinux.io

然后创建Secret对象,无论用户提供的证书和私钥文件使用的是什么名称,他们一律被转换为分别以tls.key(私钥)和tls.crt(证书)为其名

kubectl create secret tls nginx-ssl - key=./nginx.key --cert=./nginx.crt
3.1.2清单式创建

  除了标准的apiVersion、kind和metadata字段,他可用的其他字段具体如下。

  • data<map[string]string>:“key:value”格式的数据,通常是敏感信息,数据格式需是以Base64格式编码的字符串,因此需要用户事先完成编码。
  • stringData<map[string]string>:以明文格式(非Base64编码)定义的“key:value”数据,无须用户事先对数据进行Base64编码,而是在创建为Secret对象时自动进行编码并保存于data字段中;
  • type<string>:仅是为了便于编程方式处理Secret数据而提供的类型标识。
apiVersion: v1 
kind: Secret 
metadata:
  name: secret-demo 
stringData:
  username: redis
  password: redisp@ss 
  type: Opaque

3.2 Secret存储卷

  例如,将nginx-ssl关联为Pod资源名为nginxcert的Secret存储卷,而后有容器web-server挂载至/etc/nginx/ssl目录下

apiVersion: v1 
kind: Pod
metadata:
  name: secret-volume-demo
  namespace: default 
spec:
  conta工ners:
  - image: nginx:alpine
    name: web-server 
    volumeMounts:
    - name: nginxcert
      mountPath: /etc/nginx/ssl/
      readOnly: true 
  volumes :
  - name: nginxcert 
    secret:
      secretName: nginx-ssl
posted @ 2022-12-01 21:37  摩天居士-谢烟客  阅读(154)  评论(0)    收藏  举报