k8s之存儲卷及pvc


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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM