【问题标题】:Retrieve Kubernetes Secrets mounted as volumes检索作为卷挂载的 Kubernetes Secret
【发布时间】:2019-07-29 20:34:49
【问题描述】:

您好,我正在玩弄 Kubernetes 的秘密。 我的部署文件是:

---
apiVersion: v1
kind: Secret
metadata:
  name: my-secrets
  labels:
    app: my-app
data:
  username: dXNlcm5hbWU=
  password: cGFzc3dvcmQ=

我能够创建秘密并将它们安装在我的部署中,如下所示:

---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-service
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: NodePort

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-service
  labels:
    app: spring-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spring-service
  template:
    metadata:
      labels:
        app: spring-service
    spec:
      containers:
      - name: spring-service
        image: my-image:tag
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: my-secret-vol
          mountPath: "/app/secrets/my-secret"
          readOnly: true            
      volumes:
      - name: my-secret-vol
        secret:
          secretName: my-secrets

我的问题是如何访问我在 spring-boot 应用程序中秘密创建的 usernamepassword

我尝试使用${my-secrets.username}${username} 加载,但找不到值。

我还尝试在 deployment.yml 中添加秘密作为环境变量,如下所示:

env:
- name: username
  valueFrom:
    secretKeyRef:
      name: my-secrets
      key: username
- name: password
  valueFrom:
    secretKeyRef:
      name: my-secrets
      key: password

在这种情况下,值是从秘密加载的,当我在 minikube 仪表板中更改秘密值时,它不会反映所做的更改。

请帮助我了解这是如何工作的。

我使用minikubedocker 作为容器

【问题讨论】:

    标签: spring-boot kubernetes kubernetes-secrets mounted-volumes


    【解决方案1】:

    对于第一种方法,您可以在以下位置找到值:

    - /app/secrets/my-secret/username
    - /app/secrets/my-secret/password 
    

    对于第二种方法,您无法在运行时更改 env vars 的值,您需要重新启动或重新部署 pod

    【讨论】:

    • 在这两种方法中,您都必须重新启动您的 pod 才能看到内容发生了变化。此外,有些人最终将一个配置文件存储在密钥的一个密钥中(而不是每个密钥一个密钥),因为他们只想从磁盘读取一个文件。
    • @hernan-garcia,谢谢您的回答。虽然,你能告诉我在哪里以及如何使用这些值吗?我试图在application.yml 文件中指定为username: /app/secrets/my-secret/username,这显然是错误的。
    • @omer-levi-hevroni,感谢您的建议,因为如果我将机密存储在一个文件中,我不必加载多个文件。此外,在Kubernetes Docs 中,它显示Mounted Secrets are updated automatically。是我做错了什么吗?或者如何挂载秘密,以便在不重新启动 pod 的情况下更新它们?
    • @nirav 我没有意识到这一点。你检查过它是否有效吗?
    • @OmerLeviHevroni 我不确定如何使用值。你能告诉我如何从/app/secrets/my-secret/username读取值吗?
    【解决方案2】:

    您不会将秘密注入properties.yml。相反,您将密钥的内容用作properties.yml。流程如下:

    • 使用敏感数据(例如密码)创建properties.yml
    • Base64 编码此文件(例如base64 properties.yml)。
    • 获取 base64 编码值并将其放入密钥 properties.yaml 下的密钥中。

    您最终应该得到以下格式的秘密:

    apiVersion: v1
    kind: Secret
    metadata:
      name: my-secrets
      labels:
        app: my-app
    data:
      properties.yml: dXNlcm5hbWU=
    

    现在,当您将这个 secret 挂载到您的 pod 上时,Kubernetes 将解密该 secret 并将值放在相关路径下,您就可以挂载它了。

    该模式是有 2 个配置文件 - 一个具有与代码一起存储的非敏感配置,第二个(包括敏感配置)作为机密存储。我不知道是否可以使用 Spring Boot 加载多个配置文件。

    最后要说一句——这个过程很麻烦而且容易出错。对配置文件的每次更改都需要解码原始密钥并重复此手动过程。此外,很难理解发生了什么变化——你所看到的只是整个内容都发生了变化。出于这个原因,我们构建了Kamus。它让您只加密敏感值而不是整个文件。让我知道这是否与您相关:)

    【讨论】:

    • Kamus 有助于轻松加密机密。感谢您提供有关创建秘密过程的更多信息。但是,就我而言,我成功地创建了秘密并将它们安装在目录中。我只是不知道如何在 Spring Boot 应用程序中阅读它们。
    • WDYM?如果你按照我上面描述的过程,你最终会在应用程序目录中得到一个名为properties.yml 的文件,你可以阅读它。你能详细说明为什么它没有帮助吗?
    • 我有点困惑它将如何工作。我今天要试一试,然后告诉你。谢谢。
    • 谢谢你,奥马尔。我已经尝试过了,并且工作得很好。我可以从文件中读取它并使用文件的内容。但是,我将尝试在 Spring Boot 应用程序中注入配置值。我想,我从 kubernetes 方面很清楚它是如何工作的。我只需要弄清楚如何在我的应用程序中使用数据。完成后,我将编辑问题并接受您的回答。
    • 您好 Omer,按照您的回答,我能够将属性文件作为已安装的卷获取。我必须读取文件才能从中获取值。在这种情况下,每当秘密值发生变化时,k8s 都会在随机时间后更新文件值。但是,当我将 properties.yml 文件作为spring.config.location 参数注入时,它只读取一次并且不会在秘密更改时自动更新值。我认为这将是另一个问题。我真的很感谢这个答案。
    猜你喜欢
    • 2020-08-07
    • 1970-01-01
    • 2019-08-24
    • 2021-10-26
    • 2019-10-09
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2017-07-21
    相关资源
    最近更新 更多