Secret敏感信息存储
介绍
Secret是一种包含少量敏感信息例如密码、令牌或密钥的对象。这样的信息可能会被放在Pod规约种或者镜像中。使用Secret意味着你不需要再应用程序代码中包含机制数据。 由于创建Secret可以独立于使用它们的Pod,因此在创建、查看和编辑Pod的工作流程中暴露Secret(及其数据)的风险较小。Kubernetes和在集群中运行的应用程序也可以对Secret采取额外的预防措施,例如避免讲敏感数据写入非易失性存储。 Secret类似于ConfigMap但专门用来保存机密数据。
一、Secret
1.1、Secret名称与数据的约束
Secret对象的名称必须是合法的DNS子域名。 在为创建Secret编写配置文件时,你可以设置data
与/或stringData
字段。data
和stringData
字段都是可选的。data
字段中国所有键值都必须是base54编码的字符串。如果不希望指定这种base64字符串的转换操作,你可以选择设置stringData
字段,其中可以使用任何字符串作为其取值。 data
和srtingData
中的键名只能包含字母、数据、-
、_
或.
字符。stringData
字段中的所有键值对都会在内部被合并到data
字段中。如果某个主键同时出现在data
和stringData
字段中,stringData
所指定的键值具有高优先级。
1.2、尺寸限制
每个Secret的尺寸最多为1MB。驰加这一限制是为了避免用户创建非常大的Secret,进而导致API服务器和kubelet内存耗尽。不过创建很多小的Secret也可能耗尽内存。你可以使用资源配额来约束每个名称空间中Secret(后其他资源)的个数。
1.3、编辑Secret
你可以编辑一个已有的Secret。除非它是不可变更的。
1.4、可选的Secret
当你在Pod中引用Secret时,你可以将该Secret标记为可选,就像下面的例子中所展示的那样。如果可选的Secret不存在,Kubernetes将忽略它。然后直接创建你要想的资源。
apiVersion : v1
kind : Pod
metadata :
name : mypod
spec :
containers :
- name : mypod
image : redis
volumeMounts :
- name : foo
mountPath : "/etc/foo"
readOnly : true
volumes :
- name : foo
secret :
secretName : mysecret
optional : true
二、Secret创建
本文展示如何安全地将敏感数据(如密码和加密密钥)注入到Pod中。
2.1、将Secret数据转换为base-64形式
假设用户想要两条Secret数据:用户名my-app
和密码39528$vdg7Jb
。首先使用base64编码将用户名和密码转换为base-64形式。下面是一个使用常用的base程序的示例: 以下的base-64的回显结果的形式的用户名为bXktYXBw
,base-64形式的密码为Mzk1MjgkdmRnN0pi
。
[ root@master ~]
bXktYXBw
[ root@master ~]
Mzk1MjgkdmRnN0pi
2.2、创建Secret
这是一个配置文件,可以用来创建存储有用户名和密码的Secret:
[ root@master ~]
apiVersion: "v1"
kind: Secret
metadata:
name: test-secret
type: Opaque
data:
username: bXktYXBw
password: Mzk1MjgkdmRnN0pi
[ root@master ~]
[ root@master ~]
NAME TYPE DATA AGE
test-secret Opaque 2 39s
NAME:Secret存储的名称
TYPE:Secret的类型
DATA:描述Secret存储中有几个数据,一个键表示一个数据
AGE:表示Secret被创建的时间
[ root@master ~]
Name: test-secret
Namespace: default
Labels: < none>
Annotations: < none>
Type: Opaque
Data
== ==
password: 12 bytes
username: 6 bytes
2.3、直接用kubectl创建Secret
如果你希望略过Base64编码的步骤,你也可以使用kubectl create secret
的命令直接创建Secret,例如: 这是一种更为方便的方法。前面展示的详细分解步骤有助于了解究竟发生了什么事情。 你也可以使用前面相同的命令去查询这个secret。(注意名字)
[ root@master ~]
三、引用Secret
注意:以下的所有引用都可能引用刚刚创建的Secret,请先提前准备好Secret存储。
3.1、创建一个可以通过卷访问Secret数据的Pod
[ root@master ~]
apiVersion: "v1"
kind: Pod
metadata:
name: secret-test-pod
spec:
restartPolicy: Always
containers:
- name: test-container
image: nginx:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: secret-volume
mountPath: "/etc/secret-volume"
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: test-secret
[ root@master ~]
[ root@master ~]
NAME READY STATUS RESTARTS AGE
secret-test-pod 1 /1 Running 0 34s
[ root@master ~]
password username
[ root@master ~]
my-app
[ root@master ~]
39528 $vdg7Jb
3.2、映射Secret键到特定的文件路径
你还可以控制卷内Secret键的映射路径。使用.spec.volumes[].secret.items
字段来改变每个键的目标路径
[ root@master ~]
apiVersion: "v1"
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: test-secret
items:
- key: username
path: "my-group/my-username"
- key: password
path: "1/2/3/4/password.conf"
[ root@master ~]
[ root@master ~]
NAME READY STATUS RESTARTS AGE
mypod 1 /1 Running 0 107s
[ root@master ~]
my-username
[ root@master ~]
password.conf
3.3、使用Secret数据定义容器变量
在你的容器中,你可以以环境变量的方式使用Secret中的数据。 如果容器已经使用了在环境变量中的Secret,除非容器重新启动,否则容器将无法感知到Secret的更新。有第三方解决方案可以在Secret该表时触发容器重启。
[ root@master ~]
apiVersion: "v1"
kind: Pod
metadata:
name: env-single-secret
spec:
containers:
- name: envars-test-container
image: nginx:latest
imagePullPolicy: IfNotPresent
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: test-secret
key: username
[ root@master ~]
[ root@master ~]
NAME READY STATUS RESTARTS AGE
env-single-secret 1 /1 Running 0 22s
[ root@master ~]
my-app
3.4、使用来自多个Secret的数据定义环境变量
[ root@master ~]
[ root@master ~]
[ root@master ~]
apiVersion: "v1"
kind: Pod
metadata:
name: envvars-multiple-secrets
spec:
containers:
- name: envars-test-container
image: nginx:latest
imagePullPolicy: IfNotPresent
env:
- name: BACKEND_USERNAME
valueFrom:
secretKeyRef:
name: backend-user
key: backend-username
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-user
key: db-username
[ root@master ~]
[ root@master ~]
NAME READY STATUS RESTARTS AGE
envvars-multiple-secrets 1 /1 Running 0 15s
[ root@master ~]
DB_USERNAME = db-admin
BACKEND_USERNAME = backend-admin
3.5、将Secret中的所有键值对定义为环境变量
说明:此功能在Kubernetes 1.6版本之后可用
[ root@master ~]
apiVersion: "v1"
kind: Pod
metadata:
name: envfrom-secret
spec:
containers:
- name: envars-test-container
image: nginx:latest
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: test-secret
[ root@master ~]
[ root@master ~]
NAME READY STATUS RESTARTS AGE
envfrom-secret 1 /1 Running 0 25s
[ root@master ~]
username: my-app
password: 39528 $vdg7Jb