被坑惨了!! 使用 ConfigMap 管理配置, Deployment 扩容引发配置不一致的惨案!

如果在 公众号 文章发现状态为 已更新, 建议点击 查看原文 查看最新内容。

状态: 未更新

原文链接: https://typonotes.com/posts/2023/03/24/k8s-scale-issue-with-configmap/

首先声明, 不是我! 是一个朋友。

背景是这样的, 一个朋友给我说他遇到了一个情况。

Kubernetes Deployment 扩容后, 应用异常。 从请求结果来看, 应用在两种配置之间飘忽不定。 查看 ConfigMap内容 和进入 Pod查看挂载配置 内容都一致。 最后使用重启大法,删除所有 Pod 重建,解决问题。

ConfigMap 更新导致的配置不一致问题

在更新 ConfigMap 之后,如果没有及时重启相关的 Pod 或者 Deployment,就有可能导致 Pod 配置不一致的问题。

这样说有点抽象, 画图描述

  1. 首先, 服务启动的时候, 只有一个 Pod1, 并读取 ConfigMap 配置 a=1 到自己的 内存 中, 进行初始化。

到这里都是最普通的情况。

  1. 之后, 某人A 修改了 ConfigMap 将配置修改为 a=2 之后没有进行任何操作。

这个时候 Kubernetes 确实按照 声明 需求修改了 ConfigMap, 并更新了 Pod 中对应的挂载文件内容。

一切看似正常, 实际已经埋下祸根

  1. 最后, 某人B 将 Deployment 进行了扩容, 将一个 Pod 扩容到了两个甚至多个。

问题就出来了, 新出现的 Pod2 读取的是 红色配置(a=2), 而 Pod1 并没有进行 热加载或者重启 , 内存中还是使用的 黄色配置(a=1)

这个时候用户请求的时候, 得到的结果就飘忽不定了。

如何解决不一致的问题

为了避免这种问题,可以在更新 ConfigMap 之后,手动重启相关的 Pod 或者 Deployment。

  1. 运维层面: 可以通过 重启重建 的方式:
  • 使用 kubectl rollout restart 命令来重启 Deployment,
  • 使用 kubectl delete pod 命令来删除 Pod,从而触发 Pod 的重启。
  1. 应用程序方面: 探测挂在后的 config 的内容变化, 程序自己进行 热加载 操作。

常用的 ConfigMap 的错误排查和故障处理方法

ConfigMap 的错误排查和故障处理包括以下几个方面:

  • 检查 ConfigMap 是否存在: 首先要检查 ConfigMap 是否已经创建,并且是否具有正确的名称和标签。可以使用 kubectl get configmap 命令检查 ConfigMap 是否存在。
  • 检查 Pod 是否正确引用 ConfigMap: 如果 Pod 引用了 ConfigMap,需要检查 Pod 的 YAML 文件中是否正确指定了 ConfigMap 的名称和键。可以使用 kubectl describe pod 命令查看 Pod 的详细信息,以确定是否正确引用了 ConfigMap。
  • 检查 ConfigMap 的数据是否正确: 如果 Pod 引用了 ConfigMap,需要确保 ConfigMap 中的数据是正确的。可以使用 kubectl describe configmap 命令查看 ConfigMap 的详细信息,以确定数据是否正确。
  • 检查容器中的环境变量和配置文件: 如果 Pod 引用了 ConfigMap,需要检查容器中的环境变量和配置文件是否正确设置。可以使用 kubectl exec 命令进入容器,以确认环境变量和配置文件是否正确设置。
  • 检查 ConfigMap 的权限和安全性: 如果 ConfigMap 包含敏感信息,需要确保 ConfigMap 的权限和安全性得到了保护。可以使用 Kubernetes 的 RBAC 功能来限制 ConfigMap 的访问权限,以确保只有授权的用户才能访问 ConfigMap。

如果出现 ConfigMap 的故障或错误,可以使用 Kubernetes 的日志记录和监控功能来进行排查和诊断。可以使用 kubectl logs 命令查看容器的日志信息,以确定是否存在错误或异常。同时,也可以使用 Kubernetes 的监控工具来监控 ConfigMap 和相关资源的状态,以及检测是否存在异常或故障。

扩展: ConfigMap 的安全性和保护措施

ConfigMap 是 Kubernetes 中用来存储应用程序配置信息的资源对象。由于 ConfigMap 中存储的信息通常是非机密数据,因此其安全性相对较低。然而,如果 ConfigMap 中存储的信息泄露,可能会导致应用程序的配置信息泄露,从而导致安全性问题。

以下是一些保护 ConfigMap 安全性的措施:

  • 限制 ConfigMap 的访问权限: 使用 Kubernetes 的 RBAC 功能来限制 ConfigMap 的访问权限,以确保只有授权的用户才能访问 ConfigMap。可以使用 kubectl create role 命令创建 RBAC 角色,然后使用 kubectl create rolebinding 命令将角色绑定到用户或者服务账户上。
  • 加密 ConfigMap 中的敏感信息: 如果 ConfigMap 中包含敏感信息,例如密码或者密钥,可以使用 Kubernetes 的 Secret 对象将其加密。可以使用 kubectl create secret generic 命令创建 Secret 对象,然后将其挂载到容器中,以便应用程序可以读取加密后的敏感信息。
  • 使用 ConfigMap 的更新策略: 在更新 ConfigMap 时,可以使用 kubectl apply 命令的 --prune 参数来删除不再需要的键值对,以避免敏感信息的泄露。同时,也可以使用 kubectl apply 命令的 --force 参数来强制更新 ConfigMap,以确保更新后的 ConfigMap 被正确应用。
  • 监控 ConfigMap 的使用情况: 监控 ConfigMap 的使用情况,以便及时发现异常或者故障。可以使用 Kubernetes 的监控工具来监控 ConfigMap 和相关资源的状态,以及检测是否存在异常或故障。