0%

kubernetes 中 Secret 的作用, 以及为什么说它是安全的

为什么要有 Secret ?

使用过 Kubernetes 的人应该都知道, Kubernetes 对动态配置管理提供了两种管理方式, 一种是 ConfigMap 一种就是现在要讲的 Secret.

这是因为我们在 kubernetes 上部署应用的时候,经常会需要传一些动态配置给应用使用,比如数据库地址,用户名, 密码之类的信息。如果没有上面提供的方法, 我们只能使用下面几种方法.

  1. 直接打包到镜像中,这种方式不够灵活且对于敏感信息不够安全。
  2. 在部署文件里通过 ENV 环境变量传入,但是这样的话会导致修改 ENV 有需要重启所有的 Container, 也不够灵活.
  3. 应用启动的时候去数据库或者专门的配置中心拿,没问题!但是实现起来比较麻烦. 并且万一存放地址变更要更新所有应用.
  4. ……

还有一个问题就是,如果说我的配置是需要多应用共享的, 那么上述方案中除了方案3以外,都没办法进行配置的共享,如果我要改配置的话,得一个一个改。假如我们有 100 个应用,就得改 100 份配置。

所以 Kubernetes 提供了上面两种解决方案用来解决动态配置的问题.

SecretConfigMap 有什么区别?

既然两种方式都是解决同一个问题,为什么还需要存在多个解决方案?

是因为有些数据如敏感数据对数据的传输及存储方式提供了额外的安全要求。在 Kubernetes 中 Secret 用官方的说法就是 比 ConfigMap 更加安全。

但是安全在哪呢?

网上找到的基本都是再说因为 Secret 在保存时对数据进行了加密所以更安全, 更进一步的会说 Secret 使用 Base64 对数据进行加密.

稍微接触过的人应该都知道 Base64 相比称之为加密算法, 或许将其称之为编码算法可能还会更贴切一些.

所以, 如果只是 Base64 的话, 它真的更安全吗?

现有的文章都没有解释为什么使用 Base64 加密会安全.

Secret 为什么安全?

主要是 Kubernetes 对 Secret对象采取额外了预防措施。

1. 传输安全

在大多数 Kubernetes 项目维护的发行版中,用户与 API server 之间的通信以及从 API server 到 kubelet 的通信都受到 SSL/TLS 的保护。对于开启 HTTPS 的 Kubernetes 来说 Secret 受到保护所以是安全的。

2. 存储安全

只有当挂载 Secret 的POD 调度到具体节点上时,Secret 才会被发送并存储到该节点上。但是它不会被写入磁盘,而是存储在 tmpfs 中。一旦依赖于它的 POD 被删除,Secret 就被删除。

由于节点上的 Secret 数据存储在 tmpfs 卷中,因此只会存在于内存中而不会写入到节点上的磁盘。以避免非法人员通过数据恢复等方法获取到敏感信息.

3. 访问安全

同一节点上可能有多个 POD 分别拥有单个或多个Secret。但是 Secret 只对请求挂载的 POD 中的容器才是可见的。因此,一个 POD 不能访问另一个 POD 的 Secret

使用 Secret 的风险

API server 的 Secret 数据以纯文本的方式存储在 etcd 中,因此:

  1. 管理员应该限制 admin 用户访问 etcd
  2. API server 中的 Secret 数据位于 etcd 使用的磁盘上;管理员可能希望在不再使用时擦除/粉碎 etcd 使用的磁盘
  3. 如果您将 Secret 数据编码为 base64 的清单(JSON 或 YAML)文件,共享该文件或将其检入代码库,这样的话该密码将会被泄露。 Base64 编码不是一种加密方式,一样也是纯文本。
  4. 应用程序在从卷中读取 Secret 后仍然需要保护 Secret 的值,例如不会意外记录或发送给不信任方。
  5. 可以创建和使用 Secret 的 POD 的用户也可以看到该 Secret 的值。即使 API server 策略不允许用户读取 Secret 对象,用户也可以运行暴露 Secret 的 POD。
  6. 如果运行了多个副本,那么这些 Secret 将在它们之间共享。默认情况下,etcd 不能保证与 SSL/TLS 的对等通信,但管理员可以进行配置。
  7. 目前,任何节点的 root 用户都可以通过模拟 kubelet 来读取 API server 中的任何 Secret