in-tree 类型的特殊卷插件

主要是为了给容器提供配置信息的。因为容器本身是由多层叠加起来的联合挂载的镜像层所组成,构建完成之后,就无法对镜像层上的数据修改,除了附加新的镜像层 , 而且一旦把镜像运行成容器的话,是以黑盒的形式运行的,每一个容器都有它的边界 ,是隔离的文件系统。

  • configMap
  • Secret 与configMap 等同作用 ,却是为了专门存储注入敏感信息 的数据
  • downwardAPI 将运行在pod之外的信息注入到pod 中,如

如何为容器化应用提供配置呢?

  1. 启动容器时,直接向应用程序传递参数,args: []

    pod 当中 使用command args 字段定义就行了

  2. 将定义好的配置文件焙进镜像之中; (自己重新打镜像,缺点是无法再改)

  3. 通过环境变量向容器传递配置数据:有个前提要求,应用得支持从环境变量加载配置信息; 制作镜像时,使用entrypoint脚本来预处理变量,常见的做法就是使用非交互式编辑工具,将环境变量的值替换到应用的配置文件中;

    早期传统开发的应用,多数不支持这种功能

    要求 容器中的应用支持以变量的形式 加载配置信息

  4. 基于存储卷向容器传递配置文件;
    运行中的改变,需要由应用程序重载,若容器中的应用不支持重载只能restart容器;

    在k8s 当中就是configMap Secret

configMap 类型存储插件是如何为容器化应用提供配置信息:
image-20211214014049592

图中的正方形代表pod 中容器

通过两种方式:

  1. 第一种,ConfigMap以k/v格式保存配置项的名称和配置数据;而后,由Pod中的容器以环境变量的方式从ConfigMap中加载特定的键的值;
  2. 第二种方式,可以让Pod直接将ConfigMap以存储卷的形式进行附加,而由容器挂载至指定目录下,从而获取到完整的配置 文件。

configMap 是一种独立于pod 外的一种资源类型

第一种: pod 在启动时能让内部的容器,从configMap 中读取一个或者有限个数据项,加载个别数据项,将数据项的值赋值给容器的某个环境变量。==如果pod 中的某个容器支持从环境变量加载配置信息,那我们把配置信息保存在这个configmap 的一个数据项 上,就能传给pod 内部中的容器了。==而且这个数据项本身能长久的保存于k8s之上

​ 举例: 在configMap 中有一个数据项 para1:Value1、para2:Value2. pod env定义 host 字段: host 取值来于configMap , 需要什么值,加载设置对应数据项的键 即可

env:
  -name:host
   valueFrom:para1 

第二种:直接把configMap 以卷插件的方式(这个卷插件的类型就叫configMap) , 将该存储卷关联至这个pod 上来, 会把configmap 里的数据项作为一个配置文件来进行识别。 因此用这种方式就会在存储卷中看到一个配置文件,这个配置文件里都是配置数据项信息(k1v1的格式)【严格意义上来说每一个数据项就是一个文件 ,但是为了便捷性 就用了Mapstring 类型表达】

secret 与此类似 ,只是存储的数据做了base64编码的转换

[root@node01 ~]# kubectl  explain  configmap

只有data 字段最常用

eg 命令式命令创建 configmap
[root@node01 ~]# kubectl  create configmap  --help

literal 表示直接用键值

[root@node01 ~]# kubectl  create configmap configmap-demoapp --from-literal=host=0.0.0.0 --from-literal=port=8080
configmap/configmap-demoapp created

查看创建的cm

[root@node01 ~]# kubectl get cm
NAME                DATA   AGE
configmap-demoapp   2      2m38s

查看cm中的键值

[root@node01 ~]# kubectl get cm/configmap-demoapp -o yaml
apiVersion: v1
data:
  host: 0.0.0.0
  port: "8080"
kind: ConfigMap
metadata:
  creationTimestamp: "2021-12-14T07:12:56Z"
  name: configmap-demoapp
  namespace: default
  resourceVersion: "196589"
  selfLink: /api/v1/namespaces/default/configmaps/configmap-demoapp
  uid: 1c64d4d2-d2c2-43ed-8b83-5a995c2bef8e
[root@node01 ~]# 
eg --from-file:基于文件传递数据,创建configmap

默认 键是文件名, key 是文件的内容

可以用双等于号,重定义 建名称, key 仍然是文件的内容

[root@node01 nginx-conf.d]# ll myserver.conf  myserver-status.cfg 
-rw-r--r-- 1 root root 164 Dec 14 18:51 myserver.conf
-rw-r--r-- 1 root root  67 Dec 14 18:51 myserver-status.cfg


[root@node01 nginx-conf.d]# kubectl  create  configmap nginx-confs --from-file=./myserver.conf --from-file=status.cfg=./myserver-status.cfg
configmap/nginx-confs created


[root@node01 nginx-conf.d]# 
[root@node01 nginx-conf.d]# kubectl get cm/nginx-confs
NAME          DATA   AGE
nginx-confs   2      23s
[root@node01 nginx-conf.d]# 
[root@node01 nginx-conf.d]# 
[root@node01 nginx-conf.d]# 
[root@node01 nginx-conf.d]# kubectl get cm/nginx-confs -o yaml
apiVersion: v1
data:
  myserver.conf: |
    server {
        listen 8080;
        server_name www.ik8s.io;

        include /etc/nginx/conf.d/myserver-*.cfg;

        location / {
            root /usr/share/nginx/html;
        }
    }
  status.cfg: |
    location /nginx-status {
        stub_status on;
        access_log off;
    }
kind: ConfigMap

为表示 多个kv对 ,用| 隔开 键值

基于文件夹传递数据

注意: 这样就不能修改文件名称了

[root@node01 chapter6]# kubectl  create configmap  nginx-config-files  --from-file=./nginx-conf.d/
configmap/nginx-config-files created

describe 查看时, 键值对之间 换行分割。 键值之间 ====分割。

[root@node01 chapter6]# kubectl describe cm/nginx-config-files
Name:         nginx-config-files
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
myserver-gzip.cfg:
----
gzip on;
gzip_comp_level 5;
gzip_proxied     expired no-cache no-store private auth;
gzip_types text/plain text/css application/xml text/javascript;

myserver-status.cfg:
----
location /nginx-status {
    stub_status on;
    access_log off;
}

pod 引用configmap中的数据项

基于键值引用

在容器containers.env.valueFrom 指定

name 表示的是 cm 名称

key 表示的是cm 的键

option 表示是否可选 , 如果可选,假如cm 中没定义,则不会报错。如果是不可选, 没定义的话创建过程就会退出并且报错。

不一定需要全部引用键值

[root@node01 chapter6]# cat  configmaps-env-demo.yaml 
# Maintainer: MageEdu <mage@magedu.com>
# URL: http://www.magedu.com
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: demoapp-config
  namespace: default
data:
  demoapp.port: "8080"
  demoapp.host: 0.0.0.0
---
apiVersion: v1
kind: Pod
metadata:
  name: configmaps-env-demo
  namespace: default
spec:
  containers:
  - image: ikubernetes/demoapp:v1.0
    name: demoapp
    env:
    - name: PORT
      valueFrom:
        configMapKeyRef:
          name: demoapp-config
          key: demoapp.port
          optional: false
    - name: HOST
      valueFrom:
        configMapKeyRef:
          name: demoapp-config
          key: demoapp.host
          optional: true
基于存储卷的方式引用
eg1

如果这里的voulumes/cm 下 没有用key 指定特定的文件 ,默认使用cm中所有的配置文件

[root@node01 chapter6]# cat configmaps-volume-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: configmaps-volume-demo
  namespace: default
spec:
  containers:
  - image: nginx:alpine
    name: nginx-server
    volumeMounts:
    - name: ngxconfs
      mountPath: /etc/nginx/conf.d/
      readOnly: true
  volumes:
  - name: ngxconfs
    configMap:
      name: nginx-config-files
      optional: false

发现基于存储卷插件的方式引用 , 之前定义的configmap 所引用的文件,直接挂载在指定的目录下

[root@node01 chapter6]# kubectl exec -it configmaps-volume-demo -- /bin/sh
/ # cd /etc/nginx/conf.d/
/etc/nginx/conf.d # ls
myserver-gzip.cfg    myserver-status.cfg  myserver.conf
/etc/nginx/conf.d # 

验证结果

取podiP值

[root@node01 ~]# pod_ip=$(kubectl get po/configmaps-volume-demo  -o go-template={{.status.podIP}})
[root@node01 ~]# curl    -H "Host:www.ik8s.io" $pod_ip:8080/nginx-status
Active connections: 1 
server accepts handled requests
 3 3 3 
Reading: 0 Writing: 1 Waiting: 0 
[root@node01 ~]# 
eg2: 通过cm/items 选择特定cm 数据项的输出(挂载)

创建一个cm 。同时指定2种不同方式数据传递到cm, 创建一个pod ,让pod内的2个容器分别用变量和文件的方式实现数据注入

一个容器在挂载cm 时,挂载其有限个键值 而非所有的 。 如何使用环境变量 的方式 引用其他键值

[root@node01 chapter6]# kubectl  create cm demoapp-confs  --from-literal=demoapp.host=127.0.0.1 --from-literal=demoapp.port=8080 --from-file=./demoapp-conf.d/
configmap/demoapp-confs created
[root@node01 chapter6]# kubectl get cm/demoapp-confs
NAME            DATA   AGE
demoapp-confs   4      68s

这里的data 表示4个数据项 ,2个来自变量 ,2个来自./demoapp-conf.d/的2个文件

[root@node01 chapter6]# cat configmaps-volume-demo2.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: configmaps-volume-demo2
  namespace: default
spec:
  containers:
  - name: proxy
    image: envoyproxy/envoy-alpine:v1.14.1
    command: ['/bin/sh','-c','envoy -c /etc/envoy/..data/envoy.yaml']
    volumeMounts:
    - name: appconfs
      mountPath: /etc/envoy
      readOnly: true
  - name: demo
    image: ikubernetes/demoapp:v1.0
    imagePullPolicy: IfNotPresent
    env:
    - name: PORT
      valueFrom:
        configMapKeyRef:
          name: demoapp-confs
          key: demoapp.port
          optional: false
    - name: HOST
      valueFrom:
        configMapKeyRef:
          name: demoapp-confs
          key: demoapp.host
          optional: true
  volumes:
  - name: appconfs
    configMap:
      name: demoapp-confs
      items:
      - key: envoy.yaml
        path: envoy.yaml
        mode: 0644
      - key: lds.conf
        path: lds.conf
        mode: 0644
      optional: false

path 指定是挂载的文件名称, key 指定是挂载后 重新命名的键 名称

mode 挂载之后的文件权限

eg3: 通过容器中的 subpath 筛选特定文件,选择性挂载

subptah 表示不挂载根目录,而是挂载指定根目录的子目录

[root@node01 chapter6]# cat configmaps-volume-demo3.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: configmap-volume-demo3
  namespace: default
spec:
  containers:
  - image: nginx:alpine
    name: nginx-server
    volumeMounts:
    - name: ngxconfs
      mountPath: /etc/nginx/conf.d/myserver.conf
      subPath: myserver.conf
      readOnly: true
    - name: ngxconfs
      mountPath: /etc/nginx/conf.d/myserver-gzip.cfg
      subPath: myserver-gzip.cfg
      readOnly: true
  volumes:
  - name: ngxconfs
    configMap:
      name: nginx-config-files

验证结果: 无status 文件

[root@node01 chapter6]# kubectl exec -it configmap-volume-demo3 -- /bin/sh
/ # ls  /etc/nginx/conf.d/
default.conf       myserver-gzip.cfg  myserver.conf
pod 重载
[root@node01 chapter6]# kubectl  exec -it  po/configmaps-volume-demo -- /bin/sh
/ # cd  /etc/nginx/conf.d/
                         
/etc/nginx/conf.d # ls -lA
total 0
drwxr-xr-x    2 root     root            79 Dec 14 12:59 ..2021_12_14_12_59_40.479450326
lrwxrwxrwx    1 root     root            31 Dec 14 12:59 ..data -> ..2021_12_14_12_59_40.479450326
lrwxrwxrwx    1 root     root            24 Dec 14 12:59 myserver-gzip.cfg -> ..data/myserver-gzip.cfg
lrwxrwxrwx    1 root     root            26 Dec 14 12:59 myserver-status.cfg -> ..data/myserver-status.cfg
lrwxrwxrwx    1 root     root            20 Dec 14 12:59 myserver.conf -> ..data/myserver.conf
/etc/nginx/conf.d # 


/etc/nginx/conf.d # cd ..2021_12_14_12_59_40.479450326/
/etc/nginx/conf.d/..2021_12_14_12_59_40.479450326 # ls
myserver-gzip.cfg    myserver-status.cfg  myserver.conf
/etc/nginx/conf.d/..2021_12_14_12_59_40.479450326 # 

发现所有volumes 挂载的configmap中的文件 ,最终都是指向了隐藏的日期文件夹文件,

如果configmap 发生变动 ,会生成一个新的时间戳目录,会重新挂载。只要应用支持重载,就能生效,比如nginx , 虽然支持热加载,但是不会自动重载,不会自动reload ,但是一些云原生的应用会自动感知到配置信息发生改变时自动重载

eg:

修改cm

[root@node01 chapter6]# kubectl  edit cm/nginx-config-files

为nginx 添加 状态页 限制

 myserver-status.cfg: |
    location /nginx-status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all ;
    }

注意: 换行时,回车键会自动用tab 键补齐,一定得用空格

验证: 容器内的文件也会同时发生变化

/ # cat /etc/nginx/conf.d/myserver-status.cfg 
location /nginx-status {
    stub_status on;
    access_log off;
    allow 127.0.0.1/8;
    deny all;
}

同时挂载点隐藏目录日期也会发生改变

/ # ls -lA  /etc/nginx/conf.d/..2021_12_14_15_31_54.818728554/

之后nginx reload 就行

/ # nginx  -s reload  重载

/ # nginx  -T   dump 配置文件信息

因为只要修改了cm , 任何使用了该cm 的pod都会生效。所以 cm 为k8s 提供了配置中心的服务

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐