云原生技术之六ConfigMap和Secret-应用配置文件
06-ConfigMap和Secret-应用配置文件
Kubernetes 里专门用来管理配置信息的两种对象:ConfigMap 和 Secret,使用它们来灵活地配置、定制我们的应用。
ConfigMap/Secret
首先你要知道,应用程序有很多类别的配置信息,但从数据安全的角度来看可以分成两类:
- 一类是明文配置,也就是不保密,可以任意查询修改,比如服务端口、运行参数、文件路径等等。
- 另一类则是机密配置,由于涉及敏感信息需要保密,不能随便查看,比如密码、密钥、证书等等。
这两类配置信息本质上都是字符串,只是由于安全性的原因,在存放和使用方面有些差异,所以 Kubernetes 也就定义了两个 API 对象,ConfigMap 用来保存明文配置,Secret 用来保存秘密配置
什么是 ConfigMap
先来看 ConfigMap,我们仍然可以用命令 kubectl create 来创建一个它的 YAML 样板。注意,它有简写名字“cm”,所以命令行里没必要写出它的全称:
Bash |
得到的模板文件大概是这个样子:
YAML |
ConfigMap 的 YAML 和之前我们学过的 Pod、Job 不一样,除了熟悉的“apiVersion”“kind”“metadata”,居然就没有其他的了,最重要的字段“spec”哪里去了?这是因为 ConfigMap 存储的是配置数据,是静态的字符串,并不是容器,所以它们就不需要用“spec”字段来说明运行时的“规格”。
既然 ConfigMap 要存储数据,我们就需要用另一个含义更明确的字段“data”。
要生成带有“data”字段的 YAML 样板,你需要在 kubectl create 后面多加一个参数 --from-literal ,表示从字面值生成一些数据:
Bash |
注意,因为在 ConfigMap 里的数据都是 Key-Value 结构,所以 --from-literal 参数需要使用 k=v 的形式。 |
把 YAML 样板文件修改一下,再多增添一些 Key-Value,就得到了一个比较完整的 ConfigMap 对象:
YAML |
现在就可以使用 kubectl apply 把这个 YAML 交给 Kubernetes,让它创建 ConfigMap 对象了:
Bash |
创建成功后,我们还是可以用 kubectl get、kubectl describe 来查看 ConfigMap 的状态:
Bash |
你可以看到,现在 ConfigMap 的 Key-Value 信息就已经存入了 etcd 数据库,后续就可以被其他 API 对象使用。
创建 ConfigMap
使用字面值创建
Bash |
从目录创建
Bash |
从文件创建
Bash |
什么是 Secret
了解了 ConfigMap 对象,我们再来看 Secret 对象就会容易很多,它和 ConfigMap 的结构和用法很类似,不过在 Kubernetes 里 Secret 对象又细分出很多类,比如 :
Secret 有四种类型:
- Service Account:用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中;
- Opaque[oʊˈpeɪk]:base64 编码格式的 Secret,用来存储密码、密钥等;
- io/dockerconfigjson:用来存储私有 docker registry 的认证信息。
- TLS(传输层安全):用于存储TLS证书和私钥,以支持加密通信。它可以用于需要TLS证书的场景。
对应具体有用途如下:
- 访问私有镜像仓库的认证信息
- 身份识别的凭证信息
- HTTPS 通信的证书和私钥
- 一般的机密信息(格式由用户自行解释)
我们先创建 Opaque 类型的,创建 YAML 样板的命令是 kubectl create secret generic ,同样,也要使用参数
--from-literal 给出 Key-Value 值:
Bash |
得到的 Secret 对象大概是这个样子:
YAML |
Secret 对象第一眼的感觉和 ConfigMap 非常相似,只是“kind”字段由“ConfigMap”变成了“Secret”,后面同样也是“data”字段,里面也是 Key-Value 的数据。
这串“乱码”就是 Secret 与 ConfigMap 的不同之处,不让用户直接看到原始数据,起到一定的保密作用。不过它的手法非常简单,只是做了 Base64 编码,根本算不上真正的加密,我们可以直接使用 Linux 命令"base64" 来解密 :
Bash |
我们再来重新编辑 Secret 的 YAML,为它添加两个新的数据,方式可以是参数 --from-literal 自动编码,也可以是自己手动编码:
YAML |
使用 kubectl apply、kubectl get、kubectl describe 创建和查看对象:
Bash |
这样一个存储敏感信息的 Secret 对象也就创建好了,而且因为它是保密的,使用 kubectl describe 不能直接看到内容,只能看到数据的大小,你可以和 ConfigMap 对比一下。
创建Secret
- docker registry 认证的 secret
Bash |
YAML |
- TLS secret
如何使用
通过编写 YAML 文件,我们创建了 ConfigMap 和 Secret 对象,该怎么在 Kubernetes 里应用它们呢?
因为 ConfigMap 和 Secret 只是一些存储在 etcd 里的字符串,所以如果想要在运行时产生效果,就必须要以某种方式“注入”到 Pod 里,让应用去读取。在这方面的处理上 Kubernetes 和Docker 是一样的,也是两种途径:环境变量和加载文件。
先看比较简单的环境变量。
以环境变量的方式
“valueFrom”字段指定了环境变量值的来源,可以是“configMapKeyRef”或者“secretKeyRef”,然后你要再进一步指定应用的 ConfigMap/Secret 的“name”和它里面的“key”。
由于“valueFrom”字段在 YAML 里的嵌套层次比较深,初次使用最好看一下 kubectl explain 对它的说明:
Bash |
下面是 引用了 ConfigMap 和 Secret 对象的 Pod 定义
YAML |
用 kubectl apply 创建 Pod,再用 kubectl exec 进入 Pod,验证环境变量是否生效:
Bash |
这张截图就显示了 Pod 的运行结果,可以看到在 Pod 里使用 echo 命令确实输出了我们在两个 YAML 里定义的配置信息,也就证明 Pod 对象成功组合了 ConfigMap 和 Secret 对象。
以环境变量的方式使用 ConfigMap/Secret 还是比较简单的,下面来看第二种加载文件的方式。
以 Volume 的方式
Kubernetes 为 Pod 定义了一个“Volume”的概念,可以翻译成是“存储卷”。如果把 Pod 理解成是一个虚拟机,那么 Volume 就相当于是虚拟机里的磁盘。
注意: Volume 属于 Pod,不属于容器,所以它和字段“containers”是同级的,都属于“spec”。 |
下面让我们来定义两个 Volume,分别引用 ConfigMap 和 Secret,名字是 cm-vol 和 sec-vol:
YAML |
使用 “volumeMounts”字段来挂载卷,可以把定义好的 Volume 挂载到容器里的某个路径下,所以需要在里面用“mountPath” “name”明确地指定挂载路径和 Volume 的名字。
YAML |
把“volumes”和“volumeMounts”字段都写好之后,配置信息就可以加载成文件了。
下面是 Pod 的完整 YAML 描述,然后使用 kubectl apply 创建它.
YAML |
创建之后,我们还是用 kubectl exec 进入 Pod,看看配置信息被加载成了什么形式:
YAML |
ConfigMap 和 Secret 都变成了目录的形式,而它们里面的 Key-Value 变成了一个个的文件,而文件名就是 Key。
因为这种形式上的差异,以 Volume 的方式来使用 ConfigMap/Secret,就和环境变量不太一样。
环境变量用法简单,更适合存放简短的字符串,而 Volume 更适合存放大数据量的配置文件,在 Pod 里加载成文件后让应用直接读取使用。
如果配置文件发生变化,Pod 中加载的数据是否会同步更新 ?
环境变量加载 cm secret 不会热更新 ,只有重启 Pod 才会触发更新
Volume 加载的可以实现 热更新
总结
Kubernetes 里管理配置信息的 API 对象 ConfigMap 和 Secret,它们分别代表了明文信息和机密敏感信息,存储在 etcd 里,在需要的时候可以注入Pod 供 Pod 使用。
- ConfigMap 记录了一些 Key-Value 格式的字符串数据,描述字段是“data”,不是“spec”。
- Secret 与 ConfigMap 很类似,也使用“data”保存字符串数据,但它要求数据必须是 Base64
编码,起到一定的保密效果。 - 在 Pod 的 “env.valueFrom” 字段中可以引用 ConfigMap 和 Secret,把它们变成应用可以访
问的环境变量。 - 在 Pod 的 “spec.volumes” 字段中可以引用 ConfigMap 和 Secret,把它们变成存储卷,然后
在 “spec.containers.volumeMounts” 字段中加载成文件的形式。 - ConfigMap 和 Secret 对存储数据的大小没有限制,但小数据用环境变量比较适合,大数据
应该用存储卷,可根据具体场景灵活应用。 1MB etcd
- 点赞
- 收藏
- 关注作者
评论(0)