发布于 2026-01-06 0 阅读
0

教程:如何使用 Kubernetes Secrets 存储敏感配置数据

教程:如何使用 Kubernetes Secrets 存储敏感配置数据

大家好,欢迎👋👋 我们将继续“Kubernetes 入门”系列文章!在之前的博客中,我们学习了如何使用ConfigMap对象配置 Kubernetes 应用。在本文中,我们将探讨 KubernetesSecrets以及如何使用它来存储需要安全处理的敏感配置数据,例如数据库凭据、API 密钥等。

和往常一样,我们将以实例为主,您将学习到:

  • 如何创建Secrets(CLI、yaml 等),以及
  • 在应用程序中使用它们的各种方法(环境变量、卷等)

代码(以及YAML!)可在 GitHub 上找到。

欢迎通过Twitter或留言的方式给我反馈 🙏🏻

本博客分为两个逻辑部分:

  1. 创建方式 Secrets
  2. 应用程序中使用 的技术Secrets

先决条件:

要完成本文中的示例,您只需要一个minikube集群和一个kubectl用于访问集群的 CLI 工具。

在计算机上的虚拟机中安装minikube单节点 Kubernetes 集群。在 Mac 上,您可以简单地:

curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 \
  && chmod +x minikube

sudo mv minikube /usr/local/bin
Enter fullscreen mode Exit fullscreen mode

安装后kubectl即可与集群交互minikube。在 Mac 上,您可以:

curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
Enter fullscreen mode Exit fullscreen mode

创造秘密

让我们来看看你可以使用哪些技术来创建Secret

使用清单文件

使用该data部分

可以创建一个,Secret并将配置数据以键值对的形式存储在data定义部分中。

apiVersion: v1
kind: Secret
metadata:
  name: service-apikey
data:
  apikey: Zm9vYmFy
Enter fullscreen mode Exit fullscreen mode

Secret数据包含表示敏感信息的键值对数据,其中apikey键为字符串,值为base64编码后的字符串。

Secret在 Kubernetes 中创建此内容:

kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/secret-data.yaml
Enter fullscreen mode Exit fullscreen mode

为了简单起见,YAML 文件直接引用自GitHub 仓库,但您也可以将该文件下载到本地计算机并以相同的方式使用它。

确认Secret已创建:

kubectl get secret/service-apikey -o yaml
Enter fullscreen mode Exit fullscreen mode

您将收到类似如下的 (YAML) 响应:

apiVersion: v1
data:
  apikey: Zm9vYmFy
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"apikey":"Zm9vYmFy"},"kind":"Secret","metadata":{"annotations":{},"name":"service-apikey","namespace":"default"}}
  creationTimestamp: "2019-12-17T11:11:27Z"
  name: service-apikey
  namespace: default
  resourceVersion: "113009"
  selfLink: /api/v1/namespaces/default/secrets/service-apikey
  uid: 671b547c-3316-4916-b6dc-be2b551b974e
type: Opaque
Enter fullscreen mode Exit fullscreen mode

Secret使用这种方法获取详细信息kubectl get并不会泄露其内容。

请注意,这apikey: Zm9vYmFy是我们在 YAML 清单中提供的内容。您可以通过解码来查看其纯文本形式:

echo 'Zm9vYmFy' | base64 --decode

//foobar
Enter fullscreen mode Exit fullscreen mode

使用该stringData部分

上述示例中使用的属性data用于保存base64编码信息。如果要安全地存储纯文本数据,可以使用stringData`<section>` 部分。以下是一个示例:

apiVersion: v1
kind: Secret
metadata:
  name: plaintext-secret
stringData:
  foo: bar
  mac: cheese
Enter fullscreen mode Exit fullscreen mode

foo和的mac以纯文本形式传递。请创建Secret并确认:

kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/secret-plaintext.yaml

kubectl get secret/plaintext-secret -o yaml
Enter fullscreen mode Exit fullscreen mode

以下是YAML 响应的一部分。实际数据以endcoded 格式data存储。base64

data:
  foo: YmFy
Enter fullscreen mode Exit fullscreen mode

如果解码数据,可以确认它与bar我们提供的原始纯文本输入()相匹配。

echo 'YmFy' | base64 --decode

//bar
Enter fullscreen mode Exit fullscreen mode

请注意,该data部分接受纯文本属性。尝试这样做会导致类似如下的错误:illegal base64 data at input byte 8

文件内容

您也可以将整个文件的内容作为该stringData部分的输入!以下是一个示例:

apiVersion: v1
kind: Secret
metadata:
  name: secret-in-a-file
stringData:
  app-config.yaml: |-
    hello: world
    john: doe
Enter fullscreen mode Exit fullscreen mode

创建此内容Secret

kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/secret-file.yaml
Enter fullscreen mode Exit fullscreen mode

结果Secret将包含一个名为 `<key_name>` 的键app-config.yaml,其内容(值)将是base64所提供数据的编码。

与往常一样,您需要在 Kubernetes 中确认这一点,并解码其内容。

kubectl get secret/secret-in-a-file -o yaml
echo '<"data" content in yaml response> | base64 --decode
Enter fullscreen mode Exit fullscreen mode

注意:使用此方法时,您的应用程序负责解析表示Secret配置的数据。在本例中,数据恰好是以换行符分隔的键值对,但也可以是其他任何格式。

使用kubectl

你可以使用该kubectl create secret命令创建 Secret 对象。

使用--from-literal

您可以使用纯文本数据通过 CLI 创建(这将以编码格式Secret存储在 Kubernetes 中)。base64

kubectl create secret generic redis-credentials --from-literal=user=poweruser --from-literal=password='f0ob@r'
Enter fullscreen mode Exit fullscreen mode

使用--from-file

kubectl create secret generic topsecret --from-file=api_keys.txt
Enter fullscreen mode Exit fullscreen mode

这将创建一个 Secret( topsecret)

  • 一个与文件名相同的密钥,即api_keys.txt本例中的文件名。
  • 并且,值作为文件的内容

从目录中的文件

您可以直接指定一个目录,该目录下的所有文件都将用于创建文件。Secret

kubectl create secret generic topsecrets --from-file=/home/credentials/
Enter fullscreen mode Exit fullscreen mode

你最终会得到

  • 多个密钥,与单个文件名相同
  • 该值将是相应文件的内容

使用秘密

为了使 Secrets 发挥作用,我们需要确保我们的应用程序能够访问它们Pod。让我们探讨一下实现这一目标的方法。

环境变量

您可以将Secret数据作为环境变量使用Pod(就像……一样ConfigMap)。以下是一个示例:

apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
    - name: nginx
      image: nginx
      env:
        - name: API_KEY
          valueFrom:
            secretKeyRef:
              name: service-apikey
              key: apikey
Enter fullscreen mode Exit fullscreen mode

apikey我们使用Secret service-apikey,并确保其值API_KEY在内部作为环境变量可用Pod

创建Pod(假设您已根据之前的示例创建了密钥)并确认

kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/pod-secret-env.yaml
kubectl get pods -w
Enter fullscreen mode Exit fullscreen mode

等待状态Pod转换完成Running。然后,确认环境变量已注入到系统中。Pod

kubectl exec pod1 -- env | grep API_KEY
Enter fullscreen mode Exit fullscreen mode

你应该会收到这样的回复——API_KEY=foobar

与其引用 `<filename>` 中的单个条目Secret,不如使用 `<environment>` 将envFrom所有条目作为环境变量来方便地使用Pod。以下是使用方法:

apiVersion: v1
kind: Pod
metadata:
  name: pod2
spec:
  containers:
    - name: nginx
      image: nginx
      envFrom:
        - secretRef:
            name: plaintext-secret
Enter fullscreen mode Exit fullscreen mode

我们指的是plaintext-secret Secret使用envFrom.secretRef。要创建此Pod

kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/pod-secret-envFrom.yaml
kubectl get pods -w
Enter fullscreen mode Exit fullscreen mode

等待状态Pod转换完成Running,然后确认环境变量是否存在。

kubectl exec pod2 -- env | grep foo
//foo=bar

kubectl exec pod2 -- env | grep mac
//mac=cheese
Enter fullscreen mode Exit fullscreen mode

这证实了 `<value>`foomac`<value>` 都已作为环境变量添加到thePod 中,它们的解码值分别为 `<value>`bar和 ` cheese<value>`。

您可以将其挂载SecretsVolume某个位置Pod。例如

apiVersion: v1
kind: Pod
metadata:
  name: pod3
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - name: apikey-config-volume
          mountPath: /secret
          readOnly: true
  volumes:
    - name: apikey-config-volume
      secret:
        secretName: service-apikey
Enter fullscreen mode Exit fullscreen mode

体积apikey-config-volume指的是…… service-apikey Secret。要创建此内容Pod

kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/pod-secret-volume.yaml
kubectl get pods -w
Enter fullscreen mode Exit fullscreen mode

等待状态Pod转换完成Running。然后执行以下命令:

kubectl exec pod3 -- cat /secret/apikey
//foobar
Enter fullscreen mode Exit fullscreen mode

这证实了密钥apikeyservice-apikey作为文件(文件名为 `<filename> apikey`)挂载到指定/secret目录(如 Pod 中所述)。该文件的内容就是密钥值,foobar在本例中为 `<secret_value>`。

使用imagePullSecrets

有一种方法Secrets可以让应用程序 Pod 使用它来进行身份验证,并从私有 Docker 镜像仓库拉取 Docker 镜像。

实际上有三种类型Secrets

  • generic用于存储键值对,正如我们目前为止在示例中看到的那样。
  • tls- 将公钥/私钥对信息存储为Secrets
  • docker-registry- 用于向 Docker 注册表进行身份验证的凭据。

这种技术的使用方法非常简单:

  • 使用docker-registry Secret类型在 Kubernetes 中存储私有 Docker 注册表凭据
  • 然后imagePullSecrets(在 Pod 中)引用Secret包含 Docker 注册表凭据的内容

举例总是有帮助的:

apiVersion: v1
kind: Pod
metadata:
  name: pod4
spec:
  containers:
    - name: privateapp
      image: abhirockzz/test-private-repo:latest
      command: ["/bin/sh"]
      args: ["-c", "while true; do date; sleep 5;done"]
  imagePullSecrets:
    - name: docker-repo-secret
Enter fullscreen mode Exit fullscreen mode

看看它imagePullSecrets.name的是什么。让我们来创建它。Secretdocker-repo-secret

但在此之前,请确保您拥有一个私有的 Docker 镜像仓库——我使用的是 [此处应填写镜像仓库名称] DockerHub,但您可以选择任何其他镜像仓库。

首先,使用以下命令创建一个Secret名为 `<filename> docker-repo-secret` 的文件,其中包含您的 Docker 凭据:kubectl create secret docker-registry

kubectl create secret docker-registry docker-repo-secret --docker-server=DOCKER_REG_SERVER --docker-username=DOCKER_REG_USERNAME --docker-password=DOCKER_REG_PASSWORD --docker-email=DOCKER_REG_EMAIL
Enter fullscreen mode Exit fullscreen mode

例如 Docker Hub

kubectl create secret docker-registry docker-repo-secret --docker-server=https://index.docker.io/v1/ --docker-username=foobarbaz --docker-password=t0ps3cr3t --docker-email=foobarbaz@gmail.com

kubectl get secret/docker-repo-secret -o yaml
Enter fullscreen mode Exit fullscreen mode

https://index.docker.io/v1/是 Docker Hub 注册表服务器

为了测试,我们将使用一张busybox图片,tag并且

docker pull busybox

docker tag busybox [DOCKER_REG]/[DOCKER_PRIVATE_REPO]:[IMAGE_TAG]
e.g. 
docker tag busybox abhirockzz/test-private-repo:latest
Enter fullscreen mode Exit fullscreen mode

……push而且

docker push [DOCKER_REG]/[DOCKER_PRIVATE_REPO]:[IMAGE_TAG]
e.g. 
docker push abhirockzz/test-private-repo:latest
Enter fullscreen mode Exit fullscreen mode

私有仓库准备就绪后,您可以创建一个工具,Pod该工具将使用通过注册表提供的凭据从私有仓库拉取镜像。Secret

kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/pod-secret-docker.yaml
kubectl get pods -w
Enter fullscreen mode Exit fullscreen mode

等待状态Pod变更Running

如果看到ErrImagePull错误信息,则表示 Docker 镜像仓库的身份验证可能存在问题。要了解详细信息,请使用:kubectl describe pod/pod4

确认设备运行正常:kubectl logs -f pod4

由于busybox镜像本身并不执行任何操作,我们执行while true; do date; sleep 5;done(如规范中所述Pod)。因此,您应该会看到日志(每 5 秒打印一次)。

Tue Dec 17 14:17:34 UTC 2019
Tue Dec 17 14:17:39 UTC 2019
Tue Dec 17 14:17:44 UTC 2019
Tue Dec 17 14:18:49 UTC 2019
Enter fullscreen mode Exit fullscreen mode

一切正常!这意味着 Pod 能够使用注入到 `using` 语句中的 Docker 凭据,从私有 Docker 仓库拉取您的镜像,而该凭据本身又引用了 ` Podusing`语句。imagePullSecretsSecret

知道这个很有用

以下是使用时应注意的一些事项(并非全部)Secrets

  • Secret必须先创建它,才能供任何Pod想要使用它的人使用。
  • Secrets仅在一个范围内适用,即只能在同一范围内namespace使用。Podsnamespace
  • 如果(使用Pod中存在对不存在的键的引用,则不会启动。SecretsecretKeyRef
  • 单个文件的大小限制为 1MiB。Secrets

本期“Kubernetes 入门指南”系列就到这里。敬请期待更多精彩内容!

如果您有兴趣学习如何使用Azure进行 Kubernetes 和容器开发,只需创建一个免费帐户即可开始!建议您先从文档中的快速入门、教程和代码示例入手,熟悉这项服务。我也强烈推荐您查看50 天 Kubernetes 学习路径。高级用户可以参考Kubernetes 最佳实践,或者观看一些视频了解演示、主要功能和技术讲解。

我真心希望您喜欢这篇文章并从中有所收获🙌 如果喜欢的话,请点赞并关注!

文章来源:https://dev.to/itnext/tutorial-how-to-use-kubernetes-secrets-for-storing-sensitive-config-data-3dl5