LoginSignup
11
7

More than 3 years have passed since last update.

【KubernetesのPersistentVolume】その1- 外部ストレージをPodにmountする

Last updated at Posted at 2019-06-19

概要

KubernetesのPersistentVolume(永続ストレージ)を使って、NFSサーバーをPodにmountする。
Dynamic Provisioningについてはこのページでは触れない。以下を参照。
【KubernetesのPersistentVolume】その2- Dynamic Provisionerを使ってNFSサーバーをPodにmountする

目次

前提知識

PersistentVolumeの仕組み

まず、PersistentVolumeがPodにmountされる仕組みについて説明する。
以下の表の用に、3つの定義ファイルを用意する。

filename Resource description
pod.yml Pod Podの定義
persistent-volume-claim.yml PersistentVolumeClaim Podが要求するVolumeのspecを定義する
persistent-volume.yml PersistentVolume Volumeの定義
  • persistent-volume.ymlでは、Volumeの定義をする。
  • pod.ymlでpodの定義と、関連付けるpersistent-volume-claim.ymlを定義する。
  • persistent-volume-claim.ymlには、Podが要求するspecのVolumeの定義をする。
  • PersistentVolumeClaimは、要求に一番近いspecのPersistentVolume探し、mountする。

つまりPodは、PersistentVolumeClaimを通して「こういうspecのVolumeが欲しい」と要求を出すと、その要求に一番近いPersistentVolumeがmountされるという仕組みになっている。
例えば、Podが5GiのVolumeが欲しいと要求を出したが、実際には10Gi, 20GiのVolumeしか存在していない場合、一番近い10GiのVolumeがmountされる。

ただし、persistent-volume.ymlとmetadata.name、metadata.labelsと、persistent-volume-claim.ymlのspec.selector.matchLabels、spec.selector.matchExpressionsの値を合わせることで、PersistentVolumeとPersistentVolumeClaimのマッチングをより明示的に、期待したとおりにできる。
ここで指定した条件が見つからない場合には自動割当、最悪いずれも割り当てられないという状態になる。

以下のページが分かりやすい。
参考:KubernetesのConfig&Storageリソース(その2)

Dynamic Provisioningについて

Dynamic Provisioningを利用することで、PersistentVolumeClaimが要求を出したタイミングで、動的にPersistentVolumeを作成することが可能となるが、ここでは触れず、以下のページで説明する。
【KubernetesのPersistentVolume】その2- Dynamic Provisionerを使ってNFSサーバーをPodにmountする

ハンズオン

実際にやってみる。
今回はNFSサーバーの/var/share/nfsディレクトリを、Podの/usr/share/nginx/htmlにmountする。

環境

  • CentOS 7.6
  • Minikube v1.1.1
  • Kubernetes v1.14.3

ここではMinikubeで構築した環境のPodに、NFSサーバーをmountする。
関連記事:Minikubeを使ってローカルにkubernetes環境を構築

事前準備

NFSサーバーの構築

以下を参考にNFSサーバーを構築する。

PersistentVolume

Volumeの定義をする。

persistent-volume.yml
apiVersion: v1
kind: PersistentVolume
###################################################################
# persistent-volume-claim.ymlのspec.selector.matchLabels、
# spec.selector.matchExpressions以下の値と合わせることで
# PersistentVolumeとPersistentVolumeClaimのマッチング精度を高める。
###################################################################
metadata:
  # persistent-volume-claim.ymlのspec.selector.matchLabels.typeと合わせる
  name: nfs001
  labels:
    type: nfs
    environment: stg
  # Annotaion: https://blog.a-know.me/entry/2018/08/13/223633
  annotations:
    volume.beta.kubernetes.io/storage-class: "slow"
spec:
  # Volumeの容量を定義する
  capacity:
    storage: 1Gi
  ##################################################
  # ReadWriteOnce: 1つのノードからR/Wでマウントできる
  # ReadOnlyMany: 複数のノードからReadOnlyでマウントできる
  # ReadWriteMany: 複数のノードからR/Wでマウントできる
  ##################################################
  accessModes:
    - ReadWriteMany
  # PersistentVolumeClaim を削除した時の動作
  persistentVolumeReclaimPolicy: Recycle
  # persistent-volume-claim.ymlのspec.storageClassNameと合わせる
  storageClassName: slow
  # mountコマンドの-oオプション。hard, soft, nolock
  mountOptions:
    - hard
  nfs:
    # mountするNFSサーバーのディレクトリ
    path: /var/share/nfs
    # NFSサーバーのホスト
    server: xxx.xxx.xxx.xxx

PersistentVolumeClaim

Podが要求するPersistentVolumeの内容を定義する。

persistent-volume-claim.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  # pod.ymlのspec.volumes.persistentVolumeClaim.classNameと合わせる
  name: nfs-claim1
  # Annotaion: https://blog.a-know.me/entry/2018/08/13/223633
  annotations:
    "volume.beta.kubernetes.io/storage-class": "slow"
# 要求するpersistentVolumeのspec
spec:
  selector:
    matchLabels:
      # persistent-volume.ymlのmetadata.labels.typeと合わせる
      type: "nfs"
    matchExpressions:
      ###################################################################
      # persistent-volume.ymlのmetadata.labels以下の値と合わせることで
      # PersistentVolumeとPersistentVolumeClaimのマッチング精度を高める。
      # operatorはIn, NotIn, Exists, DoesNotExistのどれかを選ぶ。
      # https://kubernetes.io/docs/concepts/storage/persistent-volumes/
      ###################################################################
      - {key: environment, operator: In, values: [stg]}
  ##################################################
  # ReadWriteOnce: 1つのノードからR/Wでマウントできる
  # ReadOnlyMany: 複数のノードからReadOnlyでマウントできる
  # ReadWriteMany: 複数のノードからR/Wでマウントできる
  ##################################################
  accessModes:
    - ReadWriteMany
  # PersistentVolumeに要求するリソース
  resources:
    requests:
      storage: 1Gi
  # persistent-volume.ymlのspec.storageClassNameと合わせる
  storageClassName: slow

Pod

Podを定義する。

pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: my-nginx-pod
spec:
  # コンテナの定義
  containers:
  - name: nginx-container
    image: nginx
    ports:
      - containerPort: 80
    # マウントするディレクトリを指定
    volumeMounts:
      # 以下のspec.volumes.nameと合わせる
      - name: mydata
        # mountするコンテナ内のディレクトリ
        mountPath: "/usr/share/nginx/html"
  volumes:
    # 上記のspec.containers.volumeMounts.nameと合わせる
    - name: mydata
      # 要求(mount)するPersistentVolumeClaimを指定
      persistentVolumeClaim:
        # persistent-volume-claim.ymlのmetadata.nameと合わせる
        claimName: nfs-claim1

作成

$ sudo kubectl apply -f persistent-volume.yml -f persistent-volume-claim.yml -f pod.yml
persistentvolume/nfs001 created
persistentvolumeclaim/nfs-claim1 created
pod/my-nginx-pod created

起動確認

Podが起動した。

$ sudo kubectl get pod
NAME           READY   STATUS    RESTARTS   AGE
+my-nginx-pod   1/1     Running   0          32s

PersistentVolumeが作成された。正常に作成されるとSTATUSがBoundになる。

NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE
+nfs001   1Gi        RWX            Recycle          Bound    default/nfs-claim1   slow                    36s                                               50s

PersistentVolumeClaimが作成された。

$ sudo kubectl get pvc
NAME         STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
+nfs-claim1   Bound    nfs001   1Gi        RWX            slow           38s

mountされているか確認

NFSサーバーの/var/share/nfsディレクトリを、Podの/usr/share/nginx/htmlにmountしたので、
まず、NFSサーバーの/var/share/nfsにテスト用ファイルを作成する。

$ echo 'This is a sample page.' > /var/share/nfs/index.html

次に、Podで/var/share/nfsが/usr/share/nginx/htmlにmountされているか確認。
index.htmlが見えればOK。

$ sudo kubectl exec -it my-nginx-pod ls /usr/share/nginx/html
index.html

$ sudo kubectl exec -it my-nginx-pod cat /usr/share/nginx/html/index.html
This is a sample page.

その他

PersistentVolumeが完全にCreateされる前にPodを起動すると以下のWarningが出るが、最終的にmountされていることが確認できれば問題ない。

$ sudo kubectl describe pod my-nginx-pod
Events:
  Type     Reason            Age                    From               Message
  ----     ------            ----                   ----               -------
  Warning  FailedScheduling  6m25s (x2 over 6m25s)  default-scheduler  pod has unbound immediate PersistentVolumeClaims
  Normal   Scheduled         6m23s                  default-scheduler  Successfully assigned default/my-nginx-pod to minikube
  Normal   Pulling           6m23s                  kubelet, minikube  Pulling image "nginx"
  Normal   Pulled            6m19s                  kubelet, minikube  Successfully pulled image "nginx"
  Normal   Created           6m19s                  kubelet, minikube  Created container nginx
  Normal   Started           6m19s                  kubelet, minikube  Started container nginx

関連記事

参考

11
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7