首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

快速了解 kubernetes的ConfigMap和Secrets

(图片来源:https://unsplash.com/photos/JQ8-xG3kHjk)

我们经常都需要为我们的应用程序配置一些特殊的数据,比如密钥、Token 、数据库连接地址或者其他私密的信息。你的应用可能会使用一些特定的配置文件进行配置,比如文件,或者我们可以在应用的业务逻辑中读取环境变量或者某些标志来处理配置信息。

当然你可以直接将这些应用配置信息直接硬编码到你的应用程序中去,对于一个小型的应用,这或许是可以接受的,但是,对于一个相对较大的应用程序或者微服务的话,硬编码就会变得难以管理了。比如你现在有10个微服务,都连接了数据库A,如果现在需要更改数据库A的连接地址的话,就需要修改10个地方,显然这是难以忍受的。

当然,我们可以使用环境变量和统一的配置文件来解决这个问题,当我们想改变配置的时候,只需要更改环境变量或者配置文件就可以了,但是对于微服务来说的话,这也是比较麻烦的一件事情,允许我们在中指定环境变量,但是如果我们需要在不同的容器中引用相同的数据呢,如果我们的应用程序是运行在集群上的时候,对于配置主机的环境变量也是难以管理的了。接下来我们来写一个应用程序,最后用来管理我们的配置信息。

1. 编写应用

下面是我们简单定义的一个 WEB 服务,其中 TOKEN 和 LANGUAGE 是硬编码在程序代码中的,如下:(hardcode-app.py

如果我们现在想要改变 TOKEN 或者 LANGUAGE 的话,我们就需要手动去修改上面的代码了,这就有可能会导致新的 BUG 或者安全漏洞之类的。

下面我们来用环境变量代替上面的参数吧。

2. 使用环境变量

使用环境变量还是比较容易的,大部分编程语言都有内置的方式去读取环境变量,我们这里是 python,直接使用包下面的 getenv 方法即可获取:(read-env-app.py

现在我们就可以通过设置环境变量而不是直接去修改源码来改变我们的配置了。在 Unix 系统(MacOS和Linux)下面,我们可以通过在终端中执行下面的命令来设置环境变量:

对于 Windows 系统,我们就通过可以通过命令进入终端,执行下面的命令来设置环境变量:

另外我们也可以在启动服务的时候设置环境变量,比如,对于我们的这个应用,我们可以这样运行:

然后我们浏览器中打开地址http://127.0.0.1:5000/,可以看到下面的输出信息:

证明我们的环境变量设置生效了……

3. 使用 Docker 的环境变量

我们现在来使用容器运行我们的应用程序,我们就可以不依赖主机的环境变量了,每个容器都有自己的环境变量,所以保证容器的环境变量正确的配置就显得尤为重要了。幸运的是,Docker 可以非常轻松的构建带有环境变量的容器,在文件中,我们可以通过指令来设置容器的环境变量。

将上面的文件保存为,放置在文件同目录下面,然后我们可以构建镜像:

构建成功后,我们可以使用上面的镜像启动一个容器:

同样的我们可以通过标记来覆盖容器的环境变量:

然后我们在浏览器中打开http://127.0.0.1:5000/可以看到下面的输出信息证明我们的环境配置成功了:

4. 使用 Kubernetes 的环境变量

当我们开始使用的时候,情况又不太一样了,我们可能会在多个 Kubernetes Deployment 中使用想多的 Docker 镜像,我们也可能希望对 Deployment 进行 A/B 测试,对不同的 Deployment 设置不同的配置信息。

和上面的 Dockerfile 一样,我们可以在 Kubernetes Deployment 的文件中指定环境变量,这样我们就可以在不同的 Deployment 中设置不同的环境变量:(read-env.yaml

注意上面的 POD 的 env 部分,我们可以在这里指定我们想要设置的环境变量,比如这里我设置了 TOKEN 和 LANGUAGE 两个环境变量!

5. 使用 Kubernetes 的 Secrets 和 ConfigMap 进行配置

和环境变量的不足之处在于它们是和容器的部署相关的,如果我们想要更改它们的话,就得重新构建容器或者修改 Deployment,更麻烦的是,如果想将变量用于多个容器或 Deployment 的话,就必须将配置复制过去。

幸运的是,中提供了(用于比较私密的数据)和(用于非私密的数据)两种资源可以很好的解决我们上面的问题。

Secret 和 ConfigMap 之间最大的区别就是 Secret 的数据是用编码混淆过的,不过以后可能还会有其他的差异,对于比较机密的数据(如API密钥)使用 Secret 是一个很好的做法,但是对于一些非私密的数据(比如数据目录)用 ConfigMap 来保存就很好。

我们将 TOKEN 保存为 Secret:

然后将 LANGUAGE 参数保存为 ConfigMap:

然后我们可以通过下面的命令查看创建的 Secret 和 ConfigMap:

现在,我们可以重新修改 Kubernetes Demployment 的 YAML 文件:(final-read-env.yaml

我们将之前的硬编码 env 的值更改为从 secret 和 ConfigMap 中读取。

6. 更新 Secret 和 ConfigMap

上面我们已经提到过,使用 Kubernetes 来管理我们的环境变量后,意味这我们不必更改代码或者重新构建镜像来改变环境变量的值了。由于 POD 在启动的时候会缓存环境变量的值,所以如果我们要更改环境变量的值的话,需要以下两个步骤:

首先,更新 Secret 或者 ConfigMap:

然后,重启相关的 PODS,重启 POD 有很多方法,比如我们可以直接更新 Deployment,最简单的方法是我们可以直接手动删除 POD,然后 Deployemnt 会自动重建一个 POD起来的。

然后我们可以通过查看 POD 确定新的 POD 启动起来了:

我们可以进入到上面的 POD 容器内部打印下环境变量是否设置成功:

我们可以看到我们的环境变量已经更新成功了。

当然对于特别复杂的应用,单纯的只用 Secret 和 ConfigMap 来管理配置信息,可能也是不太现实的,这就需要引入配置中心的概念来进行统一管理我们的配置了,关于我们以后再进行相关的讨论吧。

本文涉及到的所有代码都位于此中:https://gist.github.com/cnych/d40756ce6e03035551b6a023135a78d9

参考资料

https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/

https://kubernetes.io/docs/concepts/configuration/secret/

https://medium.com/google-cloud/kubernetes-configmaps-and-secrets-68d061f7ab5b

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180210G0PUMG00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券