乐趣区

关于云计算:Kubernetes之ConfigMap详解及实践

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.yaml
apiVersion: v1
kind: Pod
metadata:
  name: command-demo
  labels:
    purpose: demonstrate-commdn
spec:
  containers:
  - name: command-demo-container
    image: busybox
    command: ["httpd"]
    args: ["-f"]
    ports:
    - containerPort: 80

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

kubectl exec -it pods/command-demo -- ps aux
PID   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.yaml
apiVersion: v1
kind: Pod
metadata:
  name: command-demo
  labels:
    purpose: demonstrate-commdn
spec:
  containers:
  - name: command-demo-container
    image: busybox
    args: ["httpd","-f"]
    ports:
    - containerPort: 80

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

kubectl exec -it pods/command-demo -- ps aux
PID   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.yaml
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.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 -- printenv
HELLO_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 configmap
NAME             DATA   AGE
special-config   2      55s


#应用 kubectl describe 能够看到 configmap 中的原始数据
kubectl describe configmap/special-config
Name:         special-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
mysql_ip:
----
172.16.0.3
mysql_port:
----
3306
Events:  <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.yaml
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: true

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

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

3. 查看创立的 ConfigMap

kubectl describe configmap elastic-configmap
Name:         elastic-configmap
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
elasticsearch.yaml:                                #咱们没有指定 key,默认以文件名称为 key
----
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: true

Events:  <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 yaml
apiVersion: v1
data:
  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: true
kind: ConfigMap
metadata:
  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-files
Name:         nginx-config-files
Namespace:    default
Labels:       <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 yaml
apiVersion: v1
data:
  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: ConfigMap
metadata:
  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.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: configmap-demo
data:
  log_level: INFO
  log_file: /var/log/test.log
kubectl describe configmap configmap-demo
Name:         configmap-demo
Namespace:    default
Labels:       <none>
Annotations:
Data
====
log_file:
----
/var/log/test.log
log_level:
----
INFO
Events:  <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.yaml
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:                             #援用来自 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.yaml
configmap/busybox-httpd-config created
pod/configmap-env-demo created

kubectl exec pods/configmap-env-demo -- ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/httpd -f -p 8080 -vv
    8 root      0:00 ps aux

kubectl exec pods/configmap-env-demo -- env | grep HTTPD
HTTPD_PORT=8080
HTTPD_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.yaml
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", "$(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 aux
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/httpd -f -p 8080 -vv
    7 root      0:00 ps aux

kubectl exec pods/configmap-env-demo -- printenv | grep HTCPG
HTCPG_verbose_level=-vv
HTCPG_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.conf
server {
        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.yaml
apiVersion: v1
kind: Pod
metadata:
  name: configmap-volume-pod
  namespace: default
spec:
  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-pod
configmap-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.d
gzip.cfg
ngx-status.cfg
vhost.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_status
Active connections: 1
server accepts handled requests
 8 8 8
Reading: 0 Writing: 1 Waiting: 0

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

挂载存储卷中的局部键值

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

apiVersion: v1
kind: Pod
metadata:
  name: configmap-volume-pod
  namespace: default
spec:
  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-pod
kubectl apply -f configmap-volume-pod.yaml

2. 验证 Nginx 配置文件

kubectl exec pods/configmap-volume-pod -- nginx -T
kubectl exec pods/configmap-volume-pod -- ls /etc/nginx/conf.d
compression.cfg
vhost.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-files
kubectl delete pods/configmap-volume-pod

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

# 创立 nginx 配置文件 configmap
kubectl create configmap nginx-config-files --from-file=./data/nginx/conf.d/

#写一个网页文件
cat data/nginx/html/configmap.html
<h1>ConfigMap-Volume-Pod-Mounts</h1>

#创立 nginx 网页文件 configmap
kubectl create configmap nginx-html-files --from-file=./data/nginx/html/configmap.html

3. 创立 Pod 资源配置清单

apiVersion: v1
kind: Pod
metadata:
  name: configmap-volume-pod
  namespace: default
spec:
  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.d
default.conf
vhost.conf

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

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

# 查看文件是否存在
kubectl exec pods/configmap-volume-pod -- ls -lrth /usr/share/nginx/html
total 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 高薪实战学习大合集

退出移动版