教程:如何使用 Kubernetes Secrets 存储敏感配置数据
大家好,欢迎👋👋 我们将继续“Kubernetes 入门”系列文章!在之前的博客中,我们学习了如何使用ConfigMap对象配置 Kubernetes 应用。在本文中,我们将探讨 KubernetesSecrets以及如何使用它来存储需要安全处理的敏感配置数据,例如数据库凭据、API 密钥等。
和往常一样,我们将以实例为主,您将学习到:
- 如何创建
Secrets(CLI、yaml 等),以及 - 在应用程序中使用它们的各种方法(环境变量、卷等)
代码(以及YAML!)可在 GitHub 上找到。
欢迎通过Twitter或留言的方式给我反馈 🙏🏻
本博客分为两个逻辑部分:
- 创建方式
Secrets - 应用程序中使用 的技术
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
安装后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
创造秘密
让我们来看看你可以使用哪些技术来创建Secret
使用清单文件
使用该data部分
可以创建一个,Secret并将配置数据以键值对的形式存储在data定义部分中。
apiVersion: v1
kind: Secret
metadata:
name: service-apikey
data:
apikey: Zm9vYmFy
该Secret数据包含表示敏感信息的键值对数据,其中apikey键为字符串,值为base64编码后的字符串。
要Secret在 Kubernetes 中创建此内容:
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/secret-data.yaml
为了简单起见,YAML 文件直接引用自GitHub 仓库,但您也可以将该文件下载到本地计算机并以相同的方式使用它。
确认Secret已创建:
kubectl get secret/service-apikey -o yaml
您将收到类似如下的 (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
Secret使用这种方法获取详细信息kubectl get并不会泄露其内容。
请注意,这apikey: Zm9vYmFy是我们在 YAML 清单中提供的内容。您可以通过解码来查看其纯文本形式:
echo 'Zm9vYmFy' | base64 --decode
//foobar
使用该stringData部分
上述示例中使用的属性data用于保存base64编码信息。如果要安全地存储纯文本数据,可以使用stringData`<section>` 部分。以下是一个示例:
apiVersion: v1
kind: Secret
metadata:
name: plaintext-secret
stringData:
foo: bar
mac: cheese
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
以下是YAML 响应的一部分。实际数据以endcoded 格式data存储。base64
data:
foo: YmFy
如果解码数据,可以确认它与bar我们提供的原始纯文本输入()相匹配。
echo 'YmFy' | base64 --decode
//bar
请注意,该
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
创建此内容Secret:
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/secret-file.yaml
结果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
注意:使用此方法时,您的应用程序负责解析表示
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'
使用--from-file
kubectl create secret generic topsecret --from-file=api_keys.txt
这将创建一个 Secret( topsecret)
- 一个与文件名相同的密钥,即
api_keys.txt本例中的文件名。 - 并且,值作为文件的内容
从目录中的文件
您可以直接指定一个目录,该目录下的所有文件都将用于创建文件。Secret
kubectl create secret generic topsecrets --from-file=/home/credentials/
你最终会得到
- 多个密钥,与单个文件名相同
- 该值将是相应文件的内容
使用秘密
为了使 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
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
等待状态Pod转换完成Running。然后,确认环境变量已注入到系统中。Pod
kubectl exec pod1 -- env | grep API_KEY
你应该会收到这样的回复——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
我们指的是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
等待状态Pod转换完成Running,然后确认环境变量是否存在。
kubectl exec pod2 -- env | grep foo
//foo=bar
kubectl exec pod2 -- env | grep mac
//mac=cheese
这证实了 `<value>`foo和mac`<value>` 都已作为环境变量添加到thePod 中,它们的解码值分别为 `<value>`bar和 ` cheese<value>`。
卷
您可以将其挂载Secrets到Volume某个位置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
体积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
等待状态Pod转换完成Running。然后执行以下命令:
kubectl exec pod3 -- cat /secret/apikey
//foobar
这证实了密钥apikey已service-apikey作为文件(文件名为 `<filename> apikey`)挂载到指定/secret目录(如 Pod 中所述)。该文件的内容就是密钥值,foobar在本例中为 `<secret_value>`。
使用imagePullSecrets
有一种方法Secrets可以让应用程序 Pod 使用它来进行身份验证,并从私有 Docker 镜像仓库拉取 Docker 镜像。
实际上有三种类型Secrets
generic用于存储键值对,正如我们目前为止在示例中看到的那样。tls- 将公钥/私钥对信息存储为Secretsdocker-registry- 用于向 Docker 注册表进行身份验证的凭据。
这种技术的使用方法非常简单:
- 使用
docker-registrySecret类型在 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
看看它指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
例如 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
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
……push而且
docker push [DOCKER_REG]/[DOCKER_PRIVATE_REPO]:[IMAGE_TAG]
e.g.
docker push abhirockzz/test-private-repo:latest
私有仓库准备就绪后,您可以创建一个工具,Pod该工具将使用通过注册表提供的凭据从私有仓库拉取镜像。Secret
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/pod-secret-docker.yaml
kubectl get pods -w
等待状态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
一切正常!这意味着 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