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/
