为什么要有 Secret
?
使用过 Kubernetes 的人应该都知道, Kubernetes 对动态配置管理提供了两种管理方式, 一种是 ConfigMap
一种就是现在要讲的 Secret
.
这是因为我们在 kubernetes 上部署应用的时候,经常会需要传一些动态配置给应用使用,比如数据库地址,用户名, 密码之类的信息。如果没有上面提供的方法, 我们只能使用下面几种方法.
- 直接打包到镜像中,这种方式不够灵活且对于敏感信息不够安全。
- 在部署文件里通过 ENV 环境变量传入,但是这样的话会导致修改 ENV 有需要重启所有的 Container, 也不够灵活.
- 应用启动的时候去数据库或者专门的配置中心拿,没问题!但是实现起来比较麻烦. 并且万一存放地址变更要更新所有应用.
- ……
还有一个问题就是,如果说我的配置是需要多应用共享的, 那么上述方案中除了方案3以外,都没办法进行配置的共享,如果我要改配置的话,得一个一个改。假如我们有 100 个应用,就得改 100 份配置。
所以 Kubernetes 提供了上面两种解决方案用来解决动态配置的问题.
Secret
和 ConfigMap
有什么区别?
既然两种方式都是解决同一个问题,为什么还需要存在多个解决方案?
是因为有些数据如敏感数据对数据的传输及存储方式提供了额外的安全要求。在 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
中,因此:
- 管理员应该限制
admin
用户访问etcd
; - API server 中的
Secret
数据位于etcd
使用的磁盘上;管理员可能希望在不再使用时擦除/粉碎etcd
使用的磁盘 - 如果您将
Secret
数据编码为base64
的清单(JSON 或 YAML)文件,共享该文件或将其检入代码库,这样的话该密码将会被泄露。Base64
编码不是一种加密方式,一样也是纯文本。 - 应用程序在从卷中读取
Secret
后仍然需要保护Secret
的值,例如不会意外记录或发送给不信任方。 - 可以创建和使用
Secret
的 POD 的用户也可以看到该Secret
的值。即使 API server 策略不允许用户读取Secret
对象,用户也可以运行暴露Secret
的 POD。 - 如果运行了多个副本,那么这些
Secret
将在它们之间共享。默认情况下,etcd
不能保证与SSL/TLS
的对等通信,但管理员可以进行配置。 - 目前,任何节点的 root 用户都可以通过模拟 kubelet 来读取 API server 中的任何
Secret
。