zoukankan      html  css  js  c++  java
  • configmap 和 secret 概述


    本篇文章是对 configmap 和 secret 的一个总结,详细信息可看 这里

    1. configmap 和 secret 概述

    在 container 的 image 中可通过 ENTRYPOINT 和 CMD 分别定义执行命令和参数。其中,ENTRYPOINT 定义容器启动时调用的可执行程序,CMD 指定传递给 ENTRYPOINT 的参数。

    传递的参数可被 pod 的文本定义覆盖。并且,对于容器的主进程也有两种形式运行:

    1. 以 shell 形式运行,此种形式下容器的主进程即 1 号进程是 bash 进程,image 中指定的可执行被 bash 进程调用。
    2. 以 exec 形式运行,该形式下容器的主进程即为 image 中指定的可执行程序。

    两种形式的执行示例如下:

    • shell 形式: ENTRYPOINT startup hello.world
    • exec 形式: ENTRYPOINT ["startup", hello.world]

    注意,以 shell 形式运行的容器,其无法响应 Kubernetes 发送的 signal TERM 信号。即在容器 graceful shutdown 时,容器会忽视 kubernetes 发送的 signal TERM 信号。对于“规定”时间内未响应的容器,kubernetes 会再次发送 KILL 信号强制 kill 容器。详细信息看 这里

    对于容器的启动命令传递参数是常见的,那么对于配置文件呢?直接传递配置文件而不是环境变量该怎么做呢?
    Kubernets 为应对这种场景(当然不局限于这一种场景),引入 configmap 的概念。configmap 和 pod 的定义解耦,使得同一份 configmap 可以被多个 pod 使用,同时 configmap 可以动态传递参数给容器,而不需要容器重启。

    configmap 可以往容器中传递环境变量,命令行参数和文本文件。其中,传递文本文件是通过 configmap 卷的方式实现的。

    类似于 configmap,secret 可以被看作为一种“加密”数据的 configmap,它存放的是“敏感”数据,如系统自带的 default serviceaccount,其访问 kubernetes 需要系统自带的 default token secret 实现认证,鉴权操作。

    2. configmap 和 pod

    前面说了使用 configmap 的好处之一是可以动态更改容器配置,而不需要重启容器。试想如果配置通过 image 传递给 pod,如果需要更改 image 的配置则势必要重新部署 pod 以使 image 改动生效。此种场景下对业务势必有影响,而使用 configmap 则不需要。

    创建 configmap 和 pod 如下:

    [root@chunqiu configmap (Master)]# cat configmap.yaml
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: initparse
    data:
      parse: |
        import json
    
    [root@chunqiu configmap (Master)]# cat statefulSet.yaml  
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: chunqiu
    spec:
      replicas: 1
      ...
      template:
        ...
        spec:
          volumes:
          - name: oam-init-volume
            configMap:
              name: initparse
          containers:
          - name: oam
            volumeMounts:$
            - name: oam-init-volume$
              mountPath: /etc/config/parse
    

    使用 statefulSet 创建 pod。其中, configmap 以卷的形式 mount 到容器中的 /etc/config/parse 路径下:

    [root@chunqiu configmap (Master)]# kubectl exec -it chunqiu-0 /bin/bash -n chunqiu
    [root@chunqiu-0:/]
    # cat /etc/config/parse/parse
    import json
    

    可以看到 configmap 中的内容已被 mount 到容器中。进一步地,修改 configmap 中的配置,查看改动是否动态映射到容器中:

    # 修改 configmap
    [root@chunqiu configmap (Master)]# kubectl edit configmaps initparse -n chunqiu
    configmap/initparse edited
    
    [root@chunqiu configmap (Master)]# kubectl describe configmaps initparse -n chunqiu
    Name:         initparse
    Namespace:    chunqiu
    
    Data
    ====
    parse:
    ----
    import json
    import log
    
    # 查看容器内文件是否改动
    [root@chunqiu configmap (Master)]# kubectl exec -it chunqiu-0 /bin/bash -n chunqiu
    [root@chunqiu-0:/]
    # cat /etc/config/parse/parse
    import json
    import log
    

    在另一个窗口 watch pod 的更新,发现 pod 未更新。可以看到改动生效了,且容器并未重启。

    这里有几点需要注意的是:

    • 修改 configmap 到容器内的改动生效是需要几分钟的延迟的,为什么有几分钟延迟可看 这里
    • 如果 configmap 中使用 subPath,那么容器对 configmap 的动态更新是无效的。
    • configmap 需要在容器创建前建好,否则容器会提示找不到 configmap。对于 mount 环境变量到容器中的 configmap,环境变量是在主进程启动前即 mount 好,所以主进程中的参数可以使用 configmap mount 的环境变量。
    • “多次”更改 configmap 并不会以相同频率更新容器中的文件。可以查看容器中的隐藏文件如下:
    [root@chunqiu-0:/etc/config/parse]
    # ls -lA
    total 0
    drwxr-xr-x. 2 root root 19 Sep  6 15:41 ..2021_09_06_15_41_46.939921926
    lrwxrwxrwx. 1 root root 31 Sep  6 15:41 ..data -> ..2021_09_06_15_41_46.939921926
    lrwxrwxrwx. 1 root root 12 Sep  6 15:40 parse -> ..data/parse
    

    映射到容器中的文本文件实际上是一个指向 ..data/parse 的软链接,该软链接经过层层链接最终指向文本为日期+时间+字符串的文本,该文本即是 kubernetes 映射到容器中的实际文件。可以看出,kubernetes 并不是对 configmap 的多次改动频繁更新,而是只更新一次。再次更新 configmap 查看文件文件内容:

    # 更新 configmap 信息
    [root@chunqiu configmap (Master)]# kubectl edit configmaps initparse -n chunqiu
    configmap/initparse edited
    [root@chunqiu configmap (Master)]# kubectl describe configmaps initparse -n chunqiu
    Name:         initparse
    
    Data
    ====
    parse:
    ----
    import json
    import log
    import print
    
    # 查看容器中文本文件
    [root@chunqiu-0:/etc/config/parse]
    # ls -lA
    total 0
    drwxr-xr-x. 2 root root 19 Sep  6 15:59 ..2021_09_06_15_59_07.176029107
    lrwxrwxrwx. 1 root root 31 Sep  6 15:59 ..data -> ..2021_09_06_15_59_07.176029107
    lrwxrwxrwx. 1 root root 12 Sep  6 15:40 parse -> ..data/parse
    
    [root@chunqiu-0:/etc/config/parse]
    # cat /etc/config/parse/parse
    import json
    import log
    import print
    

    可以看到,容器中的文本文件在过一段时间后更新,且最终链接到的文本文件亦被更新。

    2.1 secret 和 pod

    mount secret 到 pod 的方式和 configmap 类似,这里不做过多展开。值得一提的是 secret 中的数据保存在内存中,而不是硬盘:

    [root@chunqiu-0:/etc/config/parse]
    # mount | grep parse
    /dev/sda5 on /etc/config/parse type xfs (ro,relatime,seclabel,attr2,inode64,noquota)
    
    [root@chunqiu-0:/etc/config/parse]
    # mount | grep service
    tmpfs on /run/secrets/kubernetes.io/serviceaccount type tmpfs (ro,relatime,seclabel)
    

    可以看到,前面 configmap mount 到容器的文本文件,是以 xfs 形式保存在 sda5 这块硬盘上,而 secret mount 的文本文件是以 tmpfs 的形式保存在 node 上的内存中,数据不会被外部应用读写到,安全性更高。

    3. statefulSet 和 configmap

    这里简要提下 statefulSet 和 configmap,configmap 可以 mount 到多个由 statefulSet 管理的 pod 上。

    对于 statefulSet 来说其默认的管理 pod 策略是 OrderedReady,即对于 statefulSet 的更新,scale,创建,删除等操作严格按照顺序进行,前一个 pod 状态没有 running 无法进行后一个 pod 操作。

    不过,对于不需要定义这么严格的按顺序操作的 statefulSet 该怎么做呢?
    Kubernetes 提供了 .spec.podManagementPolicy 为 Parallel 的参数来修改 pod 的管理策略。对于定义为 Parallel 的管理策略,pod 的创建,删除,scale 不需要按顺序 ready,不过 pod 的更新还是和 OrderedReady 类型保持一致。

    芝兰生于空谷,不以无人而不芳。
  • 相关阅读:
    使用slf4j取代Apache Commons Logging
    IntelliJ远程调试教程
    java日志,(commons-loging 、log4j 、slf4j 、LogBack介绍)
    oracle 时间函数
    在Windows操作系统中,如何终止占有的8080端口的tomcat进程
    解决dwr报错【 Error: java.lang.SecurityException: No class by name: service】
    eclipse下使用tomcat启动maven项目
    Eclipse Java注释模板设置详解
    weblogic启动时日志重定向(nohup.out)
    信息化的基本概念
  • 原文地址:https://www.cnblogs.com/xingzheanan/p/15236464.html
Copyright © 2011-2022 走看看