漫画:Kubernetes中的ConfigMap和Secret
我们可以直接在打包镜像的时候写在应用配置文件里面,但是这种方式的坏处显而易见而且非常明显。
我们可以在配置文件里面通过 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=value2
configmap "my-config" created
# Get the ConfigMap Details for my-config
$ kubectl get configmaps my-config -o yaml
apiVersion: v1
data:
key1: value1
key2: value2
kind: ConfigMap
metadata:
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: v1
kind: ConfigMap
metadata:
name: customer1
data:
TEXT1: Customer1_Company
TEXT2: Welcomes You
COMPANY: Customer1 Company Technology Pct. Ltd.
然后,我们可以通过 kubectl create -f 来创建:
$ kubectl create -f myconfigmap.yaml
configmap "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.txt
secret "my-password" created
我们也可以手动创建一个 Secret,不过要注意,所有的 Secret 的 data 都要以 base64 进行加密:
$ cat password.txt | base64
bXlzcWxwYXN3b3JkCg==
# and then use it in the configuration file:
apiVersion: v1
kind: Secret
metadata:
name: my-password
type: Opaque
data:
password: bXlzcWxwYXN3b3JkCg==
使用Secret
获取 Secret
我们可以通过 get 和 describe 来获取 Secret,不过我们发现,kubectl 并没有向我们返回 Secret 具体的内容:
$ kubectl get secret my-password
NAME TYPE DATA AGE
my-password Opaque 1 8m
$ kubectl describe secret my-password
Name: my-password
Namespace: default
Labels: <none>
Annotations: <none>
Type Opaque
Data
====
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 了嘛?由于时间关系,更多内容下节课在讲。
推荐阅读