Level 2: ステートフルコンテナの実現¶
目的・ゴール: アプリケーションのデータ永続化を実現¶
アプリケーションは永続化領域がないとデータの保存ができません。 KubernetesではStatic provisioningとDynamic provisioningの2つの永続化の手法があります。
このレベルではDynamic provisioningを実現するためDynamic provisionerであるTridentをインストールし、 マニフェストファイルを作成しデータの永続化をすることが目標です。
流れ¶
Dynamic storage provisioningを実現(Tridentのインストール)
StorageClassの作成
PVCをkubernetesマニフェストファイルに追加
- 作成したStorageClassを使用する
- PVCをkubernetesにリクエストした時点で動的にストレージがプロビジョニングされる
アプリケーションを稼働させて永続化ができていることを確認
コンテナでの永続データのカテゴライズ¶
コンテナ化されたアプリケーション、環境での永続データは 以下のように分類して考え必要な物をリストアップしました。
- データベースのデータファイル、ログファイル
- 各サーバのログファイル
- 設定ファイル
- 共有ファイル
Dynamic provisioning¶
ステートフルコンテナを実現する上でストレージは重要なコンポーネントになります。
Dynamic volume provisiong はオンデマンドにストレージをプロビジョニングするためのものです。
Static provisioning、Dynamic provisioning それぞれを比較します。
Static provisioningの場合、クラスタの管理者がストレージをプロビジョニングして、PersitentVolumeオブジェクトを作成しkubernetesに公開する必要があります。
Dynamic provisioningの場合、Static provisioningで手動で行っていたステップを自動化し、管理者がおこなっていたストレージの事前のプロビジョニング作業をなくすことができます。
StorageClassオブジェクトで指定したプロビジョナを使用し、動的にストレージリソースをプロビジョニングすることができます。
StorageClassには様々なパラメータを指定することができアプリケーションに適したストレージカタログ、プロファイルを作成することができ、物理的なストレージを抽象化するレイヤとなります。
Dynamic Provisioningを実現するために ストレージを制御する Provisioner が必要になります。その標準的なインターフェースとして 2019/1からContainer Storage InterfaceがGAになり、 Kubernetes 1.14からは CSI 1.1がサポートされています。
ネットアップはDynamic provisioningを実現するためのNetApp Tridentというprovisionerを提供しています。
Tridentは CSIを使わない従来同様のTridentと CSIを使う CSI Tridentが提供されていますが、 19.07からは CSI Tridentがデフォルトでインストールされるようになりました。
このレベルではTridentでDynamic provisioningを行い、アプリケーションのデータ永続化を実現します。
NetApp Tridentのインストール¶
Dynamic storage provisioningを実現するためNetApp Tridentを導入します。 TridentはPodとしてデプロイされ通常のアプリケーションと同様に稼働します。
インストール事前準備¶
Trident のインストールでk8sクラスタの管理者権限が必要になります。
$ kubectl auth can-i '*' '*' --all-namespaces
バックエンドに登録するストレージのマネジメントIP(配布資料のsvmXXのIPアドレス)にk8sクラスタのコンテナから疎通が取れるかを確認します。
$ kubectl run -i --tty ping --image=busybox --restart=Never --rm -- ping [マネジメントIP]
Tridentインストール(19.07〜)¶
バイナリをダウンロードしてインストールします。(例はバージョン19.07.0)
$ wget https://github.com/NetApp/trident/releases/download/v19.07.0/trident-installer-19.07.0.tar.gz
$ tar -xf trident-installer-19.07.0.tar.gz
$ cd trident-installer
Tridentの制御にはtridentctlを使います。
tridentctl
ユーティリティではドライランモードとデバッグモードがオプションで指定できます。
2つを設定し、実行すると以下のように必要事項を事前チェックし、その内容をすべて標準出力にプリントします。
まずは、ドライランモードで実行し問題ないことを確認します。
Tridentをインストールするネームスペースを作成します。
$ kubectl create ns trident
namespace/trident created
Tridentのインストーラーをドライランモードで実行します。
$ ./tridentctl install --dry-run -n trident -d
DEBU Initialized logging. logLevel=debug
DEBU Running outside a pod, creating CLI-based client.
DEBU Initialized Kubernetes CLI client. cli=kubectl flavor=k8s namespace=default version=1.11.0
DEBU Validated installation environment. installationNamespace=trident kubernetesVersion=
DEBU Parsed requested volume size. quantity=2Gi
DEBU Dumping RBAC fields. ucpBearerToken= ucpHost= useKubernetesRBAC=true
DEBU Namespace does not exist. namespace=trident
DEBU PVC does not exist. pvc=trident
DEBU PV does not exist. pv=trident
- snip
INFO Dry run completed, no problems found.
- snip
ドライランモードで実施すると問題ない旨(INFO Dry run completed, no problems found.) が表示されれば、インストールに必要な事前要件を満たしていることが確認できます。 バージョン、実行モードによってはログの途中に出力されることもあるためログを確認しましょう。
上記の状態まで確認できたら実際にインストールを実施します。
$ ./tridentctl install -n trident -d
DEBU Initialized logging. logLevel=debug
DEBU Running outside a pod, creating CLI-based client.
DEBU Initialized Kubernetes CLI client. cli=kubectl flavor=k8s namespace=default version=1.11.0
DEBU Validated installation environment. installationNamespace=trident kubernetesVersion=
DEBU Parsed requested volume size. quantity=2Gi
DEBU Dumping RBAC fields. ucpBearerToken= ucpHost= useKubernetesRBAC=true
DEBU Namespace does not exist. namespace=trident
DEBU PVC does not exist. pvc=trident
DEBU PV does not exist. pv=trident
- snip
INFO Trident installation succeeded.
「INFO Trident installation succeeded.」が出力されればインストール成功です。
また、問題が発生した場合には tridentctl
を使用してtridentに関するログをまとめて確認することが出来ます。
$ ./tridentctl -n trident logs
time="2018-02-15T03:32:35Z" level=error msg="API invocation failed. Post https://10.0.1.146/servlets/netapp.servlets.admin.XMLrequest_filer: dial tcp 10.0.1.146:443: getsockopt: connection timed out"
time="2018-02-15T03:32:35Z" level=error msg="Problem initializing storage driver: 'ontap-nas' error: Error initializing ontap-nas driver. Could not determine Data ONTAP API version. Could not read ONTAPI version. Post https://10.0.1.146/servlets/netapp.servlets.admin.XMLrequest_filer: dial tcp 10.0.1.146:443: getsockopt: connection timed out" backend= handler=AddBackend
time="2018-02-15T03:32:35Z" level=info msg="API server REST call." duration=2m10.64501326s method=POST route=AddBackend uri=/trident/v1/backend
Tridentのバージョン確認¶
インストールが完了したらtridentのバージョンを確認します。
$ ./tridentctl version -n trident
+----------------+----------------+
| SERVER VERSION | CLIENT VERSION |
+----------------+----------------+
| 19.07.0 | 19.07.0 |
+----------------+----------------+
バージョンが表示されていればインストール成功です。
ヒント
tridentctl は tridentの podと通信をして制御を行います。 このため、各コマンドは tridentの podが存在するネームスペースを 指定する必要があります。
Tridentへのバックエンド登録¶
Tridentが、その背後で制御するストレージ(バックエンドストレージ)を登録します。
バックエンドストレージを設定するためにjsonファイルを用意します。 サンプルファイルがsample-inputディレクトリにあり、ここではONTAPのNASを設定しますので backend-ontap-nas.jsonをコピーして使います。
パラメータ名 | 説明 | 設定内容 |
---|---|---|
managementLIF | ONTAPのクラスタ管理LIFまたはSVM管理LIFを設定 | 192.168.XX.200 |
dataLIF | データ通信LIF | 192.168.XX.200 |
svm | tridentから使用するSVM | svmXX |
username/password | クラスタ管理者またはSVM管理者のクレデンシャル | SVM管理者を設定: vsadmin/netapp123 |
編集後は以下の通りとなります。 疎通が取れないIPを設定するとバックエンド登録に失敗します。
$ cat setup/backend.json
{
"version": 1,
"storageDriverName": "ontap-nas",
"backendName": "userXXBackendName",
"managementLIF": "192.168.XX.200",
"dataLIF": "192.168.XX.200",
"svm": "svmXX",
"username": "vsadmin",
"password": "netapp123"
}
「XX」はラボ環境にあわせて設定してください。
編集したjsonファイルと``tridentctl create backend``を使ってバックエンドを登録します。
$ ./tridentctl -n trident create backend -f setup/backend.json
+-------------------+----------------+--------+---------+
| NAME | STORAGE DRIVER | ONLINE | VOLUMES |
+-------------------+----------------+--------+---------+
| userXXBackendName | ontap-nas | true | 0 |
+-------------------+----------------+--------+---------+
問題発生時に実施: Tridentをアンインストールする¶
トラブルシューティング時にTridentをアンインストールする必要が出てくるケースがあります。
その際には tridentctl
ユーティリティのアンインストール用のサブコマンドを使用してアンインストールします。
インストール実行時に失敗したときなど、クリーンに再インストールしたい場合に使います。
$ ./tridentctl uninstall -n trident
ヒント
続けて trident namespaceも削除したい場合は、trident namespace 内に残るオブジェクトが完全になくなった事を確認する事をおすすめします。
Tridentインストールのバージョン間の差異¶
インストール時の動作が19.0xで何度か変化しているので整理しておきます。
Version | インストール時backend.json | 初回バックエンド登録 |
〜19.01 | 必要 | されない |
19.04 | 必要 | される |
19.07〜 | 不要 | されない |
インストール時のbackend.json¶
19.01/04では Tridentが構成情報を保存する Persistent Volumeを Provisioningするために
setup/backend.jsonファイルを作成してから tridentctl install
をする必要があります。
19.01では Trident Install後に改めて バックエンド登録をする必要がありました。 19.04では Trident Install時点で backend.jsonで指定したストレージがバックエンド登録されます。
19.07では インストール時に setup/backend.jsonが不要になりました。これはCustom Resource Definition を利用してTridentの構成情報を保存するように変更になった事によります。 ただし、これにより 19.07では インストール完了後にバックエンドの自動登録がされないため注意してください。 また、tridentctl installを実行するときのカレントパスに setup ディレクトリが必要なため注意してください。
過去のバージョンのインストール手順は下記を参考にしてください。
StorageClassの定義¶
StorageClassを定義して、ストレージのサービスカタログを作りましょう。
Trident v19.07 ではStorageClassを作成するときに以下の属性を設定できます。 これらの属性のパラメータを組み合わせてストレージサービスをデザインします。
設定可能な属性 | 例 |
---|---|
性能に関する属性 | メデイアタイプ(hdd, hybrid, ssd)、プロビジョニングのタイプ(シン、シック)、IOPS |
データ保護・管理に関する属性 | スナップショット有無、クローニング有効化、暗号化の有効化 |
バックエンドのストレージプラットフォーム属性 | ontap-nas, ontap-nas-economy, ontap-nas-flexgroup, ontap-san, solidfire-san, eseries-iscsi |
全てのパラメータ設定については以下のURLに記載があります。
NFSバックエンドのONTAPでのStorageClass¶
ストレージ構成は以下の通りです。 今回、意識する必要があるところは異なるメディアタイプ(HDDとSSD)のアグリゲートを保有しているところです。
各SVMにHDD, SSDのアグリゲートを割り当て済み
- aggr1_01:SSDのアグリゲート
- aggr2_01:HDDのアグリゲート
以下のようなイメージでStoageClassを作成しましょう。
- DB 用の高速領域: SSD を使ったストレージサービス
- Web コンテンツ用のリポジトリ: HDDを使ったストレージサービス
以下は上記の「DB 用の高速領域」のStorageClass作成方法のサンプルです。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ontap-gold
provisioner: netapp.io/trident
reclaimPolicy: Retain
parameters:
backendType: "ontap-nas"
media: "ssd"
provisioningType: "thin"
snapshots: "true"
ストレージクラスを作成します。
$ kubectl create -f StorageClassFastest.yml
storageclass "ontap-gold" created
$ kubectl get sc
NAME PROVISIONER AGE
ontap-gold netapp.io/trident 10s
注釈
デフォルトのStorageClassの設定
StorageClassは記載がないときに使用するStorageClassを指定できます。
kubectl patch storageclass ストレージクラス名 -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
Persistent Volume Claimの作成¶
アプリケーションで必要とされる永続化領域の定義をします。 PVCを作成時に独自の機能を有効化することができます。
データの保管ポリシー、データ保護ポリシー、SnapShotの取得ポリシー、クローニングの有効化、暗号化の有効化などを設定できます。
一覧については以下のURLに記載があります。
metadata.annotation
配下に記述することで様々な機能を使用することが可能となります。
デプロイ用のマニフェストファイルにPVCを追加¶
Level1で作成したマニフェストファイルにPVCの項目を追加し、ダイナミックプロビジョニングを使用しデータを永続化出来るアプリケーションを定義します。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sample-pv-claim
labels:
app: アプリケーション名
annotations:
trident.netapp.io/exportPolicy: "default"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: ontap-gold
ここでやることは主に以下の2つを実施してください。 このセクションはどうやって実現するかを考えていただくためあえて答えは書いてありません。
- 上記PVCマニフェストファイルを作成し、PVCオブジェクトを作成
- Level1で作成したアプリケーションの永続化
ヒント
Level1で作成したマニフェストにはストレージの定義がありません。
どうやってストレージの定義をし永続化するかを考えてみましょう。
また、Level1のサンプルでは永続化する対象はデータベース(MySQL)になります。
MySQLのデータファイルはデフォルトでは /var/lib/mysql
になります。
デプロイメント実施¶
上記のPVCの設定が終わったら再度アプリケーションをデプロイします。
その後、アプリケーションからデータを保存するようオペレーションを行います。 WordPressであれば記事を投稿することで簡単に確認ができます。
永続化できていることを確認するためアプリケーションの停止・起動を実施¶
永続化されていることを確認するため、一度アプリケーションを停止します。
Deploymentで必要となるポッドは起動するような設定になっているため、
簡単にアプリケーションの停止・起動を行う方法として Deployment
配下の Pod
を削除する方法がとれます。
$ kubectl delete pod -l "ラベル名"
$ kubectl get deploy
実行例は以下の通りです。
$ kubectl delete pod -l app=wordpress # app=wordpress が付与されているポッドをすべて削除
pod "wordpress-5bc75fd7bd-kzc5l" deleted
pod "wordpress-mysql-565494758-jjdl4" deleted
$ kubectl get deploy # Podはデプロイメントで管理されているため、すぐ再起動される
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
wordpress 1 1 1 0 31d
wordpress-mysql 1 1 1 0 31d
DeploymentによってPodの起動数は管理されるため新たにPodが起動します。
AVAILABLE
の数が正常になるまで待ちましょう。
$ kubectl get deploy
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
wordpress 1 1 1 1 31d
wordpress-mysql 1 1 1 1 31d
再デプロイメント後の確認¶
再起動したPodに対して永続化されたデータが使用されていることを確認します。 2つの視点から確認したいと思います。
- アプリケーションであれば再度ログインして保存したデータを確認します。
- バックエンドストレージに動的にボリュームが作成されていることを確認します。
$ ssh vsadmin@192.168.XX.200 vol show
Password:
Vserver Volume Aggregate State Type Size Available Used%
--------- ------------ ------------ ---------- ---- ---------- ---------- -----
tridentsvm root aggr1 online RW 1GB 972.2MB 5%
tridentsvm trident_trident aggr1 online RW 1.86GB 1.77GB 5%
tridentsvm trident_trident_basic_f4048 aggr1 online RW 1GB 972.4MB 5%
3 entries were displayed.
Tridentの特徴的な機能: Volume Cloningのストレージオフロード¶
NetAppのストレージOSは FlexCloneや Cloneと呼ばれるストレージオフロード可能な、 高速データ複製機能=クローニングテクノロジーを利用できます。[1]
CSI Tridentでは PersistentVolumeClaimの dataSourceにコピー元となる PVC/Snapshotを指定する事で 巨大なボリュームでも容量消費せずに超高速にデータをコピーする クローニングテクノロジーが使用されます。
注釈
Volume Data Source Feature Gate Kubernetesで CSI Tridentを使って dataSourceを指定してCloningをするには featuregateを有効にする必要があります。
Feature Gates | 機能 | Kubernetes Support | Feature Gate指定 | Trident Support |
VolumePVCDataSource | PersistentVolumeClaimを指定してClone | Kubernetes 1.15 αサポート
Kubernetes 1.16 βサポート
|
必要
不要
|
19.10〜
19.10〜
|
VolumeSnapshotDataSource | VolumeSnapshotを指定してClone | Kubernetes 1.12 αサポート | 必要 | 19.07〜 |
kindにデータソースの種類(VolumeSnapshot/PersistentVolumeClaim)とnameにデータソースの名前を指定します。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: clone-of-pvc-1
namespace: myns
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
dataSource: (このフィールドにオブジェクトの種類と名前を記述)
kind: PersistentVolumeClaim
name: pvc-1
従来の Tridentでも、PVCアノテーションである、trident.netapp.io/cloneFromPVC
を介してクローニングテクノロジーを利用できます。
引数にPVC名を指定します。
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: basicclone
annotations:
trident.netapp.io/cloneFromPVC: database (<-ここにクローンしたい既存のPVC名(ボリューム名)を記述)
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: ontap-gold
ここではサンプルでPVC Cloning を活用したOracle Databaseを複数デプロイするデモ動画をご覧ください。
[1] | 必要な機能が利用できるモデル/ライセンスである事をご確認ください。 |
クローニング技術によって実現可能なこと¶
クローニング技術はシンプルですが非常に多く用途で使用することができます。 例としてあげられるのが以下の用途です。
- プレビルド環境の高速展開
- 本番環境に影響せずに大規模な並列テスト
- 運用時のデータリストアの高速化、瞬時に論理障害を戻す
Tridentのアップグレード方法¶
TridentはKubernetesのアップデートと同じサイクルでリリースされています。 Kubernetesのバージョンがあがってから約1ヶ月以内くらいにTridentがリリースされます。
kubernetesのバージョンにサポートの有無があります。
バージョンに対応したTridentを確認するには以下のページを参照ください。
https://netapp-trident.readthedocs.io/en/stable-v19.07/support/requirements.html
すでにインストールされているTridentをアップグレードするには以下のようにアンインストール、インストールをくりかえすことで実現できます。
$ ./tridentctl uninstall -n <namespace>
$ ./tridentctl install -n <namespace>
アンインストールコマンドのデフォルトの挙動はTridentでデプロイされたPVC,PVは削除しません。 Tridentの状態をそのままにしているため、アンインストール後にインストールをすることでアップグレードとして機能させることができます。
Tridentアップグレード時の注意¶
アップグレード時に Kubernetesのバージョンによっては考慮が必要な場合があります。
また、19.07では etcdから CRDへと Tridentの構成情報の記録場所が変更になったため、アップグレード時には、そのコピーが行われます。
アップグレード中の動作等、詳細は下記のアップグレードについてのオフィシャルドキュメントを参照してください。
https://netapp-trident.readthedocs.io/en/stable-v19.07/kubernetes/upgrading.html
まとめ¶
アプリケーションに対して動的に永続化領域をプロビジョニングしデータの永続化を実現しました。
今回はStorageClassの作成からアプリケーションにPersistentVolumeを割り当てるところまでを一連の流れで実現しました。
運用を考えた場合、それぞれのコンポーネントで担当が異なるため以下のような分担になるかと思います。
- StorageClassの作成: インフラ・kubernetesクラスタの管理者
- PersistentVolumeClaimの作成: アプリケーション開発者
今後障害時の動作が気になると思いますが、 Level 4: 運用編 での検討事項とします。
ここまでで Level2 は終了です。