date: 2020-07-31title: k8s之secret #标题
tags: secret #标签
categories: k8s # 分类
k8s中使用secret对象来存储敏感信息,例如密码,证书,ssh密钥等,如果不使用 Secret,此类信息可能被放置在 Pod 定义中或者容器镜像中。将此类敏感信息存储到 Secret 中,可以更好地控制其使用以及降低泄露的风险。
创建secret
secret有如下几种使用场景:
- 作为 Pod 的数据卷挂载
- 作为 Pod 的环境变量
- kubelet 在抓取容器镜像时,作为 docker 镜像仓库的用户名密码
假设某个pod需要访问数据库,我们就可以通过secret来存储数据库的账户信息,然后挂载到pod中。
下面记录下创建secret资源对象的几种方式。
通过—from-file的方式创建
# 准备数据文件
$ echo -n "admin" > .username.txt
$ echo -n "1f2d1e2e67df" > .passwd.txt
# 通过--from-file的方式创建
$ kubectl create secret generic db-user-pass --from-file=.username.txt --from-file=.passwd.txt
secret/db-user-pass created
通过—from-literal的方式创建
$ kubectl create secret generic db-user-pass --from-literal=username=admin --from-literal=password=1f2d1e2e67df
secret/db-user-pass created
通过—from-env-file的方式创建
# 准备变量文件
$ cat > env.txt <<EOF
> username=admin
> password=1f2d1e2e67df
> EOF
# 创建
$ kubectl create secret generic db-user-pass --from-env-file=env.txt
通过yaml配置文件文件来创建
# 先将数据加密
$ echo admin | base64
YWRtaW4K
$ echo 1f2d1e2e67df | base64
MWYyZDFlMmU2N2RmCg==
# 编写yaml文件
$ cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-user-pass
type: Opaque
data:
username: YWRtaW4K
password: MWYyZDFlMmU2N2RmCg==
在yaml文件中定义secret有以下两种方式:
- data:使用 data 字段时,取值的内容必须是 base64 编码的。
- stringData:使用 stringData 时,更为方便,可以直接将取值以明文的方式写在 yaml 文件中。
以下是使用stringData来编写的yaml文件,stringData 中的取值部分将被 apiserver 自动进行 base64 编码之后再保存。
$ cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-user-pass
type: Opaque
stringData:
username: admin
password: 1f2d1e2e67df
$ kubectl apply -f secret.yaml # 执行yaml文件
同时定义了data和stringData
如果同时定义了 data 和 stringData,对于两个对象中key 重复的字段,最终将采纳 stringData 中的 value。如下:
$ cat secret.yaml # yaml文件如下
apiVersion: v1
kind: Secret
metadata:
name: my-name
type: Opaque
data:
username: YWRtaW4K # 这是admin加密后的字符串
stringData:
username: administrator
password: 1f2d1e2e67df
$ kubectl apply -f secret.yaml # 创建
$ kubectl get secret/my-name -o yaml # 查看
apiVersion: v1
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW5pc3RyYXRvcg==
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"username":"YWRtaW4K"},"kind":"Secret","metadata":{"annotations":{},"name":"my-name","namespace":"default"},"stringData":{"password":"1f2d1e2e67df","username":"administrator"},"type":"Opaque"}
$ echo 'YWRtaW5pc3RyYXRvcg==' | base64 --decode # 将username的值解密后如下
administrator
查看secret资源对象
$ kubectl describe secret/db-user-pass # 查看创建的secret对象详细信息
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations:
Type: Opaque
Data
====
password: 13 bytes
username: 6 bytes
默认情况下,kubectl get 和 kubectl describe 命令都避免展示 Secret 的内容。这种做法可以避免密码被偷窥,或者被存储到终端的日志中。
但如果输出yaml文件的,就有点不一样了,如下:
$ kubectl get secret/db-user-pass -o yaml # 执行此命令输出如下
apiVersion: v1
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW4=
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"db-user-pass","namespace":"default"},"stringData":{"password":"1f2d1e2e67df","username":"admin"},"type":"Opaque"}
creationTimestamp: "2020-07-29T23:45:16Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:password: {}
f:username: {}
f:metadata:
f:annotations:
.: {}
f:kubectl.kubernetes.io/last-applied-configuration: {}
f:type: {}
manager: kubectl
operation: Update
time: "2020-07-29T23:45:16Z"
name: db-user-pass
namespace: default
resourceVersion: "81928"
selfLink: /api/v1/namespaces/default/secrets/db-user-pass
uid: e95603a1-ce84-4616-bacb-d061cc373e96
type: Opaque
注意:
- 此时annotation 中可以看到 password 的明文,这也许并不是我们所期望的
- 输出的 Secret 对象中,stringData 字段不再出现
使用generator创建secret
从 kubernetes v1.14 开始,kubectl 集成了 Kustomize。通过 Kustomize,我们可以使用 generator(Kustomize 的概念)创建 Secret,并保存到 API Server。Generator 必须在 kustomization.yaml 文件中指定。
从文件生成secret
# 准备文件
$ echo "admin" > username.txt
$ echo "123.com" > passwd.txt
# 准备yaml文件
$ cat << EOF > kustomization.yaml
> secretGenerator:
> - name: user-pass
> files:
> - username.txt
> - passwd.txt
> EOF
$ kubectl apply -k . # 执行创建secret
secret/user-pass-9ddfk46m67 created
# 这种方式创建的secret不会将信息明文显示出来。
# 从明文创建secret的文件内容如下:
$ cat << EOF > kustomization.yaml
> secretGenerator:
> - name: db-user-pass
> literals:
> - username=admin
> - password=secret
> EOF
解码secret信息
# secret中的信息可以通过下面指令获取
kubectl get secret/user-pass-tkkkhcd4t8 -o yaml
# 获取到信息后,可以使用下面指令进行解码
$ echo 'MTIzLmNvbWFiYwo=' | base64 --decode