2018年、Kubernetes がやっと日本でも本格化してきた感じですね。
Rancher JP では、Rancher Meetup Tokyo #15で Storage特集をしたのですが、
その時用に作成していた資料を発表しないままになっていたのでQiitaに書いておこうと思います。
1. Rancher のストレージとは?
- 基本的にKubernetesのストレージRancherはそのUIをしています
- PV,PVC,StorageClassが実装されています
- Kubernetesなストレージなので、基本的にそのまま使えます
- CloudProviderRancherからKubernetesをデプロイする場合は、CloudProviderの指定が必須です
2. Kubernetes のストレージおさらい
今回の記事は、@hhiroshell (早川博)さんの資料をご本人に許可をいただいて使用しております。
早川さん、ありがとうございました。
3. Kubernetesでストレージを利用する方法
以下の3種類
- Volumeを直接指定してContainerにマウントする
- Volumeの要件を指定して、満たすものを自動的にマウントする
- Volumeの要件を指定して、満たすストレージを動的にプロビジョニングしてマウントする
3-1. Volume
- コンテナにマウント可能なボリュームを定義する情報
- ストレージの実態をポイントする
3-2. PersistentVolume(PV)/PersistentVolumeClaim(PVC)
- PVでストレージの実態をポイントする
- PVCで必要なディスクの要件(容量/書き込み権限の有無など)を指定しておき、それをVolumeから参照する
- PVCの要件を満たすPVが自動的に選択され、使用される
3-3. StorageClassを使ったPVCの動的プロビジョニング
- PVCでPVの代わりにStorageClassを指定
- 上記PVCをKubernetes内に作ると、StorageClassで設定されたProvisionerがストレージをプロビジョニングし、それが利用される
- StorageClassでは、ディスク速度やサービスレベル等のパラメータを指定
4. 今回作った構成
Rancher + Minikube + NFS の構成を作ってみました。
RancherをMinikubeに入れなかったのは、minikube環境をminikubeコマンドで作ったり消したり気軽にできるようにしておきたかったからです。NFSはUbuntu上で設定しました。
4-1. 2つのNFSマウント方法
上の図のようにNFSサーバーをストレージとして利用する方法は2つあります。
-
①通常のNFSサーバーとしてマウントする
- メリット
・他のコンテナー(or Pod)からも共有できる
・通常のNFSサーバーの使い方
・他のストレージを用意するよりも楽 - デメリット
・セキュリティーなし
・どこからでもマウント可能
- メリット
-
②Storage ClassとしてNFSサーバーをマウントする
- メリット
・コンテナ固有のストレージとして利用可能
・Namespace(or Project)間で覗かれることはない - デメリット
・NFSサーバーというよりもストレージクラスとしての利用
- メリット
4-2. NFSサーバーの作り方
NFSサーバーの作り方は一般的なので今回は省略します
5. 通常のNFSサーバーとしてマウントする
5-1. NFS ボリュームマウントを作るのに必要なもの
NFSサーバーがあればOK
5-2. 通常のNFSサーバーとしてマウントする
manifestファイルならこう
apiVersion: v1
kind: Pod
metadata:
name: welcome-nfs
spec:
containers:
- name: welcome-nfs
image: busybox
args: [/bin/sh, -c, 'tail -f /mnt/ngs/hello.txt']
volumeMounts:
- name: nfs-example
mountPath: "/mnt/nfs"
volumes:
- name: nfs-example
nfs:
server: 10.0.40.8
path: "/nfs-example"
Rancherでどうなるかも知りたいですよね。。
5-3. RancherでのNFSマウントの仕方
5-4. ボリュームを追加
「ボリューム」を開いて、「ボリュームを追加▽」を押して「エフェメラルボリュームを追加」をクリックします
5-5. NFS共有を選択
5-6. NFSサーバーの設定
NFSサーバー側のパスとサーバーIPアドレスを入力してvolumesを定義
5-7. コンテナー側マウント設定
6. Storage ClassとしてNFSサーバーをマウントする
6-1. Storage Classを作るのに必要なもの
- NFS
- nfs-client-provisioner
- NFS Client ProvisionerのRBAC
- NFSのStorage Class
を用意する
6-2. Manifest
6-2-1. nfs-provisioner-deployment.yaml
nfs-provisioner-deployment.yamlは以下の通り
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate
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
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: minikube.stylez.co.jp/nfs
- name: NFS_SERVER
value: 192.168.99.1
- name: NFS_PATH
value: /home/t-yano/ext/nfs
volumes:
- name: nfs-client-root
nfs:
server: 192.168.99.1
path: /home/t-yano/ext/nfs
6-2-2. nfs-storageclass.yaml
nfs-storageclass.yamlは以下の通り
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-nfs
provisioner: minikube.stylez.co.jp/nfs
6-2-3. nfs-client-provisioner-rbac.yaml
nfs-client-provisioner-rbac.yamlは以下の通り
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
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"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
7. Rancherの3つのメニューレベル
これらをRancherで同じように適用すればOK
なのですが、その前にRancherが持っているメニューのレベル(設定適用範囲)が3つあります。
それぞれのManifestをメニューレベルに応じた設定をする必要があります。
7-1. Rancher カタログの nfs-provisionerについて
Rancher カタログに nfs-provisioner ってのがあるよね?これ使えないの?
このNFSプロビジョナーは、KubernetesホストがNFSサーバーをマウントしているのが前提です
これは使えず、nfs-client-provisionerを利用する必要があります
7-2. NFSクライアントプロビジョナーをデプロイ
7-2-1. 名前とDockerイメージ
7-2-2. 環境変数
7-2-3. ボリューム
7-2-4. ラベル& アノテーション
7-2-5. ストレージクラスの作成
7-2-6. Storage Classを作成
7-2-7. nfs-client-rbacを設定
7-2-8. Rancher UIから設定
残念ながら、Rancher UIから設定できず。。
kubectl で nfs-rbac.yamlを適用します
$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
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"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
EOF
8. Pod をデプロイ
ここまで来てやっとPodをデプロイできます。