k8s-Secret
k8s 中的 secret 介绍,以及在各种场景中的应用。
Secret 介绍
secret 它是用于管理敏感信息的 api 对象。就类似于程序中的配置文件,在写项目时,对于数据库的用户名和密码都是存放在配置文件中,而不是直接写死在代码中。
secret 把 pod 想要访问的加密数据存放到 etcd 中。然后用户就可以通过在 Pod 的容器里挂载 Volume 的方式或者环境变量的方式访问到这些 Secret 里保存的信息了。
Secret 目前有八种类型,但常用的有以下三种:
- Opaque:base64 编码格式的 Secret,用来存储密码、密钥等;但数据是可以通过base64–decode 解码得到原始数据,所以加密性很弱。
- kubernetes.io/service-account-token:用来存放标识某 serviceAccount 的令牌凭据。当创建 serviceAccount 账户时会自动创建;也可以自己手动创建,但前提是必须先创建了 serviceAccount 对象。
- kubernetes.io/dockerconfigjson: 用来存储私有 docker registry 的认证信息。
Opaque 类型
Opaque 类型的数据是一个 map 类型,要求value是base64编码。
base64加密
$ echo -n 'admin' | base64
YWRtaW4=
$ echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm
解密
$ echo 'MWYyZDFlMmU2N2Rm' | base64 --decode
1f2d1e2e67df
这里需要注意的是,像这样创建的 Secret 对象,它里面的内容仅仅是经过了转码,而并没有被加密。在真正的生产环境中,你需要在 Kubernetes 中开启 Secret 的加密插件,增强数据的安全性。
kubernetes.io/service-account-token 类型
Service Account 对象的作用,就是 Kubernetes 系统内置的一种“服务账户”,它是 Kubernetes 进行权限分配的对象。比如, Service Account A,可以只被允许对 Kubernetes API 进行 GET 操作,而 Service Account B,则可以有 Kubernetes API 的所有操作权限。
Secret 用来存放标识某 serviceAccount 的令牌凭据。
使用这种 Secret 类型时,应该先创建 ServiceAccount 对象,然后将 serviceAccount 的name 放到该 secret 注解 kubernetes.io/service-account-name 中。
如果不知道什么是 serviceAccount ,那就说明这个东西对目前的我们没用,之后会介绍到。
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 创建
kubectl create secret 命令
username.txt和password.txt文件内容如下:
$ 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 文件创建
#secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
user: YWRtaW4=
pass: MWYyZDFlMmU2N2Rm
kubectl create -f secret.yaml
secret使用
通过Volume挂载的方式
# 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
通过环境变量
#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
volume 挂载 和 环境变量的区别
通过Volume挂载到容器内部时,当该Secret的值发生变化时,容器内部具备自动更新的能力;
但是通过环境变量设置到容器内部该值不具备自动更新的能力。所以一般推荐使用Volume挂载的方式使用Secret。
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 不区分类型
secret volume 用于将敏感信息(密码)传递给 pod。可以将 secrets 存储在 k8s API 中,使用的时候以文件的形式挂载到 pod 中,而不用连接 api。
secret 最典型的场景,莫过于存放数据库的 Credential 信息,如:
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 中,它声明挂载的 Volume 是 projected 类型。而这个 Volume 的数据来源(sources),则是名为 user 和 pass 的 Secret 对象,分别对应的是数据库的用户名和密码。
这里用到的数据库的用户名、密码,正是以 Secret 对象的方式交给 Kubernetes 保存的。完成这个操作的指令,如下所示:
$ cat ./username.txt
admin
$ cat ./password.txt
c1oudc0w!
$ kubectl create secret generic user --from-file=./username.txt
$ kubectl create secret generic pass --from-file=./password.txt
其中,username.txt 和 password.txt 文件里,存放的就是用户名和密码;而 user 和 pass,是 Secret 对象指定的名字。
查看 Secret 对象的话,执行 kubectl get 命令:
$ kubectl get secrets
NAME TYPE DATA AGE
user Opaque 1 51s
pass Opaque 1 51s
除了使用 kubectl create secret 指令外,也可以直接通过编写 YAML 文件的方式来创建这个 Secret 对象,比如:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
user: YWRtaW4=
pass: MWYyZDFlMmU2N2Rm
END
更多推荐
所有评论(0)