有没有推荐的方式来使用 Kubernetes Secrets?它们可以作为环境变量公开,也可以使用卷装载公开。一个比另一个更安全吗?
https://www.oreilly.com/library/view/velocity-conference-2017/9781491985335/video316233.html
环境变量公开的 Kubernetes 机密可以通过/proc/在主机上枚举。如果是这种情况,通过卷装载加载它们可能更安全。
我同意 TMC 的回答,但想为那些正在思考"但是 12 因素呢??"的人添加一个注释。有时会有人反对使用卷挂载的机密,因为 12F 似乎要求将配置存储为 ENV var。首先,这些是建议的,自愿的,您的里程可能会有所不同的最佳实践建议。第二,有这个部分:
在 12 因素应用中,env 变量是精细控件,每个控件与其他 env 变量完全正交。它们永远不会作为"环境"分组在一起,而是为每个部署独立管理。这是一个可以顺利扩展的模型,因为应用在其生存期内自然会扩展到更多部署。
来源: https://12factor.net/config
基本上,结合描述的其余部分,我理解 12F 配置管理的指导原则是:
- 将配置排除在源代码之外
- 能够将配置注入到源工件(例如 docker 容器)中
- 能够对所需的配置值集进行精细更改
以我的拙见,卷载的 Kubernetes Secrets可以实现这些目标,这取决于你创建的 Secret 对象类型以及你如何管理它们。
挂载的机密会自动更新
-
更新卷中已使用的机密时,投影密钥最终也会更新。Kubelet 正在检查挂载的密钥在每次定期同步时是否是最新的。但是,它使用其本地缓存来获取密钥的当前值。
-
在多容器 Pod 中,Pod 中的每个容器都必须请求其卷中的机密卷挂载,才能在容器中可见。这可用于在 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 因素应用程序,我同意詹姆斯科南特的观点。我认为没有任何区别。在这两种情况下,它们都是机密规范的一部分,机密规范是信息的来源,无论它是投影为文件还是环境变量。如果需要,可以将机密规范(和其他规范)放在单独的存储库中,以将代码与配置完全分离。
- 除非在 etcd 中静态加密,否则机密是不安全的。正如Andre B所指出的,其他选项如Vault是可能的。
根据Kubernetes in Action第二版的书,在某些方面,存储在secrets-volumes
中的秘密比存储在environment-variables
中的更安全。
。将机密注入环境变量与 注入配置映射。但即使 Kubernetes 允许你暴露 秘密 以这种方式,它可能不是最好的主意,因为它可以构成一个 安全风险。应用程序通常输出环境变量 错误报告,甚至在启动时将它们写入应用程序日志, 如果您将机密注入其中,可能会无意中暴露机密 环境变量。此外,子进程继承所有环境 父流程中的变量。因此,如果您的应用程序调用 第三方子进程,你不知道你的秘密最终在哪里。