kubernetes-8-永続的なpv / pvc / StorageClass

1 PV / PVC / StorageClassを知る

ストレージの管理は、コンピューティングの管理における明らかな問題です。PersistentVolumeサブシステムは、ユーザーと管理者が消費パターンに基づいてストレージの詳細を提供する方法を抽象化するためのAPIを提供します。この目的のために、PersistentVolumeとPersistentVolumeClaimという2つの新しいAPIリソースを導入しました。

PersistentVolume(PV)は、クラスター内の管理者によって構成されたネットワークストレージのセクションですノードがクラスターリソースであるのと同じように、これはクラスター内のリソースです。PVはボリュームなどの容量プラグインですが、そのライフサイクルはPVを使用する単一のポッドから独立していますこのAPIオブジェクトは、NFS、iSCSI、またはクラウドプロバイダー固有のストレージシステムなど、ストレージの実装に関する詳細情報をキャプチャします。

PersistentVolumeClaim(PVC)は、ユーザーによって行われたストレージ要求です。ポッドに似ています。ポッドはノードリソースを消費し、PVCはPVリソースを消費しますポッドは、特定のレベルのリソース(CPUとメモリ)を要求できます。ステートメントは、特定のサイズとアクセスモードを要求できます(たとえば、読み取り/書き込みを1回、または読み取り専用を複数回行うことができます)。

PersistentVolumeClaimsを使用すると、ユーザーは抽象ストレージリソースを使用できますが、PersistentVolumesは通常、さまざまな問題に対してさまざまな属性(パフォーマンスなど)を必要とします。クラスタ管理者は、サイズやアクセスモードだけでなく、さまざまなPersistentVolumeをさまざまな方法で提供できる必要があります。これらのボリュームがどのように実装されているかを、ユーザーに通知する必要はありません。これらのニーズのために、StorageClassリソースがあります。

StorageClassは、管理者が提供するストレージの「クラス」を説明する方法を提供します。さまざまなクラスが、サービス品質レベル、バックアップ戦略、またはクラスター管理者によって決定された任意の戦略にマップされる場合があります。Kubernetes自体は、カテゴリが何を表しているかを自明です。この概念は、他のストレージシステムでは「プロファイル」と呼ばれることもあります。

PVCとPVの間には1対1の対応があります。

1.1ライフサイクル

PVはクラスター内のリソースです。PVCはこれらのリソースの要求であり、リソースのチェックとしても機能します。PVとPVCの間の相互作用は、次のライフサイクルに従います。

プロビジョニング——->バインディング——–>使用->リリース->リサイクル

(1)プロビジョニング
は、クラスター外のストレージシステムまたはクラウドプラットフォームを介してストレージ永続性サポートを提供します。
(1-1)静的プロビジョニング静的:クラスター管理者は複数のPVを作成します。これらは、クラスターのユーザーが使用できる実際のストレージに関する詳細情報を伝達します。それらはKubernetesAPIに存在し、消費に使用できます。

(1-2)動的の動的プロビジョニング:管理者によって作成された静的PVがユーザーのPersistentVolumeClaimと一致しない場合、クラスターはPVCのボリュームを動的に構成しようとする場合があります。この構成はStorageClassesに基づいています。PVCはクラスを要求する必要があり、動的に構成するには、管理者がクラスを作成して構成している必要があります。このクラスの宣言は、それ自体の動的構成を効果的に無効にするために必要です。
(2)
ユーザーをバインドしてpvcを作成し、必要なリソースとアクセスモードを指定します。使用可能なPVが見つかるまで、PVCはバインドされないままになります。
(3)
ユーザーを使用すると、ボリュームのようなポッドでpvc使用できます。
(4)リリース
ユーザーを解放してpvcを削除し、ストレージリソースを再利用すると、pvは「解放済み」ステータスになります。以前のデータは引き続き保持されるため、これらのデータはさまざまな戦略に従って処理する必要があります。そうしないと、これらのストレージリソースを他のPVCで使用できません。
(5)リサイクルリサイクル
pvは、保持、リサイクル、削除の3つのリサイクル戦略を設定できます。
(5-1)保持戦略:保持されたデータの手動処理を許可します。
(5-2)削除戦略:pvおよび外部に関連付けられたストレージリソースが削除され、プラグインのサポートが必要になります。
(5-3)リサイクル戦略:クリーンアップ操作を実行し、新しいPVCで使用できるようにするため、プラグインのサポートが必要です。

注:現在、NFSおよびHostPathタイプのボリュームのみがリカバリ戦略をサポートしています。AWSEBS、GCE PD、Azure Disk、およびCinderは削除戦略をサポートしています。

1.2PVタイプ

ここに画像の説明を挿入します

1.3PVボリュームステージステータス

(1)使用可能な
リソースが要求されていません。
(2)バインドされた
ボリュームが要求にバインドされています。
(3)解放された
要求が削除されます。ボリュームは解放された状態ですが、クラスターによって再要求されていません。
(4)失敗した
ボリュームの自動回復に失敗しました

1.4 pv3つのアクセス方法

https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes。
Kubenetesシステムでは、永続ストレージボリュームごとに3つのアクセス方法があります。ReadWriteOnce(RWO)、ReadOnlyMany(ROX)、ReadWriteMany(RWX)です。

現在の定義では、これら3つのメソッドはすべてノードレベルです。つまり、永続ボリュームの場合、RWOの場合、特定のKubernetesワーカーノード(以下、ノードと呼びます)にのみマウントできます。他のノードに再度マウントするために、システムはマルチアタッチエラーを報告します(もちろん、スケジュール可能なノードが1つしかない場合は、RWOでも複数のポッドで同時に使用できます)。

RWXの場合、同時に複数のノードにマウントして、異なるポッドで使用できます。

ここに画像の説明を挿入します
3つのアクセス方法。
ここに画像の説明を挿入します

2デモ:PV静的プロビジョニングを作成する

(1)まず、nfsサーバーのストレージボリュームに対応するディレクトリを作成します

cd /data/volumes
mkdir v{1,2,3,4,5}
echo "<h1>static stor 01</h1>" > v1/index.html
echo "<h1>static stor 02</h1>" > v2/index.html
echo "<h1>static stor 03</h1>" > v3/index.html
echo "<h1>static stor 04</h1>" > v4/index.html
echo "<h1>static stor 05</h1>" > v5/index.html

(2)nfs
#vim / etc / exportsの設定を変更します

/data/volumes/v1        *(rw,no_root_squash)
/data/volumes/v2        *(rw,no_root_squash)
/data/volumes/v3        *(rw,no_root_squash)
/data/volumes/v4        *(rw,no_root_squash)
/data/volumes/v5        *(rw,no_root_squash)

その中で、rw:読み取り/書き込み権限、読み取り専用権限のパラメータはroです。
その中で、no_root_squash:NFSサーバー共有ディレクトリユーザーの属性です。ユーザーがrootの場合、共有ディレクトリにはroot権限があります。
(3)nfs
#exportfs-arvの構成を表示します
ここに画像の説明を挿入します

(4)構成を有効にする
#showmount -e

2.1永続ボリュームPVを作成する

さまざまなストレージサイズとさまざまな読みやすさを備えた5つのPVを作成します。pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
    path: /data/volumes/v1
    server: myuse1
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  storageClassName: slow
  capacity:
    storage: 5Gi

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
    path: /data/volumes/v2
    server: myuse2
  accessModes: ["ReadWriteOnce"]
  storageClassName: slow
  capacity:
    storage: 5Gi

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/volumes/v3
    server: myuse3
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  storageClassName: slow
  capacity:
    storage: 5Gi

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
    path: /data/volumes/v4
    server: myuse4
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  storageClassName: slow
  capacity:
    storage: 10Gi

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
    path: /data/volumes/v5
    server: myuse5
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  storageClassName: slow
  capacity:
    storage: 15Gi

#kubectl apply -f pv.yaml
#kubectl get pv
ここに画像の説明を挿入します

#kubectl delete pv pv001指定されたpvを削除します
(1)リサイクル戦略:保持します
(2)使用可能なリソースが要求されていません

PVは、storageClassName属性をStorageClassの名前に設定することによって指定されるクラスを持つことができます。特定のカテゴリのPVは、そのカテゴリを要求するPVCにのみバインドできます。storageClassNameのないPVにはクラスがなく、特定のクラスを必要としないPVCにのみバインドできます。
以前は、storageClassName属性の代わりにアノテーションvolume.beta.kubernetes.io/storage-classが使用されていました。アノテーションは引き続き機能しますが、将来のKubernetesバージョンでは適用されなくなります。

2.2永続ボリューム宣言PVCを作成する

2.2.1セレクターとストレージクラスを指定する

pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
  namespace: default
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 2Gi
  storageClassName: slow
  selector:
    matchLabels:
      name: pv003

#kubectl get pvc
#kubectl get pv

2.2.2ストレージクラスのみを指定する

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
  namespace: default
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 6Gi
  storageClassName: slow

#kubectl get pv
ここに画像の説明を挿入しますpvc作成するには、6Gストレージが必要です。したがって、pv001、pv002、pv003とは一致しません。#
kubectl get pvc
ここに画像の説明を挿入します

2.2.3終了状態のpvを削除する

#kubectl patch pvc  mypvc  -p '{"metadata":{"finalizers":null}}'

2.3ポッドでPVCを使用する

2.31テストTomcatイメージ

#docker pull tomcat
#docker run -id -p 8080:8080 --name=c_tomcat -v /data/volumes/:/usr/local/tomcat/webapps tomcat:latest
#docker exec -it c_tomcat /bin/bash

http://10.23.241.97:8080/v1/index.html
http://10.23.241.97:8080/v2/index.html
ここに画像の説明を挿入します#docker stop c_tomcat

2.3.2ファイルdeployment.yaml

apiVersion: v1
kind: Pod
metadata:
  name: vol-pvc
  namespace: default
  labels:
    app: myapp
spec:
  volumes:
  - name: html
    persistentVolumeClaim:
      claimName: mypvc
  containers:
  - name: myapp
    image: tomcat:latest
    volumeMounts:
    - name: html
      mountPath: /usr/local/tomcat/webapps

デプロイ

#kubectl apply -f deployment.yaml
#kubectl exec -it vol-pvc -n default -- /bin/bash

ディレクトリ/ data / volumes / v4
#mkdir aa
#cp index.html./aaにサブディレクトリを作成します。
ポッドを入力してTomcatの操作を表示します。
ここに画像の説明を挿入します

2.3.3ファイルservice.yaml

kind: Service
apiVersion: v1
metadata:
  name: mysvc
  namespace: default
spec:
  type: NodePort
  ports:
    - port: 8123
      nodePort: 32001
      targetPort: 8080
  selector:
    app: myapp

サービスに関係する
ポートには、主に3つのタイプがあります(1)ポートはclusterIP上のサービスによって公開されるポートを表し、clusterIP:ポートはkubernetesサービスにアクセスするためにクラスターに提供される入り口です。
(2)targetPort
はcontainerPortでもあり、targetPortはポッド上のポートです。ポートとnodePortからのデータは、最終的にkube-proxyを介してバックエンドポッドのtargetPortに流れ込み、コンテナーに入ります。
(3)nodePort
nodeIP:nodePortは、クラスターの外部からkubernetesサービスにアクセスするために提供される入り口です。

通常、portとnodePortはどちらもサービスポートです。前者はクラスター内からのアクセスサービスに公開され、後者はクラスター外からアクセスされるサービスに公開されます。これら2つのポートから到着したデータは、リバースプロキシkube-proxyを通過して、バックエンド固有のポッドのtargetPortに流れ込み、ポッドのコンテナーに入る必要があります。

ここに画像の説明を挿入します

サービス作成のタイプは異なり、さまざまなモードに分けることができます。
(1)ClusterIPデフォルトモードClusterIPが生成されるかどうかによって、通常のサービスとヘッドレスサービスの2つのタイプに分けることができます。
(1-1)通常のサービス:クラスター内でアクセス可能な固定仮想IP(クラスターIP)をKubernetesサービスに割り当てる、クラスター内のアクセスが実現されます。最も一般的な方法。
(1-2)ヘッドレスサービス:このサービスは、クラスターIPを割り当てたり、リバースプロキシと負荷分散にkube-proxyを使用したりしません。代わりに、DNSはアクセス用の安定したネットワークIDを提供し、DNSはヘッドレスサービスのバックエンドをpodIPリストに直接解決します。主にStatefulSetによって使用されます。

(2)NodePort:クラスターIPの使用に加えて、サービスのポートをクラスター内の各ノードの同じポートにマップし、nodeIP:nodePortを介してクラスターの外部からサービスにアクセスします。
ここに画像の説明を挿入しますウェブページを見る
ここに画像の説明を挿入します

2.4PVCを削除する

一般的な削除手順は次のとおりです。最初の削除ポッドは、その後、PVC、最後にPV
(1)削除ポッド
#kubectl削除ポッドvolumeop-基本csgvg-275778418 -n kubeflow
#kubectl削除ポッドvolumeop-基本csgvg-3408782246 -n kubeflow
(2 )PVCの
削除#kubectl delete pvc volumeop-basic-csgvg-my-pvc -n kubeflow
(3)pvの削除
pvcを削除すると、pvは自動的に削除されます。

3ストレージクラスに基づくPV動的プロビジョニングを実現します

ステートフルアプリケーションをk8sにデプロイする場合、通常、データ永続ストレージが必要です。
ストレージクラスに基づいて、自動PV供給を実現します;
(ストレージクラスを作成し、リソースリストでアドレスと共有マウントボリュームディレクトリを指定して、永続ストレージを実現します)
プロジェクトのダウンロード:

for file in class.yaml deployment.yaml rbac.yaml test-claim.yaml ; 
do wget https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/$file ;
done

3.1 class.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-nfs-storage
provisioner: fuseim.pri/ifs
parameters:
  archiveOnDelete: "false"

プロビジョナー:fuseim.pri / ifs#または別の名前を選択し、デプロイメントのenv PROVISIONER_NAME 'と一致する必要があります

3.2 rbac.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
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: ["create", "update", "patch"]

---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io

---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]

---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

3.3deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: fuseim.pri/ifs
            - name: NFS_SERVER
              value: 192.168.0.165
            - name: NFS_PATH
              value: /some/path
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.0.165
            path: /some/path

ストレージクラスを作成する

#kubectl create -f class.yaml

#kubectl create -f rbac.yaml

#kubectl create -fdeployment.yaml

3.4デフォルトとしてストレージクラスを変更する

defaultは、このストレージクラスがデフォルトであることを示します。

# kubectl patch storageclass managed-nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

4テスト

PVCまたは宣言されたストレージアプリケーションをデプロイし、PVが自動的に作成され、PVCに自動的にバインドされるかどうかをテストします。

4.1 test-claim.yaml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
  annotations:
    volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi

テスト

#kubectl create -f test-claim.yaml

4.2 nginx-demo.yaml

StatefulSetにデプロイされたNginxアプリケーション

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
     app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        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

おすすめ

転載: blog.csdn.net/qq_20466211/article/details/113251635