理解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 的流程,有一些簡化。
 
參考連接:

感謝您的閱讀,歡迎關注個人微信公衆號:

相關文章
相關標籤/搜索