1.存儲卷概述
因為pod是有生命周期的,pod一重啟,里面的數據就沒了,所以我們需要數據持久化存儲,在k8s中,存儲卷不屬於容器,而是屬於pod,也就是說同一個pod中的容器可以共享一個存儲卷,存儲卷可以是宿主機上的目錄,也可以是掛載在宿主機上的外部設備.
存儲卷類型:
emptyDIR存儲卷:pod一重啟,存儲卷也刪除,這叫emptyDir存儲卷,一般用於當做臨時空間或緩存關系;
hostPath存儲卷:宿主機上目錄作為存儲卷,這種也不是真正意義實現了數據持久性;
SAN(iscsi)或NAS(nfs、cifs):網絡存儲設備;
分布式存儲:ceph,glusterfs,cephfs,rbd
雲存儲:亞馬遜的EBS,Azure Disk,阿里雲,關鍵數據一定要有異地備份
a.emptyDIR存儲卷
vim podtest/pod-vol-demo.yaml apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v2 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 volumeMounts: - name: html mountPath: /usr/share/nginx/html - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent volumeMounts: - name: html mountPath: /data/ command: ["/bin/sh"] args: ["-c","while true;do echo $(date) >> /data/index.html; sleep 10;done"] volumes: - name: html emptyDir: {} volumeMounts:把哪個存儲卷掛到pod中的哪個目錄下 emptyDir:不設置意味着對這個參數下的兩個選項不做限制
b.hostPath:使用宿主機上目錄作為存儲卷
kubectl explain pods.spec.volumes.hostPath.type DirectoryOrCreate:要掛載的路徑是一個目錄,不存在就創建目錄; Directory:宿主機上必須實現存在目錄,如果不存在就報錯; FileOrCreate:表示掛載的是文件,如果不存在就創建; File:表示要掛載的文件必須事先存在,否則就報錯. cat pod-hostpath-vol.yaml apiVersion: v1 kind: Pod metadata: name: pod-vol-hostpath namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v2 volumeMounts: - name: html mountPath: /usr/share/nginx/html/ volumes: - name: html hostPath: path: /data/pod/volume1 type: DirectoryOrCreate hostPath:宿主機上的目錄. volumes的名字可以隨便取,這是存儲卷的名字,但是上面的volumeMounts指定時, name必須和存儲卷的名字一致,這樣兩者才建立了聯系.
c.nfs做共享存儲
這里為了方便,把master節點當做nfs存儲,三個節點均執行 yum -y install nfs-utils # 然后在master上啟動nfs mkdir /data/volumes cat /etc/exports /data/volumes 10.0.0.0/16(rw,no_root_squash) systemctl start nfs 在node1和node2上試掛載 mount -t nfs k8s-master:/data/volumes /mnt cat pod-vol-nfs.yaml apiVersion: v1 kind: Pod metadata: name: pod-vol-nfs namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v2 volumeMounts: - name: html mountPath: /usr/share/nginx/html/ volumes: - name: html nfs: path: /data/volumes server: k8s-master kubectl apply -f pod-vol-nfs.yaml 此時不管pod被建立在哪個節點上,對應節點上是不存放數據的,數據都在nfs主機上
d.pvc和pv
用戶只需要掛載pvc到容器中而不需要關注存儲卷采用何種技術實現.pvc和pv的關系與pod和node關系類似,前者消耗后者的資源,pvc可以向pv申請指定大小的存儲資源並設置訪問模式.
在定義pod時,我們只需要說明我們要一個多大的存儲卷就行了,pvc存儲卷必須與當前namespace的pvc建立直接綁定關系,pvc必須與pv建立綁定關系,而pv是真正的某個存儲設備上的空間.
一個pvc和pv是一一對應關系,一旦一個pv被一個pvc綁定了,那么這個pv就不能被其他pvc綁定了,一個pvc是可以被多個pod所訪問的,pvc在名稱空間中,pv是集群級別的.
將master作為存儲節點,創建掛載目錄
cd /data/volumes && mkdir v{1,2,3,4,5} cat /etc/exports /data/volumes/v1 10.0.0.0/16(rw,no_root_squash) /data/volumes/v2 10.0.0.0/16(rw,no_root_squash) /data/volumes/v3 10.0.0.0/16(rw,no_root_squash) exportfs -arv showmount -e kubectl explain pv.spec.nfs accessModes模式有: ReadWriteOnce:單路讀寫,可以簡寫為RWO; ReadOnlyMany:多路只讀,可以簡寫為ROX; ReadWriteMany:多路讀寫,可以簡寫為RWX # 先將存儲設備定義為pv cat pv-demo.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv001 # 定義pv時不用加名稱空間,因為pv是集群級別 labels: name: pv001 spec: nfs: path: /data/volumes/v1 server: k8s-master accessModes: ["ReadWriteMany","ReadWriteOnce"] capacity: # 分配磁盤空間大小 storage: 3Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv002 labels: name: pv002 spec: nfs: path: /data/volumes/v2 server: k8s-master accessModes: ["ReadWriteOnce"] capacity: storage: 5Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv003 labels: name: pv003 spec: nfs: path: /data/volumes/v3 server: k8s-master accessModes: ["ReadWriteMany","ReadWriteOnce"] capacity: storage: 8Gi kubectl apply -f pv-demo.yaml kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS pv001 3Gi RWO,RWX Retain Available pv002 5Gi RWO Retain Available pv003 8Gi RWO,RWX Retain Available
回收策略:
如果某個pvc在pv里面存數據了,后來pvc刪了,那么pv里面的數據怎么處理
reclaim_policy:即pvc刪了,但pv里面的數據不刪除,還保留着;
recycle:即pvc刪了,那么就把pv里面的數據也刪了;
delete:即pvc刪了,那么就把pv也刪了.
# 創建pvc的清單文件 kubectl explain pods.spec.volumes.persistentVolumeClaim cat pod-vol-pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim # 簡稱pvc metadata: name: mypvc namespace: default # pvc和pod在同一個名稱空間 spec: accessModes: ["ReadWriteMany"] # 一定是pv策略的子集 resources: requests: storage: 7Gi # 申請一個大小至少為7G的pv --- apiVersion: v1 kind: Pod metadata: name: pod-vol-pvc namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html # 使用的存儲卷的名字 mountPath: /usr/share/nginx/html/ #掛載路徑 volumes: - name: html persistentVolumeClaim: claimName: mypvc # 表示要使用哪個pvc
所以pod的存儲卷類型如果是pvc,則:pod指定的pvc需要先匹配一個pv,才能被pod所掛載,在k8s 1.10之后,不能手工從底層刪除pv.
參考博客:http://blog.itpub.net/28916011/viewspace-2214804/