Kubernetes Secrets Volumes 与环境变量

Kubernetes Secrets Volumes vs Environment Variables

是否有推荐的使用方法Kubernetes Secrets?它们可以作为环境变量或使用卷安装公开。一个比另一个更安全吗?

https://www.oreilly.com/library/view/velocity-conference-2017/9781491985335/video316233.html

环境变量公开的 Kubernetes 机密可能能够通过 /proc/ 在主机上枚举。如果是这种情况,通过卷装载加载它们可能更安全。

我同意 TMC 的回答,但想为正在思考的人添加注释,"But what about 12-factor??"。有时会反对使用卷安装的秘密,因为 12F 似乎需要将配置存储为 ENV 变量。首先,这些是建议的、自愿的、你的里程可能会有所不同的最佳实践建议。其次,还有这一段:

In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as “environments”, but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime.

来源:https://12factor.net/config

基本上,结合其余描述,我理解12F Config管理的指导原则是:

  • 将配置保留在源之外
  • 能够将配置注入源工件(例如 docker 容器)
  • 能够对一组必需的配置值进行精细更改

以我的愚见,卷挂载的 Kubernetes Secrets 可以 实现这些目标,具体取决于您创建的 Secret 对象类型以及管理它们的方式。

装载的秘密会自动更新

  • 当卷中已经使用的秘密被更新时,预计密钥最终也会更新。 Kubelet 会在每次定期同步时检查挂载的秘密是否新鲜。但是,它正在使用其本地缓存来获取 Secret 的当前值。

  • 在多容器 Pod 中,Pod 中的每个容器都必须在其 volumeMounts 中请求秘密卷,以便它在容器中可见。这可用于在 pod 级别构建有用的安全分区。

从官方文档 secret by volume mount 上面的发现看起来是一个更好的选择。

我认为在安全性上没有任何区别。 因为如果一个节点被破坏,他们可以看到秘密。

示例:

---
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

是这样写的

If a node is compromised, the only secrets that could potentially be exposed should be the secrets belonging to containers scheduled onto it

所以我认为秘密似乎并不能保证在节点被破坏时保护容器的秘密。

我也有同样的问题,并且一直在寻找关于环境变量与卷的明确答案。我找不到任何东西,just discussions like these. The Kuberentes documentation doesn't address this either, except to noted by DT. 上面,甚至还缺少一点。对于此处讨论的一些内容,我有自己的看法,这些看法不一定正确,只是我能够推测的。如果我误解了什么,我欢迎更正。这是我的理解:

  1. bells17 一样,我没有发现环境变量和 volumes/files 之间的安全性有任何区别,只需登录 pod 即可轻松访问两者。
  2. WRT 12 因素应用,我同意 jamesconant。我认为没有任何区别。在这两种情况下,它们都是秘密规范的一部分,无论它是被投影为文件还是环境变量,它都是信息的来源。如果需要将代码与配置完全分开,您可以将秘密规范(和其他规范)放在单独的存储库中。
  3. 秘密是不安全的,除非 encrypted at rest in etcd. As noted by Andre B other options like Vault 是可能的。