Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 这样的信息可能会被放在 PodSpecification中或者container image中。 使用 Secret 意味着你不需要在应用程序代码中包含机密数据。
由于创建 Secret 可以独立于使用它们的 Pod, 因此在创建、查看和编辑 Pod 的工作流程中暴露 Secret(及其数据)的风险较小。 Kubernetes 和在集群中运行的应用程序也可以对 Secret 采取额外的预防措施, 例如避免将机密数据写入非易失性存储。
Secret 类似于 ConfigMap 但专门用于保存机密数据。
一个 Secret
可以包含 Pod 访问数据库所需的用户凭证。 例如,由用户名和密码组成的数据库连接字符串。 你可以在本地计算机上,将用户名存储在文件 ./username.txt
中,将密码存储在文件 ./password.txt
中。
echo -n 'system' > ./username.txt
echo -n 'system123' > ./password.txt
在这些命令中,-n
标志确保生成的文件在文本末尾不包含额外的换行符。 这一点很重要,因为当 kubectl
读取文件并将内容编码为 base64 字符串时,多余的换行符也会被编码。
kubectl create secret
命令将这些文件打包成一个 Secret 并在 API 服务器上创建对象。
kubectl create secret generic testsecretbyfile \
--from-file=./username.txt \
--from-file=./password.txt
默认密钥名称是文件名。 你可以选择使用 --from-file=[key=]source
来设置密钥名称。例如:
kubectl create secret generic testsecretbyfile \
--from-file=username=./username.txt \
--from-file=password=./password.txt
你可以先用 JSON 或 YAML 格式在一个清单文件中定义 Secret
对象,然后创建该对象。 Secret 资源包含 2 个键值对:data
和 stringData
。 data
字段用来存储 base64 编码的任意数据。 提供 stringData
字段是为了方便,它允许 Secret 使用未编码的字符串。
$ echo -n "system" | base64
c3lzdGVt
$ echo -n "system123" | base64
c3lzdGVtMTIz
my_secret.yml,
apiVersion: v1
kind: Secret
metadata:
name: testsecret
type: Opaque
data:
password: c3lzdGVtMTIz
username: c3lzdGVt
通过下面命令创建
kubectl apply -f my_secret.yml
apiVersion: v1
kind: Secret
metadata:
name: testsecret
type: Opaque
stringData:
password: system123
username: system
你可以在 kustomization.yaml
中定义 secreteGenerator
字段,并在定义中引用其它本地文件生成 Secret。 例如:下面的 kustomization 文件 引用了 ./username.txt
和 ./password.txt
文件:
secretGenerator:
- name: testsecret
files:
- username.txt
- password.txt
你也可以在 kustomization.yaml
文件中指定一些字面量定义 secretGenerator
字段。 例如:下面的 kustomization.yaml
文件中包含了 username
和 password
两个字面量:
secretGenerator:
- name: testsecret
literals:
- username=system
- password=system123
你也可以使用 .env
文件在 kustomization.yaml
中定义 secretGenerator
。 例如:下面的 kustomization.yaml
文件从 .env.secret
文件获取数据。
secretGenerator:
- name: testsecret
envs:
- .env.secret
检查 secret 是否已创建:
kubectl get secrets
输出类似于:
NAME TYPE DATA AGE
testsecret Opaque 2 51s
你可以查看 Secret
的描述:
kubectl describe secrets/testsecret
删除创建的 Secret:
kubectl delete secret testsecret
创建好secret之后,有两种方式来使用它:
加下面配置在spec.volumes和spec.containers.volumeMounts这两个标签里。
spec:
volumes:
- name: secrets
secret:
secretName: testsecret
containers:
- name: test123
image: test-demo1:v1.0
volumeMounts:
- name: secrets
mountPath: /etc/secrets
readOnly: true
利用下面命令重新部署你的项目
#kubectl apply -f yourapp.yaml
进入你的pod , 注:test123-5595d9fdf9-bsdj6是我pod名字
#Kubectl exec -ti test123-5595d9fdf9-bsdj6 -- /bin/sh
在/etc/secrets/目录里查看password文件
root@test123-5595d9fdf9-bsdj6:/# cd etc/secrets/
root@test123-5595d9fdf9-bsdj6:/etc/secrets# cat password
system123
注意:如果你重新编辑secret的password,每个pod里的password也会改变。
完整的yourapp.yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: test123
labels:
app: test123
spec:
replicas: 1
template:
metadata:
name: test123
labels:
app: test123
spec:
volumes:
- name: secrets
secret:
secretName: testsecret
containers:
- name: test123
image: test-demo1:v1.0
imagePullPolicy: IfNotPresent
volumeMounts:
- name: secrets
mountPath: /etc/secrets
readOnly: true
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
restartPolicy: Always
selector:
matchLabels:
app: test123
---
apiVersion: v1
kind: Service
metadata:
name: test123-service
labels:
app: test123-service
spec:
selector:
app: test123
ports:
- port: 8087
targetPort: 8089
nodePort: 30082
type: NodePort
在Container的env里配置下面环境参数
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: testsecret
key: username
optional: false # same as default; "mysecret" must exist
# and include a key named "username"
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: testsecret
key: password
optional: false # same as default; "mysecret" must exist
# and include a key named "password"
利用下面命令重新部署你的项目
#kubectl apply -f yourapp.yaml
进入你的pod , 注:test123-675b6f7c8-psh6w是我pod名字
#Kubectl exec -ti test123-675b6f7c8-psh6w -- /bin/sh
输出环境变量
root@test123-675b6f7c8-psh6w:/# echo SECRET_USERNAME
SECRET_USERNAME
root@test123-675b6f7c8-psh6w:/# echo $SECRET_PASSWORD
system123
完整的yaml 文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: test123
labels:
app: test123
spec:
replicas: 1
template:
metadata:
name: test123
labels:
app: test123
spec:
containers:
- name: test123
image: test-demo1:v1.0
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: testsecret
key: username
optional: false # same as default; "mysecret" must exist
# and include a key named "username"
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: testsecret
key: password
optional: false # same as default; "mysecret" must exist
# and include a key named "password"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
restartPolicy: Always
selector:
matchLabels:
app: test123
---
apiVersion: v1
kind: Service
metadata:
name: test123-service
labels:
app: test123-service
spec:
selector:
app: test123
ports:
- port: 8087
targetPort: 8089
nodePort: 30082
type: NodePort
Built-in Type | Usage |
---|---|
Opaque | arbitrary user-defined data |
kubernetes.io/service-account-token | ServiceAccount token |
kubernetes.io/dockercfg | serialized ~/.dockercfg file |
kubernetes.io/dockerconfigjson | serialized ~/.docker/config.json file |
kubernetes.io/basic-auth | credentials for basic authentication |
kubernetes.io/ssh-auth | credentials for SSH authentication |
kubernetes.io/tls | data for a TLS client or server |
bootstrap.kubernetes.io/token | bootstrap token data |
参考资料