Oracle Cloud Infrastructure Container Engine foe Kubernetesはコンテナ化されたアプリケーションをクラウド上にデプロイするのに使える、フルマネージドのスケーラブル、高可用性のサービスです。
コンテナ化されたアプリケーションのベストプラクティスのひとつに、ステートレスコンテナの利用があります。しかし、実際には多くのアプリケーションにはコンテナにステートフルな動作が必要です。たとえば、クラシックな3層アプリケーションは以下のような3つのコンテナを持つでしょう:
- プレゼンテーションレイヤー用にひとつ、ステートレス
- アプリケーションレイヤー用にひとつ、ステートレス
- 永続化(データベースなど)レイヤー用にひとつ、ステートフル
Kubernetesでは、各コンテナはそれぞれのファイルシステムを読み書きできます。しかし、コンテナが再起動すると、全てのデータがロストします。したがって、ステートを保持する必要のあるコンテナではデータをNetwork File System(NFS)のような永続化ストレージに保存することになります。NFSに保存済のデータは、ひとつ~複数のコンテナで構成されるポッドが破壊されても削除されません。また、NFSには複数のポッドから同時にアクセスすることが可能なので、ポッドをまたいでデータをシェアするのにもNFSを使うことができます。この性質は、コンテナやアプリケーションが単一の共有ファイルシステムから設定データを読み込む必要があるとき、また、複数のコンテナが単一の共有ファイルシステムのデータを読み書きするときにとても有用です。
Oracle Cloud Infrastructure File Storageは堅牢、スケーラブルで分散したエンタープライズグレードのネットワークファイルシステムを提供しており、NFSバージョン3とNetwork Lock Manager(NLM)をサポートしています。Virtual Cloud Network(VCN)内のどのベアメタルあるいはVM、コンテナインスタンスからもFile Storegeにアクセスすることができます。また、Oracle Cloud Infrastructure FastConnectかInternet Protocol Security(IPSec) Virtual Private Network(VPN)を使えば、VCN外からもファイルシステムにアクセスすることができます。File Storageはフルマネージドサービスなので、ハードウェアの導入と維持、キャパシティプランニングやソフトウェアアップグレード、セキュリティパッチなどは気にしなくて済みます。わずか数キロバイトのデータからファイルシステムを使いだして、ゆくゆくは8エクサバイトのデータまで扱うこともできます。
このポストではFile Storage(しばしばFSSと呼ばれます)をContainer Engine for Kubernetes(OKEと呼ばれます)を組み合わせて使う方法を解説します。ここではふたつのポッドを作成します。ひとつはWorker Node 1上で動き、もうひとつはWorker Node 2上で動いており、File Storageファイルシステムを共有します。
ではここから、ポッドの中身と、File Storageと組み合わせる方法を見ていきましょう。
前提条件:
- 利用するテナンシーのOracle Cloud Infrastructureアカウントの認証情報
- テナンシー内に作成済のOKEクラスターがあること。Container Engine for Kubernetes documentationに例が載っています。
- Security lists configured to support File Storage as explained in the File Storage documentationに説明があるように、File Storageをサポートするようにセキュリティリストが構成されていること。以下はセキュリティリスト設定の例です。
- Announcing File Storage Service UI 2.0の手順にしたがって作成された、ファイルシステムとマウント対象。
手順の概要
- Storage Classの作成
- Persistent Volume (PV)の作成
- Persistent Volume Claim(PVC)の作成
- PVCを利用するポッドの作成
Storage Classの作成
作成したファイルシステムのマウントターゲットIDを参照するStorage Classを作成します:
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
name: oci-fss
provisioner: oracle.com/oci-fss
parameters:
# Insert mount target from the FSS here
mntTargetId: ocid1.mounttarget.oc1.iad.aaaaaaaaaaaaaaaaaaaaaaaaaa
Persistent Volume(PV)の作成
apiVersion: v1
kind: PersistentVolume
metadata:
name: oke-fsspv
spec:
storageClassName: oci-fss
capacity:
storage: 100Gi
accessModes:
- ReadWriteMany
mountOptions:
- nosuid
nfs:
# Replace this with the IP of your FSS file system in OCI
server: 10.0.32.8
# Replace this with the Path of your FSS file system in OCI
path: "/okefss"
readOnly: false
Persistent Volume Claim (PVC)の作成
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: oke-fsspvc
spec:
storageClassName: oci-fss
- ReadWriteMany
resources:
requests:
# Although storage is provided here it is not used for FSS file systems
storage: 100Gi
volumeName: oke-fsspv
PVCがバインドされたことを確認します:
raghpras-Mac:fss raghpras$ kubectl get pvc oke-fsspvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
oke-fsspvc Bound oke-fsspv 100Gi RWX oci-fss 1h
raghpras-Mac:fss raghpras$
Worker Nodeのラベル付け
ふたつのWorker Nodeにラベルを付け、ポッドをアサインできるようにしておきます:
kubectl label node 129.213.110.23 nodeName=node1
kubectl label node 129.213.137.236 nodeName=node2
ポッドでのPVC利用
次のWorker Node 1(node1)上のポッド(oke-fsspod)がファイルシステムPVC(oke-fsspvc)を使用します:
#okefsspod.yaml
apiVersion: v1
kind: Pod
metadata:
name: oke-fsspod
spec:
containers:
- name: web
image: nginx
volumeMounts:
- name: nfs
mountPath: "/usr/share/nginx/html/"
ports:
- containerPort: 80
name: http
volumes:
- name: nfs
persistentVolumeClaim:
claimName: oke-fsspvc
readOnly: false
nodeSelector:
nodeName: node1
ポッドを作成します:
kubectl apply -f okefsspod.yaml
テスト
ポッドを作成したら、kubectl execで共有ファイルを書き込むことができるかテストします:
raghpras-Mac:fss raghpras$ kubectl get pods oke-fsspod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
oke-fsspod 1/1 Running 0 33m 10.244.2.11 129.213.110.23 <none>
raghpras-Mac:fss raghpras$
kubectl execを使用し、ファイルシステムに書き込みます:
raghpras-Mac:fss raghpras$ kubectl exec -it oke-fsspod bash
root@oke-fsspod:/# echo "Hello from POD1">> /usr/share/nginx/html/hello_world.txt
root@oke-fsspod:/# cat /usr/share/nginx/html/hello_world.txt
Hello from POD1
root@oke-fsspod:/#
もうひとつのポッドでも繰り返し
Worker Node 2 (node2)上のもうひとつのポッド(oke-fsspod2)でもこのファイルシステムがマウントできることを確認します:
apiVersion: v1
#okefsspod2.yaml
kind: Pod
metadata:
name: oke-fsspod2
spec:
containers:
- name: web
image: nginx
volumeMounts:
- name: nfs
mountPath: "/usr/share/nginx/html/"
ports:
- containerPort: 80
name: http
volumes:
- name: nfs
persistentVolumeClaim:
claimName: oke-fsspvc
readOnly: false
nodeSelector:
nodeName: node2
raghpras-Mac:fss raghpras$ kubectl apply -f okefsspod2.yaml
pod/oke-fsspod2 created
raghpras-Mac:fss raghpras$ kubectl get pods oke-fsspod oke-fsspod2 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
oke-fsspod 1/1 Running 0 12m 10.244.2.17 129.213.110.23 <none>
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
oke-fsspod2 1/1 Running 0 12m 10.244.1.9 129.213.137.236 <none>
raghpras-Mac:fss raghpras$ kubectl exec -it oke-fsspod2 -- cat /usr/share/nginx/html/hello_world.txt
Hello from POD1
raghpras-Mac:fss raghpras$
もういちどテスト
後で作成したポッドでも共有ファイルに書き込めることをテストします:
raghpras-Mac:fss raghpras$ kubectl exec -it oke-fsspod2 bash
root@oke-fsspod2:/# echo "Hello from POD2">> /usr/share/nginx/html/hello_world.txt
root@oke-fsspod2:/# cat /usr/share/nginx/html/hello_world.txt
Hello from POD1
Hello from POD2
root@oke-fsspod2:/# exit
exit
まとめ
File StorageとOKEは両方ともフルマネージドサービスで、高可用性があり、スケーラブルです。File Storageはさらに、Oracle Cloud Infrastructure上でデータを高度に永続化する、堅牢なストレージです。File Storageは分散アーキテクチャ上に構築され、データとそのアクセスをスケーラブルにします。これらのサービスを利用することで、クラウド上でのワークフローをシンプルにし、柔軟性とコンテナデータをどのように保存するかの選択肢を得ることができます。
What's Next
開発中のFile Storageサービスでの動的なボリュームプロビジョニングでは、Kubernetesクラスターの中からファイルストレージをリクエストし、ファイルシステムの作成とマウントを行います。
Oracle Cloud Infrastructure、OKE、OCI File Storageについてもっと知りたい場合は、まずはクラウドランディングページを見てみるのがいいと思います。