![Kubernetes 1.2 新功能解析:ConfigMap (中)](https://static001.infoq.cn/resource/image/87/48/871d1e67e749ab2d5579770278fb2948.jpg)
使用 ConfigMap
很多应用程序的配置需要通过配置文件,命令行参数和环境变量的组合配置来完成。这些配置应该从 image 内容中解耦,以此来保持容器化应用程序的便携性。ConfigMap API 资源提供了将配置数据注入容器的方式,同时保持容器是不知道 Kubernetes 的。ConfigMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者 JSON 二进制大对象。
ConfigMap 总览
ConfigMap API 资源保持键-值对配置数据,这个数据可以在 pods 里使用,或者被用来为像 controller 一样的系统组件存储配置数据。虽然 ConfigMap 跟 Secrets 类似,但是 configmap 可以更方便的处理不包含敏感信息的字符串
让我们来看看完成的例子吧:
![](https://static001.infoq.cn/resource/image/33/5d/33b9f28a7516fe185a9e9ff8c74e715d.jpg)
data 一栏包括了配置数据。就如同你们看到的那样,ConfigMap 可以被用来保存单个属性,也可以用来保存一个配置文件。
配置数据可以通过很多种方式在 Pods 里被使用。ConfigMaps 可以被用来:
1、设置环境变量的值
2、在容器里设置命令行参数
3、在数据卷里面创建 config 文件
用户和系统组件两者都可以在 ConfigMap 里面存储配置数据。
创建 ConfigMaps
你可以使用 kubectl create configmap 命令轻松从文字值、文件或者目录来创建 ConfigMaps。
让我们来看一看创建 ConfigMap 的很多不同的方法吧:
从目录创建
现在我们已经有一个包含一些文件的目录,它已经包含了我们想要设置 ConfigMaps 的数据:
![](https://static001.infoq.cn/resource/image/d7/ae/d7a4c3da0be2fa4fcfd69842519f45ae.jpg)
kubectl create configmap 命令可以被用来创建 ConfigMap 来存储这个目录里面每个文件的内容:
![](https://static001.infoq.cn/resource/image/ba/85/ba7da71c2cc4111c71ae1f521ba9e185.jpg)
当–from-file 指向目录的时候,每个在目录底下的所有文件会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容。
让我们来看一下这个命令创建的 ConfigMap:
![](https://static001.infoq.cn/resource/image/90/01/901cecb2ea630d676029e7e3d532b001.jpg)
你可以看到在映射里面的两个是从 kubectl 指定的目录中创建的文件名。这些键的内容可能会很大,所以在 kubectl describe 的输出中,你只能够看到键的名字和他们的大小。
如果我们想要看到键的值的话,我们可以仅仅只是 kubectl get 资源:
![](https://static001.infoq.cn/resource/image/74/03/7478332947e525cb5120e28763bf0603.jpg)
从文件创建
我们也可以传递给–from-file 一个特定文件,并且多次传递到 kubectl。以下命令跟上文例子中的结果是一样的:
![](https://static001.infoq.cn/resource/image/c9/ba/c9efc6515d2e3cabde523b868336a2ba.jpg)
我们也可以用 --from-file 通过传递 key=value 为个别文件设置键来使用:
![](https://static001.infoq.cn/resource/image/27/5d/27338158d0eff771770336c1b56ce35d.jpg)
![](https://static001.infoq.cn/resource/image/97/09/97051631564af13a9ee460fedaa5a809.jpg)
从字面值创建
为 ConfigMap 使用 kubectl create configmap 提供字面值。–from-literal 选项采用了 语法,这个语法允许字面值被直接运用到命令行:
![](https://static001.infoq.cn/resource/image/6f/72/6faeb0ef9c6d6734fa2d87d094971972.jpg)
在 pods 里面使用 ConfigMap
使用案例:在环境变量中使用 ConfigMap
ConfigMap 可以被用来填入环境变量。举个例子,思考以下的 ConfigMap:
![](https://static001.infoq.cn/resource/image/20/1b/20b60744255ec72815259869206bf71b.jpg)
我们可以像这样在一个 pod 中来使用这个 ConfigMap 的键:
![](https://static001.infoq.cn/resource/image/00/c4/00303a7ca4c4e1efa69b3de89ec865c4.jpg)
当这个 pod 运行的时候,它的输出将包括以下几行:
![](https://static001.infoq.cn/resource/image/4e/d8/4e4f29b82245577ee1fcca0c565efbd8.jpg)
使用案例:用 ConfigMap 设置命令行参数
ConfigMap 也可以被使用来设置容器中的命令或者参数值。这是一个已经完成的使用 Kubernetes$(VAR_NAME)替换的语法。考虑 ConfigMap:
![](https://static001.infoq.cn/resource/image/af/29/afee2a5a0090b6e233227b0ab8791f29.jpg)
为了输入值到命令行里面,我们必须使用我们想要使用的键来作为环境变量,就如在上一个例子中的一样。然后我们可以参考他们,在容器的命令里使用 $(VAR_NAME)语法。
![](https://static001.infoq.cn/resource/image/c9/4b/c96395399a4956ffcf2e83da67818b4b.jpg)
当这个 pod 正在运行的时候,从 test-container 容器的输出将会是:
![](https://static001.infoq.cn/resource/image/71/de/716e3054e43f2c87853dc72b76e189de.jpg)
使用案例:通过数据卷插件使用 ConfigMap
ConfigMap 也可以在数据卷里面被使用。再次回到我们的 ConfigMap 的例子:
![](https://static001.infoq.cn/resource/image/f9/1c/f96b0075ee523bbeeb268e9b0dfb911c.jpg)
在数据卷里面使用这个 ConfigMap,我们有不同的选项。最基本的就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容:
![](https://static001.infoq.cn/resource/image/b0/f1/b056c36cdc06f0af1f0ae766ebe76ff1.jpg)
当这个 pod 运行的时候,输出是这样的:
![](https://static001.infoq.cn/resource/image/3b/4e/3b716f917852121a567d6123d4bedb4e.jpg)
我们也可以在 ConfigMap 值被映射的数据卷里控制路径。
![](https://static001.infoq.cn/resource/image/73/40/731393758ad5ba71b2ea5c54383a1040.jpg)
当 pod 运行的时候,输出是这样的:
![](https://static001.infoq.cn/resource/image/ef/d6/efd0cab36674156e0843198c49d764d6.jpg)
真实案例:配置 Redis
让我们来看一下真实的案例:用 Configmap 配置 redis。我们想要将 redis 作为一个缓存用推荐配置来输入 redis。Redis 配置应该包括:
![](https://static001.infoq.cn/resource/image/c9/76/c9906a67aa343c8edec20aaaf3fd8676.jpg)
docs/user-guide/configmap/redis 里面有这样一个文件;有了它,我们可以使用下面的命令来创建一个 ConfigMap 实例:
![](https://static001.infoq.cn/resource/image/68/f7/684d6dfd098f69d4b21103b80ff34bf7.jpg)
![](https://static001.infoq.cn/resource/image/e3/81/e3c24fc2f9afa6ef22319f8127e4bc81.jpg)
现在,让我们用这个配置来创建一个 pod:
![](https://static001.infoq.cn/resource/image/0b/a2/0be8a220af286f9d5b5ce0b9d8b817a2.jpg)
注意,这个 pod 有一个 ConfigMap 数据卷,它在一个叫 redis.conf 的文件里替代了 example-redis-config ConfigMap 的 redis-config 密钥。这个数据卷增长到 redis 容器的 /redis-master 目录里,在/redis-master/redis.conf 里替代了我们的配置文件,/redis-master/redis.conf
就是 image 为 master 查找的 redis 配置文件。
![](https://static001.infoq.cn/resource/image/5f/cf/5fc38252c987cbde86bf501b35c212cf.jpg)
如果我们 kubectl exec 到这个 pod,并且运行 redis-cli 工具,我们可以检查到我们的配置被正确运用:
![](https://static001.infoq.cn/resource/image/d6/64/d6e680dcc2c1d84e983f1b0f900e4664.jpg)
限制条件
ConfigMaps 必须在 pod 中被使用之前创建。Controllers 可以会被写来容忍某些配置文件数据的缺失。Configmaps 属于 namespace。他们只有在相同的 namespaces 中通过 pods 被引用。
ConfigMap 大小的配额是已经一个设置好的功能。
Kubelet 只支持从 API 服务器的 pods 使用 ConfigMap。这包括了任意的用 Kubectl 创建的 pods,或者间接的通过 replication controller 创建的 pods。它不包括通过 Kubelet 的 --manifest-url 标志创建的 pods,也不包括从它的 REST API 创建的 pods(一般不用这些方法创建 pods)。
本文转载自才云 Caicloud 公众号。
原文链接:https://mp.weixin.qq.com/s/qBL9P6LkU4_ko_o33IuqZg
评论