1. 程式人生 > 其它 >(二十一)Kubernetes資源管理PV&PVC

(二十一)Kubernetes資源管理PV&PVC

kubernetes支援持久卷的儲存外掛:
https://kubernetes.io/docs/concepts/storage/persistent-volumes/
PersistenVolume(PV):對儲存資源建立和使用的抽象,使得儲存作為叢集中的資源管理,分為有靜態與動態。(可以連線:NFS,CEPG/GFS、Ceph)
PersistentVolumeClaim(PVC):讓使用者不需要關心具體的Volume實現細節

  • PV:提供者、提供儲存容量,由k8s配置的儲存,PV同樣是叢集的一類資源,
  • PVC:消費者、消費容量

注:PV與PVC成繫結關係。(容器應用-->卷需求模板-->資料卷定義)

一、 Kubernetes靜態PV使用

kubernetes支援持久卷的儲存外掛:
https://kubernetes.io/docs/concepts/storage/persistent-volumes/

  • 缺點:手動建立pv比較繁瑣、不適合大工程
  • 優點:小規模使用方便靈活

1、建立pvc yaml檔案

vim pvc.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx6
spec:
  containers:
  - name: nginx6
    image: nginx
    # 掛在點
    volumeMounts:
    - name: wwwroot
      mountPath: /usr/share/nginx/html
    ports:
    - containerPort: 80
  # 掛載來源
  volumes:
  - name: wwwroot
    # 定義PVC
    persistentVolumeClaim:
      # 定義PVC名稱
      claimName: my-pvc
---
apiVersion: v1
# 使用PVC型別
kind: PersistentVolumeClaim
metadata:
  # 與容器應用PVC相同
  name: my-pvc
spec:
  # 定義讀寫許可權
  accessModes:
    - ReadWriteMany
  # 請求資源
  resources:
    requests:
      # 儲存空間 5G
      storage: 5Gi

2、建立pv yaml檔案

vim pv.yaml
apiVersion: v1
# PV型別
kind: PersistentVolume
metadata:
  # PV名稱與PVC相同
  name: my-pv
spec:
  # 定義容量
  capacity:
    storage: 5Gi
  # 讀寫許可權
  accessModes:
    - ReadWriteMany
  # nfs分配網路儲存
  nfs:
    path: /data/nfs
    server: 192.168.1.115

3、執行建立pv容器

kubectl apply -f pv.yaml

4、檢視建立pv

kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
# RWX:讀寫模式、Available:為可用狀態
my-pv 5Gi RWX Retain Available 23s

5、建立pvc容器

kubectl apply -f pvc.yaml

6、檢視pvc建立容器

kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx6 1/1 Running 0 20s

7、檢視pv與pvc狀態

kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
# Bound:已經使用以成繫結裝填
persistentvolume/my-pv 5Gi RWX Retain Bound default/my-pvc 3m44s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
# 以繫結到pv
persistentvolumeclaim/my-pvc Bound my-pv 5Gi RWX 78s

8、nfs共享目錄下建立一個index.html

echo "<h1>xxxxxxxxx</h1>" > /data/nfs/index.html

9、進入容器測試

kubectl exec -it nginx6 bash
ls /usr/share/nginx/html
index.html

NFS型別PV模板

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0001
spec:
  capacity:        # PV容量
    storage: 5Gi
  volumeMode: Filesystem    # 掛載的型別,Filesystem\block
  accessModes:    # PV訪問模式
    - ReadWriteOnce    # 可以被單節點讀寫的模式掛載
  persistentVolumeReclaimPolicy: Recycle    # 回收策略
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /tmp
    server: 172.17.0.2

persistenVolumeReclaimPolicy: Recycle: 回收/Retain: 保留/Delete刪除(pvc刪除pv也會刪除,動態儲存的預設方式)

  • ReadWriteOnce # 可以被單節點讀寫的模式掛載
  • ReadWriteMany # 可以被多個點讀寫的模式掛載
  • ReadOnlyOnce # 可以多個節點只讀的模式掛載

PV的狀態:

  • Availabe:空閒PV,沒有被任何PVC繫結
  • Bond:已被PVC繫結
  • Released:PVC被刪除,但是資源未被重新使用
  • Failed:自動回收失敗

PVC模板

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:    #選擇和標籤匹配的PVC
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}

建立POD掛載PVC

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: myfrontend
      image: nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: mypd
  volumes:
    - name: mypd
      persistentVolumeClaim:
        claimName: myclaim

很多情況下:(建立PVC之後,一直繫結不上PV[Pending狀態])

  1. PVC的空間申請大小大於PV的大小
  2. PVC的StorageClassName沒有和PV一致
  3. PVC的accessMode和PV的不一致

建立掛載了PVC的Pod之後,一直處於Pending狀態:

  1. PVC沒有建立成功,或者被創
  2. PVC和Pod不在同一個Namespace

刪除PVC後---->k8s會建立一個用於回收的Pod---->根據PV的回收策略進行PV的回收---->回收完以後PV的狀態會變成可繫結的狀態也就是空閒狀態---->其他Pending狀態的PVC如果匹配到了這個PV,他就能和這個PV進行繫結。

二、Kubernetes 動態PV使用

Kubernetes支援動態供給的儲存外掛:
https://kubernetes.io/docs/concepts/storage/storage-classes/

  • Dynamic Provisioning機制工作的核心在於StorageClass的API物件。
  • StorageClass宣告儲存外掛,用於自動建立PV

建立動態PVStorageClass

1、建立storageclass相關檔案

1.1、vim storageclass-nfs.yaml:標識外掛建立storageclass名稱

apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
  # StorageClass名稱
  name: managed-nfs-storage
# 預設不支援nfs儲存,新增支援web外掛標識
provisioner: fuseim.pri/ifs

1.2、vim deployment-nfs.yaml:建立nfs相關儲存指定服務名稱

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      imagePullSecrets:
        - name: registry-pull-secret
      # 繫結角色定義的名稱
      serviceAccount: nfs-client-provisioner
      containers:
        # 映象拉取
        - name: nfs-client-provisioner
          image: lizhenliang/nfs-client-provisioner:v2.0.0
          # 自定義變數格式處理
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              # 指定標識外掛的值
              value: fuseim.pri/ifs
            - name: NFS_SERVER
              # nfs地址
              value: 192.168.1.115
            - name: NFS_PATH
              # 掛在路徑
              value: /data/nfs
      volumes:
        - name: nfs-client-root
          nfs:
            # nfs地址
            server: 192.168.1.115
            # 共享路徑
            path: /data/nfs

1.3、vim rbac.yaml:建立rbac授權apiserver

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: nfs-client-provisioner-runner
# 角色中可以訪問的許可權
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["list", "watch", "create", "update", "patch"]
---
# 角色繫結
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: run-nfs-client-provisioner
subjects:
  # 繫結角色 ServiceAccount
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io

2、建立檔案

kubectl apply -f storageclass-nfs.yaml
kubectl apply -f rbac.yaml
kubectl apply -f deployment-nfs.yaml

3、檢視建立的storageclass

kubectl get storageclass
NAME PROVISIONER AGE
managed-nfs-storage fuseim.pri/ifs 57s

4、檢視建立的nfs容器

kubectl get pods
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-565b4456f6-v9b97 1/1 Running 0 67s

使用動態 PV StorageClass 案例一:部署mysql

1、建立yaml配置檔案。vim mysql.yaml

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
  - port: 3306
    name: mysql
  # 建立service為無頭服務,標識容器
  clusterIP: None
  selector:
    app: mysql-public
---
apiVersion: apps/v1beta1
kind: StatefulSet
# 名稱
metadata:
  name: db
spec:
  # 指定service名稱
  serviceName: "mysql"
  # 標籤選擇器
  template:
    metadata:
      labels:
        app: mysql-public
    spec:
      # 映象容器編輯
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        # 建立資料庫使用者密碼
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"
        # 建立資料庫
        - name: MYSQL_DATABASE
          value: test
        # 啟用埠
        ports:
        - containerPort: 3306
        # 資料卷
        volumeMounts:
        # 掛在容器目錄
        - mountPath: "/var/lib/mysql"
          # 使用來源
          name: mysql-data
      # 使用資料捲來源
      volumes:
      # 資料卷名稱
      - name: mysql-data
        # 指定資料捲動態供給
        persistentVolumeClaim:
          # pvc動態供給名稱
          claimName: mysql-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  # pvc名稱
  name: mysql-pvc
spec:
  # 讀寫許可權
  accessModes:
    - ReadWriteMany
  # 使用的儲存類
  storageClassName: managed-nfs-storage
  # 定義容量
  resources:
    requests:
      storage: 5Gi

2、建立容器

kubectl apply -f mysql.yaml

3、檢視持久卷

kubectl get PersistentVolumeClaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-public-mysql-public-0 Bound default-mysql-public-mysql-public-0-pvc-2b4979b7-c89a-11e9-8b0e-000c29400317 2Gi RWO managed-nfs-storage 39m
mysql-pvc Bound default-mysql-pvc-pvc-b8584af2-c89d-11e9-9db0-000c292e28d6 5Gi RWX managed-nfs-storage 14m

使用動態 PV StorageClass 案例二

1、建立檔案

vim sts.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: nginx-statefulset
  namespace: default
spec:
  serviceName: nginx
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "managed-nfs-storage"
      resources:
        requests:
          storage: 1Gi

2、建立容器

kubectl create -f sts.yaml

3、檢視pod

kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-statefulset-0 1/1 Running 0 3m21s
nginx-statefulset-1 1/1 Running 0 3m16s
nginx-statefulset-2 1/1 Running 0 3m11s

4、檢視動態pv,pvc儲存kubectl get pv,pvc

kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/default-mysql-public-mysql-public-0-pvc-2b4979b7-c89a-11e9-8b0e-000c29400317 2Gi RWO Delete Bound default/mysql-public-mysql-public-0 managed-nfs-storage 63m
persistentvolume/default-www-nginx-statefulset-0-pvc-8063e4f9-c8a1-11e9-8b0e-000c29400317 1Gi RWO Delete Bound default/www-nginx-statefulset-0       managed-nfs-storage 11m
persistentvolume/default-www-nginx-statefulset-1-pvc-836c1466-c8a1-11e9-8b0e-000c29400317 1Gi RWO Delete Bound default/www-nginx-statefulset-1 managed-nfs-storage 11m
persistentvolume/default-www-nginx-statefulset-2-pvc-868a4a51-c8a1-11e9-8b0e-000c29400317 1Gi RWO Delete Bound default/www-nginx-statefulset-2 managed-nfs-storage 11m
persistentvolume/my-pv 5Gi RWX Retain Bound default/my-pvc 133m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/my-pvc Bound my-pv 5Gi RWX 133m
persistentvolumeclaim/mysql-public-mysql-public-0 Bound default-mysql-public-mysql-public-0-pvc-2b4979b7-c89a-11e9-8b0e-000c29400317 2Gi RWO managed-nfs-storage 63m
persistentvolumeclaim/www-nginx-statefulset-0 Bound default-www-nginx-statefulset-0-pvc-8063e4f9-c8a1-11e9-8b0e-000c29400317 1Gi RWO managed-nfs-storage 11m
persistentvolumeclaim/www-nginx-statefulset-1 Bound default-www-nginx-statefulset-1-pvc-836c1466-c8a1-11e9-8b0e-000c29400317 1Gi RWO managed-nfs-storage 11m
persistentvolumeclaim/www-nginx-statefulset-2 Bound default-www-nginx-statefulset-2-pvc-868a4a51-c8a1-11e9-8b0e-000c29400317 1Gi RWO managed-nfs-storage 11m

5、nfs伺服器會自動建立pv資料

[root@localhost nfs]# ls
default-www-nginx-statefulset-0-pvc-8063e4f9-c8a1-11e9-8b0e-000c29400317
default-www-nginx-statefulset-1-pvc-836c1466-c8a1-11e9-8b0e-000c29400317
default-www-nginx-statefulset-2-pvc-868a4a51-c8a1-11e9-8b0e-000c29400317