TKE/EKS之configmap,secret只读挂载
使用eks/tke集群部署服务的时候,很多时候会需要通过configmap或者secret来挂载配置文件到容器里,但是通过configmap或者secret挂载的配置文件,直接登陆容器取进行写操作的时候会提示报错,文件只读,这是怎么回事呢?下面我们来简要分析下。
bash-5.1# echo "aaaaa" > tls.crt
bash: tls.crt: Read-only file system
1. 问题现象
这里通过configmap和secret的方式挂载文件到容器内,具体的yaml如下,通过configmap挂载了kubeconfig到/root/.kube文件下,然后通过secret挂载证书到/tmp目录下。
apiVersion: apps/v1
kind: Deployment
Metadata:
labels:
k8s-app: a-kubectl
qcloud-app: a-kubectl
name: a-kubectl
namespace: weixnie
spec:
replicas: 1
selector:
matchLabels:
k8s-app: a-kubectl
qcloud-app: a-kubectl
template:
Metadata:
labels:
k8s-app: a-kubectl
qcloud-app: a-kubectl
spec:
containers:
- command:
- sleep
- 360d
image: mohamedltaief/kubctl-helm:latest
imagePullPolicy: Always
name: a-kubectl
resources: {}
securityContext:
privileged: false
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /root/.kube/config
name: vol
subPath: config
- mountPath: /tmp
name: vol1
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: qcloudregistrykey
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- configMap:
defaultMode: 511
name: kubectl-config
name: vol
- name: vol1
secret:
defaultMode: 420
secretName: tls-secret
pod启动正常后,登陆容器修改对应的挂载文件,会报错bash: xxxx: Read-only file system
从上面测试结果看,执行用户是root,而且文件的权限也是777,为什么写文件就提示文件只读呢?
2. 原因分析经过翻阅资料,https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.8.md
发现了k8s在1.8版本后,secret, configMap等资源都是只读挂载了。
Changes secret, configMap, downwardAPI and projected volumes to mount read-only, instead of allowing applications to write data and then reverting it automatically. Until version 1.11, setting the feature gate ReadOnlyAPIDataVolumes=false will preserve the old behavior. (#58720, @joelsmith)
那么这个只读挂载是如何实现的呢?这里简要的翻了下docker的文档https://docs.docker.com/storage/bind-mounts/
,发现在挂载的时候是可以指定参数来指定容器内挂载点是否只读。
这里我们登陆节点,查看下pod对应的容器挂载选项是怎么样的
从查看容器的详细信息看,挂载配置都是设置的只读,那么说明k8s里面通过secret和configmap挂载到容器内的文件都是只读的。即使你给文件设置的权限是777,但是docker底层的挂载参数决定了你的挂载文件在容器内的是否只读。
但是细心的人会发现,在yaml里面volume有个defaultMode字段,这个也是决定挂载到容器内文件的权限的,那么这个有什么作用呢?首先可以看下这个字段的解释说明https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/config-and-storage-resources/volume/
defaultMode 是可选的:默认情况下,模式位用于为已创建的文件设置权限。 必须是 0000 到 0777 之间的八进制值或 0 到 511 之间的十进制值。 YAML 既接受八进制值也接受十进制值,JSON 针对模式位需要十进制值。此字段默认为 0644。 路径内的目录不受此设置的影响。这可能与影响文件模式的其他选项(如 fsGroup)有冲突,且结果可以是其他模式位也被设置。
这个字段是来给容器内通过configmap和secret挂载的文件设置权限的,支持10进制和8进制的设置,如果8进制设置,就和linux文件权限设置一样,0000-0777,r的权限是4,w的权限2,x权限是1,如果是10进制的话,值就是0-511,需要转换下,511转换为8进制就是0777。
其实defaultMode最主要作用还是给文件设置权限,让容器内的启动用户能有足够权限读取这个文件,但是还是无法进行写操作,即使给了写权限,因为docker底层挂载设置了只读,也就是说,这里是否设置写权限,都不重要,因为都不会生效。
3. 解决方案这里如果通过secret或者configmap挂载配置文件到容器内,如果要更新配置,当前只能更新configmap或secret,一般修改了configmap和secret后,k8s会自动更新容器内的数据。但是如果是subPath的方式挂载,就无法自动更新,需要重建pod更新才行。
https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/
https://kubernetes.io/zh-cn/docs/concepts/configuration/configmap/
原文地址:https://cloud.tencent.com/developer/article/2045940
总结以上是真正的电脑专家为你收集整理的TKE/EKS之configmap,secret只读挂载的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得真正的电脑专家网站内容还不错,欢迎将真正的电脑专家推荐给好友。