K8s的存儲卷:
它有四種存儲卷:
1. emptyDir: 空目錄,這種存儲卷會隨着Pod的刪除而被清空,它一般作為緩存目錄使用,或臨時目錄,
當做緩存目錄時,通常會將一塊內存空間映射到該目錄上,讓Pod做為緩存目錄使用。
2. hostPath
SAN(存儲區域網絡): iSCSI,FB
NAS(網絡附加存儲): nfs,cifs
分布式存儲: Glusterfs, ceph(rbd), cephfs
雲存儲: EBS(彈性塊存儲),Azure Disk
#emptyDir存儲卷的示例: vim pod-volume.yaml apiVersion:v1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend annotations: magedu.com/created-by: “cluster admin” spec: containers: - name: httpd image: busybox:latest imagePullPolicy: IfNotPresent #設定鏡像策略為即便本地沒有鏡像也不去下載. command: ["/bin/httpd","-f","-h", " /data/web/html"] ports: - name: http containerPort: 80 volumeMounts: #存儲卷可被一個Pod中的多個容器掛載.誰需要就定義掛載即可. - name: html mountPath: /data/web/html/ - name: busybox image: busybox: latest imagePullPolicy: IfNotPresent volumeMounts: - name: html mountPath: /data/ command: - “/bin/sh” - “-c” - "while true; do echo $(date) >> /data/index.html; sleep 2; done” volumes: - name: html emptyDir: {}
#開始創建Pod
kubectl apply -f pod-volume.yaml
kubectl get pods
kubectl exec -it pod-demo -c busybox -- /bin/sh #聯入pod-demo這個Pod中叫busybox的容器中.
#注意:
當一個Pod中有多個容器時,當Pod啟動出現錯誤,可通過
kubectl describe pods pod-demo #查看其中每個容器的Status,來確認每個容器的運行狀態。
gitRepo類型的存儲卷:
gitRepo:這種類型的存儲卷是在容器啟動時,將遠程git倉庫中的數據(如: 網站代碼)給克隆一份到本地,然后啟動容器使用該克隆的數據來提供服務,這份克隆的數據在容器運行過程中不會將更新的數據同步到git倉庫中,同時git倉庫中的更新也不會同步到該容器中,若要實現當git倉庫發生改變時,能同步到容器的存儲卷中,還要借助於輔助容器,每隔一段時間就去克隆一份git倉庫中的數據, 當本地數據改變時,再同步到git倉庫中。
hostPath類型的存儲卷:
它有一下幾種類型:
1. DirectoryOrCreate: 它可以是宿主機上的一個已存在的目錄,也可不存在,若不存在則自動創建.
2. Directory: 它必須是宿主機上一個已經存在的目錄。
3. FileOrCreate: 它可以是宿主機上的一個文件,若此文件不存在則創建一個空文件來掛載。
4. File:宿主機上的一個已經存在的文件,若不存在則報錯。
5. Socket:宿主機上一個已經存在的Unix Socket文件.
6. CharDevice: 宿主機上一個已存在的字符類型的設備文件.
7. BlockDevice: 宿主機上一個已存在的塊類型的設備文件。
#創建一個hostPath類型的存儲卷示例: vim pod-hostpath-vol.yaml apiVersion: v1 kind: Pod metadata: name: pod-hostpath-vol namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html/ volumes: - name: html hostPath: #這是定義宿主機上那個目錄作為容器myapp的存儲卷的. path: /data/pod/volume1 type: DirectoryOrCreate
創建Pod前的准備:
1. 因為不確定Pod會被調度到那個節點上,因此再兩個節點上都創建/data/pod/volume1
並再該目錄中都創建一個網頁文件,並有意讓兩個節點上的目錄中的網頁文件內容不同
以便查看效果。
創建Pod
kubectl apply -f pod-hostpath-vol.yaml
kubectl get pods -o wide
curl http://Pod_IP
#刪除看它若調度到第二個節點上,繼續訪問Pod_IP,會發現依然可訪問.
#但這僅實現了節點級別數據持久,若節點掛了,數據依然不保!
kubectl delete -f pod-hostpath-vol.yaml
NFS類型的網絡共享存儲卷:
1. 配置前的准備工作
node10:
在集群外的一台主機上啟動NFS服務,讓它來提供網絡共享存儲.
yum install -y nfs nfs-utils
vim /etc/exports
/data/volumes 192.168.111.0/24(rw,no_root_squash)
mkdir -pv /data/volumes
systemctl start nfs
2. 在集群內運行Pod的兩個宿主機上測試掛載nfs共享,若能掛載,則Pod一定是能使用NFS共享存儲的。
yum install -y nfs-utils
mount -t nfs node10:/data/volumes /mnt #若能成功掛載,就可以卸載了.
3. 創建NFS 共享存儲卷的配置清單: vim pod-nfs-vol.yaml apiVersion: v1 kind: Pod metadata: name: pod-nfs-vol namespace: default spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: html mountPath: /usr/share/nginx/html/ volumes: - name: html nfs: path: /data/volumes server: node10.test.com #先測試直接讓Pod掛載NFS共享
#應用上面的清單文件,創建Pod來測試
kubectl apply -f pod-nfs-vol.yaml
kubectl get pods
node10: #在NFS共享目錄中創建index.html
echo “<h1> NFS share stroage server </h1>” >> /data/volumes/index.html
回到pod所在節點:
curl http://Pod_IP #可以看到正常返回NFS Share ....的信息.
PVC 使用示例:
PV的訪問模型:
accessModes:
ReadWriteOnce【簡寫:RWO】: 單路讀寫,即僅能有一個節點掛載讀寫
ReadOnlyMany【ROX】: 多路只讀
ReadWriteMany【RWX】:多路讀寫
1. 准備后端存儲環境:
node10:
mkdir /data/volumes/{v1,v2,v3,v4,v5}
vim /etc/exports
/data/volumes/v1 192.168.111.0/24(rw,no_root_squash)
/data/volumes/v2 192.168.111.0/24(rw,no_root_squash)
/data/volumes/v3 192.168.111.0/24(rw,no_root_squash)
exportfs -arv
showmount -e
2. 將這幾個共享存儲卷在K8s上定義為PV vim pv-demo.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv01 #PV是集群級別的資源,因此它不能定義在名稱空間中,它可以被任何名稱空間使用. 名稱空間也不能嵌套,因為它也是集群級別的資源. labels: name: pv01 rate: high #添加一個速度標簽,用於標明其存儲效率更高,以便后期標簽選擇器選擇. spec: nfs: path: /data/volumes/v1 server: node10.test.com #對於訪問模型,可定義為底層共享存儲的子集,但不能是超集 #即: NFS支持RWO,ROX,RWX,但我創建PV時,可只提供其中一個或多個. accessModes: ["ReadWriteMany", “ReadWriteOnce”] capacity: #對於存儲能力,它的單位有:T,P,G,M,K或 Ti,Pi,Gi,Mi,Ki 區別:加i的是以1024為換算單位的。 storage: 2Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv02 labels: name: pv02 rate: high spec: nfs: path: /data/volumes/v2 server: node10.test.com accessModes: ["ReadWriteMany","ReadOnlyMany"] capacity: storage: 5Gi --- apiVersion: v1 kind: PersistentVolume metadata: name: pv03 labels: name: pv03 rate: high spec: nfs: path: /data/volumes/v3 server: node10.test.com accessModes: ["ReadWriteMany","ReadOnlyMany"] capacity: storage: 10Gi
創建PV
kubectl apply -f pv-demo.yaml
kubectl get pv
RECLAIM POLICY:回收策略
Retain: 保留,即若Pod綁定了一個PVC,PVC綁定了一個PV,后來Pod刪除了,那么PV中的數據要怎么處理?
Retain是默認回收策略,即這些數據保留着,以便Pod再次創建時還能使用。
Released: 這種回收策略是, 不保留數據, 即Pod刪除,則PV自動回收,清空里面的數據,並允許其他Pod綁定使用.
Delete: 刪除,即PVC和PV解除綁定后,PV自動刪除.數據也就被清空了。
創建PVC: vim pod-pvc-vol.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc namespace: default spec: #它必須是PV的子集,即PV必須能符合它的要求. accessModes: ["ReadWriteMany"] resources: requests: storage: 6Gi --- 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
# kubectl apply -f pod-pvc-vol.yaml #驗證: # kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv01 1Gi RWO,RWX Retain Available 7m3s pv02 2Gi ROX,RWX Retain Available 7m3s pv03 5Gi ROX,RWX Retain Available 6m3s pv04 10Gi ROX,RWX Retain Bound default/mypvc 6m3s pv05 20Gi ROX,RWX Retain Available 6m3s # kubectl describe pod pod-vol-pvc Name: pod-vol-pvc Namespace: default ..... Mounts: /var/lib/nginx/html from html (rw) /var/run/secrets/kubernetes.io/serviceaccount from default-token-6xlcj (ro) ....... Volumes: html: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: mypvc ReadOnly: false # kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE mypvc Bound pv04 10Gi ROX,RWX 100s # kubectl describe pvc mypvc Name: mypvc Namespace: default StorageClass: Status: Bound Volume: pv04 ....... Capacity: 10Gi Access Modes: ROX,RWX VolumeMode: Filesystem Events: <none> Mounted By: pod-vol-pvc #這里可查看此PVC當前掛載到那個容器里了,本例中是掛載到 pod-vol-pvc這個容器中了。 注意: PVC 它是K8s中的標准資源,它存儲在API Server的etcd(集群狀態存儲)存儲數據庫中,即便Pod因為故障被刪除了,依然不影響PVC的存在,下次Pod啟動后,依然可以使用PVC.