kubenetes入門學習-十二-存儲卷1

最近學習k8s遇到很多問題,建了一個qq羣:153144292,交流devops、k8s、docker等

存儲卷

=========================
應用分類:
   有狀態、有存儲
   有狀態,無存儲
   無狀態,有存儲
   無狀態,無存儲

當pod故障被刪除或者用戶被刪除,從新被編排到其他node上運行,數據隨之pod結束就結束了,pod是有生命週期的,這裏就需要存儲了,持久化存儲數據。

基於以上原因就k8s提供了存儲卷,存儲卷不屬於k8s,屬於pod,創建pod的是基於pause基礎架構容器,都是基於他的網絡名稱空間。

如果是宿主機的存儲卷,node宕機就有問題了。這樣就需要跨node的存儲捲了
=========================
一、存儲卷的概念和類型
    emptyDir(Pod刪除,數據也會被清除、用於數據的臨時存儲)
    hostPath(docker之前學的)
    傳統意義的san(iscsi..)設備或者nas(nfs、cifs..)
    分佈式存儲(glusterfs、rbd、cephfs)
    雲存儲(aws ebs、Azure Disk...)

    爲了保證數據的持久性,必須保證數據在外部存儲在docker容器中,爲了實現數據的持久性存儲,在宿主機和容器內做映射,可以保證在容器的生命週期結束,數據依舊可以實現持久性存儲。但是在k8s中,由於pod分佈在各個不同的節點之上,並不能實現不同節點之間持久性數據的共享,並且,在節點故障時,可能會導致數據的永久性丟失。爲此,k8s就引入了外部存儲卷的功能。

k8s支持的類型:
    kubectl explain pod.spec.volumes
    發現很多種類型的存儲
    pvc(persistentVolumeClaim):pod上定義一個pvc類型,關聯到ns,這個是申請,申請跟pv建立關聯關係。pv纔是存儲上的存儲空間。
         公有云的情況是在存儲之上抽象一層,當用戶申請的時候,自動幫助用戶分配匹配的存儲空間大小。

k8s要使用存儲卷,需要2步:
    1、在pod定義volume,並指明關聯到哪個存儲設備
    2、在容器使用volume mount進行掛載,然後才能使用
========================
二、emptyDir實驗
    一個emptyDir 第一次創建是在一個pod被指定到具體node的時候,並且會一直存在在pod的生命週期當中,
正如它的名字一樣,它初始化是一個空的目錄,pod中的容器都可以讀寫這個目錄,這個目錄可以被掛在到各
個容器相同或者不相同的的路徑下。當一個pod因爲任何原因被移除的時候,這些數據會被永久刪除。

注意:一個容器崩潰了不會導致數據的丟失,因爲容器的崩潰並不移除pod

emptyDir 磁盤的作用:
(1)普通空間,基於磁盤的數據存儲
(2)作爲從崩潰中恢復的備份點
(3)存儲那些那些需要長久保存的數據,例web服務中的數據

默認的,emptyDir 磁盤會存儲在主機所使用的媒介上,可能是SSD,或者網絡硬盤,這主要取決於你的環境。
當然,我們也可以將emptyDir.medium的值設置爲Memory來告訴Kubernetes 來掛在一個基於內存的目錄tmpfs,
因爲tmpfs速度會比硬盤塊度了,但是,當主機重啓的時候所有的數據都會丟失。

kubectl explain pod.spec.volumes.emptyDir  #查看emptyDir存儲定義
kubectl explain pod.spec.containers
kubectl explain pod.spec.containers.volumeMounts #查看容器掛載方式

[root@master ~]# cd manifests/
[root@master manifests]# mkdir volumes
[root@master manifests]# cd volumes/
[root@master volumes]# ls
[root@master volumes]# cp ../pod-demo.yaml ./
[root@master volumes]# ll
total 4
-rw-r--r--. 1 root root 408 Mar 14 11:53 pod-demo.yaml
[root@master volumes]# mv pod-demo.yaml pod-vol-demo.yaml
[root@master volumes]# cat pod-vol-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    magedu.com/create-by:"cluster admin"
spec:
  containers:
  - name: myapp
    image: nginx
    ports:
    - name: http
      containerPort: 80
    volumeMounts:                #在容器內定義掛載存儲名稱和掛載路徑
    - name: html
      mountPath: /usr/share/nginx/html/  
  - name: busybox
    image: busybox:latest
    volumeMounts:                #在容器內定義掛載存儲名稱和掛載路徑
    - name: html
      mountPath: /data/
    command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done']
  volumes:                      #定義存儲卷     
  - name: html                   #定義存儲卷名稱 
    emptyDir: {}                 #定義存儲卷類型

[root@master volumes]# kubectl apply -f pod-vol-demo.yaml 
pod/pod-demo created
[root@master volumes]# kubectl get pods
NAME                                 READY   STATUS    RESTARTS   AGE
liveness-httpget-pod                 1/1     Running   1          9d
myapp-backend-pod-69dc8c7655-pqwk8   1/1     Running   0          24h
myapp-backend-pod-69dc8c7655-sgpw6   1/1     Running   0          24h
myapp-backend-pod-69dc8c7655-v4jvx   1/1     Running   0          24h
myapp-deploy-69dc8c7655-jkkwv        1/1     Running   0          4d8h
myapp-deploy-69dc8c7655-q97jc        1/1     Running   0          4d8h
myapp-deploy-69dc8c7655-sldk8        1/1     Running   0          4d8h
myapp-deploy-69dc8c7655-v9dvc        1/1     Running   0          4d8h
myapp-deploy-69dc8c7655-x5qth        1/1     Running   0          4d8h
nginx-7849c4bbcd-dscjr               1/1     Running   0          12d
nginx-7849c4bbcd-vdd45               1/1     Running   0          12d
nginx-7849c4bbcd-wrvks               1/1     Running   0          12d
nginx-deploy-84cbfc56b6-mjcw5        1/1     Running   0          13d
pod-demo                             2/2     Running   0          7s  這裏下面兩個容器
tomcat-backed-64d5bc78f7-b9tlh       1/1     Running   0          24h
tomcat-backed-64d5bc78f7-lv844       1/1     Running   0          24h
tomcat-backed-64d5bc78f7-s62j8       1/1     Running   0          24h
[root@master volumes]# kubectl get pods -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
liveness-httpget-pod                 1/1     Running   1          9d     10.244.2.17   node02   <none>           <none>
myapp-backend-pod-69dc8c7655-pqwk8   1/1     Running   0          24h    10.244.1.27   node01   <none>           <none>
myapp-backend-pod-69dc8c7655-sgpw6   1/1     Running   0          24h    10.244.1.28   node01   <none>           <none>
myapp-backend-pod-69dc8c7655-v4jvx   1/1     Running   0          24h    10.244.2.30   node02   <none>           <none>
myapp-deploy-69dc8c7655-jkkwv        1/1     Running   0          4d8h   10.244.1.24   node01   <none>           <none>
myapp-deploy-69dc8c7655-q97jc        1/1     Running   0          4d8h   10.244.2.25   node02   <none>           <none>
myapp-deploy-69dc8c7655-sldk8        1/1     Running   0          4d8h   10.244.2.27   node02   <none>           <none>
myapp-deploy-69dc8c7655-v9dvc        1/1     Running   0          4d8h   10.244.2.28   node02   <none>           <none>
myapp-deploy-69dc8c7655-x5qth        1/1     Running   0          4d8h   10.244.1.25   node01   <none>           <none>
nginx-7849c4bbcd-dscjr               1/1     Running   0          12d    10.244.1.13   node01   <none>           <none>
nginx-7849c4bbcd-vdd45               1/1     Running   0          12d    10.244.2.15   node02   <none>           <none>
nginx-7849c4bbcd-wrvks               1/1     Running   0          12d    10.244.1.14   node01   <none>           <none>
nginx-deploy-84cbfc56b6-mjcw5        1/1     Running   0          13d    10.244.2.9    node02   <none>           <none>
pod-demo                             2/2     Running   0          117s   10.244.2.33   node02   <none>           <none>  這裏
tomcat-backed-64d5bc78f7-b9tlh       1/1     Running   0          24h    10.244.1.29   node01   <none>           <none>
tomcat-backed-64d5bc78f7-lv844       1/1     Running   0          24h    10.244.2.32   node02   <none>           <none>
tomcat-backed-64d5bc78f7-s62j8       1/1     Running   0          24h    10.244.2.31   node02   <none>           <none>
在上面,我們定義了2個容器,其中一個容器是輸入日期到index.html中,然後驗證訪問nginx的html是否可以獲取日期。
以驗證兩個容器之間掛載的emptyDir實現共享。如下訪問驗證:
[root@master volumes]# curl 10.244.2.33
Thu Mar 14 15:59:22 UTC 2019
Thu Mar 14 15:59:24 UTC 2019
Thu Mar 14 15:59:26 UTC 2019
Thu Mar 14 15:59:28 UTC 2019
Thu Mar 14 15:59:30 UTC 2019
Thu Mar 14 15:59:32 UTC 2019
Thu Mar 14 15:59:34 UTC 2019
Thu Mar 14 15:59:36 UTC 2019
Thu Mar 14 15:59:38 UTC 2019

========================
三、gitRepo
    把git倉庫當作存儲卷使用,宿主機必須有git命令,他也是在emptyDir之上。
說明:
    克隆倉庫的內容
    修改不會同步git倉庫
    如果pod運行過程,git倉庫發生改變,不會從新同步新數據,當然如果想同步,可以做個輔助容器定時同步,實現同步。
[root@master volumes]# vim vol-gitrepo-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: vol-gitrepo-pod
  namespace: default
  labels:
    app: wolf
    tier: frontend
spec:
  containers:
  - name: wolf
    image: nginx:1.12-alpine
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
  volumes:
  - name: html
    gitRepo:
      repository: https://github.com/iKubernetes/k8s_book.git
      directory: .
      revision: "master"
這裏創建失敗,回頭找原因
=======================
四、hostPath
    hostPath宿主機路徑,就是把pod所在的宿主機之上的脫離pod中的容器名稱空間的之外的宿主機的文件
系統的某一目錄和pod建立關聯關係,在pod刪除時,存儲數據不會丟失。

1、查看hostPath存儲類型定義
[root@master ~]#kubectl explain pods.spec.volumes.hostPath 
[root@master ~]#kubectl explain pods.spec.volumes.hostPath.type

https://kubernetes.io/docs/concepts/storage/volumes#hostpath
type:
DirectoryOrCreate  宿主機上不存在創建此目錄  
Directory 必須存在掛載目錄  
FileOrCreate 宿主機上不存在掛載文件就創建  
File 必須存在文件
[root@master volumes]# vim pod-hostpath--vol.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-hostpath
  namespace: default
spec:
  containers:
  - name: myapp
    image: nginx
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html
    hostPath:
      path: /data/pod/volume1
      type: DirectoryOrCreate
爲了顯示效果,去node1和node2上建立/data/pod/volume1,並創建index.html文件,分別寫入node1和node2
[root@master volumes]# kubectl apply -f pod-hostpath--vol.yaml 
pod/pod-vol-hostpath created
[root@master volumes]# kubectl get pod
NAME                                 READY   STATUS    RESTARTS   AGE
pod-vol-hostpath                     1/1     Running   0          22s
[root@master volumes]# kubectl get pod -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-hostpath                     1/1     Running   0          36s    10.244.2.35   node02   <none>           <none>

[root@master volumes]# kubectl get pod -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-hostpath                     1/1     Running   0          4s     10.244.2.37   node02   <none>           <none>

[root@master volumes]# curl 10.244.2.37
node02

[root@master volumes]# kubectl delete -f pod-hostpath--vol.yaml 
pod "pod-vol-hostpath" deleted
[root@master volumes]# kubectl apply -f pod-hostpath--vol.yaml 
pod/pod-vol-hostpath created
[root@master volumes]# kubectl get pod -o wide
NAME                                 READY   STATUS              RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-hostpath                     0/1     ContainerCreating   0          3s     <none>        node02   <none>           <none>

[root@master volumes]# kubectl get pod -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-hostpath                     1/1     Running   0          6s     10.244.2.38   node02   <none>           <none>

[root@master volumes]# curl 10.244.2.38
node02

hostPath可以實現持久存儲,但是在node節點故障時,也會導致數據的丟失

========================
五、nfs共享存儲卷
  nfs使的我們可以掛在已經存在的共享到的我們的Pod中,和emptyDir不同的是,emptyDir會被刪除
當我們的Pod被刪除的時候,但是nfs不會被刪除,僅僅是解除掛在狀態而已,這就意味着NFS能夠允許
我們提前對數據進行處理,而且這些數據可以在Pod之間相互傳遞.並且,nfs可以同時被多個pod掛在並
進行讀寫。

[root@master volumes]# kubectl explain pv      #查看pv的定義方式
FIELDS:
    apiVersion
    kind
    metadata
    spec

[root@master volumes]# kubectl explain pv.spec       #查看pv定義的規格
spec:
  nfs(定義存儲類型)
    path(定義掛載卷路徑)
    server(定義服務器名稱)
  accessModes(定義訪問模型,有以下三種訪問模型,以列表的方式存在,也就是說可以定義多個訪問模式)
    ReadWriteOnce(RWO)  單節點讀寫
    ReadOnlyMany(ROX)  多節點只讀
    ReadWriteMany(RWX)  多節點讀寫
  capacity(定義PV空間的大小)
    storage(指定大小)    


[root@master volumes]# kubectl explain pvc   #查看PVC的定義方式
KIND:     PersistentVolumeClaim
VERSION:  v1
FIELDS:
   apiVersion   <string>
   kind <string>  
   metadata <Object>
   spec <Object>
[root@master volumes]# kubectl explain pvc.spec
spec:
  accessModes(定義訪問模式,必須是PV的訪問模式的子集)
  resources(定義申請資源的大小)
    requests:
      storage: 
    
注意:必須先報紙NFS服務器正常運行在我們進行掛在nfs的時候

在master節點上安裝nfs,並配置nfs服務
[root@master volumes]#yum install nfs-utils -y
[root@master volumes]# mkdir /data/volumes -pv
[root@master data]# cat /etc/exports
/data/wolf 10.249.6.0/24(rw,no_root_squash)
[root@master volumes]# systemctl start nfs
[root@master data]# showmount -e
Export list for master:
/data/wolf 10.249.6.0/24

在node01和node02節點上安裝nfs-utils,並測試掛載

[root@node01 ~]# yum install -y nfs-utils
[root@node01 ~]# mount -t nfs master:/data/wolf /tmp
[root@node01 ~]# mount
master:/data/wolf on /tmp 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=10.249.6.101,local_lock=none,addr=10.249.6.100)
[root@node01 ~]# umount /tmp

[root@node02 ~]# yum install -y nfs-utils
[root@node02 ~]# mount -t nfs master:/data/wolf /tmp
[root@node02 ~]# umount /tmp

創建nfs存儲卷的使用清單
[root@master volumes]# cp pod-hostpath--vol.yaml pod-nfs-vol.yaml
[root@master volumes]# vi pod-nfs-vol.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-nfs
  namespace: default
spec:
  containers:
  - name: myapp
    image: nginx
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html
    nfs:
      path: /data/wolf
      server: master
[root@master volumes]# kubectl apply -f pod-nfs-vol.yaml 
pod/pod-vol-nfs created
[root@master volumes]# kubectl get pods -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-nfs                          1/1     Running   0          9s     10.244.2.39   node02   <none>           <none>

在nfs服務器上創建index.html
[root@master wolf]# vi index.html
[root@master wolf]# cat index.html 
<h1>wolf nfs</h1>
[root@master wolf]# curl 10.244.2.39
<h1>wolf nfs</h1>
[root@master wolf]# curl 10.244.2.39
<h1>wolf nfs</h1>
[root@master wolf]# curl 10.244.2.39
<h1>wolf nfs</h1>

刪除pod,重建,可以看出數據持久化
[root@master volumes]# kubectl delete -f pod-nfs-vol.yaml 
pod "pod-vol-nfs" deleted
[root@master volumes]# kubectl apply -f pod-nfs-vol.yaml 
pod/pod-vol-nfs created
[root@master volumes]# kubectl get pods -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-nfs                          1/1     Running   0          15s    10.244.2.40   node02   <none>           <none>
[root@master volumes]# curl 10.244.2.40
<h1>wolf nfs</h1>
========================
========================
PVC和PV的概念
    我們前面提到kubernetes提供那麼多存儲接口,但是首先kubernetes的各個Node節點能管理這些存儲,但是各
種存儲參數也需要專業的存儲工程師才能瞭解,由此我們的kubernetes管理變的更加複雜的。由此kubernetes提出
了PV和PVC的概念,這樣開發人員和使用者就不需要關注後端存儲是什麼,使用什麼參數等問題。

PersistentVolume(PV)是集羣中已由管理員配置的一段網絡存儲。 集羣中的資源就像一個節點是一個集羣資源。 
PV是諸如卷之類的卷插件,但是具有獨立於使用PV的任何單個pod的生命週期。 該API對象捕獲存儲的實現細節,
即NFS,iSCSI或雲提供商特定的存儲系統。

PersistentVolumeClaim(PVC)是用戶存儲的請求。PVC的使用邏輯:在pod中定義一個存儲卷(該存儲卷類型爲PVC)
,定義的時候直接指定大小,pvc必須與對應的pv建立關係,pvc會根據定義去pv申請,而pv是由存儲空間創建出來的
。pv和pvc是kubernetes抽象出來的一種存儲資源。

雖然PersistentVolumeClaims允許用戶使用抽象存儲資源,但是常見的需求是,用戶需要根據不同的需求去創建PV,
用於不同的場景。而此時需要集羣管理員提供不同需求的PV,而不僅僅是PV的大小和訪問模式,但又不需要用戶瞭解
這些卷的實現細節。 對於這樣的需求,此時可以採用StorageClass資源。這個在前面就已經提到過此方案。

PV是集羣中的資源。 PVC是對這些資源的請求,也是對資源的索賠檢查。 PV和PVC之間的相互作用遵循這個生命週期:
Provisioning(配置)---> Binding(綁定)--->Using(使用)---> Releasing(釋放) ---> Recycling(回收)

Provisioning
   這裏有兩種PV的提供方式:靜態或者動態

靜態-->直接固定存儲空間:
    集羣管理員創建一些 PV。它們攜帶可供集羣用戶使用的真實存儲的詳細信息。 它們存在於Kubernetes API中,可
用於消費。

動態-->通過存儲類進行動態創建存儲空間:
    當管理員創建的靜態 PV 都不匹配用戶的 PVC 時,集羣可能會嘗試動態地爲 PVC 配置卷。此配置基於 
StorageClasses:PVC 必須請求存儲類,並且管理員必須已創建並配置該類才能進行動態配置。 要求該類的聲明有
效地爲自己禁用動態配置。

Binding
    在動態配置的情況下,用戶創建或已經創建了具有特定數量的存儲請求和特定訪問模式的PersistentVolumeClaim。
主機中的控制迴路監視新的PVC,找到匹配的PV(如果可能),並將 PVC 和 PV 綁定在一起。 如果爲新的PVC動態配置
PV,則循環將始終將該PV綁定到PVC。 否則,用戶總是至少得到他們要求的內容,但是卷可能超出了要求。 一旦綁定,
PersistentVolumeClaim綁定是排他的,不管用於綁定它們的模式。

    如果匹配的卷不存在,PVC將保持無限期。 隨着匹配卷變得可用,PVC將被綁定。 例如,提供許多50Gi PV的集羣將
不匹配要求100Gi的PVC。 當集羣中添加100Gi PV時,可以綁定PVC。

Using
    Pod使用PVC作爲卷。 集羣檢查聲明以找到綁定的卷並掛載該卷的卷。 對於支持多種訪問模式的卷,用戶在將其聲
明用作pod中的卷時指定所需的模式。

    一旦用戶有聲明並且該聲明被綁定,綁定的PV屬於用戶,只要他們需要它。 用戶通過在其Pod的卷塊中包含
PersistentVolumeClaim來安排Pods並訪問其聲明的PV。


Releasing
    當用戶完成卷時,他們可以從允許資源回收的API中刪除PVC對象。 當聲明被刪除時,卷被認爲是“釋放的”,但是它
還不能用於另一個聲明。 以前的索賠人的數據仍然保留在必須根據政策處理的捲上.

Reclaiming
    PersistentVolume的回收策略告訴集羣在釋放其聲明後,該卷應該如何處理。 目前,卷可以是保留,回收或刪除。 
保留可以手動回收資源。 對於那些支持它的卷插件,刪除將從Kubernetes中刪除PersistentVolume對象,以及刪除外部
基礎架構(如AWS EBS,GCE PD,Azure Disk或Cinder卷)中關聯的存儲資產。 動態配置的卷始終被刪除

Recycling
    如果受適當的卷插件支持,回收將對卷執行基本的擦除(rm -rf / thevolume / *),並使其再次可用於新的聲明。

========================
六、NFS使用PV和PVC
pod--pvc--pv-nfs

[root@master volumes]# kubectl explain pv        #查看pv的定義方式

[root@master volumes]# kubectl explain pv.spec   #查看pv定義的規格
spec:
  nfs(定義存儲類型)
    path(定義掛載卷路徑)
    server(定義服務器名稱)
  accessModes(定義訪問模型,有以下三種訪問模型,以列表的方式存在,也就是說可以定義多個訪問模式)
    ReadWriteOnce(RWO)  單節點讀寫
    ReadOnlyMany(ROX)  多節點只讀
    ReadWriteMany(RWX)  多節點讀寫
  capacity(定義PV空間的大小)
    storage(指定大小)

[root@master volumes]# kubectl explain pvc   #查看PVC的定義方式
KIND:     PersistentVolumeClaim
VERSION:  v1
FIELDS:
   apiVersion   <string>
   kind <string>  
   metadata <Object>
   spec <Object>
[root@master volumes]# kubectl explain pvc.spec
spec:
  accessModes(定義訪問模式,必須是PV的訪問模式的子集)
  resources(定義申請資源的大小)
    requests:
      storage:
      
1、配置nfs存儲
[root@master volumes]# mkdir -p /data/wolf{1,2,3,4,5}
[root@master volumes]# ll /data/
total 0
drwxr-xr-x. 3 root root 21 Mar 15 10:27 pod
drwxr-xr-x. 2 root root  6 Mar 16 03:51 volumes
drwxr-xr-x. 2 root root 24 Mar 16 13:12 wolf
drwxr-xr-x. 2 root root  6 Mar 16 13:25 wolf1
drwxr-xr-x. 2 root root  6 Mar 16 13:25 wolf2
drwxr-xr-x. 2 root root  6 Mar 16 13:25 wolf3
drwxr-xr-x. 2 root root  6 Mar 16 13:25 wolf4
drwxr-xr-x. 2 root root  6 Mar 16 13:25 wolf5
[root@master volumes]# cat /etc/exports
/data/wolf 10.249.6.0/24(rw,no_root_squash)

echo "/data/wolf1 10.249.6.0/24(rw,no_root_squash)" >>/etc/exports
echo "/data/wolf2 10.249.6.0/24(rw,no_root_squash)" >>/etc/exports
echo "/data/wolf3 10.249.6.0/24(rw,no_root_squash)" >>/etc/exports
echo "/data/wolf4 10.249.6.0/24(rw,no_root_squash)" >>/etc/exports
echo "/data/wolf5 10.249.6.0/24(rw,no_root_squash)" >>/etc/exports

[root@master volumes]# cat /etc/exports
/data/wolf 10.249.6.0/24(rw,no_root_squash)
/data/wolf1 10.249.6.0/24(rw,no_root_squash)
/data/wolf2 10.249.6.0/24(rw,no_root_squash)
/data/wolf3 10.249.6.0/24(rw,no_root_squash)
/data/wolf4 10.249.6.0/24(rw,no_root_squash)
/data/wolf5 10.249.6.0/24(rw,no_root_squash)

[root@master volumes]# exportfs -arv
exporting 10.249.6.0/24:/data/wolf5
exporting 10.249.6.0/24:/data/wolf4
exporting 10.249.6.0/24:/data/wolf3
exporting 10.249.6.0/24:/data/wolf2
exporting 10.249.6.0/24:/data/wolf1
exporting 10.249.6.0/24:/data/wolf
[root@master volumes]# showmount -e
Export list for master:
/data/wolf5 10.249.6.0/24
/data/wolf4 10.249.6.0/24
/data/wolf3 10.249.6.0/24
/data/wolf2 10.249.6.0/24
/data/wolf1 10.249.6.0/24
/data/wolf  10.249.6.0/24

2、定義PV
這裏定義5個PV,並且定義掛載的路徑以及訪問模式,還有PV劃分的大小。
[root@master volumes]# kubectl explain pv
[root@master volumes]# kubectl explain pv.spec.nfs
[root@master volumes]# vim pv-demo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
    path: /data/wolf1
    server: master
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
    path: /data/wolf2
    server: master
  accessModes: ["ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/wolf3
    server: master
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
    path: /data/wolf4
    server: master
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
    path: /data/wolf5
    server: master
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 5Gi
    
[root@master volumes]# kubectl apply -f pv-demo.yaml 
persistentvolume/pv001 created
persistentvolume/pv002 created
persistentvolume/pv003 created
persistentvolume/pv004 created
persistentvolume/pv005 created
[root@master volumes]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001   1Gi        RWO,RWX        Retain           Available                                   8s
pv002   2Gi        RWO            Retain           Available                                   8s
pv003   2Gi        RWO,RWX        Retain           Available                                   8s
pv004   4Gi        RWO,RWX        Retain           Available                                   8s
pv005   5Gi        RWO,RWX        Retain           Available                                   8s

3、定義PVC
    這裏定義了pvc的訪問模式爲多路讀寫,該訪問模式必須在前面pv定義的訪問模式之中。定義PVC申請的大小爲2Gi,
此時PVC會自動去匹配多路讀寫且大小爲2Gi的PV,匹配成功獲取PVC的狀態即爲Bound

[root@master volumes]#vi pod-vol-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
  namespace: default
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 2Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-pvc
  namespace: default
spec:
  containers:
  - name: myapp
    image: nginx
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
    - name: html
      persistentVolumeClaim:
        claimName: mypvc

[root@master volumes]# kubectl apply -f pv-demo.yaml 
persistentvolume/pv001 created
persistentvolume/pv002 created
persistentvolume/pv003 created
persistentvolume/pv004 created
persistentvolume/pv005 created
[root@master volumes]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001   1Gi        RWO,RWX        Retain           Available                                   8s
pv002   2Gi        RWO            Retain           Available                                   8s
pv003   2Gi        RWO,RWX        Retain           Available                                   8s
pv004   4Gi        RWO,RWX        Retain           Available                                   8s
pv005   5Gi        RWO,RWX        Retain           Available                                   8s
[root@master volumes]# kubectl get pvv
error: the server doesn't have a resource type "pvv"
[root@master volumes]# kubectl get pvc
No resources found.
[root@master volumes]# vi pod-vol-pvc.yaml
[root@master volumes]# kubectl apply -f pod-vol-pvc.yaml 
persistentvolumeclaim/mypvc created
pod/pod-vol-pvc created
[root@master volumes]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON   AGE
pv001   1Gi        RWO,RWX        Retain           Available                                           2m27s
pv002   2Gi        RWO            Retain           Available                                           2m27s
pv003   2Gi        RWO,RWX        Retain           Bound       default/mypvc                           2m27s
pv004   4Gi        RWO,RWX        Retain           Available                                           2m27s
pv005   5Gi        RWO,RWX        Retain           Available                                           2m27s
[root@master volumes]# kubectl get pvc
NAME    STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc   Bound    pv003    2Gi        RWO,RWX                       18s

4、測試訪問
在存儲服務器上創建index.html,並寫入數據,通過訪問Pod進行查看,可以獲取到相應的頁面。
[root@master data]# ls
pod  volumes  wolf  wolf1  wolf2  wolf3  wolf4  wolf5
[root@master data]# cd wolf3
[root@master wolf3]# ls
[root@master wolf3]# echo "use pv3" >index.html
[root@master wolf3]# kubectl get pods -o wide
NAME                                 READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-pvc                          1/1     Running   0          2m40s   10.244.2.41   node02   <none>           <none>

[root@master wolf3]# curl 10.244.2.41
use pv

========================

k8s支持的類型
[root@master ~]# kubectl explain pod.spec.volumes
KIND:     Pod
VERSION:  v1

RESOURCE: volumes <[]Object>

DESCRIPTION:
     List of volumes that can be mounted by containers belonging to the pod.
     More info: https://kubernetes.io/docs/concepts/storage/volumes

     Volume represents a named volume in a pod that may be accessed by any
     container in the pod.

FIELDS:
   awsElasticBlockStore    <Object>    這裏是aws ebs
     AWSElasticBlockStore represents an AWS Disk resource that is attached to a
     kubelet's host machine and then exposed to the pod. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

   azureDisk    <Object>  微軟雲
     AzureDisk represents an Azure Data Disk mount on the host and bind mount to
     the pod.

   azureFile    <Object> 微軟雲
     AzureFile represents an Azure File Service mount on the host and bind mount
     to the pod.

   cephfs    <Object>  這個不說了撒 ceph
     CephFS represents a Ceph FS mount on the host that shares a pod's lifetime

   cinder    <Object>  
     Cinder represents a cinder volume attached and mounted on kubelets host
     machine More info:
     https://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md

   configMap    <Object>
     ConfigMap represents a configMap that should populate this volume

   downwardAPI    <Object>
     DownwardAPI represents downward API about the pod that should populate this
     volume

   emptyDir    <Object>
     EmptyDir represents a temporary directory that shares a pod's lifetime.
     More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir

   fc    <Object>
     FC represents a Fibre Channel resource that is attached to a kubelet's host
     machine and then exposed to the pod.

   flexVolume    <Object>
     FlexVolume represents a generic volume resource that is
     provisioned/attached using an exec based plugin.

   flocker    <Object>
     Flocker represents a Flocker volume attached to a kubelet's host machine.
     This depends on the Flocker control service being running

   gcePersistentDisk    <Object>
     GCEPersistentDisk represents a GCE Disk resource that is attached to a
     kubelet's host machine and then exposed to the pod. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

   gitRepo    <Object>
     GitRepo represents a git repository at a particular revision. DEPRECATED:
     GitRepo is deprecated. To provision a container with a git repo, mount an
     EmptyDir into an InitContainer that clones the repo using git, then mount
     the EmptyDir into the Pod's container.

   glusterfs    <Object>
     Glusterfs represents a Glusterfs mount on the host that shares a pod's
     lifetime. More info:
     https://releases.k8s.io/HEAD/examples/volumes/glusterfs/README.md

   hostPath    <Object>
     HostPath represents a pre-existing file or directory on the host machine
     that is directly exposed to the container. This is generally used for
     system agents or other privileged things that are allowed to see the host
     machine. Most containers will NOT need this. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#hostpath

   iscsi    <Object>
     ISCSI represents an ISCSI Disk resource that is attached to a kubelet's
     host machine and then exposed to the pod. More info:
     https://releases.k8s.io/HEAD/examples/volumes/iscsi/README.md

   name    <string> -required-
     Volume's name. Must be a DNS_LABEL and unique within the pod. More info:
     https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

   nfs    <Object>
     NFS represents an NFS mount on the host that shares a pod's lifetime More
     info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

   persistentVolumeClaim    <Object>
     PersistentVolumeClaimVolumeSource represents a reference to a
     PersistentVolumeClaim in the same namespace. More info:
     https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims

   photonPersistentDisk    <Object>
     PhotonPersistentDisk represents a PhotonController persistent disk attached
     and mounted on kubelets host machine

   portworxVolume    <Object>
     PortworxVolume represents a portworx volume attached and mounted on
     kubelets host machine

   projected    <Object>
     Items for all in one resources secrets, configmaps, and downward API

   quobyte    <Object>
     Quobyte represents a Quobyte mount on the host that shares a pod's lifetime

   rbd    <Object>
     RBD represents a Rados Block Device mount on the host that shares a pod's
     lifetime. More info:
     https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md

   scaleIO    <Object>
     ScaleIO represents a ScaleIO persistent volume attached and mounted on
     Kubernetes nodes.

   secret    <Object>
     Secret represents a secret that should populate this volume. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#secret

   storageos    <Object>
     StorageOS represents a StorageOS volume attached and mounted on Kubernetes
     nodes.

   vsphereVolume    <Object>
     VsphereVolume represents a vSphere volume attached and mounted on kubelets
     host machine

[root@master ~]# kubectl explain pod.spec.volumes.emptyDir
KIND:     Pod
VERSION:  v1

RESOURCE: emptyDir <Object>

DESCRIPTION:
     EmptyDir represents a temporary directory that shares a pod's lifetime.
     More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir

     Represents an empty directory for a pod. Empty directory volumes support
     ownership management and SELinux relabeling.

FIELDS:
   medium    <string>  媒介類型  
     What type of storage medium should back this directory. The default is ""
     which means to use the node's default medium. Must be an empty string
     (default) or Memory. More info: 
     https://kubernetes.io/docs/concepts/storage/volumes#emptydir

   sizeLimit    <string>
     Total amount of local storage required for this EmptyDir volume. The size
     limit is also applicable for memory medium. The maximum usage on memory
     medium EmptyDir would be the minimum value between the SizeLimit specified
     here and the sum of memory limits of all containers in a pod. The default
     is nil which means that the limit is undefined. More info:
     http://kubernetes.io/docs/user-guide/volumes#emptydir
     
[root@master ~]#  kubectl explain pods.spec.volumes.hostPath 
KIND:     Pod
VERSION:  v1

RESOURCE: hostPath <Object>

DESCRIPTION:
     HostPath represents a pre-existing file or directory on the host machine
     that is directly exposed to the container. This is generally used for
     system agents or other privileged things that are allowed to see the host
     machine. Most containers will NOT need this. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#hostpath

     Represents a host path mapped into a pod. Host path volumes do not support
     ownership management or SELinux relabeling.

FIELDS:
   path    <string> -required-               #指定宿主機的路徑
     Path of the directory on the host. If the path is a symlink, it will follow
     the link to the real path. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#hostpath

   type    <string>
     Type for HostPath Volume Defaults to "" More info:
     https://kubernetes.io/docs/concepts/storage/volumes#hostpath
     
[root@master volumes]# kubectl explain pv      #查看pv的定義方式
KIND:     PersistentVolume
VERSION:  v1

DESCRIPTION:
     PersistentVolume (PV) is a storage resource provisioned by an
     administrator. It is analogous to a node. More info:
     https://kubernetes.io/docs/concepts/storage/persistent-volumes

FIELDS:
   apiVersion   <string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#resources

   kind <string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds

   metadata     <Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata

   spec <Object>
     Spec defines a specification of a persistent volume owned by the cluster.
     Provisioned by an administrator. More info:
     https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistent-volumes

   status       <Object>
     Status represents the current information/status for the persistent volume.
     Populated by the system. Read-only. More info:
     https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistent-volumes
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章