Bootstrap

ConfigMap学习笔记

ConfigMAP 一般用configmap去管理一些配置文件,或者一些大量的环境变量信息

ConfigMap将配置和pod分开,有一个nginx ,nginx.Conf->configmap.nginx更易于配置文件的更改和管理

ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。使用时, Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件

ConfigMap | Kubernetes

ConfigMap 允许你将配置文件与镜像文件分离,以使容器化的应用程序具有可移植性

基于目录创建 ConfigMap

# 创建本地目录

mkdir -p configure-pod-container/configmap/

# 将实例文件下载到 `configure-pod-container/configmap/` 目录

wget https://kubernetes.io/examples/configmap/game.properties -O configure-pod-container/configmap/game.properties

wget https://kubernetes.io/examples/configmap/ui.properties -O configure-pod-container/configmap/ui.properties

# 创建 configmap

kubectl create configmap game-config --from-file=configure-pod-container/configmap/

基于文件创建 ConfigMap 

kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties

你可以多次使用 --from-file 参数,从多个数据源创建 ConfigMap

kubectl create configmap game-config-2 --from-file=configure-pod-container/configmap/game.properties --from-file=configure-pod-container/configmap/ui.properties

指定文件名

kubectl create configmap game-config-3 --from-file=game-special-key=configure-pod-container/configmap/game.properties

具体格式

kubectl create configmap game-config-3 --from-file=<我的键名>=<文件路径>

查看创建的configmap

kubectl describe configmaps game-config-2

使用 --from-env-file 选项从环境文件创建 ConfigMap

Env 文件包含环境变量列表。其中适用以下语法规则:

  • Env 文件中的每一行必须为 VAR=VAL 格式。
  • 以#开头的行(即注释)将被忽略。
  • 空行将被忽略。
  • 引号不会被特殊处理(即它们将成为 ConfigMap 值的一部分)。

wget https://kubernetes.io/examples/configmap/game-env-file.properties -O configure-pod-container/configmap/game-env-file.properties

wget https://kubernetes.io/examples/configmap/ui-env-file.properties -O configure-pod-container/configmap/ui-env-file.properties

kubectl create configmap game-config-env-file \       --from-env-file=configure-pod-container/configmap/game-env-file.properties

从 Kubernetes 1.23 版本开始,kubectl 支持多次指定 --from-env-file 参数来从多个数据源创建 ConfigMap。

kubectl create configmap config-multi-env-files \        --from-env-file=configure-pod-container/configmap/game-env-file.properties \        --from-env-file=configure-pod-container/configmap/ui-env-file.properties

根据字面值创建 ConfigMap

kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm

你可以传入多个键值对。命令行中提供的每对键值在 ConfigMap 的 data 部分中均表示为单独的条目。

kubectl get configmaps special-config -o yaml

apiVersion: v1

kind: ConfigMap

metadata:

  creationTimestamp: 2016-02-18T19:14:38Z

  name: special-config

  namespace: default

  resourceVersion: "651"

  selfLink: /api/v1/namespaces/default/configmaps/special-config

  uid: dadce046-d673-11e5-8cd0-68f728db1985

data:

  special.how: very

  special.type: charm

基于生成器创建 ConfigMap

自 1.14 开始,kubectl 开始支持 kustomization.yaml。 你还可以基于生成器(Generators)创建 ConfigMap,然后将其应用于 API 服务器上创建对象。 生成器应在目录内的 kustomization.yaml 中指定

基于文件生成 ConfigMap

例如,要基于 configure-pod-container/configmap/kubectl/game.properties 文件生成一个 ConfigMap:

# 创建包含 ConfigMapGenerator 的 kustomization.yaml 文件

cat <<EOF >./kustomization.yaml

configMapGenerator:

- name: game-config-4  

files:  - configure-pod-container/configmap/kubectl/game.properties

EOF

使用 ConfigMap 数据定义容器环境变量

kubectl create configmap special-config --from-literal=special.how=very

apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

    - name: test-container

      image: k8s.gcr.io/busybox

      command: [ "/bin/sh", "-c", "env" ]

      env:

        # 定义环境变量

        - name: SPECIAL_LEVEL_KEY

          valueFrom:

            configMapKeyRef:

              # ConfigMap 包含你要赋给 SPECIAL_LEVEL_KEY 的值

              name: special-config

              # 指定与取值相关的键名

              key: special.how

  restartPolicy: Never

使用来自多个 ConfigMap 的数据定义容器环境变量

apiVersion: v1

kind: ConfigMap

metadata:

  name: special-config

  namespace: default

data:

  special.how: very

---

apiVersion: v1

kind: ConfigMap

metadata:

  name: env-config

  namespace: default

data:

  log_level: INFO

---

apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

    - name: test-container

      image: k8s.gcr.io/busybox

      command: [ "/bin/sh", "-c", "env" ]

      env:

        - name: custom-value-test

          value: 3306

        - name: SPECIAL_LEVEL_KEY

          valueFrom:

            configMapKeyRef:

              name: special-config

              key: special.how

        - name: LOG_LEVEL

          valueFrom:

            configMapKeyRef:

              name: env-config

              key: log_level

  restartPolicy: Never

将 ConfigMap 中的所有键值对配置为容器环境变量

apiVersion: v1

kind: ConfigMap

metadata:

  name: special-config

  namespace: default

data:

  SPECIAL_LEVEL: very

  SPECIAL_TYPE: charm

---

apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

    - name: test-container

      image: k8s.gcr.io/busybox

      command: [ "/bin/sh", "-c", "env" ]

      envFrom:  #和Env是同一级别

      - configMapRef:

          name: special-config

  restartPolicy: Never

在 Pod 命令中使用 ConfigMap 定义的环境变量

你可以使用 $(VAR_NAME) Kubernetes 替换语法在容器的 command 和 args 属性中使用 ConfigMap 定义的环境变量。

apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

    - name: test-container

      image: k8s.gcr.io/busybox

      command: [ "/bin/echo", "$(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]

      env:

        - name: SPECIAL_LEVEL_KEY

          valueFrom:

            configMapKeyRef:

              name: special-config

              key: SPECIAL_LEVEL

        - name: SPECIAL_TYPE_KEY

          valueFrom:

            configMapKeyRef:

              name: special-config

              key: SPECIAL_TYPE

  restartPolicy: Never

将 ConfigMap 数据添加到一个卷中

apiVersion: v1

kind: ConfigMap

metadata:

  name: special-config

  namespace: default

data:

  SPECIAL_LEVEL: very

  SPECIAL_TYPE: charm

在 Pod 规约的 volumes 部分下添加 ConfigMap 名称。 这会将 ConfigMap 数据添加到 volumeMounts.mountPath 所指定的目录 (在本例中为 /etc/config)。 command 部分引用存储在 ConfigMap 中的 special.level

apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

    - name: test-container

      image: k8s.gcr.io/busybox

      command: [ "/bin/sh", "-c", "ls /etc/config/" ]

      volumeMounts:

      - name: config-volume  #挂载卷volumeMounts的名字一定要和volumes的名字一致

        mountPath: /etc/config

  volumes:

    - name: config-volume

      configMap:

        # 提供包含要添加到容器中的文件的 ConfigMap 的名称

        name: special-config

  restartPolicy: Never

将 ConfigMap 数据添加到卷中的特定路径

使用 path 字段为特定的 ConfigMap 项目指定预期的文件路径。 在这里,ConfigMap 中键 SPECIAL_LEVEL 的内容将挂载在 config-volume 卷中 /etc/config/keys 文件中

apiVersion: v1

kind: Pod

metadata:

  name: dapi-test-pod

spec:

  containers:

    - name: test-container

      image: k8s.gcr.io/busybox

      command: [ "/bin/sh","-c","cat /etc/config/keys" ]

      volumeMounts:

      - name: config-volume

        mountPath: /etc/config

  volumes:

    - name: config-volume

      configMap:

        name: special-config

        items:

        - key: SPECIAL_LEVEL

          path: keys

  restartPolicy: Never

挂载的 ConfigMap 将自动更新 

当某个已被挂载的 ConfigMap 被更新,所投射的内容最终也会被更新。 对于 Pod 已经启动之后所引用的、可选的 ConfigMap 才出现的情形, 这一动态更新现象也是适用的。

kubelet 在每次周期性同步时都会检查已挂载的 ConfigMap 是否是最新的。 但是,它使用其本地的基于 TTL 的缓存来获取 ConfigMap 的当前值。 因此,从更新 ConfigMap 到将新键映射到 Pod 的总延迟可能与 kubelet 同步周期(默认 1 分钟) + ConfigMap 在 kubelet 中缓存的 TTL (默认 1 分钟)一样长。 你可以通过更新 Pod 的某个注解来触发立即更新。

当卷中使用的 ConfigMap 被更新时,所投射的键最终也会被更新。 kubelet 组件会在每次周期性同步时检查所挂载的 ConfigMap 是否为最新。 不过,kubelet 使用的是其本地的高速缓存来获得 ConfigMap 的当前值。 高速缓存的类型可以通过 KubeletConfiguration 结构. 的 ConfigMapAndSecretChangeDetectionStrategy 字段来配置。

ConfigMap 既可以通过 watch 操作实现内容传播(默认形式),也可实现基于 TTL 的缓存,还可以直接经过所有请求重定向到 API 服务器。 因此,从 ConfigMap 被更新的那一刻算起,到新的主键被投射到 Pod 中去, 这一时间跨度可能与 kubelet 的同步周期加上高速缓存的传播延迟相等。 这里的传播延迟取决于所选的高速缓存类型 (分别对应 watch 操作的传播延迟、高速缓存的 TTL 时长或者 0)。

以环境变量方式使用的 ConfigMap 数据不会被自动更新。 更新这些数据需要重新启动 Pod

使用 ConfigMap 作为 subPath 卷挂载的容器将不会收到 ConfigMap 的更新

不可变更的 ConfigMap 

Kubernetes 特性 Immutable Secret 和 ConfigMaps 提供了一种将各个 Secret 和 ConfigMap 设置为不可变更的选项。对于大量使用 ConfigMap 的集群 (至少有数万个各不相同的 ConfigMap 给 Pod 挂载)而言,禁止更改 ConfigMap 的数据有以下好处:

  • 保护应用,使之免受意外(不想要的)更新所带来的负面影响。
  • 通过大幅降低对 kube-apiserver 的压力提升集群性能, 这是因为系统会关闭对已标记为不可变更的 ConfigMap 的监视操作。

此功能特性由 ImmutableEphemeralVolumes 特性门控来控制。 你可以通过将 immutable 字段设置为 true 创建不可变更的 ConfigMap。 例如:

apiVersion: v1

kind: ConfigMapmetadata:  

...

data:  

...

immutable: true

一旦某 ConfigMap 被标记为不可变更,则 无法 逆转这一变化,,也无法更改 data 或 binaryData 字段的内容。你只能删除并重建 ConfigMap。 因为现有的 Pod 会维护一个已被删除的 ConfigMap 的挂载点,建议重新创建这些 Pods

mountPath结合subPath(也可解决多个configmap挂载同一目录,导致覆盖)作用

之所以会产生这种挂载,是为了解决多配置文件挂载,互相覆盖的问题,这种模式只会覆盖单一的配置文件

apiVersion: v1

kind: ConfigMap

metadata:

  name: nginx-conf

data:

  nginx.conf: |-

    user nginx;

    worker_processes auto;

    error_log /var/log/nginx/error.log;

    pid /run/nginx.pid;

    include /usr/share/nginx/modules/*.conf;

    events {

        worker_connections 1024;

    }

    http {

        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                          '$status $body_bytes_sent "$http_referer" '

                          '"$http_user_agent" "$http_x_forwarded_for"';

        access_log  /var/log/nginx/access.log  main;

        sendfile            on;

        tcp_nopush          on;

        tcp_nodelay         on;

        keepalive_timeout   65;

        types_hash_max_size 4096;

        include             /etc/nginx/mime.types;

        default_type        application/octet-stream;

        include /etc/nginx/conf.d/*.conf;

    }

  default.conf: |-

    server {

     listen 90;

     server_name www.hzl.com;

     location / {

     root /daima;

     autoindex on;

     autoindex_localtime on;

     autoindex_exact_size on;

     }

    }

---

apiVersion: apps/v1

kind: Deployment

metadata:

  name: nginx

spec:

  selector:

    matchLabels:

      app: nginx

  template:

    metadata:

      name: nginx

      labels:

        app: nginx

    spec:

      containers:

        - name: nginx

          image: nginx

          volumeMounts:

            - mountPath: /etc/nginx/conf.d

              name: nginx-default

            - mountPath: /etc/nginx/nginx.conf # 精确到文件

              name: nginx-conf

              subPath: nginx.conf # 精确到文件

      volumes:

        - name: nginx-default

          configMap:

            name: nginx-conf

            items:

              - key: default.conf

                path: default.conf

        - name: nginx-conf

          configMap:

            name: nginx-conf

            items:

              - key: nginx.conf

                path: nginx.conf

configmap(热更新

在不停服的前提下,可以更新配置文件

实现修改配置文件可以做到动态更新

1)使用该 ConfigMap 挂载的 Env 不会同步更新,POD的变量来自于 ConfigMap和Secret定义的内容,那么ConfigMap和Secret更新后,也不会更新POD中的变量

2>使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新

3)ConfigMap和Secret如果是以subPath的形式挂载,那么pod是不会感知到ConfigMap和Secret的更新的。可以通过挂载到其他目录下,然后通过ln -s软连接的方式链接到对应的目录下,使用容器的postStart特性

当ConfigMap以数据卷的形式挂载进Pod时,更新ConfigMap(或删掉重建ConfigMap),Pod内挂载的配置信息会热更新,但使用环境变量方式加载到pod,则不会自动更新(ENV 是在容器启动的时候注入的,启动之后 kubernetes 就不会再改变环境变量的值)。且同一个 namespace 中的 pod 的环境变量是不断累加的

更新configmap的命令

kubectl edit cm nginx-conf #针对比较小的configmap文件可以,大的文件由于显示不全

针对大的configmap文件

kubectl create cm nginx-conf --from-file=nginx.conf --dry-run -o yaml >nginx-conf-new.yaml

kubectl replace -f nginx-conf-new.yaml

合成命令就是kubectl create cm nginx-conf --from-file=nginx.conf --dry-run -o yaml|kubectl replace -f-

Service Account用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中

[root@m01 ~]# kubectl exec nginx-6cf7488b57-bd887 -- ls /run/secrets/kubernetes.io/serviceaccount

ca.crt

namespace

Token

Secret更倾向于存储和共享敏感,加密的信息。

;