Kubernetes Secret 对象可以用来储存敏感信息,例如:密码、OAuth token、ssh 密钥等
一、Secret概述
概述
Kubernetes Secret 对象可以用来储存敏感信息,例如:密码、OAuth token、ssh 密钥等。如果不使用 Secret,此类信息可能被放置在 Pod 定义中或者容器镜像中。将此类敏感信息存储到 Secret 中,可以更好地:
- 控制其使用
- 降低信息泄露的风险
用户可以直接创建 Secret,Kubernetes 系统也会创建一些 Secret。
Secret有如下几种使用方式:
- 作为 Pod 的数据卷挂载
- 作为 Pod 的环境变量
- kubelet 在抓取容器镜像时,作为 docker 镜像仓库的用户名密码
内建Secret
Service Account 将自动创建 Secret
Kubernetes 自动创建包含访问 Kubernetes APIServer 身份信息的 Secret,并自动修改 Pod 使其引用这类 Secret。
如果需要,可以禁用或者自定义自动创建并使用 Kubernetes APIServer 身份信息的特性。然而,如果期望安全地访问 Kubernetes APIServer,应该使用默认的 Secret 创建使用过程。
自建Secret
可以使用如下方式创建自己的 Secret:
- 使用 kubectl 创建 Secret
- 手动创建 Secret
- 使用 Generator 创建 Secret
解码和编辑
Kubenetes 中,Secret 使用 base64 编码存储,您可以将其解码获得对应信息的原文,创建 Secret 之后,您也可以再次编辑Secret
二、创建Secret(使用kubectl)
假设某个 Pod 需要访问数据库。在您执行 kubectl 命令所在机器的当前目录,创建文件 ./username.txt 文件和 ./password.txt 暂存数据库的用户名和密码,后续我们根据这两个文件配置 kubernetes secrets。
1 | echo -n 'admin' > ./username.txt |
在 Kubernetes APIServer 中创建 Secret 对象,并将这两个文件中的内容存储到该 Secret 对象中,执行命令,输出结果如下所示:
1 | [root@k8s-master 0425]# kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt |
上述命令的执行效果与此命令执行效果相同:
kubectl create secret generic db-user-pass –from-literal=username=admin –from-literal=password=1f2d1e2e67df如果密码中包含特殊字符需要转码(例如
$、*、\、!),请使用\进行转码。例如:实际密码为S!B\*d$zDsb,kubectl 命令应该写成kubectl create secret generic dev-db-secret –from-literal=username=devuser –from-literal=password=S\!B\\*d\$zDsb。如果通过文件创建(–from-file),则无需对文件中的密码进行转码。检查 Secret 的创建结果,输出信息如下所示:
1 | [root@k8s-master 0425]# kubectl get secrets |
查看 Secret 详情,输出信息如下所示:
1 | [root@k8s-master 0425]# kubectl describe secrets db-user-pass |
默认情况下,kubectl get 和 kubectl describe 命令都避免展示 Secret 的内容。这种做法可以避免密码被偷窥,或者被存储到终端的日志中
三、创建Secret(手动)
可以在 yaml 文件中定义好 Secret,然后通过 kubectl apply -f 命令创建。通过如下两种方式在 yaml 文件中定义 Secret:
- data:使用 data 字段时,取值的内容必须是 base64 编码的
- stringData:使用 stringData 时,更为方便,您可以直接将取值以明文的方式写在 yaml 文件中
在 yaml 中定义 data
- 假设要保存
username=admin和password=1f2d1e2e67df到 Secret 中,要先将数据的值转化为 base64 编码,执行如下命令:
1 | echo -n 'admin' | base64 |
创建 secret.yaml 文件,内容如下所示:
1 | apiVersion: v1 |
执行命令创建:
1 | kubectl apply -f ./secret.yaml |
在 yaml 中定义 stringData
假如并不想先将用户名和密码转换为 base64 编码之后再创建 Secret,则,可以通过定义 stringData 来达成,此时 stringData 中的取值部分将被 apiserver 自动进行 base64 编码之后再保存。
- 创建文件 secret.yaml,内容如下所示:
1 | apiVersion: v1 |
执行命令
1 | kubectl apply -f ./secret.yaml |
执行命令 kubectl get -f ./secret.yaml -o yaml 输出结果如下所示:
1 | apiVersion: v1 |
同时定义了 data 和 stringData
如果同时定义了 data 和 stringData,对于两个对象中key 重复的字段,最终将采纳 stringData 中的 value
创建文件 secret.yaml,该文件同时定义了 data 和 stringData,内容如下所示:
1 | apiVersion: v1 |
执行命令
1 | kubectl apply -f ./secret.yaml |
执行命令 kubectl get -f ./secret.yaml -o yaml 输出结果如下所示:
1 | [root@k8s-master 0425]# kubectl get -f secret.yaml -o yaml |
此处 YWRtaW5pc3RyYXRvcg== 解码后的值是 administrator
将配置文件存入 Secret
假设某个应用程序需要从一个配置文件中读取敏感信息,此时,可以将该文件的内容存入 Secret,再通过数据卷的形式挂载到容器。
例如,应用程序需要读取如下配置文件内容:
1 | apiUrl: "https://my.api.com/api/v1" |
可以使用下面的 secret.yaml 创建 Secret
1 | apiVersion: v1 |
执行命令:
1 | kubectl apply -f ./secret.yaml |
1 | [root@k8s-master 0425]# kubectl get -f secret.yaml -o yaml |
四、解码和编辑Secret
解码Secret
Secret 中的信息可以通过 kubectl get secret 命令获取。
执行命令 kubectl get secret mysecret -o yaml 可获取所创建的 Secret,输出信息如下:
1 | [root@k8s-master 0425]# kubectl get secret mysecret -o yaml |
执行命令 echo 'MWYyZDFlMmU2N2Rm' | base64 --decode 可解码密码字段,输出结果如下:
1 | [root@k8s-master 0425]# echo 'MWYyZDFlMmU2N2Rm' | base64 --decode |
执行命令 echo 'YWRtaW4=' | base64 --decode 可解码用户名字段,输出结果如下:
1 | [root@k8s-master 0425]# echo 'YWRtaW4=' | base64 --decode |
编辑Secret
执行命令 kubectl edit secrets mysecret 可以编辑已经创建的 Secret,该命令将打开一个类似于 vi 的文本编辑器,可以直接编辑已经进行 base64 编码的字段,如下所示:
1 | [root@k8s-master 0425]# kubectl edit secrets mysecret |