容器技术
ubuntu使用APT安装docker并指定版本
Helm部署与使用
Helm常用命令
从Helm仓库创建应用流程示例
Helm部署与使用
K8S中部署mysql-ha高可用集群
helm启动mysql-ha
helm几个常用仓库
Kubernetes使用helm部署Mysql-Ha
k8s入门:Helm 构建 MySQL
docker批量修改tag(批量push)
k8s之yaml文件详解
将 MySQL 通过 bitpoke/mysql-operator 部署到 k8s 内部
k8s pvc扩容:pvc创建后扩容
K8S性能分析
部署Metrics Server
Kubernetes集群搭建
kubespray 部署常见问题和优化汇总
kubernetes-sigs/kubespray at release-2.15
K8S-pod配置文件详解
KubeSphere知识库
在 Kubernetes 上最小化安装 KubeSphere
卸载 KubeSphere 和 Kubernetes
KubeSphere 应用商店
修改pod中容器的时区
k8s之Pod安全策略
Harbor 登陆失败,用户名或者密码不正确。405 Not Allowed
Docker-leanote_n1
kubesphere/kubekey
Kubernetes Static Pod (静态Pod)
kubernets kube-proxy的代理 iptables和ipvs - 30岁再次出发 - 博客园
k8s生产实践之获取客户端真实IP - SSgeek - 博客园
kube-proxy ip-tables故障解决
k8s入门:Helm 构建 MySQL
docker批量修改tag(批量push)
prometheus operator 监控redis-exporter
Helm3 安装 ElasticSearch & Kibana 7.x 版本
kubernete强力删除namespace_redis删除namespace命令
EFK (Elasticsearch + Fluentd + Kibana) 日志分析系统
k8s日志收集实战(无坑)
fluentd收集k8s集群pod日志
Elasticsearch+Fluentd+Kibana 日志收集系统的搭建
TKE/EKS之configmap,secret只读挂载
K8s基于Reloader的ConfigMap/Secret热更新
使用 Reloader 实现热部署_k8s reloader
k8s使用Reloader实现更新configmap后自动重启pod
在 Kubernetes 上对 gRPC 服务器进行健康检查 | Kubernetes
Kubernetes ( k8s ) gRPC服务 健康检查 ( livenessProbe ) 与 就绪检查 ( readinessProbe )
排查kubernetes中高磁盘占用pod
helm 安装 MongoDB 集群
helm 安装 Redis 1 主 2 从 3哨兵
【k8s】使用 Reloader 实现热部署
k8s证书过期,更新后kubelet启动失败
kubeadm证书/etcd证书过期处理
三种监控 Kubernetes 集群证书过期方案
K8s 集群(kubeadm) CA 证书过期解决方案
k8s调度、污点、容忍、不可调度、排水、数据卷挂载
5分钟搞懂K8S的污点和容忍度(理论+实战)
Kubernetes进阶-8基于Istio实现微服务治理
macvlan案例配置
快速解决Dockerhub镜像站无法访问问题
info_scan开源漏洞扫描主系统部署
本文档使用 MrDoc 发布
-
+
首页
TKE/EKS之configmap,secret只读挂载
使用eks/tke集群部署服务的时候,很多时候会需要通过configmap或者secret来挂载配置文件到容器里,但是通过configmap或者secret挂载的配置文件,直接登陆容器取进行写操作的时候会提示报错,文件只读,这是怎么回事呢?下面我们来简要分析下。 ```js bash-5.1# echo "aaaaa" > tls.crt bash: tls.crt: Read-only file system ``` ## 1\. 问题现象 这里通过configmap和secret的方式挂载文件到容器内,具体的yaml如下,通过configmap挂载了kubeconfig到/root/.kube文件下,然后通过secret挂载证书到/tmp目录下。 ```js 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](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.8.md) 发现了k8s在1.8版本后,secret, configMap等资源都是只读挂载了。 ```js 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/](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/](https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/config-and-storage-resources/volume/) ```js 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/secret/) [https://kubernetes.io/zh-cn/docs/concepts/configuration/configmap/](https://kubernetes.io/zh-cn/docs/concepts/configuration/configmap/)
adouk
2023年4月24日 09:18
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码