ConfigMap和Secret是Kubernetes零碎上两种非凡类型的存储卷,ConfigMap对象用于为容器中的利用提供配置文件等信息。然而比拟敏感的数据,例如密钥、证书等由Secret对象来进行配置。它们将相应的配置信息保留于对象中,而后在Pod资源上以存储卷的模式挂载并获取相干的配置,以实现配置与镜像文件的解耦。

容器化利用配置形式

每个应用程序都是可执行程序文件,例如Nginx、Tomcat、MySQL等,但咱们应用中,通常不会通过默认的配置参数来运行利用,个别都须要自定义合乎咱们场景的配置,那么就须要定义配置文件来实现。那咱们的利用运行在容器中,应该如何定义配置信息呢?例如为Tomcat的JVM配置堆内存大小等,在容器中启动时,咱们能够向容器命令传递参数,将定义好的配置文件嵌入镜像文件中、通过环境变量(Environment Variables)传递配置数据,以及基于Docker卷传送配置文件等。

以下将介绍向容器提供配置信息的几种办法。

通过命令行参数进行配置

在制作Docker镜像时,Dockerfile中的ENTRYPOINT和CMD指令可用于指定容器启动时要运行的程序及相干参数。CMD指令以列表的模式指定要运行的程序和相干参数,然而如果同时存在ENTRYPOINT指令,则CMD指令中列表的所有元素都将被作为由ENTRYPOINT指定程序的命令行参数。另外在基于某镜像应用Docker命令创立容器时,能够在命令行向ENTRYPOINT中的程序传递额定的自定义参数,甚至还能够批改要运行的应用程序自身,例如以下命令应用docker run创立并启动容器的格局为:
docker run [OPTINS] IMAGE [COMMAND] [ARG]

COMMAND为自定义运行的程序,ARG为传递给程序的参数,如果定义相干镜像文件时应用了ENTRYPOINT指令,则COMMANDARG都会被当作命令行参数传递给ENTRYPOINT指令中指定的程序,除非运行docker run命令时额定应用--entrypoint选项来笼罩镜像文件中的ENTRYPOINT指定的程序。

在Kubernetes零碎上创立Pod资源时,也可能向容器化利用传递命令行参数,甚至指定运行其它应用程序,相干的字段别离为pods.spec.containers.commandpods.spec.containers.args

将配置文件载入镜像文件

在通过Dockerfile制作镜像时,能够应用COPY或者ADD指定将定义好的配置文件间接复制到镜像文件零碎上的相应地位,或者应用RUN指令调用sed或echo一类的命令批改配置文件从而达到为容器化利用提供自定义配置文件之目标。应用Docker Hub上的某镜像文件额定增加配置文件即能合乎须要,则克隆其Dockerfile文件批改至合乎需要之后再将之推送至GitHub,并由Docker Hub主动构建出镜像文件即可。

通过环境变量向容器注入配置信息

通过环境变量为容器提供配置信息是Docker Hub上最常见的应用形式,例如,应用MySQL官网提供的镜像文件启动MySQL容器时应用的MYSQL_ROOT_PASSWORD环境变量,它用于为MYSQL服务器的root用户设置登陆密码。

在基于此类镜像启动容器时,用户为 docker run 命令通过 -e 选项向环境变量传值即能实现利用配置,命令的应用格局为 docker run -e SETTING1=foo -e SETTING2=bar ... <image name>。启动时,容器的ENTRYPOINT启动脚本会抓取到这些环境变量,并在启动容器利用之前,通过sed或echo等一类的命令将变量值替换到配置文件中。

通过存储卷向容器注入配置信息

Docker存储卷(volumes)可能将宿主机之上的任何文件或目录映射到容器文件系统之上,因而,能够当时将配置文件搁置于宿主机之上的某个门路中,而后在启动容器时进行加载。这种形式灵便易用,但也依赖于用户须要当时将配置数据提供在宿主机上的特定门路下,而且在多主机模型中,若容器存在被调度至任一主机运行的可能性时,用户还须要将配置共享到任一宿主机来确保容器可能失常地获取到它们。

借助Docker config进行容器配置

Docker swarm service自1.13版本起反对应用secret于容器之外保留二进制数据,包含口令、SSH私钥、SSL证书以及其它不倡议通过网络传输或不应该在Dockerfile及程序源码中加载保留的秘密数据,用户可应用secret集群化治理这类数据并将其关联至那些须要拜访这些数据的容器中。

另外,Docker自17.06版本起为swarm service引入了容许用户容器之外存储非敏感信息(如配置文件)的组件service config,从而反对用户创立通过目标镜像文件,并且不再须要通过挂载存储卷或应用环境变量为容器提供配置文件。

Docker swarm service secret和config为容器化利用的配置提供了极大的灵活性,不过,它们也只能利用于Docker swarm service环境中,而不能利用于独自运行的容器之上。

Kubernetes零碎也有相似的组件,它们被称为Secret和ConfigMap,而且是Kubernetes零碎上一等类别的资源对象,它们要么被Pod资源以存储卷的模式加载,要么由容器通过envFrom字段以变量的模式加载。

1. 通过命令行参数配置容器利用

创立Pod资源时,能够在容器中自定义要运行的命令以及选项和参数。
在容器的配置上下文中,应用command字段指定要运行的程序,而args字段则可用于指定传递给程序的选项和参数。在配置文件中定义command和args会笼罩镜像文件中相干的默认设定,这类程序会被间接运行,而不会由shell解释器解释运行,因而与sehll相干的个性均不被反对,如命令行开展符号 {}、重定向等操作。

上面是定义在 command-demo.yaml 文件中的Pod资源示例,它在容器 command-demo-container中将busybox镜像文件中默认运行的命令 ["/bin/sh", "-c"]批改为["httpd"],并为其额定传递了["-f"]选项。

cat command-demo.yamlapiVersion: v1kind: Podmetadata:  name: command-demo  labels:    purpose: demonstrate-commdnspec:  containers:  - name: command-demo-container    image: busybox    command: ["httpd"]    args: ["-f"]    ports:    - containerPort: 80

资源清单编辑之后创立Pod对象,而后查看容器所运行的程序,后果如下父过程为 httpd -f

kubectl exec -it pods/command-demo -- ps auxPID   USER     TIME  COMMAND    1 root      0:00 httpd -f   22 root      0:00 ps aux

事实上,咱们也能够只在容器配置的上下文提供 args 字段,以实现向默认运行的程序提供额定的参数,如果默认的命令为Shell解析器或 entrypoint 启动脚本,那么这些参数自身甚至还能够是要运行的命令及其参数,例如,上面的容器配置,示意要运行的程序为/bin/sh -c httpd -f,实现了shell解释器解释运行执行的程序之目标。

cat command-demo.yamlapiVersion: v1kind: Podmetadata:  name: command-demo  labels:    purpose: demonstrate-commdnspec:  containers:  - name: command-demo-container    image: busybox    args: ["httpd","-f"]    ports:    - containerPort: 80

创立Pod对象,并查看容器的父过程

kubectl exec -it pods/command-demo -- ps auxPID   USER     TIME  COMMAND    1 root      0:00 httpd -f    8 root      0:00 ps aux

由上述的示例可见,Kubernetes配置文件中的command对应于Dockerfile中的ENTRYPOINT,而配置文件的args则对应于Dockerfile中的CMD。在Kubernetes中只给出command字段时,他会笼罩Dockerfile中的ENTRYPOINT和CMD,只给出args字段时,它仅笼罩CMD,而同时给出command和args时,它会对应笼罩ENTRYPOINT和CMD。

2. 利用环境变量配置容器利用

在Kubernetes中应用镜像启动容器时,能够在Pod资源或Pod模版资源为容器配置应用env参数来定义所应用的环境变量列表,即使容器中的利用自身不处于环境变量,也一样能够向容器传递环境变量,只不过它不被应用罢了。

环境变量配置容器化利用时,须要在容器配置段中嵌套应用env字段,它的值是一个由环境变量构建的列表。环境变量由name和value(或valueFrom)字段形成。

  • name<string>:环境变量的名称,必须字段。
  • value<string>:环境变量的值,通过 ${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。
  • resourceFieldRef<Object>:以后容器的特定系统资源的最小值(配额)或最大值(限额),目前反对的援用包含limits.cpu、limts.ephemeral-storage、requests、cpu、requests.memory、requests.ephemeral-storage。

上面是定义在配置文件 env-demo.yaml 中的Pod资源,其通过环境变量援用以后Pod资源及其所在节点的相干属性值配置容器,fieldRef字段的值是一个对象,它个别由apiVersion(创立以后Pod资源的API版本)或fidldPath嵌套字段所定义:

cat env-demo.yamlapiVersion: v1kind: Podmetadata:  name: env-demo  labels:    purpose: demonstrate-environment-variablesspec:  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.hostIP    - name: MY_POD_NAMESPACE      valueFrom:        fieldRef:          fieldPath: metadata.namespace  restartPolicy: OnFailure

创立Pod对象

kubectl apply -f env-demo.yaml

而后打印它的环境变量列表

kubectl exec -it pods/env-demo -- printenvHELLO_WORLD=just a demo                            #在清单中定义的HELLO_WORLD变量与值MY_NODE_NAME=k8s-node03                            #在清单中定义的MY_NODE_NAME变量与从spec.nodeName获取到的值MY_NODE_IP=192.168.31.233                          #在清单中定义的MY_NODE_IP变量与从status.hostIP获取的值MY_POD_NAMESPACE=default                           #在清单中定义的MY_POD_NAMESPACE变量与从metadata.namespec获取到的值

容器的启动脚本或应用程序调用或解决这些环境变量、即可实现容器化利用的配置。相较于命令行参数的形式来说,应用环境变量的配置形式更清晰、易懂,尤其是对于首次应用相干容器的用户来说,这种形式可能疾速理解容器的配置形式,不过这两种配置形式有一个独特缺点:无奈在容器利用运行过程中更新环境变量从而达到更新利用目标。这通常意味着用户不得不为production、development和qa等不同的环境别离配置Pod资源。好在,用户还有ConfigMap资源可用。

3. ConfigMap介绍之各姿态创立ConfigMap

ConfigMap诞生的起因

分布式环境中,基于负载、容错性等需要的思考,简直所有的服务都须要在不同的机器节点上部署不止一个实例。随着程序性能的日益简单,程序的配置日益增多,而且配置文件的批改频率通常远远大于代码自身,这种状况下,有时仅仅是一个配置内容的批改,就不得不从新将代码提交到SVN/Git、打包、散发上线的流程。部署规定较大的场景中,散发上线工作即繁冗又惨重。

究其基本,所有的这些麻烦都是因为配置和代码在治理和公布的过程中不加区分所致。配置自身源于代码,是为了进步代码的灵活性而提取进去的一些常常变动的或须要定制的内容,而正是配置的这种天生变动个性为部署过程中带来了不小的麻烦,也最终催生了分布式系统配置管理系统,将配置内容从代码中齐全分离出来,及时牢靠高效地提供配置拜访和更新服务。

提醒:国内分布式配置核心相干的开源我的项目有 Diamond(阿里)、Apollo(携程)、Qconf(奇虎360)和disconf(百度)等。

作为分布式系统的Kubernetes也提供了对立配置管理计划——ConfigMap。Kubernetes基于ConfigMap对象实现了将配置文件从容器镜像中解耦,从而加强了容器利用的可移植性。简略来说,一个ConfigMap对象就是一系列配置数据的汇合,这些数据可“注入”到Pod对象中,并为容器利用所应用,注入形式有挂载为存储卷和传递为环境变量两种。

ConfigMap介绍

ConfigMap对象将配置数据以键值对的模式进行存储,这些数据能够在Pod对象中应用或者为零碎组件提供配置,例如控制器对象等。不过无论应用程序如何应用ConfigMap对象中的数据,用户都齐全能够通过在不同的环境中创立名称雷同但内容不同的ConfigMap对象,从而为不同环境中同一性能的Pod资源提供不同的配置信息,实现利用与配置的灵便勾兑。

ConfigMap对象创立

ConfigMap创立的形式与其它资源一样有两种:

  • kubectl create configmap 命令间接创立
  • 通过资源配置清单创立
    以上两种对于ConfigMap都算是比拟罕用的创立形式,通过kubectl create configmap命令,用户能够依据目录、文件或者间接创立ConfigMap对象,命令的语法格局如下:
    kubectl create configmap <map-name> <data-source>

<map-name>为ConfigMap对象的名称,<data-source>是数据源,数据源能够间接给定K/V类型的数据,也能够指定文件以及目录来获取,无论是哪一种数据源,它都要转换为ConfigMap对象中的Key-Value数据,其中Key由用户在命令行给出或是文件数据源的文件名,它仅能由字母、数字、连接号和点号组成,而Value则是间接值或文件数据源的内容。

通过键值创立ConfigMap

利用kubectl create configmap命令应用--from-literal选项可在命令行间接给出键值对来创立ConfigMap对象,重复使用此选项则能够传递多个键值对,命令格局如下:
kubectl create configmap configmap_name --from-literal=key-name01=value-1

例如上面用命令创立special-config configmap时传递来两个键值对:
键值对第一个key为mysql_ip值为172.16.0.3
键值对第二个key为mysql_port值为3306

kubectl create configmap special-config \--from-literal=mysql_ip=172.16.0.3 --from-literal=mysql_port=3306

查看创立的ConfigMap

kubectl get configmapNAME             DATA   AGEspecial-config   2      55s#应用kubectl describe能够看到configmap中的原始数据kubectl describe configmap/special-configName:         special-configNamespace:    defaultLabels:       <none>Annotations:  <none>Data====mysql_ip:----172.16.0.3mysql_port:----3306Events:  <none>

此类形式提供的数据量无限,个别是在仅通过无限的几个数据项即可为Pod资源提供足够的配置信息时应用。

通过文件创建ConfigMap

利用kubectl create configmap命令应用--from-file选项可基于文件内容来创立ConfigMap对象,它的命令格局如下:
kubectl create configmap <configmap_name> --from-file=<[key=]source>

1.筹备配置文件
咱们先筹备好要载入容器的配置文件,等下通过kubectl create configmap config_name --from-file 来指定咱们的配置文件即可创立configmap,以下筹备了一个elasticsearch.yaml的配置文件

cat elasticsearch.yamlcluster.name: elasticsearchnode.name: elasticpath.data: /usr/local/elastic7.4/datapath.logs: /usr/local/elastic7.4/logsbootstrap.memory_lock: truenetwork.host: 0.0.0.0network.tcp.no_delay: truenetwork.tcp.keep_alive: truenetwork.tcp.reuse_address: truenetwork.tcp.send_buffer_size: 256mbnetwork.tcp.receive_buffer_size: 256mbtransport.tcp.port: 9300transport.tcp.compress: truehttp.max_content_length: 200mbhttp.cors.enabled: truehttp.cors.allow-origin: "*"http.port: 9200cluster.initial_master_nodes: ["127.0.0.1:9300"]xpack.security.enabled: truexpack.license.self_generated.type: basicxpack.security.transport.ssl.enabled: truexpack.monitoring.collection.enabled: true

2.通过文件创建configMap
如果指定文件创建configmap的时候没有指定key,那么kubernetes则以文件名称为key

kubectl create configmap elastic-configmap --from-file=./elasticsearch.yaml

3.查看创立的ConfigMap

kubectl describe configmap elastic-configmapName:         elastic-configmapNamespace:    defaultLabels:       <none>Annotations:  <none>Data====elasticsearch.yaml:                                #咱们没有指定key,默认以文件名称为key----cluster.name: elasticsearchnode.name: elasticpath.data: /usr/local/elastic7.4/datapath.logs: /usr/local/elastic7.4/logsbootstrap.memory_lock: truenetwork.host: 0.0.0.0network.tcp.no_delay: truenetwork.tcp.keep_alive: truenetwork.tcp.reuse_address: truenetwork.tcp.send_buffer_size: 256mbnetwork.tcp.receive_buffer_size: 256mbtransport.tcp.port: 9300transport.tcp.compress: truehttp.max_content_length: 200mbhttp.cors.enabled: truehttp.cors.allow-origin: "*"http.port: 9200cluster.initial_master_nodes: ["127.0.0.1:9300"]xpack.security.enabled: truexpack.license.self_generated.type: basicxpack.security.transport.ssl.enabled: truexpack.monitoring.collection.enabled: trueEvents:  <none>

也能够以yaml格局显示configmap信息

kubectl get configmap elastic-configmap -o yaml

如果须要指定键名称,如下在文件后面写入key名称即可

kubectl create configmap elastic-configmap --from-file=elastic=./elasticsearch.yaml

如下再查看key名称则变为了咱们所指定的elastic

kubectl get configmap elastic-configmap -o yamlapiVersion: v1data:  elastic: |    cluster.name: elasticsearch    node.name: elastic    path.data: /usr/local/elastic7.4/data    path.logs: /usr/local/elastic7.4/logs    bootstrap.memory_lock: true    network.host: 0.0.0.0    network.tcp.no_delay: true    network.tcp.keep_alive: true    network.tcp.reuse_address: true    network.tcp.send_buffer_size: 256mb    network.tcp.receive_buffer_size: 256mb    transport.tcp.port: 9300    transport.tcp.compress: true    http.max_content_length: 200mb    http.cors.enabled: true    http.cors.allow-origin: "*"    http.port: 9200    cluster.initial_master_nodes: ["127.0.0.1:9300"]    xpack.security.enabled: true    xpack.license.self_generated.type: basic    xpack.security.transport.ssl.enabled: true    xpack.monitoring.collection.enabled: truekind: ConfigMapmetadata:  creationTimestamp: "2020-06-05T07:00:45Z"  managedFields:  - apiVersion: v1    fieldsType: FieldsV1    fieldsV1:      f:data:        .: {}        f:elastic: {}    manager: kubectl    operation: Update    time: "2020-06-05T07:00:45Z"  name: elastic-configmap  namespace: default  resourceVersion: "418525"  selfLink: /api/v1/namespaces/default/configmaps/elastic-configmap  uid: 16e8074a-4d4e-4e6e-b704-339876357951

通过目录创立ConfigMap

如果配置文件数量较多时,kubectl还提供了基于目录间接将多个文件别离收纳为键值数据的ConfigMap资源创立形式,将--from-file选项后所跟的门路指向一个目录门路就能把目录下的所有文件一起创立同一哥个 ConfigMap 资源中,命令格局如下:
kubectl create configmap <configmap_name> --from-file=<path-to-directory>

如下命令所示,将/data/configs/nginx/conf.d目录下的所有文件都保留于nginx-config-files对象中

ls /data/configs/nginx/conf.d/myserver.conf  myserver-gzip.cfg  myserver-status.cfg
kubectl create configmap nginx-config-files --from-file=/data/configs/nginx/conf.d/

查看创立的configmap对象

留神:kubectl describe 和 kubectl get -o yaml 命令都能够显示由文件创建的键值,不过两者应用的键和值之间的分隔符不同
kubectl describe configmap nginx-config-filesName:         nginx-config-filesNamespace:    defaultLabels:       <none>Annotations:  <none>Data====myserver-gzip.cfg:----gzip on;gzip_comp_level 5;myserver-status.cfg:----     location /ngx_status     {    stub_status on;    access_log off;    allow 127.0.0.1;    deny all;    }myserver.conf:----server {  listen 8080;  server_name www.k8sops.cn;  include /etc/nginx/conf.d/myserver-*.cfg;  location / {      root /usr/lshare/nginx/html;  }}Events:  <none>
kubectl get configmap nginx-config-files -o yamlapiVersion: v1data:  myserver-gzip.cfg: |    gzip on;    gzip_comp_level 5;  myserver-status.cfg: "     location /ngx_status     {\n  \tstub_status on;\n  \taccess_log    off;\n\tallow 127.0.0.1;\n \tdeny all;\n \t}\n"  myserver.conf: "server {\n\tlisten 8080;\n\tserver_name www.k8sops.cn;\n\n\tinclude    /etc/nginx/conf.d/myserver-*.cfg;\n\tlocation / {\n\t    root /usr/lshare/nginx/html;\n\t}\n}\n"kind: ConfigMapmetadata:  creationTimestamp: "2020-06-05T07:44:16Z"  managedFields:  - apiVersion: v1    fieldsType: FieldsV1    fieldsV1:      f:data:        .: {}        f:myserver-gzip.cfg: {}        f:myserver-status.cfg: {}        f:myserver.conf: {}    manager: kubectl    operation: Update    time: "2020-06-05T07:44:16Z"  name: nginx-config-files  namespace: default  resourceVersion: "426082"  selfLink: /api/v1/namespaces/default/configmaps/nginx-config-files  uid: d83d033c-c478-495f-b9c6-6fba829ab52a

通过资源配置清单创立

基于配置文件创立ConfigMap时,它所应用的字段通常包含apiVersionkind和metadata字段,以及用于存储数据的关键字段data
上面就应用配置清单创立一个ConfigMap

cat configmap.yamlapiVersion: v1kind: ConfigMapmetadata:  name: configmap-demodata:  log_level: INFO  log_file: /var/log/test.log
kubectl describe configmap configmap-demoName:         configmap-demoNamespace:    defaultLabels:       <none>Annotations:Data====log_file:----/var/log/test.loglog_level:----INFOEvents:  <none>

如果配置信息来自文件内容时,则应用配置清单创立ConfigMap资源的便捷性还不如间接通过命令行的形式,因而倡议间接应用命令行加载文件或目录的形式进行创立,为了便于配置留存,能够在创立实现后应用 get -o yaml命令获取到相干信息后在进行编辑留存。

4. ConfigMap载入Pod形式之环境变量

在Pod中,获取环境变量值的形式之一就包含ConfigMap对象中的数据,这一点通过在env字段中为valueFrom内嵌configMapKeyRef对象即可实现,格局如下:

valueFrom:  configMapKeyRef:    key:    name:    optional:

字段name值为要援用的ConfigMap对象的名称
字段key可用于指定要援用ConfigMap对象中某键的键名
字段optional用于为以后Pod资源指明此援用是否为可选

此类环境变量的应用形式与间接定义的环境变量并无区别,它们可被用于容器的启动脚本或间接传递给容器利用等。

传递ConfigMap中的单个Key

上面示例中蕴含了两个资源,彼此之间应用 "--" 相分隔,第一个资源是名为 busybox-httpd-config 的 ConfigMap 对象,它蕴含了两个键值数据;第二个资源是名为 configmap-env-demo 的 Pod对象,它通过环境变量援用了busybox-httpd-config对象中的键值数据,并将其间接传给了自定义运行的容器利用httpd:

cat busybox.yamlapiVersion: v1kind: ConfigMapmetadata:  name: busybox-httpd-config  namespace: defaultdata:  httpd_port: "8080"  verbose_level: "-vv"---apiVersion: v1kind: Podmetadata:  name: configmap-env-demo  namespace: defaultspec:  containers:  - image: busybox    name: busybox-httpd    command: [ "/bin/httpd" ]    args: [ "-f","-p","$(HTTPD_PORT)","$(HTTPD_LOG_VERBOSE)" ]    env:    - name: HTTPD_PORT                            #定义第一个变量名称      valueFrom:                                          #援用变量        configMapKeyRef:                             #援用来自configMap的变量          name: busybox-httpd-config            #指定ConfigMap的名称          key: httpd_port                                  #指定ConfigMap中要援用的key名称    - name: HTTPD_LOG_VERBOSE      valueFrom:        configMapKeyRef:          name: busybox-httpd-config          key: verbose_level          optional: true

留神,在command和args字段中援用环境变量要应用$(VAR_NAME)的格局,待下面配置文件中的资源创立实现后,能够通过如下命令验证Pod资源监听的端口等配置信息是否为 busybox-httpd-config中定义的内容:

kubectl apply -f busybox.yamlconfigmap/busybox-httpd-config createdpod/configmap-env-demo createdkubectl exec pods/configmap-env-demo -- ps auxPID   USER     TIME  COMMAND    1 root      0:00 /bin/httpd -f -p 8080 -vv    8 root      0:00 ps auxkubectl exec pods/configmap-env-demo -- env | grep HTTPDHTTPD_PORT=8080HTTPD_LOG_VERBOSE=-vv
留神:创立援用了ConfigMap资源的Pod对象时,被援用的资源必须当时存在,否则将无奈启动相应的容器,直到被依赖的资源创立实现为止。不过,那些未援用不存在的ConfigMap资源的容器将不受此影响。另外,ConfigMap是名称空间级别的资源,它必须与援用它的Pod资源在同一个名称空间中。

传递ConfigMap中的所有Key

如果咱们要引入的变量有很多呢?此时,为容器顺次配置相应的环境变量是一件很焦躁的事件,而且容易出错,对此,Pod资源反对在容器中应用envFrom字段间接将ConfigMap资源中的所有键值一次性地残缺导入。格局如下:

spec:  containers:  - name: busybox    image: busybox    envFrom:    - prefix: HTCPG_      configMapRef:        name: configmap_name        optional: true

envFrom字段是对象列表,可用于同时从多个ConfigMap对象导入键值数据。
为了防止从多个ConfigMap引入键值数据时产生键key重名(名称抵触),能够在每个援用中将被导入的键应用 prefix 字段指定一个个性的前缀,如 HTCPG_ 一类的字符串,于是,ConfigMap对象中的httpd_port将成为Pod资源中名为HTCPG_httpd_port的变量。

如果键名中应用了连接线 "-",那么在转换为变量时,连接线将主动被替换为下划线 "_"。

如下:

cat envFrom.yamlapiVersion: v1kind: ConfigMapmetadata:  name: busybox-httpd-config  namespace: defaultdata:  httpd_port: "8080"  verbose_level: "-vv"---apiVersion: v1kind: Podmetadata:  name: configmap-env-demo  namespace: defaultspec:  containers:  - image: busybox    name: busybox-httpd    command: [ "/bin/httpd" ]    args: [ "-f", "-p", "$(HTCPG_httpd_port)", "$(HTCPG_verbose_level)" ]    envFrom:    - prefix: HTCPG_      configMapRef:        name: busybox-httpd-config        optional: false

待Pod资源创立实现后,可通过查看其环境变量验证其导入的后果:

kubectl apply -f envFrom.yaml
kubectl exec pods/configmap-env-demo -- ps auxPID   USER     TIME  COMMAND    1 root      0:00 /bin/httpd -f -p 8080 -vv    7 root      0:00 ps auxkubectl exec pods/configmap-env-demo -- printenv | grep HTCPGHTCPG_verbose_level=-vvHTCPG_httpd_port=8080
留神:从ConfigMap对象导入资源时,prefix为可选字段,不定义时,所有变量名同ConfigMap中的键名。如果不存在键名抵触的可能性,例如从单个ConfigMap对象导入变量或在ConfigMap对象中定义键名时仍然增加了特定的前缀,那么省略前缀的定义即不会导致键名抵触,又能放弃变量的简洁。

5. ConfigMap载入Pod形式之存储卷

若ConfigMap对象中的键值来源于较长的文件内容,那么应用环境变量将其导入会使得变量值占据过多的内存空间而不易清理。此类数据通常用于为容器利用提供配置文件,因而将其内存间接作为文件进行援用方为较好的抉择,其实现形式是,在定义Pod资源时,将此类ConfigMap对象配置为ConfigMap类型的存储卷,而后由容器将其挂载至特定的挂载点后间接进行拜访。

挂载整个存储卷

关联为Pod资源的存储卷时,ConfigMap对象中的每个键都对应地对应为一个文件,键名转为文件名,而值则为相应文件的内容,即使是通过间接创立的键值数据,也一样体现为文件视图。挂载于容器上之后,由键值数据体现出的文件位于挂载点目录中,容器中的过程可间接读取这些文件的内容。

配置Pod资源时,基于存储卷的形式援用ConfigMap对象的办法非常简单,仅须要指明卷名称及要利用的ConfigMap对象名称即可。

1.创立配置文件
咱们上面创立三个Nginx配置文件,而后将这三个配置文件挂载到Nginx的配置目录中

在咱们的宿主机上创立咱们的文件目录

k8sops@k8s-master01:~$ mkdir data/nginx/{conf.d,html} -p

创立配置文件vhost.conf

cat data/nginx/conf.d/vhost.confserver {        listen       80;    server_name  www.k8sops.cn;    include /etc/nginx/conf.d/*.conf;        location  / {            root   /usr/share/nginx/html;            index index.html index.htm;        }}

创立配置文件gzip.conf

cat data/nginx/conf.d/gzip.cfg    gzip on;    gzip_min_length 1k;    gzip_buffers 16 64K;    gzip_http_version 1.1;    gzip_comp_level 6;    gzip_types text/plain application/x-javascript text/css application/xml application/javascript;    gzip_vary on;    gzip_proxied any;    underscores_in_headers on;    proxy_ignore_client_abort on;

创立配置文件ngx-status.conf

cat data/nginx/conf.d/ngx-status.cfg     location /ngx_status     {        stub_status on;        access_log off;        allow 127.0.0.1;        deny all;        }

2.创立ConfigMap对象

基于目录创立nginx-config-files对象

kubectl create configmap nginx-config-files --from-file=./data/nginx/conf.d/

查看创立的configmap

kubectl describe configmap nginx-config-files

3.创立Pod资源清单来援用ConfigMap对象并将其挂载至相应指定的目录中

cat configmap-volume-pod.yamlapiVersion: v1kind: Podmetadata:  name: configmap-volume-pod  namespace: defaultspec:  containers:  - name: configmap-containers    image: nginx:latest    volumeMounts:                                    #卷挂载配置    - name: ngx-config                                #卷名称      mountPath: /etc/nginx/conf.d/                #挂载到容器中的门路目录      readOnly: true                                    #是否只读  volumes:                                                    #卷配置  - name: ngx-config                                    #定义一个卷名称    configMap:                                                #configMap配置      name: nginx-config-files                            #指定configMap名称

4.创立Pod对象

kubectl apply -f configmap-volume-pod.yaml

5.查看Pod状态

kubectl get pods -o wide | grep configmap-volume-podconfigmap-volume-pod          1/1     Running   0          48s     172.20.1.14   k8s-node01   <none>           <none>

6.查看Pod挂载状态

kubectl describe pods/configmap-volume-pod | grep -A 2  Mounts    Mounts:      /etc/nginx/conf.d/ from ngx-config (ro)      /var/run/secrets/kubernetes.io/serviceaccount from default-token-xxqkj (ro)

7.验证挂载

查看配置

kubectl exec pods/configmap-volume-pod -- ls /etc/nginx/conf.dgzip.cfgngx-status.cfgvhost.conf

测试Nginx配置打印出配置

kubectl exec pods/configmap-volume-pod -- nginx -T

拜访stub_status模块

kubectl exec pods/configmap-volume-pod -- curl 2>/dev/null  http://127.0.0.1/ngx_statusActive connections: 1server accepts handled requests 8 8 8Reading: 0 Writing: 1 Waiting: 0

如上可见,nginx-config-files中的三个文件都被增加到来容器中,并实现了由容器利用Nginx加载并失效

挂载存储卷中的局部键值

有时候,用户很可能不冀望在容器中挂载某ConfigMap存储卷中的所有文件,这在通过一个ConfigMap对象为单个Pod资源中的多个容器别离提供配置时尤其常见。例如后面示例中,用户可能只冀望在容器中挂载ConfigMap存储卷后只“导出”其中出vhost.conf和gzip.cfg文件,只提供给传输压缩性能,而不输入 nginx stub status信息,此时将其 volumes 配置段改为如下所示的内容即可。

apiVersion: v1kind: Podmetadata:  name: configmap-volume-pod  namespace: defaultspec:  containers:  - name: configmap-containers    image: nginx:latest    volumeMounts:                        #卷挂载配置    - name: ngx-config                    #挂载的卷名称      mountPath: /etc/nginx/conf.d/        #挂载在容器中的指标门路      readOnly: true                        #是否为只读  volumes:                                        #卷配置  - name: ngx-config                        #定义一个卷名称    configMap:                                    #卷从configMap中取值      name: nginx-config-files                #指定要挂载的configMap名称      items:                                            #nginx-config-files ConfigMap中的键      - key: vhost.conf                                #指定要挂载键        path: vhost.conf                            #挂载的门路        mode: 0644                                    #挂载后的文件权限      - key: gzip.cfg        path: compression.cfg        mode: 0644

ConfigMap存储卷的items字段的值是一个对象列表,可嵌套应用的字段有三个,具体如下:

  • key<strting>:要援用的键名称,必选字段。
  • path<string>:对应的键于挂载点目录中生成的文件相对路径,能够不同于键名称,必选字段。
  • mode<integer>:文件的权限模型,可用范畴为0到0777。

1.将原来的Pod删除,而后从新创立Pod

kubectl delete pods/configmap-volume-podkubectl apply -f configmap-volume-pod.yaml

2.验证Nginx配置文件

kubectl exec pods/configmap-volume-pod -- nginx -Tkubectl exec pods/configmap-volume-pod -- ls /etc/nginx/conf.dcompression.cfgvhost.conf

独立挂载存储卷中的键值

下面的两种形式中,无论是装载所有文件还是局部文件,挂载点目录下原有的文件都会被暗藏或者称为笼罩,在咱们没有挂载的时候,/etc/nginx/conf.d目录下有default.conf文件,当咱们挂载之后default.conf就被暗藏或者说笼罩掉了,但有时候咱们心愿挂载进的文件不笼罩相应目录下的其它文件,这个时候就能够通过volumeMounts属性中的subPath字段来解决,它能够反对用户从存储卷挂载单个文件或者单个目录而非整个存储卷。

例如上面示例 /etc/nginx/conf.d 目录中挂载一个 vhost.conf 文件,并且不笼罩原来目录下的 default.conf 文件。
/usr/share/nginx/html目录中挂载一个configmap.html文件,并且不笼罩原来目录下的 index.html 文件。

1.删除原来创立的ConfigMap和Pod

kubectl delete configmap nginx-config-fileskubectl delete pods/configmap-volume-pod

2.创立两个ConfigMap,别离用于nginx配置文件和nginx网页文件

#创立nginx配置文件configmapkubectl create configmap nginx-config-files --from-file=./data/nginx/conf.d/#写一个网页文件cat data/nginx/html/configmap.html<h1>ConfigMap-Volume-Pod-Mounts</h1>#创立nginx网页文件configmapkubectl create configmap nginx-html-files --from-file=./data/nginx/html/configmap.html

3.创立Pod资源配置清单

apiVersion: v1kind: Podmetadata:  name: configmap-volume-pod  namespace: defaultspec:  containers:  - name: configmap-containers    image: nginx:latest    volumeMounts:    - name: ngx-config      mountPath: /etc/nginx/conf.d/vhost.conf      subPath: vhost.conf      readOnly: true    - name: ngx-html      mountPath: /usr/share/nginx/html/configmap.html      subPath: configmap.html      readOnly: true  volumes:  - name: ngx-config    configMap:      name: nginx-config-files  - name: ngx-html    configMap:      name: nginx-html-files

4.创立Pod对象

kubectl apply -f configmap-volume-pod.yaml

5.查看Pod对象挂载状态

kubectl describe pods/configmap-volume-pod | grep -A 3 Mounts    Mounts:      /etc/nginx/conf.d/vhost.conf from ngx-config (ro,path="vhost.conf")      /usr/share/nginx/html/configmap.html from ngx-html (ro,path="configmap.html")      /var/run/secrets/kubernetes.io/serviceaccount from default-token-xxqkj (ro)

6.验证Pod Nginx配置

kubectl exec pods/configmap-volume-pod -- ls /etc/nginx/conf.ddefault.confvhost.confkubectl exec pods/configmap-volume-pod -- nginx -T

7.验证Pod网页文件挂载配置

#查看文件是否存在kubectl exec pods/configmap-volume-pod -- ls -lrth /usr/share/nginx/htmltotal 12K-rw-r--r-- 1 root root 612 May 26 15:00 index.html-rw-r--r-- 1 root root 494 May 26 15:00 50x.html-rw-r--r-- 1 root root  37 Jun  9 07:02 configmap.html#拜访configmap网页文件curl http://172.20.1.17/configmap.html<h1>ConfigMap-Volume-Pod-Mounts</h1>

# 6. 应用ConfigMap资源的注意事项

在Pod资源中调用ConfigMap对象时须要留神以下几个问题。

  • 以存储卷拜访援用的ConfigMap必须在Pod启动前存在,除非在Pod中将他们全副标记为optional,否则会导致Pod无奈失常启动的谬误,同样即便存在ConfigMap,在援用ConfigMap中的键不存在时,也会导致一样的谬误。
  • 当以环境变量注入的ConfigMap中的键不存在时会被疏忽,Pod能够失常启动,但谬误援用的信息会以InvalidVariableNames事件记录于日志中。
  • ConfigMap是名称空间级的资源,因而援用它的Pod必须处于同一名称空间中。
  • kubelet不反对援用Kubernetes API Server上不存在的ConfigMap,这包含那些通过kubelet的--manifest-url--config选项,以及 kubelet REST API 创立的Pod。

有段时间没跟大家分享资源福利了,看了下本人的资料夹,整顿了一些我认为比拟好的Python学习材料了。置信这套材料能够对你进阶高级工程师有帮忙

学习工具

大厂实战手册

自学视频(局部)

【材料收费支付形式】:点这里:2020Python高薪实战学习大合集