GKE Autopilotの永続ボリュームに Filestoreを使ってみた
はじめに
GKEの永続ボリュームとして Filestoreを使用しています。
導入時の背景とセットアップ方法について、説明していきます。
KubernetesやGCPの基本的な使い方を理解している方が読まれる事を想定して書いています。
導入の経緯
- ファイルへのアクセスを高速に行う
- 障害への対策として複数のゾーンにまたがるGKEクラスタを利用する必要性
という要件・制約の元でファイルの保存先を決める必要がありました。
ファイルのマウントではなくObjectストレージ(GCS)で
ファイル読み書きを行うことも検討しましたが、速度を考慮して
一時保存はFilestore、最終保存先としてGCSを使用することにしました。
また可用性向上のため、GKEリージョン クラスタをデプロイする必要がありました。
複数のNodeから読み書きを行うため、
ディスクへのアクセス方法 を ReadWriteMany
にしました。
(補足ですが、ゾーンクラスタの場合 ComputeEngineの永続ディスクを利用することが可能で、費用を安く抑えることができます。)
Compute Engine クライアントでのファイル共有のマウント
を行うか Filestore を使ってマウントを行うかどちらかという選択肢の中で
費用は高くても高速でマネージドなFilestoreを使うことになりました。
実際にデプロイする
gcloud
(GCPコンソールでも可能), kubectl
のコマンドが必要になります。
基本的な使い方については解説しないです。
AutopilotモードのGKEをデプロイしていきます。
GKEデプロイ
gcloud container \
--project ${YOUR_PROJECT} \
clusters create-auto "test-autopilot-cluster-1" \
--region "asia-northeast1" \
--release-channel "regular" \
--network ${YOUR_VPC_NETWORK} \
--subnetwork ${YOUR_SUB_NETWORK} \
--cluster-ipv4-cidr "/17" --services-ipv4-cidr "/22"
数分後作成したクラスタの情報が表示されるので、
kubectl get nodes
等で接続の確認を行ってください。
Filestoreのデプロイ
次に Filestoreのデプロイを行なって行きます。料金が高いので消し忘れには注意してください
--network=name
は作成したクラスタと同じにしてください。
同じVPC内に配置しないとマウントすることができません。
# 最小が1TBなので、1TBを指定
gcloud filestore instances create test-filestore \
--project=${YOUR_PROJECT} \
--zone=asia-northeast1-b \
--file-share=capacity=1TB,name=test_shared \
--network=name=${YOUR_VPC_NETWORK} \
--tier=STANDARD
数分後に作成されたインスタンス情報が表示されます。
作成後に
gcloud filestore instances list
> INSTANCE_NAME LOCATION TIER CAPACITY_GB FILE_SHARE_NAME IP_ADDRESS ~
test-filestore asia-northeast1-b STANDARD 1024 test_shared 10.225.83.106 ~
を入力して IPアドレスをメモしておきます。
デプロイ直後のディレクトリのパーミッションはroot
権限になっているため
Filestore をフォーマッティングして行きます。
AutopilotのPodからの変更はできないので、GCEのインスタンスを立てます。
gcloud compute instances create temp-workload \
--zone=asia-northeast1-b \
--machine-type=f1-micro \
--network=${YOUR_VPC_NETWORK} \
--subnet=${YOUR_SUB_NETWORK}
GCEインスタンスの作成後
インスタンスへ sshを行い以下のように権限を変更します
# ssh
gcloud compute ssh temp-workload --zone=asia-northeast1-b
> $gcpusername
sudo apt-get update && sudo apt-get install nfs-common
# マウント
sudo mkdir -p /opt/shared && sudo mount $FilestoreIP:/test_shared /opt/shared
# 権限を変更
sudo chmod 766 /opt/shared
$FilestoreIP
には先ほどコピーしたFilestoreのIPアドレスをを入力してください。
以上で Filestoreのデプロイは完了です。
永続ボリュームのデプロイ
次に永続ボリュームをデプロイして行きます。
動的なプロビジョニングを行います
PersistentVolume(PV), PersistentVolumeClaim(PVC)のリソースを作成します。
PVとは 噛み砕くとクラスタに配置されるストレージそのもののようなイメージで、
PVCは ユーザが要求するストレージ(使用するサイズ等を指定できる)です。
NodeとPod(CPUやメモリを調節できる)のような関係で理解するとわかりやすいと思います。
詳細はこちらを確認してください。
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-pv
labels:
app: test-volume
spec:
capacity: # Filestoreの容量
storage: 1T
accessModes: # アクセス方法
- ReadWriteMany
nfs:
path: /test_shared
server: 10.225.83.106 # コピーした FilestoreのIPを入力してください。
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-disk
spec:
storageClassName: ""
accessModes: # アクセス方法
- ReadWriteMany
resources:
requests: # 使用するサイズ (pvc < pv)
storage: 1T
selector:
matchLabels:
app: test-disk
上記のファイルをデプロイし、取得が確認できたら完了です。
kubectl apply -f persistent-volume.yaml
> persistentvolume/test-pv created
persistentvolumeclaim/test-disk created
kubectl get pv
> NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
test-pv 1T RWX Retain Available 12s
> kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-disk Pending 12s
# STATUS は要求時に変更される
動作確認
Podをデプロイして本当にマウントされているか確認します。
まず永続ボリュームをデプロイします
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment1
labels:
service: test1
spec:
replicas: 2
selector:
matchLabels:
service: test1
template:
metadata:
labels:
service: test1
spec:
volumes:
- name: test-volume
persistentVolumeClaim:
claimName: test-pvc # PVCを要求する
containers:
- name: test
image: alpine:latest
command: [ "sleep" ]
args: [ "infinity" ]
resources:
limits:
cpu: 500m
memory: 128Mi
volumeMounts: # test-volume という名前のボリュームを /mnt/test にマウントする
- mountPath: /mnt/test
name: test-volume
次に Deploymentをデプロイして、Pod内に入ってファイルの確認を行なっていきます。
# Deploymentをデプロイ
kubectl apply -f test-deployment.yaml
# 名称を変えて別の Deploymentを作ってみる。
vim test-deployment.yaml
> metadata:
name: test-deployment2
kubectl apply -f test-deployment.yaml
# pod を確認
kubectl get pods
> NAME READY STATUS RESTARTS AGE
test-deployment1-5fd94f4bc6-k9nfc 1/1 Running 0 7m38s
test-deployment1-5fd94f4bc6-vpgq9 1/1 Running 0 9m16s
test-deployment2-5fd94f4bc6-768fj 1/1 Running 0 7m4s
test-deployment2-5fd94f4bc6-qtplg 1/1 Running 0 7m4s
# podに入る
kubectl exec -it test-deployment1-5fd94f4bc6-k9nfc -- sh # - 1
kubectl exec -it test-deployment1-5fd94f4bc6-vpgq9 -- sh # - 2 1と同じDeploymentにひもづくPod
kubectl exec -it test-deployment2-5fd94f4bc6-768fj -- sh # - 3 別のDeploymentにひもづくPod
> /
/ cd mnt/test # - 1, 2, 3 で実行
echo "Hello World!!" > test.txt # -1 で実行
cat test.txt # - 2, 3で実行
> Hello Workd!!
vi test.txt, rm test.txt # 2, 3 で変更や削除を確認
という感じで複数のPodからファイルの確認や変更ができるようになりました。
注意
作成したリソースをそのままにすると結構な料金が発生してしまうので、
作成後使わない場合は忘れず削除してください!
# GCE
gcloud compute instances delete temp-workload --zone=asia-northeast1-b
# Filestore
gcloud filestore instances delete test-filestore --zone=asia-northeast1-b
# GKE
gcloud container clusters delete test-autopilot-cluster-1 --region asia-northeast1
むすびに
sweeepでは一緒に働くエンジニアを募集しています!
なぜを追求して、技術選定を行いたい!
自動化大好き!インフラ効率化したい!技術大好き!
なエンジニアの方一緒に働きましょう!
Discussion