



每个应用程序都需要一定的配置。这可能是每页显示的日志条目数量、特定页面的背景色、节假日的特殊显示或其他各种配置。通常,将配置信息与应用程序本身分离是一种值得遵循的最佳实践。
将应用和配置分离的好处有很多。首先,你可能想要在不同的环境中对应用程序进行不同的配置。例如,你可能想要在欧洲推出复活节专题,而在中国展现春节专题。除了环境的特殊性之外,应用与配置分离也能提高系统的灵活性。通常,一个发布的二进制文件中包含多个不同的新功能,如果通过代码来启用这些功能,那么唯一能够修改现有功能的方式就是重新构建和发布新的二进制文件,这可能是一个昂贵且缓慢的过程。
使用配置来管理功能开关意味着你可以快速地(甚至动态地)开启或关闭相关的功能,以应对用户需求变化或代码缺陷。每个功能都支持独立开关,这种灵活性确保了即使某些功能需要回滚以解决性能或正确性问题,你也可以持续不断地推进大多数功能。
在Kubernetes中,这种类型的配置由称为ConfigMap的资源表示。ConfigMap包含多个描述配置信息或者文件的键值对。此配置信息可以通过文件或环境变量的方式呈现给Pod中的容器。如果在上述示例应用中,你想要配置每页可显示的日志条目数,可以按如下方式定义一个ConfigMap:
你需要将ConfigMap中的配置信息作为环境变量提供给应用程序。为此,可以在我们之前定义的Deployment的容器资源部分添加以下内容:
虽然这里展示了如何使用ConfigMap配置应用程序,但在Deployment的实际应用中,你希望每周一次甚至更频繁地进行常规的配置变更。看上去只需简单地修改ConfigMap就可以让配置生效,但实际上这并不是最佳做法,原因如下:第一,更改配置实际上不会触发对现有Pod的更新。配置仅在Pod重新启动时才会生效。这样会导致配置修改不是基于健康检查的,可能是临时的或随机的。第二,ConfigMap只在版本控制系统中进行版本管理,执行回滚可能非常困难。
更好的方式是在ConfigMap的命名中加入版本号。例如采用frontend-config-v1而不是frontend-config来命名ConfigMap。当你想要进行更改时,只需要创建一个新的v2版本,然后更新Deployment资源以使用该版本的ConfigMap,而不是直接更新现有的ConfigMap。这样,Deployment将会自动触发重新部署,执行恰当的健康检查和服务停顿以切换配置。此外,如果需要回滚,由于v1的配置仍然保留在集群中,只需再次更新Deployment即可。