一、Secret概述
Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 这样的信息可能会被放在 Pod 规约中或者镜像中。 使用 Secret 意味着你不需要在应用程序代码中包含机密数据。
由于创建 Secret 可以独立于使用它们的 Pod, 因此在创建、查看和编辑 Pod 的工作流程中暴露 Secret(及其数据)的风险较小。 Kubernetes 和在集群中运行的应用程序也可以对 Secret 采取额外的预防措施, 例如避免将机密数据写入非易失性存储。
Secret 类似于 ConfigMap 但专门用于保存机密数据。
二、Secret作用
Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用.
默认情况下,Kubernetes Secret 未加密地存储在 API 服务器的底层数据存储(etcd)中。 任何拥有 API 访问权限的人都可以检索或修改 Secret,任何有权访问 etcd 的人也可以。 此外,任何有权限在命名空间中创建 Pod 的人都可以使用该访问权限读取该命名空间中的任何 Secret; 这包括间接访问,例如创建 Deployment 的能力。
为了安全地使用 Secret,请至少执行以下步骤:
1)为 Secret 启用静态加密;
2)启用或配置 RBAC 规则来限制读取 Secret 的数据(包括通过间接方式)。
3)在适当的情况下,还可以使用 RBAC 等机制来限制允许哪些主体创建新 Secret 或替换现有 Secret。
三、Secret概览
要使用 Secret,Pod 需要引用 Secret。 Pod 可以用三种方式之一来使用 Secret:
1)作为挂载到一个或多个容器上的 卷 中的文件。
2)作为容器的环境变量
3)由 kubelet 在为 Pod 拉取镜像时使用
Kubernetes 控制平面也使用 Secret; 例如,引导令牌 Secret 是一种帮助自动化节点注册的机制。
Secret 对象的名称必须是合法的 DNS 子域名。 在为创建 Secret 编写配置文件时,你可以设置 data 与/或 stringData 字段。 data 和 stringData 字段都是可选的。data 字段中所有键值都必须是 base64 编码的字符串。如果不希望执行这种 base64 字符串的转换操作,你可以选择设置 stringData 字段,其中可以使用任何字符串作为其取值。
四、Secret 的类型
创建 Secret 时,你可以使用 Secret 资源的 type 字段, 或者与其等价的 kubectl 命令行参数(如果有的话)为其设置类型。 Secret 的 type 有助于对不同类型机密数据的编程处理。
Kubernetes 提供若干种内置的类型,用于一些常见的使用场景。 针对这些类型,Kubernetes 所执行的合法性检查操作以及对其所实施的限制各不相同。
•Service Account :用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的/run/secrets/kubernetes.io/serviceaccount 目录中
•Opaque : base64 编码格式的 Secret,用来存储密码、密钥等
•kubernetes.io/dockerconfigjson :用来存储私有 docker registry 的认证信息
内置类型 |
用法 |
Opaque |
用户定义的任意数据 |
kubernetes.io/service-account-token |
服务账号令牌 |
kubernetes.io/dockercfg |
~/.dockercfg 文件的序列化形式 |
kubernetes.io/dockerconfigjson |
~/.docker/config.json 文件的序列化形式 |
kubernetes.io/basic-auth |
用于基本身份认证的凭据 |
kubernetes.io/ssh-auth |
用于 SSH 身份认证的凭据 |
kubernetes.io/tls |
用于 TLS 客户端或者服务器端的数据 |
bootstrap.kubernetes.io/token |
启动引导令牌数据 |
通过为 Secret 对象的 type 字段设置一个非空的字符串值,你也可以定义并使用自己 Secret 类型。如果 type 值为空字符串,则被视为 Opaque 类型。 Kubernetes 并不对类型的名称作任何限制。不过,如果你要使用内置类型之一, 则你必须满足为该类型所定义的所有要求。、
五、Service Account示例
Service Account 用来访问 Kubernetes API,甶 Kubernetes 自动创建,并且会自动挂载到Pod 的/run/secrets/kubernetes.io/serviceaccount 目录中
[root@kubernetes-master-001 ~]# kubectl run nginx --image nginx
pod/nginx created
[root@kubernetes-master-001 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 25s
[root@kubernetes-master-001 ~]# kubectl exec nginx ls /run/secrets/kubernetes.io/serviceaccount
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
ca.crt
namespace
token
六、Opaque Secret示例
Opaque类型的数据是一个map类型,要求value是base64编码格式。
1.Secret 变量形式挂载Pod示例
1)创建Secret加密数据
[root@kubernetes-master-001 ~]# echo -n 'admin' |base64
YWRtaW4=
[root@kubernetes-master-001 ~]# echo -n 'Jinhuino1' |base64
SmluaHVpbm8x
[root@kubernetes-master-001 ~]# vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: SmluaHVpbm8x
2)部署Secret
#1.部署Secret
[root@kubernetes-master-001 ~]# kubectl create -f secret.yaml
secret/mysecret created
#2.查看Secret
[root@kubernetes-master-001 ~]# kubectl get secret
NAME TYPE DATA AGE
default-token-668jw kubernetes.io/service-account-token 3 4d3h
mysecret Opaque 2 14s
3)编写Pod文件
#1.编写Pod文件
[root@kubernetes-master-001 ~]# vim secret-val.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nginx
image: nginx:1.18
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
4)部署Pod
[root@kubernetes-master-001 ~]# kubectl apply -f secret-val.yaml
pod/mypod created
[root@kubernetes-master-001 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
ds-test-7krrv 1/1 Running 0 24h
ds-test-jnxzm 1/1 Running 0 24h
mypod 1/1 Running 0 44s
web-5bb6fd4c98-54ll2 1/1 Running 0 3d1h
web-5bb6fd4c98-585rn 1/1 Running 0 3d1h
5)验证Secret
[root@kubernetes-master-001 ~]# kubectl exec -it mypod bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@mypod:/# echo $SECRET_USERNAME
admin
root@mypod:/# echo $SECRET_PASSWORD
Jinhuino1
2.Secret 以卷挂载pod容器示例
1)删除原有的pod
[root@kubernetes-master-001 ~]# kubectl delete -f secret-val.yaml
pod "mypod" deleted
2)编写Pod文件
#1.编写Pod文件
[root@kubernetes-master-001 ~]# vim secret-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
3)部署Pod
[root@kubernetes-master-001 ~]# kubectl apply -f secret-volume.yaml
pod/mypod created
[root@kubernetes-master-001 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mypod 1/1 Running 0 54s
4)验证Secret
[root@kubernetes-master-001 ~]# kubectl exec -it mypod bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@mypod:/# cd /etc/foo
root@mypod:/etc/foo# ls
password username
root@mypod:/etc/foo# cat password
Jinhuino1root@mypod:/etc/foo# cat username
adminroot@mypod:/etc/foo#
七、dockerconfigjson示例
用来存储私有docker registry的认证信息。
1.创建secret
[root@kubernetes-master-001 ~]# export DOCKER_REGISTRY_SERVER=10.0.0.100
[root@kubernetes-master-001 ~]# export DOCKER_USER=root
[root@kubernetes-master-001 ~]# export DOCKER_PASSWORD=root@123
[root@kubernetes-master-001 ~]# export DOCKER_EMAIL=root@123.com
[root@kubernetes-master-001 ~]# kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
secret/myregistrykey created
2.查看secret
[root@kubernetes-master-001 ~]# kubectl get secrets
NAME TYPE DATA AGE
default-token-668jw kubernetes.io/service-account-token 3 7d21h
myregistrykey kubernetes.io/dockerconfigjson 1 52s
mysecret Opaque 2 3d17h
[root@kubernetes-master-001 ~]# kubectl describe secrets myregistrykey
Name: myregistrykey
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson: 161 bytes
3.创建测试secret
[root@kubernetes-master-001 ~]# vim secret-docker.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: mysecret
spec:
selector:
matchLabels:
app: mysecret
template:
metadata:
labels:
app: mysecret
spec:
containers:
- name: nginx
imagePullSecrets:
- name: myregistrykey