我们可以直接在打包镜像的时候写在应用配置文件里面,但是这种方式的坏处显而易见而且非常明显。
我们可以在配置文件里面通过 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 来获取:
# Create the ConfigMap$ kubectl create configmap my-config --from-literal=key1=value1 --from-literal=key2=value2configmap "my-config" created # Get the ConfigMap Details for my-config$ kubectl get configmaps my-config -o yamlapiVersion: v1data: key1: value1 key2: value2kind: ConfigMapmetadata: creationTimestamp: 2017-05-31T07:21:55Z name: my-config namespace: default resourceVersion: "241345" selfLink: /api/v1/namespaces/default/configmaps/my-config uid: d35f0a3d-45d1-11e7-9e62-080027a46057
-o yaml 的作用是通过 yaml 的形式来返回我们所要求的配置信息。
From Configuration File 方法:
除了上面的方式,我们还可以直接通过配置文件来创建(好吧,虽然我感觉是同一种,只不过是放到文件里面了而已……),首先,我们得有一个配置文件,假设名字叫做 myconfigmap.yaml:
apiVersion: v1kind: ConfigMapmetadata: name: customer1data: TEXT1: Customer1_Company TEXT2: Welcomes You COMPANY: Customer1 Company Technology Pct. Ltd.
然后,我们可以通过 kubectl create -f 来创建:
$ kubectl create -f myconfigmap.yamlconfigmap "customer1" created
同时也有两种使用方法,通过 env 和通过 Volume。
通过 env 方法:
我们可以设置 env从ConfigMap 读取:
.... containers: - name: rsvp-app image: teamcloudyuga/rsvpapp env: - name: MONGODB_HOST value: mongodb - name: TEXT1 valueFrom: configMapKeyRef: name: customer1 key: TEXT1 - name: TEXT2 valueFrom: configMapKeyRef: name: customer1 key: TEXT2 - name: COMPANY valueFrom: configMapKeyRef: name: customer1 key: COMPANY....
这样,我们的 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,如下:
# Create a file with password$ echo 'mysqlpassword' > password.txt# Make sure there is no trailing newline in the file, after our password. # To remove any newline, we can use the tr command:$ tr -Ccsu '\n' < password.txt > .strippedpassword.txt && mv .strippedpassword.txt password.txt# Create the Secret $ kubectl create secret generic my-password --from-file=password.txtsecret "my-password" created
我们也可以手动创建一个 Secret,不过要注意,所有的 Secret 的 data 都要以 base64 进行加密:
$ cat password.txt | base64bXlzcWxwYXN3b3JkCg==# and then use it in the configuration file:apiVersion: v1kind: Secretmetadata: name: my-passwordtype: Opaquedata: password: bXlzcWxwYXN3b3JkCg==
使用Secret
获取 Secret
我们可以通过 get 和 describe 来获取 Secret,不过我们发现,kubectl 并没有向我们返回 Secret 具体的内容:
$ kubectl get secret my-passwordNAME TYPE DATA AGE my-password Opaque 1 8m$ kubectl describe secret my-passwordName: my-passwordNamespace: defaultLabels: <none>Annotations: <none>Type OpaqueData====password.txt: 13 bytes
在 Pod 里面使用
和 ConfigMap 一样,我们可以通过设置成 env 或者挂载成 volume 来使容器可以使用我们的 Secret。
具体格式如下:
..... spec: containers: - image: wordpress:4.7.3-apache name: wordpress env: - name: WORDPRESS_DB_HOST value: wordpress-mysql - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: name: my-password key: password.txt.....
关于如何在 Volume 中使用的还是需要自行查询文档学习。
其实目前 Secret 的实现,就是 ConfigMap 把 value 用 base64 encode了一下,所以,其实不存在任何安全性,只要 decode 一下就能出现原来结果,相当于明文存储。
base64 这玩意儿都不能叫做加密,只能叫做编码,所以我们都不说 encrypt,而是 encode 和 decode。
当然,Kubernetes 社区有在计划对 Secret 进行下一步的安全性增强,当然这是后话了,截止目前为止,Secret 基本和 ConfigMap一样是明文存储。
好了,大家理解了 ConfigMap 和 Secret 了嘛?由于时间关系,更多内容下节课在讲。