k8s-數據持久化存儲卷,nfs,pv/pvc,StorageClass


數據持久化-儲存卷

	我們知道,Pod是由容器組成的,而容器宕機或停止之后,數據就隨之丟了,那么這也就意味着我們在做Kubernetes集群的時候就不得不考慮存儲的問題,而存儲卷就是為了Pod保存數據而生的。存儲卷的類型有很多,我們常用到一般有四種:emptyDir,hostPath,NFS以及雲存儲(ceph, glasterfs...)等。

官方文檔

https://kubernetes.io/zh/docs/concepts/storage/volumes/#emptydir

https://kubernetes.io/zh/docs/concepts/storage/volumes/#hostpath

存儲卷類型

emptyDir,hostPath,NFS以及雲存儲(ceph, glasterfs...)等。

1.emptyDir

		emptyDir類型的volume在pod分配到node上時被創建,kubernetes會在node上自動分配一個目錄,因此無需指定宿主機node上對應的目錄文件。這個目錄的初始內容為空,當Pod從node上移除時,emptyDir中的數據會被永久刪除。
emptyDir Volume主要用於某些應用程序無需永久保存的臨時目錄.
作用:
1.用於容器間分享文件   
2.用於創建臨時目錄
注:emptyDir不能夠用來做數據持久化

例子1:

kind: Deployment
apiVersion: apps/v1
metadata:
  name: emptydir
spec:
  selector:
    matchLabels:
      app: emptydir
  template:
    metadata:
      labels:
        app: emptydir
    spec:
      containers:
        - name: nginx
          image: nginx
          volumeMounts:  ## 掛載
            - mountPath: /usr/share/nginx/nginx  ## 掛在目錄
              name: test-emptydir  # 存儲卷名稱
      volumes: ## 創建存儲卷
        - name: test-emptydir # 創建存儲卷名稱
          emptyDir: {}

2.hostpath

https://kubernetes.io/zh/docs/concepts/storage/volumes/#hostpath

警告:
HostPath 卷存在許多安全風險,最佳做法是盡可能避免使用 HostPath。 當必須使用 HostPath 卷時,它的范圍應僅限於所需的文件或目錄,並以只讀方式掛載。

如果通過 AdmissionPolicy 限制 HostPath 對特定目錄的訪問, 則必須要求 volumeMounts 使用 readOnly 掛載以使策略生效。

hostPath 卷能將主機節點文件系統上的文件或目錄掛載到你的 Pod 中。 雖然這不是大多數 Pod 需要的,但是它為一些應用程序提供了強大的逃生艙。

例如,hostPath 的一些用法有:

  • 運行一個需要訪問 Docker 內部機制的容器;可使用 hostPath 掛載 /var/lib/docker 路徑。
  • 在容器中運行 cAdvisor 時,以 hostPath 方式掛載 /sys
  • 允許 Pod 指定給定的 hostPath 在運行 Pod 之前是否應該存在,是否應該創建以及應該以什么方式存在。

除了必需的 path 屬性之外,用戶可以選擇性地為 hostPath 卷指定 type

支持的 type 值如下:

取值 行為
空字符串(默認)用於向后兼容,這意味着在安裝 hostPath 卷之前不會執行任何檢查。
DirectoryOrCreate 如果在給定路徑上什么都不存在,那么將根據需要創建空目錄,權限設置為 0755,具有與 kubelet 相同的組和屬主信息。
Directory 在給定路徑上必須存在的目錄。
FileOrCreate 如果在給定路徑上什么都不存在,那么將在那里根據需要創建空文件,權限設置為 0644,具有與 kubelet 相同的組和所有權。
File 在給定路徑上必須存在的文件。
Socket 在給定路徑上必須存在的 UNIX 套接字。
CharDevice 在給定路徑上必須存在的字符設備。
BlockDevice 在給定路徑上必須存在的塊設備。

當使用這種類型的卷時要小心,因為:

  • HostPath 卷可能會暴露特權系統憑據(例如 Kubelet)或特權 API(例如容器運行時套接字), 可用於容器逃逸或攻擊集群的其他部分。

  • 具有相同配置(例如基於同一 PodTemplate 創建)的多個 Pod 會由於節點上文件的不同 而在不同節點上有不同的行為。

  • 下層主機上創建的文件或目錄只能由 root 用戶寫入。你需要在 特權容器 中以 root 身份運行進程,或者修改主機上的文件權限以便容器能夠寫入 hostPath

hostPath 配置示例:****

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # 宿主上目錄位置
      path: /data
      # 此字段為可選
      type: Directory
      
注意: FileOrCreate 模式不會負責創建文件的父目錄。 如果欲掛載的文件的父目錄不存在,Pod 啟動會失敗。 為了確保這種模式能夠工作,可以嘗試把文件和它對應的目錄分開掛載,如 FileOrCreate 配置 所示。

hostPath FileOrCreate 配置示例

apiVersion: v1
kind: Pod
metadata:
  name: test-webserver
spec:
  containers:
  - name: test-webserver
    image: k8s.gcr.io/test-webserver:latest
    volumeMounts:
    - mountPath: /var/local/aaa
      name: mydir
    - mountPath: /var/local/aaa/1.txt
      name: myfile
  volumes:
  - name: mydir
    hostPath:
      # 確保文件所在目錄成功創建。
      path: /var/local/aaa
      type: DirectoryOrCreate
  - name: myfile
    hostPath:
      path: /var/local/aaa/1.txt
      type: FileOrCreate

3.pv/pvc(推薦使用)

nfs官方文檔

nfs官方文檔:https://kubernetes.io/zh/docs/concepts/storage/volumes/#nfs

作用

動態存儲,網絡存儲。動態生成存儲卷

安裝測試nfs

1. 在所有節點上安裝nfs(所有節點)
		yum -y install nfs-utils rpcbind
2.配置nfs
[root@sg-14 opt]# vi /etc/exports
/data/k8s  *(rw,sync,no_root_squash)  # 允許共享的ip和目錄
/home/jeff  192.168.0.216(rw,sync,no_root_squash)  # 允許共享的ip和目錄
/nfs/v1/  192.168.0.216(rw,no_root_squash)
/nfs/v2/  192.168.0.216(rw,no_root_squash)
/nfs/v3/  192.168.0.216(rw,no_root_squash)
/nfs/v4/  192.168.0.216(rw,no_root_squash)
/nfs/v5/  192.168.0.216(rw,no_root_squash)
/nfs/v6/  192.168.0.216(rw,no_root_squash)
/nfs/v7/  192.168.0.216(rw,no_root_squash)
/nfs/v8/  192.168.0.216(rw,no_root_squash)
/nfs/v9/  192.168.0.216(rw,no_root_squash)
/nfs/v10/ 192.168.0.216(rw,no_root_squash)


[root@sg-14 opt]# systemctl enable --now nfs
[root@sg-14 opt]# mkdir -pv /nfs/v{1..10}
[root@sg-14 opt]# cd /nfs/
[root@sg-14 opt]# systemctl restart rpcbind.service && systemctl restart nfs.service
3.測試k8s使用nfs
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs
spec:
  selector:
    matchLabels:
      app: nfs
  template:
    metadata:
      labels:
        app: nfs
    spec:
      nodeName: sg-16  # 指定部署機器
      containers:
        - name: nginx
          image: nginx
          volumeMounts:  # 掛載容器內部目錄
            - mountPath: /home/test
              name: nfs
      volumes: ## 存儲卷
        - name: nfs
          nfs:
            path: /nfs/v1  # master上目錄
            server: 192.168.0.214  # master機器ip
    
4. 使用pv/pvc來管理nfs
#########################################################################################
#  1、部署MySQL集群
#     1、創建命名空間
#     2、創建service提供負載均衡
#     3、使用控制器部署MySQL實例
###
#  2、部署Discuz應用
#     1、創建命名空間
#     2、創建Service提供負載均衡(Headless Service)
#     3、創建服務並掛載代碼
#     4、創建Ingress,用於域名轉發(https)
###
#  3、服務之間的互連
#     1、Discuz連接MySQL  --->  mysql.mysql.svc.cluster.local
#########################################################################################

pv/pvc管理nfs

官方文檔

https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/#reclaim-policy

pv/pvc解釋

注:pv是集群級資源,pvc是名稱空間級資源

PVC和PV的設計,類似“接口”和“實現”的思想,開發者只知道使用“接口”PVC,運維人員負責給“接口”綁定具體的實現PV,說白了PVC就是一種特殊的Volume存儲卷
PVC和PV的實現原理
PVC:描述 Pod想要使用的持久化屬性,比如存儲大小、讀寫權限等
PV:描述一個具體的Volume屬性,比如Volume的類型、掛載目錄、遠程存儲服務器地址等

1. PV 的訪問模式(accessModes)

模式 解釋
ReadWriteOnce(RWO) 可讀可寫,但只支持被單個節點掛載。
ReadOnlyMany(ROX) 只讀,可以被多個節點掛載。
ReadWriteMany(RWX) 多路可讀可寫。這種存儲可以以讀寫的方式被多個節點共享。不是每一種存儲都支持這三種方式,像共享方式,目前支持的還比較少,比較常用的是 NFS。在 PVC 綁定 PV 時通常根據兩個條件來綁定,一個是存儲的大小,另一個就是訪問模式。

2. PV 的回收策略(persistentVolumeReclaimPolicy)

策略 解釋
Retain 不清理, 保留 Volume(需要手動清理)
Recycle 刪除數據,即 rm -rf /thevolume/*(只有 NFS 和 HostPath 支持)
Delete 刪除存儲資源,比如刪除 AWS EBS 卷(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)

3. PV 的狀態

狀態 解釋
Available 可用。
Bound 已經分配給 PVC。
Released PVC 解綁但還未執行回收策略。
Failed 發生錯誤。

4.創建pv

kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv001
  labels:
    app: pv001
spec:
  nfs:
    path: /nfs/v2  # master機器共享目錄
    server: 192.168.0.214  # master機器
  capacity:
    storage: 20Gi  # 指定存儲卷大小
  persistentVolumeReclaimPolicy: Retain  # 回收策略
  accessModes: # 訪問模式,支持縮寫
    - "ReadWriteMany"
    - "ReadWriteOnce"
    
kubectl apply -f pv.yaml
[root@sg-14 nfs]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001   20Gi       RWO,RWX        Retain           Available                                   7s

STATUS狀態:無

5.pvc插件

官方文檔

https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/#access-modes

pvc使用pv-創建pvc

---
# 創建pv
kind: PersistentVolume
apiVersion: v1
metadata:
  name: pv001
  labels:
    app: pv001
spec:
  nfs:
    path: /nfs/v2  # master機器共享目錄
    server: 192.168.0.214  # master機器
  capacity:
    storage: 20Gi  # 指定存儲卷大小
  persistentVolumeReclaimPolicy: Retain  # 回收策略
  accessModes: # 訪問模式,支持縮寫
    - "ReadWriteMany"
    - "ReadWriteOnce"
---
# 創建名稱空間
apiVersion: v1
kind: Namespace
metadata:
  name: mysql 
  labels:
    app: test-Namespace
---
# 創建pvc存儲卷
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc1  # 存儲卷名字
  namespace: mysql # 指定名稱空間,pvc是名稱空間級資源
spec:
  accessModes:  # 訪問模式
    - "ReadWriteMany"
  resources:
    requests:
      storage: "6Gi"
      
kubectl apply -f pvc.yaml
[root@sg-14 nfs]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM          STORAGECLASS   REASON   AGE
pv001   20Gi       RWO,RWX        Retain           Bound    default/pvc1                           47m

[root@sg-14 nfs]# kubectl get pvc
NAME   STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc1   Bound    pv001    20Gi       RWO,RWX                       2m22s

狀態:Bound CLAIM:default/pvc1

pv-pvc.yaml 使用nfs

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pv-pvc-mysql
  namespace: mysql # 指定名稱空間
spec:
  replicas: 3 # 部署個數
  selector:
    matchLabels:
      app: pv-pvc
  template:
    metadata:
      labels:
        app: pv-pvc
    spec:
      containers:
        - name: mysql
          image: mysql:5.7 
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "123456"
          volumeMounts:  # 掛載容器內部目錄
            - mountPath: /var/lib/mysql
              name: pv-pvc
      volumes: ## 存儲卷master
        - name: pv-pvc
          persistentVolumeClaim:
            claimName: pvc1  # 指定存儲卷名字
            
kubectl apply -f pv-pvc.yaml
此時:所有的容器/var/lib/mysql目錄和master的/nfs/v2實現共享


kubectl exec -it npv-pvc-f76d748dd-ps7rs -- bash  # 進入容器
mysql -u root -p # 登陸數據庫

4.StorageClass

​ 在一個大規模的Kubernetes集群里,可能有成千上萬個PVC,這就意味着運維人員必須實現創建出這個多個PV,此外,隨着項目的需要,會有新的PVC不斷被提交,那么運維人員就需要不斷的添加新的,滿足要求的PV,否則新的Pod就會因為PVC綁定不到PV而導致創建失敗。而且通過 PVC 請求到一定的存儲空間也很有可能不足以滿足應用對於存儲設備的各種需求,而且不同的應用程序對於存儲性能的要求可能也不盡相同,比如讀寫速度、並發性能等,為了解決這一問題,Kubernetes 又為我們引入了一個新的資源對象:StorageClass,通過 StorageClass 的定義,管理員可以將存儲資源定義為某種類型的資源,比如快速存儲、慢速存儲等,kubernetes根據 StorageClass 的描述就可以非常直觀的知道各種存儲資源的具體特性了,這樣就可以根據應用的特性去申請合適的存儲資源了。

4.1定義StorageClass

​ 每一個存儲類都包含provisioner、parameters和reclaimPolicy這三個參數域,當一個屬於某個類的PersistentVolume需要被動態提供時,將會使用上述的參數域。

# 下載helm
wget https://get.helm.sh/helm-v3.3.4-linux-amd64.tar.gz

# 解壓
tar xf helm-v3.3.4-linux-amd64.tar.gz
# 安裝
mv linux-amd64/helm /usr/local/bin/

# 驗證
helm version

# 添加阿里雲鏡像倉庫
helm repo add ali-stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

# 添加官方倉庫
helm repo add stable https://kubernetes-charts.storage.googleapis.com/

# 添加微軟雲helm倉庫
helm repo add azure http://mirror.azure.cn/kubernetes/charts/

# 下載nfs
helm pull ckotzbauer/nfs-client-provisioner

### 解壓
[root@k8s-m-01 /opt]# tar -xf nfs-client-provisioner-1.0.2.tgz 

### 修改values.yaml
[root@k8s-m-01 /opt]# cd nfs-client-provisioner/
[root@k8s-m-01 /opt/nfs-client-provisioner]# vim values.yaml 
nfs:
  server: 192.168.0.214
  path: /nfs/v6 
storageClass:
  accessModes: ReadWriteMany  ## 修改訪問類型
  reclaimPolicy: Retain  ## 修改回收策略

### 安裝nfs-client
[root@k8s-m-01 /opt/nfs-client-provisioner]# helm install nfs-client ./
NAME: nfs-client
LAST DEPLOYED: Wed Dec  8 11:38:02 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

[root@sg-14 nfs-client-provisioner]# kubectl get sc

案例:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  namespace: default
  name: test-nfs
  labels:
    app: test-nfs
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-client
  resources:
    requests:
      storage: 8Gi
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: test-nfs-storageclass
  namespace: default
  labels:
    app: test-nfs
spec:
  selector:
    matchLabels:
      app: test-nfs
  template:
    metadata:
      labels:
        app: test-nfs
    spec:
      containers:
        - name: nginx
          image: nginx
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - mountPath: /usr/share/nginx/html
              name: test-nfs
      volumes:
        - name: test-nfs
          persistentVolumeClaim:
            claimName: test-nfs


免責聲明!

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



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