Secret介绍
k8s secrets用于存储和管理一些敏感数据,比如密码,token,密钥等敏感信息。它把 Pod 想要访问的加密数据存放到 Etcd 中。然后用户就可以通过在 Pod 的容器里挂载 Volume 的方式或者环境变量的方式访问到这些 Secret 里保存的信息了。
Secret有三种类型
Opaque:base64 编码格式的 Secret,用来存储密码、密钥等;但数据也可以通过base64 –decode解码得到原始数据,所有加密性很弱。
Service Account:用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的 /run/secrets/kubernetes.io/serviceaccount 目录中。
kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。
1. Opaque类型
Opaque 类型的数据是一个 map 类型,要求value是base64编码。
手动创建base64加密
$ echo -n 'admin' | base64
YWRtaW4=
$ echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm
解密
$ echo 'MWYyZDFlMmU2N2Rm' | base64 --decode
1f2d1e2e67df
这里需要注意的是,像这样创建的 Secret 对象,它里面的内容仅仅是经过了转码,而并没有被加密。在真正的生产环境中,你需要在 Kubernetes 中开启 Secret 的加密插件,增强数据的安全性。
2. Service Account类型
Service Account 对象的作用,就是 Kubernetes 系统内置的一种“服务账户”,它是 Kubernetes 进行权限分配的对象。比如,Service Account A,可以只被允许对 Kubernetes API 进行 GET 操作,而 Service Account B,则可以有 Kubernetes API 的所有操作权限。
3. kubernetes.io/dockerconfigjson类型
用来创建用户docker registry认证的Secret,直接使用kubectl create命令创建即可,如下:
kubectl create secret docker-registry myregistry --docker-server=DOCKER_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
如果我们需要拉取私有仓库中的docker镜像的话就需要使用到上面的myregistry这个Secret:
apiVersion: v1
kind: Pod
metadata:
name: foo
spec:
containers:
- name: foo
image: 192.168.1.100:5000/test:v1
imagePullSecrets:
- name: myregistry
Secret创建及使用方法
1.Secret创建方式
方式一: kubectl create secret 命令
username.txt 账户名和 password.tx 密码 文件内容如下:
$ cat ./username.txt
admin
$ cat ./password.txt
1f2d1e2e67df
generic子命令可以通过本地文件、目录或者literal(键值对)
$ kubectl create secret generic user --from-file=./username.txt
$ kubectl create secret generic pass --from-file=./password.txt
默认情况下key为文件名或者直接通过键值对创建
$ kubectl create secret generic user --from-literal=username=admin
$ kubectl create secret generic pass --from-literal=password=1f2d1e2e67df
方式二: 通过yaml文件创建
vi secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
user: YWRtaW4=
pass: MWYyZDFlMmU2N2Rm
注:通过yaml创建Opaque类型的Secret值需要base64编码
创建secret
kubectl create -f secret.yaml
2.secret使用
方式一:通过Volume挂载的方式
vi test-projected-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-projected-volume
spec:
containers:
- name: test-secret-volume
image: busybox
args:
- sleep
- "86400"
volumeMounts:
- name: mysql-cred
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: mysql-cred
projected:
sources:
- secret:
name: user
- secret:
name: pass
创建pod对象
$ kubectl create -f test-projected-volume.yaml
当 Pod 变成 Running 状态之后,我们再验证一下这些 Secret 对象是不是已经在容器里了:
$ kubectl exec -it test-projected-volume -- /bin/sh
$ ls /projected-volume/
user
pass
$ cat /projected-volume/user
admin
$ cat /projected-volume/pass
1f2d1e2e67df
方式二:通过环境变量
vi pod-secret-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-secret-env
spec:
containers:
- name: myapp
image: busybox
args:
- sleep
- "86400"
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: user
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: pass
restartPolicy: Never
创建pod
$kubectl create -f pod-secret-env.yaml
pod运行成功后:
$ kubectl exec -it pod-secret-env -- /bin/sh
进入容器中查看环境变量
通过volume挂载和环境变量的区别:
通过Volume挂载到容器内部时,当该Secret的值发生变化时,容器内部具备自动更新的能力,但是通过环境变量设置到容器内部该值不具备自动更新的能力。所以一般推荐使用Volume挂载的方式使用Secret。
Secret 与 ConfigMap 对比,最后我们来对比下Secret和ConfigMap这两种资源对象的异同点:
相同点:
key/value的形式
属于某个特定的namespace
可以导出到环境变量
可以通过目录/文件形式挂载
通过 volume 挂载的配置信息均可热更新
不同点:
Secret 可以被 ServerAccount 关联
Secret 可以存储 docker register 的鉴权信息,用在 ImagePullSecret 参数中,用于拉取私有仓库的镜像
Secret 支持 Base64 加密
Secret 分为 kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque 三种类型,而 Configmap 不区分类型