查看原文
其他

漫画:Kubernetes中的ConfigMap和Secret

吴迪 K8S中文社区 2019-12-18


  • 我们可以直接在打包镜像的时候写在应用配置文件里面,但是这种方式的坏处显而易见而且非常明显。


  • 我们可以在配置文件里面通过 env 环境变量传入,但是这样的话我们要修改env就必须去修改 yaml 文件,而且需要重启所有的 Container 才行。


  • 我们可以在应用启动的时候去数据库或者某个特定的地方拿,没问题!但是第一,实现起来麻烦;第二,如果配置的地方变了怎么办?


而且,还有一个问题就是,如果说我的一个配置,是要多个应用一起使用的,以上除了第三种方案,都没办法进行配置的共享,就是说我如果要改配置的话,那得一个一个手动改。假如我们有100个应用,就得改100份配置,以此类推……


那就没有其他方法解决这些问题嘛?


| ConfigMap


ConfigMap让我们能够从容器镜像中把配置的详细信息给解耦出来。通过ConfigMap 我们能够把配置以 key-value 对的形式传递到 Container 或者别的系统组件(比如Controller)里面。


如何创建ConfigMap?


我们可以通过两种方式来创建 ConfigMap:

From Literal Values和From Configuration File;


From Literal Values 方法:

我们可以用 kubectl create 来创建一个 ConfigMap,然后通过 kubectl get 来获取:


  1. # Create the ConfigMap

  2. $ kubectl create configmap my-config --from-literal=key1=value1 --from-literal=key2=value2

  3. configmap "my-config" created

  4. # Get the ConfigMap Details for my-config

  5. $ kubectl get configmaps my-config -o yaml

  6. apiVersion: v1

  7. data:

  8.  key1: value1

  9.  key2: value2

  10. kind: ConfigMap

  11. metadata:

  12.  creationTimestamp: 2017-05-31T07:21:55Z

  13.  name: my-config

  14.  namespace: default

  15.  resourceVersion: "241345"

  16.  selfLink: /api/v1/namespaces/default/configmaps/my-config

  17.  uid: d35f0a3d-45d1-11e7-9e62-080027a46057


-o yaml 的作用是通过 yaml 的形式来返回我们所要求的配置信息。


From Configuration File 方法:

除了上面的方式,我们还可以直接通过配置文件来创建(好吧,虽然我感觉是同一种,只不过是放到文件里面了而已……),首先,我们得有一个配置文件,假设名字叫做 myconfigmap.yaml:


  1. apiVersion: v1

  2. kind: ConfigMap

  3. metadata:

  4.  name: customer1

  5. data:

  6.  TEXT1: Customer1_Company

  7.  TEXT2: Welcomes You

  8.  COMPANY: Customer1 Company Technology Pct. Ltd.


然后,我们可以通过 kubectl create -f 来创建:


  1. $ kubectl create -f myconfigmap.yaml

  2. configmap "customer1" created




同时也有两种使用方法,通过 env 和通过 Volume。


通过 env 方法:

我们可以设置 env从ConfigMap 读取:


  1. ....

  2. containers:

  3.      - name: rsvp-app

  4.        image: teamcloudyuga/rsvpapp

  5.        env:

  6.        - name: MONGODB_HOST

  7.          value: mongodb

  8.        - name: TEXT1

  9.          valueFrom:

  10.            configMapKeyRef:

  11.              name: customer1

  12.              key: TEXT1

  13.        - name: TEXT2

  14.          valueFrom:

  15.            configMapKeyRef:

  16.              name: customer1

  17.              key: TEXT2

  18.        - name: COMPANY

  19.          valueFrom:

  20.            configMapKeyRef:

  21.              name: customer1

  22.              key: COMPANY

  23. ....


这样,我们的 Container 就可以读取到 ConfigMap 里面存储的信息了。

不过一般情况下,我个人推荐使用另一种方式:


通过Volume

这种方式我比较推荐,因为随着 ConfigMap 被修改(比如你想要更新一些设置),Container 里面对应的文件内容也会被修改,这样可以不用重启Container 就让应用能够得到最新的配置信息。


这个内容需要一些 Volume 相关的知识,在此不做更多讲解,大家可以去参考官方文档。

https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#adding-configmap-data-to-a-volume



通过上面的部分,我们可以看到 ConfigMap 是用来做一些配置信息。



| 就是我们介绍的 Secret 方法:


看到这个名字大家应该就明白了吧,Kubernetes 提供了 Secret 来存储相关的信息。具体为什么要存在 Secret 里面,Secret 和 ConfigMap 有什么区别,后面会讲到。


先介绍如何创建和使用 Secret。


创建Secret

我们可以通过 kubectl create secret 来通过一个文件创建一个 Secret,如下:


  1. # Create a file with password

  2. $ echo 'mysqlpassword' > password.txt

  3. # Make sure there is no trailing newline in the file, after our password.

  4. # To remove any newline, we can use the tr command:

  5. $ tr -Ccsu '\n' < password.txt > .strippedpassword.txt && mv .strippedpassword.txt password.txt

  6. # Create the Secret

  7. $ kubectl create secret generic my-password --from-file=password.txt

  8. secret "my-password" created



我们也可以手动创建一个 Secret,不过要注意,所有的 Secret 的 data 都要以 base64 进行加密:


  1. $ cat password.txt | base64

  2. bXlzcWxwYXN3b3JkCg==

  3. # and then use it in the configuration file:

  4. apiVersion: v1

  5. kind: Secret

  6. metadata:

  7.  name: my-password

  8. type: Opaque

  9. data:

  10.  password: bXlzcWxwYXN3b3JkCg==


使用Secret


获取 Secret

我们可以通过 get 和 describe 来获取 Secret,不过我们发现,kubectl 并没有向我们返回 Secret 具体的内容:


  1. $ kubectl get secret my-password

  2. NAME          TYPE     DATA   AGE

  3. my-password   Opaque   1      8m

  4. $ kubectl describe secret my-password

  5. Name:          my-password

  6. Namespace:     default

  7. Labels:        <none>

  8. Annotations:   <none>

  9. Type  Opaque

  10. Data

  11. ====

  12. password.txt:  13 bytes


在 Pod 里面使用

和 ConfigMap 一样,我们可以通过设置成 env 或者挂载成 volume 来使容器可以使用我们的 Secret。


具体格式如下:


  1. .....

  2.         spec:

  3.      containers:

  4.      - image: wordpress:4.7.3-apache

  5.        name: wordpress

  6.        env:

  7.        - name: WORDPRESS_DB_HOST

  8.          value: wordpress-mysql

  9.        - name: WORDPRESS_DB_PASSWORD

  10.          valueFrom:

  11.            secretKeyRef:

  12.              name: my-password

  13.              key: password.txt

  14. .....


关于如何在 Volume 中使用的还是需要自行查询文档学习。




其实目前 Secret 的实现,就是 ConfigMap 把 value 用 base64 encode了一下,所以,其实不存在任何安全性,只要 decode 一下就能出现原来结果,相当于明文存储。


base64 这玩意儿都不能叫做加密,只能叫做编码,所以我们都不说 encrypt,而是 encode 和 decode。


当然,Kubernetes 社区有在计划对 Secret 进行下一步的安全性增强,当然这是后话了,截止目前为止,Secret 基本和 ConfigMap一样是明文存储。


好了,大家理解了 ConfigMap 和 Secret 了嘛?由于时间关系,更多内容下节课在讲。




推荐阅读

漫画:小黄人学 Kubernetes对象

漫画:小黄人学 Kubernetes Service

梁胜博士:写给程序员的话

创建最新版 Kubernetes1.9 集群

40张技术图谱,架构师阶梯 (附高清下载)



    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存