k8s使用volume将ConfigMap作为文件或目录直接挂载_【大强哥-k8s从入门到放弃06】Secret详解...

468e04551456f816764fcdb5fc25c36a.png

1、secret介绍

secret用来保存小片敏感数据的k8s资源,例如密码,token,或者秘钥。这类数据当然也可以存放在Pod或者镜像中,但是放在Secret中是为了更方便的控制如何使用数据,并减少暴露的风险。

用户可以创建自己的secret,系统也会有自己的secret。

Pod需要先引用才能使用某个secret

Pod有2种方式来使用secret:

  1. 作为volume的一个域被一个或多个容器挂载
  2. 在拉取镜像的时候被kubelet引用。

2、secret类型

內建的Secrets:

由ServiceAccount创建的API证书附加的秘钥
k8s自动生成的用来访问apiserver的Secret,所有Pod会默认使用这个Secret与apiserver通信

创建自己的Secret:

方式1:使用kubectl create secret命令
方式2:yaml文件创建Secret

3、创建secret

3.1、命令方式创建secret

假如某个Pod要访问数据库,需要用户名密码,分别存放在2个文件中:username.txt,password.txt

例子

# echo -n 'admin' > ./username.txt
# echo -n '1f2d1e2e67df' > ./password.txt

kubectl create secret指令将用户名密码写到secret中,并在apiserver创建Secret

# kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt

secret "db-user-pass" created

查看创建结果

# kubectl get secrets
NAME                TYPE                    DATA    AGE

db-user-pass      Opaque                    2       51s
注:
opaque:英[əʊˈpeɪk] 美[oʊˈpeɪk] 模糊
# kubectl describe secrets/db-user-pass

Name:       db-user-pass

Namespace:    default

Labels:      <none>

Annotations:   <none>

Type:       Opaque
Data
====
password.txt:   12 bytes
username.txt:   5 bytes

get或describe指令都不会展示secret的实际内容,这是出于对数据的保护的考虑,如果想查看实际内容使用命令:

# kubectl get secret db-user-pass -o json

3.2、yaml方式创建Secret

创建一个secret.yaml文件,内容用base64编码

# echo -n 'admin' | base64
YWRtaW4=

# echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm

yaml文件内容

# vim secret.yaml

创建

# kubectl create -f ./secret.yaml

secret "mysecret" created

解析Secret中内容

# kubectl get secret mysecret -o yaml

4、使用Secret

secret可以作为数据卷挂载或者作为环境变量暴露给Pod中的容器使用,也可以被系统中的其他资源使用。比如可以用secret导入与外部系统交互需要的证书文件等。

4.1、在Pod中以文件的形式使用secret

创建一个Secret,多个Pod可以引用同一个Secret

修改Pod的定义,在spec.volumes[]加一个volume,给这个volume起个名字,spec.volumes[].secret.secretName记录的是要引用的Secret名字

在每个需要使用Secret的容器中添加一项spec.containers[].volumeMounts[],指定spec.containers[].volumeMounts[].readOnly = true,spec.containers[].volumeMounts[].mountPath要指向一个未被使用的系统路径。

修改镜像或者命令行使系统可以找到上一步指定的路径。此时Secret中data字段的每一个key都是指定路径下面的一个文件名

一个Pod中引用Secret的列子:

# vim pod_use_secret.yaml

每一个被引用的Secret都要在spec.volumes中定义

如果Pod中的多个容器都要引用这个Secret那么每一个容器定义中都要指定自己的volumeMounts,但是Pod定义中声明一次spec.volumes就好了。

4.2、映射secret key到指定的路径

可以控制secret key被映射到容器内的路径,利用spec.volumes[].secret.items来修改被映射的具体路径

apiVersion

发生了什么呢?

username被映射到了文件/etc/foo/my-group/my-username而不是/etc/foo/username

而password没有被使用,这种方式每个key的调用需要单独用key像username一样调用

4.3、Secret文件权限

可以指定secret文件的权限,类似linux系统文件权限,如果不指定默认权限是0644,等同于linux文件的-rw-r--r--权限

设置默认权限位

apiVersion

上述文件表示将secret挂载到容器的/etc/foo路径,每一个key衍生出的文件,权限位都将是0400

这里用十进制数256表示0400,可以使用八进制0400

同理可以单独指定某个key的权限

apiVersion

从volume中读取secret的值

以文件的形式挂载到容器中的secret,他们的值已经是经过base64解码的了,可以直接读出来使用。

# ls /etc/foo/
username
password

# cat /etc/foo/username
admin

# cat /etc/foo/password
1f2d1e2e67df

4.4、secret扩展内容

被挂载的secret内容自动更新

也就是如果修改一个Secret的内容,那么挂载了该Secret的容器中也将会取到更新后的值,但是这个时间间隔是由kubelet的同步时间决定的。最长的时间将是一个同步周期加上缓存生命周期(period+ttl)

特例:以subPath(https://kubernetes.io/docs/concepts/storage/volumes/#using-subpath)形式挂载到容器中的secret将不会自动更新

以环境变量的形式使用Secret

创建一个Secret,多个Pod可以引用同一个Secret

修改pod的定义,定义环境变量并使用env[].valueFrom.secretKeyRef指定secret和相应的key

修改镜像或命令行,让它们可以读到环境变量

变量名:admin(secretkey(mysecret-->username=admin))

apiVersion

容器中读取环境变量,已经是base64解码后的值了:

# echo $SECRET_USERNAME
admin

# echo $SECRET_PASSWORD
1f2d1e2e67df

使用imagePullSecrets

创建一个专门用来访问镜像仓库的secret,当创建Pod的时候由kubelet访问镜像仓库并拉取镜像,具体描述文档在 这里

设置自动导入的imagePullSecrets

可以手动创建一个,然后在serviceAccount中引用它。所有经过这个serviceAccount创建的Pod都会默认使用关联的imagePullSecrets来拉取镜像,参考文档

自动挂载手动创建的Secret

参考文档:https://kubernetes.io/docs/tasks/inject-data-application/podpreset/

限制

需要被挂载到Pod中的secret需要提前创建,否则会导致Pod创建失败

secret是有命名空间属性的,只有在相同namespace的Pod才能引用它

单个Secret容量限制的1Mb,这么做是为了防止创建超大的Secret导致apiserver或kubelet的内存耗尽。但是创建过多的小容量secret同样也会耗尽内存,这个问题在将来可能会有方案解决

kubelet只支持由API server创建出来的Pod中引用secret,使用特殊方式创建出来的Pod是不支持引用secret的,比如通过kubelet的--manifest-url参数创建的pod,或者--config参数创建的,或者REST API创建的。

通过secretKeyRef引用一个不存在你secret key会导致pod创建失败

用例

Pod中的ssh keys

创建一个包含ssh keys的secret

kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub

创建一个Pod,其中的容器可以用volume的形式使用ssh keys

kind

Pod中区分生产和测试证书

创建2种不同的证书,分别用在生产和测试环境

# kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
secret "prod-db-secret" created

# kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
secret "test-db-secret" created

再创建2个不同的Pod

apiVersion

两个容器中都会有下列的文件

/etc/secret-volume/username
/etc/secret-volume/password

以“.”开头的key可以产生隐藏文件

kind

会在挂载目录下产生一个隐藏文件,/etc/secret-volume/.secret-file

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值