有没有推荐的方式来使用Kubernetes Secrets?它们可以作为环境变量公开或使用卷安装。一个比另一个更安全吗?
5 回答
https://www.oreilly.com/library/view/velocity-conference-2017/9781491985335/video316233.html
环境变量暴露的 Kubernetes 机密可能能够通过 /proc/ 在主机上枚举。如果是这种情况,通过卷安装加载它们可能更安全。
我同意 TMC 的回答,但想为那些正在思考的人添加一个注释,“但是 12 因子呢??”。由于 12F 似乎要求将配置存储为 ENV 变量,因此有时会反对使用卷挂载机密。首先,这些是建议的、自愿的、您的里程可能会有所不同的最佳实践建议。其次,还有这一段:
在十二因素应用程序中,环境变量是精细控件,每个控件都与其他环境变量完全正交。它们从不组合为“环境”,而是为每个部署独立管理。这是一个随着应用程序在其生命周期内自然扩展到更多部署而平滑扩展的模型。
来源:https ://12factor.net/config
基本上,结合其余的描述,我理解 12F 配置管理的指导原则是:
- 让配置远离源代码
- 能够将配置注入源工件(例如 docker 容器)
- 能够对一组所需的配置值进行细粒度更改
在我看来,卷挂载的 Kubernetes Secret可以实现这些目标,具体取决于您创建的 Secret 对象类型以及管理它们的方式。
安装的秘密会自动更新
当卷中已经使用的秘密被更新时,预计的密钥最终也会被更新。Kubelet 会在每次定期同步时检查挂载的密钥是否是新的。但是,它使用本地缓存来获取 Secret 的当前值。
在多容器 pod 中,pod 中的每个容器都必须请求其 volumeMounts 中的秘密卷,才能在容器中看到它。这可用于在 pod 级别构建有用的安全分区。
通过卷安装从官方文档中找到上述发现看起来是一个更好的选择。
我认为安全性没有任何区别。因为如果一个节点被入侵,他们可以看到这个秘密。
例子:
---
apiVersion: v1
kind: Secret
metadata:
name: mount
type: Opaque
data:
foo: ""
---
apiVersion: v1
kind: Secret
metadata:
name: env
type: Opaque
data:
BAR: "BAR"
---
apiVersion: v1
kind: Pod
metadata:
name: mount
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
envFrom:
- secretRef:
name: env
volumeMounts:
- name: mount
mountPath: "/opt/mount"
readOnly: true
volumes:
- name: mount
secret:
secretName: mount
$ kubectl exec mount -- ls -la /opt/mount
total 0
drwxrwxrwt 3 root root 100 Jan 8 03:00 .
drwxr-xr-x 1 root root 19 Jan 8 03:00 ..
drwxr-xr-x 2 root root 60 Jan 8 03:00 ..2020_01_08_03_00_13.066710719
lrwxrwxrwx 1 root root 31 Jan 8 03:00 ..data -> ..2020_01_08_03_00_13.066710719
lrwxrwxrwx 1 root root 10 Jan 8 03:00 foo -> ..data/foo
$ kubectl exec mount -- env | grep BAR
BAR=
$ docker ps | grep mount
8dbde26864a4 nginx "nginx -g 'daemon of…" 8 minutes ago Up 8 minutes k8s_nginx_mount_default_3438a94b-e4af-41a7-8d85-7668fcbd9928_0
$ docker inspect 8dbde26864a4 | grep -A 1 '"Env"'
"Env": [
"BAR=",
$ docker inspect 8dbde26864a4 | grep '"Source"' | grep mount
"Source": "/var/lib/kubelet/pods/3438a94b-e4af-41a7-8d85-7668fcbd9928/volumes/kubernetes.io~secret/mount"
$ ls -la /var/lib/kubelet/pods/3438a94b-e4af-41a7-8d85-7668fcbd9928/volumes/kubernetes.io~secret/mount
合計 0
drwxrwxrwt 3 root root 100 1月 8 12:00 .
drwxr-xr-x 4 root root 46 1月 8 12:00 ..
drwxr-xr-x 2 root root 60 1月 8 12:00 ..2020_01_08_03_00_13.066710719
lrwxrwxrwx 1 root root 31 1月 8 12:00 ..data -> ..2020_01_08_03_00_13.066710719
lrwxrwxrwx 1 root root 10 1月 8 12:00 foo -> ..data/foo
你可以看到秘密设计提案 https://github.com/kubernetes/community/blob/master/contributors/design-proposals/auth/secrets.md
是这样写的
如果一个节点被破坏,唯一可能暴露的秘密应该是属于调度到它的容器的秘密
所以我认为这个秘密似乎并不能保证当一个节点被破坏时容器的秘密得到保护。
我也有同样的问题,并且一直在寻找关于环境变量与卷的明确答案。我找不到任何东西,只有这样的讨论。Kuberentes 文档也没有解决这个问题,除非DT 指出。上面,甚至还有一点欠缺。针对这里讨论的一些内容,我有我的观点,这些观点不一定正确,只是我能够推测的。如果我有什么误解,欢迎指正。以下是我的理解:
- 与bells17一样,我看不到环境变量和卷/文件之间的安全性有任何区别,只需登录到 pod 即可轻松访问两者。
- WRT 12 因素应用程序,我同意jamesconant。我不认为有任何区别。在这两种情况下,它们都是秘密规范的一部分,该规范是信息的来源,无论它是被投影为文件还是环境变量。如果需要将代码与配置完全分离,您可以将秘密规范(和其他规范)放在单独的存储库中。
- 除非在 etcd 中静态加密,否则秘密是不安全的。正如Andre B所指出的,其他选项(例如Vault)也是可能的。