导入
简介
秘密的概述及其使用方式。
密钥
在应用程序中传递敏感配置(如凭证和私钥)是很常见的需求。虽然我们可以使用 ConfigMap 来存储这些配置,但当关注这些值的安全性时,有更好的选择:Secrets。
Secret 的使用方式与 ConfigMap 非常相似,但在底层实现上有一些关键区别:
Secrets仅分发给需要它们的 Pod 所在节点。- 它们不会被写入物理存储。
- 在主节点上,它们以加密形式存储。
- 当我们读取一个
Secret时,获取到的数据是经过base64编码的。这主要是为了能够存储二进制数据,而不是一种强安全机制,因为base64很容易被解码。
基于这些特性,下面我们来看看如何创建和使用 Secret。
1# hellok8s-secret.yaml 2apiVersion: v1 3kind: Secret 4metadata: 5 name: hellok8s-secret 6data: 7 SECRET_MESSAGE: "SXQgd29ya3Mgd2l0aCBhIFNlY3JldAo="
如你所见,它与 ConfigMap 非常相似,只是 data 部分的值是经过 base64 编码的。我们可以使用类似以下命令生成该字符串:
1echo 'It works with a Secret' | base64 2# SXQgd29ya3Mgd2l0aCBhIFNlY3JldAo=
将密钥注入为环境变量
很好!将密钥注入到部署中作为环境变量的方式也非常类似:
1apiVersion: apps/v1 2kind: Deployment 3metadata: 4 name: hellok8s 5spec: 6 replicas: 2 7 selector: 8 matchLabels: 9 app: hellok8s 10 template: 11 metadata: 12 labels: 13 app: hellok8s 14 spec: 15 containers: 16 - image: brianstorti/hellok8s:v4 17 name: hellok8s-container 18 env: 19 - name: MESSAGE 20 valueFrom: 21 secretKeyRef: 22 name: hellok8s-secret 23 key: SECRET_MESSAGE
唯一的不同是,我们使用了 secretKeyRef 而不是 configMapKeyRef。
No configuration found for ID: d764a4c231e59f982a1e66bd6bddf6a4138bc083a9cc04807ecc7033af886b7e
我们可以确认它的行为与之前相同:
1kubectl apply -f hellok8s-secret.yaml 2kubectl apply -f deployment.yaml 3 4kubectl get pods 5# NAME READY STATUS 6# hellok8s-6d7579848d-f56wb 1/1 Running 7# hellok8s-6d7579848d-kzq57 1/1 Running 8 9# 将 pod 名称替换为你本地运行的实际名称 10kubectl exec -it hellok8s-6d7579848d-kzq57 -- env | grep MESSAGE 11# MESSAGE=It works with a Secret
从密钥注入所有值
此外,我们也可以像使用 ConfigMap 一样,将 Secret 中的所有值注入到容器中:
1apiVersion: apps/v1 2kind: Deployment 3metadata: 4 name: hellok8s 5spec: 6 replicas: 2 7 selector: 8 matchLabels: 9 app: hellok8s 10 template: 11 metadata: 12 labels: 13 app: hellok8s 14 spec: 15 containers: 16 - image: brianstorti/hellok8s:v4 17 name: hellok8s-container 18 envFrom: 19 - secretRef: 20 name: hellok8s-secret
使用 stringData
每次创建 Secret 前都需要手动进行 base64 编码,这会很麻烦。如果我们只需要存储字符串类型的数据(如本例所示),而不需要处理二进制数据,可以使用 stringData 字段以原始格式创建密钥:
1apiVersion: v1 2kind: Secret 3metadata: 4 name: hellok8s-secret 5stringData: 6 SECRET_MESSAGE: "It works with a Secret"
这种方式的效果是一样的。当我们查看实际生成的 YAML 文件时,会发现该值仍然以 base64 编码形式存在:
1kubectl get secret hellok8s-secret -o yaml 2 3# apiVersion: v1 4# kind: Secret 5# data: 6# SECRET_MESSAGE: SXQgd29ya3Mgd2l0aCBhIFNlY3JldAo= 7# ...
但从容器的角度来看,结果完全相同。因此,这主要是一种便利功能,让我们无需在创建 Secret 前手动编码字符串。