理解OpenShift(5):从 Docker Volume 到 OpenShift Persistent Volume

理解OpenShift(1):网络之 Router 和 Routehtml

理解OpenShift(2):网络之 DNS(域名服务)node

理解OpenShift(3):网络之 SDNlinux

理解OpenShift(4):用户及权限管理git

理解OpenShift(5):从 Docker Volume 到 OpenShift Persistent Volumegithub

 

** 本文基于 OpenShift 3.11,Kubernetes 1.11 进行测试 ***docker

1. 从 Docker Volume 到 OpenShift/Kubernetes Persistent Volume

1.1 Docker 容器层(Container layer)

Docker 镜像是不可修改的。使用一Docker 镜像启动一个容器实例后,Docker 会在镜像层之上添加一个可读写的容器层(Container layer)。容器中全部新增或修改的数据都保存在该容器层之中。在容器实例被删除后,该层也会随之被自动删除,所以全部写入的或修改的数据都会丢失。具体可阅读Docker 相关文档,好比 https://docs.docker.com/v17.09/engine/userguide/storagedriver/imagesandcontainers/ubuntu

1.2 Docker Volume

在容器的可写层中保存数据是可能的,可是有一些缺点:后端

  • 当容器实例不在运行时,数据不会被保存下来,所以数据是易失性的,不是持久性的。
  • 很难将容器中的数据弄到容器外面,若是其它进行须要访问它的话。
  • 容器的可写层和容器所在的宿主机紧耦合,数据没法被移动到其它宿主机上。
  • 向容器的可写层中写入数据须要经过存储驱动(storage driver,好比AUFS,Brtfs,OverlayFS等)来管理文件系统。存储驱动利用Linux内核提供联合文件系统(union file system),这会下降IO性能。

为了解决以上问题,Docker 提供了 Volume (卷)功能。本质上,一个数据卷(data volume)是 Docker 容器所在宿主机上的一个目录或文件,它被挂载(mount)进容器。Docker 卷具备本身独立的生命周期,可使用 Docker volume 命令独立地被建立和管理。在容器实例被删除后,卷依然存在,所以卷中的数据会被保留,从而实现数据持久化。并且,数据卷直接将数据写入宿主机文件系统,性能相比容器的可写层有提升。centos

Docker 提供三种方式将宿主机文件或文件夹挂载到容器中:bash

  • volume(卷):卷保存在宿主机上由Docker 管理的文件系统中,一般在 /var/lib/docker/volumes/ 目录下。
  • bind mount(绑定挂载):被挂载的文件或文件夹能够在宿主机上文件系统的任何地方。
  • tmpfs volume:数据保存在宿主机内存中,而不写入磁盘。

 

三种方式各自有合适的场景,一般建议使用 Docker Volume。Docker Volume 还支持经过各类卷插件(volume plugin),接入各类外置存储。本质上,都是存储插件将存储的卷挂载到Docker宿主机上的某个目录,而后Docker 将目录在挂载给容器。

 

更详细信息,请阅读 https://docs.docker.com/v17.09/engine/admin/volumes/#good-use-cases-for-tmpfs-mounts 等官方文档。

1.3 Kubernetes/OpenShift Volume

OpenShift 利用 Kubernetes 的存储机制来实现其 Volume 功能。和Docker volume 概念相似,本质上,一个 K8S Volume 也是一个能被Pod 中的容器访问的目录。至于该目录是怎么来的,后端介质是什么,内容是什么,则是由所使用的具体卷类型(volume type)决定的。Kubernetes Volume 支持多种存储类型:

关于 K8S Volume 概念的更多信息,请阅读相关文档。

1.3.1 K8S NFS Volume 示例

下面以 Glusterfs Volume 为例介绍 K8S Volume 的使用:

(1)OpenShift 管理员在集群中建立一个 endpoints 对象,指向 Glusterfs 服务器的 IP 地址。在个人测试环境中,由两台服务器提供Glusterfs服务。

(2) 存储管理员在 Glusterfs 上建立卷 glustervol1.
(3) 开发工程师 建立一个 pod,使用 glusterfs 类型的 volume。 
(4)Pod 运行后,OpenShift 会先将 Glusterfs 卷挂载到宿主机上 ,成为宿主机上的一个目录
172.20.80.7:glusterfsvol1 on /var/lib/origin/openshift.local.volumes/pods/bd8914b5-00d9-11e9-a6cf-fa163eae8505/volumes/kubernetes.io~glusterfs/glustervol1 type fuse.glusterfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072)

(5)而后,宿主机上的这个目录会经过 Docker bind mounted 挂载进容器 

(6)Pod 中的进程使用所挂载的 /var/volume 目录进行数据读写。

1.3.2 K8S/OpenShfit Volume 使用方式总结

从上面过程能够看出,使用卷的过程须要至少有存储工程师和开发人员。要使用某种卷,开发人员须要了解后端存储的具体配置信息。  

可是实际上,存储信息对于应用开发人员来讲,实际上是不须要可见的。他们只关心有没有知足要求的存储可用,而不须要关心后端是什么存储。

为了解耦存储供给和存储使用(pod中的存储定义),Kubernetes 建立了两个概念:PV (Persistent Volume)和 PVC (Persistent Volume Claim)这些概念。

1.4 Kubernetes/OpenShift Persistent Volume

1.4.1 概念

  • PV:Persistent Volume。由 OpenShfit 管理员建立,后端是各类类型的存储,好比 AWS EBS,GCE Disk,NFS 等。管理员能够建立多个PV,造成一个存储池,供开发人员使用。
  • StorageClass:在须要动态建立 PV 时由 OpenShfit 管理员建立。 管理员利用 StorageClass 来描述他们所提供的存储的类型(classes)。Storage class 向管理员提供了一种方式,用于描述他们所提供的存储的信息。不一样的class 可映射到不一样的 SLA,备份策略,等等。每一个 StorageClass 包括 provisoner、parameters、reclaimPolicy 字段。
  • PVC:Persistent Volume Claim。由开发人员建立,一个实例表示对某种存储资源的一个申请。每当开发人员建立一个新的PVC后,Kubernetes 会在已有的PV 池中进行搜索,找到一个最佳匹配的PV 来使用。PVC 中只包含通用的存储需求,好比访问模式(AccessModes)、容量(request)等,而不须要关心后端存储的具体信息。 Pod 经过 PVC 使用 PV,PV 由实际的存储系统提供物理存储。

以 Glusterfs 为例,这是各类概念之间对照图(来源: http://blog.leifmadsen.com/blog/2017/09/19/persistent-volumes-with-glusterfs/):

根据 PV 的不一样建立方式,又能够分为静态建立PV 和 动态建立PV两种方式。前面一种PV由OpenShift 管理员手工建立,后者一种的PV由系统自动建立。具体可参考后面的两个例子。

1.4.2 PV 的生命周期

PV 的生命周期包括四大部分:
  • 供给:分为静态供给和动态供给。
    • 静态供给是指管理员会预先建立好必定数目的PV,每一个PV 包含供集群使用的真实后端存储的详细信息,这些PV造成一个持久化卷的资源池。
    • 动态供给是集群管理员预先建立 StorageClass,而后PVC申请StorageClass,而后集群会动态建立PV,供PVC消费。  动态卷供给是 Kubernetes独有的功能,这一功能容许按需建立存储建。在此以前,集群管理员须要事先在集群外由存储提供者或者云提供商建立存储卷,成功以后再建立PersistentVolume对象,才可以在kubernetes中使用。动态卷供给能让集群管理员没必要进行预先建立存储卷,而是随着用户需求进行建立。
  • 绑定:用户在部署容器应用时会定义PVC,其中会声明所需的存储资源的特性,如大小和访问方式。K8S 的一个控制器(controller)会负责在PV 资源池中寻找匹配的PV,并将PVC与目标PV 进行对接。这是PV和PVC的状态将变成 Bound,即绑定状态。PV 和 PVC 之间的绑定是1:1的,这意味着PVC对PV的占据是独占的、排它的。
  • 使用:Pod 经过使用 PVC 来经过卷(volume)来使用后端存储(storage)资源。Pod 和它要使用的 PVC 必须在同一个 project 中。
    • 集群为 pod 在同一个 project 中定位到 PVC。
    • 经过 PVC 找到 PV。若是没找到且存在合适的StorageClass,则自动建立一个PV。
    • 存储卷挂载到宿主机,而后被 pod 使用。
  • 释放:当应用再也不使用存储时,能够删除PVC,此时PV的状态为 released,即释放。Kubernetes 支持使用保护模式(Storage Object in Use Protection)。当该功能启用后,若是用户删除被一个正被pod 使用着的 PVC,该 PVC 不会立刻被删除,而是会推迟到 pod 再也不使用该PVC时。若是用户删除PV,它也不会被立刻删除,而是会等到该PV再也不绑定到PVC 的时候。是否启用了该保护,能够从 PV 和 PVC 的 finalizers:   - kubernetes.io/pvc-protection 上看出来。
  • 回收:当 PV 的状态变为 released,K8S 会根据 PV 定义的回收策略回收持久化卷。
    • retain:保留数据,人工回收持久化卷。
    • recycle:经过执行 rm -rf 删除卷上全部数据。目前只有 NFS 和 host path 支持。
    • delete:动态地删除后端存储。须要底层 iaas 支持,目前 AWS EBS,GCE PD 和 OpenStack Cinder 支持。 

2. 静态建立PV示例及Volume 权限(以NFS为例)

2.1 静态建立PV的流程

(1)存储管理员准备 NFS 环境

网上有不少关于NFS安装步骤的文章,这里再也不重复。个人测试环境上,NFS 服务器的IP 地址为 172.20.80.4,它暴露了三个文件夹供客户端使用:

 

(2)OpenShift 管理员建立 PV, 后端使用上述 NFS 存储的 

(3)开发人员建立一个 PVC,使用上一步骤中建立的PV。该 PVC实例会存在于某个project 之中,而PV则是在集群范围内共享的。

(4)NFS folder4 文件夹被挂载到Pod 所在的宿主机上。

172.20.80.4:/mnt/folder4 on /var/lib/origin/openshift.local.volumes/pods/863e9b2d-01a0-11e9-a6cf-fa163eae8505/volumes/kubernetes.io~nfs/pv-folder4-2 type nfs4 (rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=172.22.122.8,local_lock=none,addr=172.20.80.4)

(5)宿主机上的目录被 bind mounted 给容器,成为其 /var/volume 文件夹。

2.2 Pod volume 权限

2.2.1 NFS 权限控制

每种存储后端都有其本身的权限管理方式。在NFS 中,在 /etc/exports 文件中国年,可使用如下原语来设置每一个将被共享出来的文件夹的权限:

  • 读写模式
    •   ro:共享目录只读;
    •   rw:共享目录可读可写;
  • 用户管理
    •   all_squash:全部访问用户都映射为匿名用户或用户组;
    •   no_all_squash(默认):访问用户先与本机用户匹配,匹配失败后再映射为匿名用户或用户组;
    •   root_squash(默认):未来访的root用户映射为匿名用户或用户组;
    •   no_root_squash:来访的root用户保持root账号权限;
    •   anonuid=<UID>:指定匿名访问用户的本地用户UID,默认为nfsnobody(65534);
    •   anongid=<GID>:指定匿名访问用户的本地用户组GID,默认为nfsnobody(65534);
  • 端口管理
    •   secure(默认):限制客户端只能从小于1024的tcp/ip端口链接服务器;
    •   insecure:容许客户端从大于1024的tcp/ip端口链接服务器;
  • 数据写入方式
    •   sync:将数据同步写入内存缓冲区与磁盘中,效率低,但能够保证数据的一致性;
    •   async:将数据先保存在内存缓冲区中,必要时才写入磁盘;
    •   wdelay(默认):检查是否有相关的写操做,若是有则将这些写操做一块儿执行,这样能够提升效率;
    •   no_wdelay:如有写操做则当即执行,应与sync配合使用;
  • 文件夹权限
    •   subtree_check(默认) :若输出目录是一个子目录,则nfs服务器将检查其父目录的权限;
    •   no_subtree_check :即便输出目录是一个子目录,nfs服务器也不检查其父目录的权限,这样能够提升效率;

NFS 用户认证及权限控制基于 RPC。在 NFS 3 和 4 版本中,最经常使用的认证机制是 AUTH_Unix。客户端系统上的 uid 和 gid 经过 RPC 调用传到 NFS 端,而后这些 id 所拥有的权限会被校验,以肯定可否访问目标资源。所以,客户端和服务器端上的 uid 和 gid 必须相同。同时,可使用一些设置来作特定处理:

  • all_squash:将全部用户和组都映射为匿名用户和组。默认为 nfsnobody 用户(id 为 65534)和 nfsnodbody 组(id 为 65534)。也能够经过 anonuid 和 anongid 指定。
  • no_all_squash:访问用户先与本机用户经过 id 进行匹配,若是有 id 相同的用户则匹配成功,若匹配失败后再映射为匿名用户或用户组。这是默认选项。
  • root_squash:未来访的 root 用户(id 为 0)映射为匿名用户。这是默认选型,可使用 no_root_squash 不进行这种映射,而保持为 root 用户。

在咱们当前的例子中,folder4 的文件夹权限为 /mnt/folder4 172.22.122.0/24(insecure,rw,sync,no_root_squash,no_all_squash)。这表示它:

  • 容许 172.22.122.0/24 网段的客户端访问(备注:这个网段其实是宿主机所在的网段,而不是Pod 网段,由于 NFS 其实是被挂载给宿主机的,而后再 bind mount 给容器的)。
  • insecure:容许经过端口号大于 1024 的 tcp 链接访问它。
  • no_root_squash:保持客户端 root 用户,将其映射为服务器端 root 用户。理论上这是一种危险的配置。
  • no_all_squash:先将经过 PRC 传入的 uid 和 gid 在本地进行匹配。成功则使用 NFS 服务器上的同id 的用户或组;不然使用匿名用户或组。

NFS 上的 folder4 的目录权限为:drwxr--r-x 2 nfsnobody nfsnobody 4096 Dec 17 10:11 folder4。这意味着 nfsnobody 用户能够对它作读写,其它用户(包括nfsnobody组内的用户和其它用户)都只能读。

Pod 中的用户 id 为:uid=1001(default) gid=0(root) groups=0(root)。

查询共享目录OK。

写入失败:Permission denied。这是由于本地用户 uid 1001 在 NFS 服务器上有匹配的用户 (cloud-user2:x:1001:1001::/home/cloud-user2:/bin/bash),而该用户并无 folder4 文件夹写权限。

2.2.2 几种权限作法

从上面对 NFS 权限控制原理的分析能够看出有几种方式来保证Pod 中的用户的写入成功。

(1)将 NFS 暴露出来的文件夹的全部者修改成 nfsnobody:nfsnobody,而后在文件夹上设置 all_squash,这会将全部客户端 uid 和 gid 映射为NFS服务器端的 nfsnobody 用户和 nfsnobdy 组。

在 pod 中的 id: uid=1001(default) gid=0(root) groups=0(root)

在 pod 中写入文件,而后在 NFS 上查看:

可见是uid 和 gid 都是映射成功了的。

(2)上述方法一将全部客户端的用户都映射为 nfsnobody:nfsnobody,这有了统一性,可是也消灭了独特性。有时候还须要保留客户端上的已知uid。此时会在 NFS 共享的文件夹上设置 no_all_squash,这样会先作匹配找到两地都有的user,匹配不成功则走步骤(1)中的作法。

这种状况下,若是匹配成功,则NFS 会对服务器端的同 uid 和 gid 的用户的权限进行校验。一般状况下,NFS 服务器端匹配到的用户不会是 nfsnobdy,根据文件夹上的权限设置,此时Pod 中是没法写入文件的。这就是 2.2.1 中说描述的场景的结果。此时有两种处理方式:

(a)将文件夹上 other user 加上写权限。这种作法比较简单粗暴,权限暴露过大,不推荐使用。

chmod o+w folder5 -R

(b)使用 supplemental group id

Linux 系统中, supplemental group ID 是进程所拥有的附加组的一个集合。在 Linux 上,文件系统的用户(user)、组(group)的 ID,连同辅助组(supplementary group)的ID,一块儿肯定对文件系统的操做权限,包括打开(open)、修改全部者(change ownership)、修改权限(permission)。具体请阅读相关 Linux 文档。

首先修改NFS 文件夹的 gid 为某个数值,好比下面的命令修改gid为 2000(这里其实是 gid,不是 supplemental gid。gid 对文件夹有意义,而 supplemental gid 对文件夹无心义而对进程有意义)。

chown :2000 folder4 -R

而后在 pod 上进行配置,使得 Pod 中的主进程的辅助组id 为这里所设置的gid。

2.2.3 设置Pod 中主进程的 uid 和 supplemental gid

(1)Pod 的 uid,gid 和 supplemental gid

Kubernets 目前还不支持设置 gid,所以全部 pod 中运行主进程的 gid 都是 0。

对一个非 cluster admin role 用户启动的 pod,它的默认 service account  为 restricted。它要求 uid 必须在指定的区间内,而它本身并无指定用户id 区间:

此时 pod 的 uid 区间受pod 所在的 project 上的定义的相应 annotation 限制:

此时pod 中的 uid 和 suppenmental gid 以下图所示:(备注:与前面的例子中的 uid 不一样,是由于前面的 pod 是 cluster admin user 启用的,所以 pod 的 scc 为 anyuid):

在不显式指定 uid 和 supplemental gid 的状况下,会使用区间的最小值做为默认值。

(2)修改 Pod 的 uid

根据前面对 NFS 权限管理的分析,能够将 Pod 中的 uid 修改成 nfsnobody 对应的 uid,这样Pod 就会具备 NFS 共享目录的写入权限。可是,默认的 nfsnobdy 的 uid 为 65534,这个 uid 并不在service account restricted 容许的 uid 区间 [1000000000, 1000009999] 以内,所以没法将 uid 设置为 65534.

此时,能够基于 restricted scc 建立一个新的 scc,别的配置不变,除了将 RunAsUser 策略修改成 RunAsAny 之外。此时,就能够在 Pod 中指定 uid 为 65534 了。

新的scc:

 

pod 中指定 uid:

   

pod 的 uid:

挂载的文件夹可写。操做成功。

(3)修改 supplementantal gid

由于 uid 会和太多因素关联,因此直接修改 uid 这种作法比较重。除了 uid 外,Pod 中还能够:

  • 设置 fsGroup,它主要面向向块存储
  • 设置 suppmental gid,它主要面向共享文件系统

由于 Glusterfs 是共享文件存储,所以需设置辅助组id。具体步骤包括:

  • 修改 pod 的 suppemental gid,其作法与修改 uid 的作法相似,再也不重复。
  • 修改 NFS 文件夹的 group 权限,加上 w 和 x,并设置其 gid 为 pod 所使用的 suppemental gid。 

这两,在NFS客户端(pod)和服务器端(文件夹)上经过 group id 将把权限打通了。 

更详细说明,请阅读 OpenShift 官方文档 https://docs.okd.io/latest/install_config/persistent_storage/pod_security_context.html

3. 动态建立PV示例(以Clusterfs 为例)

3.1 流程概述

3.1.1 从 OpenShift 角度看

下图展现了从 OpenShift 角度看的动态建立PV的流程。在步骤 3.2,当开发人员建立好PVC之后,OpenShift 会在当前StorageClass中查找知足要求的 StorageClass。一旦找到,就会根据PVC中的配置自动建立一个PV,并调用StorageClass中的 storage provisioner 自动建立一个存储volume。在开发人员建立使用该 PVC 的 Pod 后,存储卷就会被挂载给Pod 所在的宿主机,而后经过 bind mounted 被挂载给Pod。

 

这么作的好处是显而易见的,好比:

  • 集群管理员不须要预先准备好PV
  • PV的容量和PVC的容量是同样的,这样就不会存在存储浪费。
  • 在删除PVC时,PV 会被自动删除,存储卷也会被自动删除。

另外一方面,OpenShift 会为每一个PVC 在后端存储上建立一个卷。这样,在有大量PVC时,存储中将出现大量的小容量卷,这对某些存储会产生至关大的压力,特别是对于一些传统存储。这些存储可能就不能知足现代容器云平台对存储的要求了。

3.1.2 从存储角度看

由于 Glusterfs 自己不提供 REST API,所以须要在它前面部署一个Proxy。Heketi 就是一种开源的这种Proxy,它的项目地址是 https://github.com/heketi/heketi。它暴露Gluster Volume 操做的REST API,并经过 SSH 来运行 Glusterfs 命令,完成各类卷相关的操做,好比建立,映射等。OpenShift 经过调用 Heketi API 来实现 Gluesterfs 卷的动态建立和管理。 

 3.2 示例

(1)OpenShift 管理员建立 StorageClass

每一个 StorageClass 会包含几个属性:

  • provisioner:指定建立PV所使用的存储插件(volume plugin)。Kubernets/OpenShift 带有它们所支持的存储插件。
  • parameters:后端存储的各类参数。
  • reclaimPolicy:存储空间回收策略。

关于StorageClass的详细说明,请阅读 https://kubernetes.io/docs/concepts/storage/storage-classes/

(2)开发人员建立一个PVC

其中关键的一项是在 storageClassName 中制定 StorageClass 的名称。

(3)OpenShfit 自动建立一个PV,以及其它资源。

OpenShfit 会根据 StorageClass 及 PVC 中的有关属性,动态建立一个 PV。 

以及 Service:

及其 Endpoints:

OpenShift 是经过该 service 调用 storage provisioner 的。

(4)Volume plugin 会自动地建立存储卷

 Heketi 在 Glusterfs 中建立改卷的过程大体以下:

(a)Glusterfs 系统初始化时会为每一个物理磁盘建立一个 Volume Group:

pvcreate --metadatasize=128M --dataalignment=256K '/dev/vde'
vgcreate --autobackup=n vg_c04281d30edfa285bb51f0f323ab7690 /dev/vde
(b)Heketi 调用 glusterfs 命令建立一个 volume
gluster --mode=script volume create vol_e22dc22f335de8f8c90f7c66028edf37 172.20.80.7:/var/lib/heketi/mounts/vg_c04281d30edfa285bb51f0f323ab7690/brick_97d37975df78714e2e0bfea850a9e4aa/brick
mkdir -p /var/lib/heketi/mounts/vg_c04281d30edfa285bb51f0f323ab7690/brick_97d37975df78714e2e0bfea850a9e4aa
lvcreate --autobackup=n --poolmetadatasize 8192K --chunksize 256K --size 1048576K --thin vg_c04281d30edfa285bb51f0f323ab7690/tp_97d37975df78714e2e0bfea850a9e4aa --virtualsize 1048576K --name brick_97d37975df78714e2e0bfea850a9e4aa
mkfs.xfs -i size=512 -n size=8192 /dev/mapper/vg_c04281d30edfa285bb51f0f323ab7690-brick_97d37975df78714e2e0bfea850a9e4aa 
mount -o rw,inode64,noatime,nouuid /dev/mapper/vg_c04281d30edfa285bb51f0f323ab7690-brick_97d37975df78714e2e0bfea850a9e4aa /var/lib/heketi/mounts/vg_c04281d30edfa285bb51f0f323ab7690/brick_97d37975df78714e2e0bfea850a9e4aa

#这个目录是在 Glusterfs 节点上实际保存数据的目录 

mkdir /var/lib/heketi/mounts/vg_c04281d30edfa285bb51f0f323ab7690/brick_97d37975df78714e2e0bfea850a9e4aa/brick

#该命令会目录的 gid 修改成前述第(3)步中的 gid

chown :2000 /var/lib/heketi/mounts/vg_c04281d30edfa285bb51f0f323ab7690/brick_97d37975df78714e2e0bfea850a9e4aa/brick
chmod 2775 /var/lib/heketi/mounts/vg_c04281d30edfa285bb51f0f323ab7690/brick_97d37975df78714e2e0bfea850a9e4aa/brick

 (5)开发人员建立一个使用上述PVC的 Pod

(6)Pod 启动时,系统会

首先 Glusters volume 被挂接到pod所在的宿主机上:
[root@node2 cloud-user]# mount  | grep gluster
172.20.80.7:vol_e22dc22f335de8f8c90f7c66028edf37 on /var/lib/origin/openshift.local.volumes/pods/5d97c7db-ff75-11e8-8b3e-fa163eae8505/volumes/kubernetes.io~glusterfs/pvc-10438bac-ff75-11e8-8b3e-fa163eae8505 type fuse.glusterfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072)

而后该宿主机目录做为一个 mountpoint 被挂载给容器:

 
挂载的目录(最后一行):
 
 Pod 中的 glusterfs 挂载点:
172.20.80.7:vol_e22dc22f335de8f8c90f7c66028edf37 on /var/volume type fuse.glusterfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072)

查看用户,它有id 为 2000 辅助组。

 
该 gid 和 Glusterfs 上的文件夹目录的权限相同,这样就能够确保对存储的访问没有权限问题。
 
这里能够看出来有对 gid/supplemental gid 有管理。 系统有对 PV 分配 gid,而后该 gid 会成为 Pod 主进程的 supplemetnal group ID,同时还会被设置为后端实际存储目录的 gid。这么作,相对手工建立PV 的流程,有一些简化。
 
参考连接:

感谢您的阅读,欢迎关注个人微信公众号:

相关文章
相关标签/搜索