【AKS】git-sync を使って Azure Files にgitリポジトリをコピーする
はじめに
こんにちは。
k8s全然わからない民です。やればやるほどわからん。
今回やったのは、
永続ボリュームに git repository のフォルダ・ファイルを永続ボリュームに同期させて、各アプリケーションポッドで使えるようにしよう
という内容です。
AKSで gitrepo ボリュームを作りたかったんですが、現在非推奨[1]です。
調べたところ、 git-sync を代用として使うみたいです。
READMEにも書いてますが、本来はサイドカーコンテナとして使う代物のようですので、このやり方は本来の使い方ではないと思われます。
が、gitと同期させたいファイルやらが多いのとサイズも大きめなので、pod側は永続ボリュームをマウントして使う利用方法にしました。
全体的に運用に耐えられるかどうかも含めて、このやり方があってるかはわかりませんが、検証ベースでやりたいことはとりあえずできた、というレベルです。
イメージ
こんな感じのことをします。
概念なので、間違ってる可能性は大いにあります。あくまでイメージです。
前準備
必要なもの
Azure Cloud Shell
AKS
Storage Account / Azure Files
git repository
AKSにおけるストレージオプション
PersistentVolume やら PersistentVolumeClaim の話は公式のドキュメントを一通り読んだ方がいいです。やってる最中は全然わからなかったんですが😂
Azure Files CSI ドライバー
Azure Files との共有ファイルストレージは公式にある設定でだいたいできます。
今回やるのは静的プロビジョニングになります。
Azure Files の作り方もファイル共有も上記のサイトに書いてますので、ここでは詳細は割愛します。
マニュフェストファイル
ここからが本題。
git-sync pod
apiVersion: v1
kind: Pod
metadata:
name: git-sync
namespace: git-sync-app
labels:
app: git-sync
spec:
containers:
- name: git-sync
image: registry.k8s.io/git-sync/git-sync:v4.1.0
securityContext:
runAsUser: 0
runAsGroup: 0
volumeMounts:
- name: azurefile
mountPath: /mnt/azurefiles # マウントするパスはなんでもよい
args:
- --repo=<git repository のURL>
- --depth=1
- --period=30s
- --ref=main
- --link=current
- --root=/mnt/azurefiles # 上の mounthPath と合わせる
volumes:
- name: azurefile
persistentVolumeClaim:
claimName: azurefile-pvc # AzureFilesのCSIドライバーを使ってプロビジョニングされたファイル共有を参照するPVCの名前
Azure Files を使用する場合、一番ハマったのが、securityContext でユーザをrootユーザ(0)にしないと、permission で怒られます。
このsecurityContextがポイント。
ボリュームをマウントするのはrootユーザ(0)
git-syncでcloneとかするときにchmodしたりするらしんだけど、その時のユーザと一致してなくてpermissionで怒られたらしい。
明示的にsecurityContextでユーザを指定してあげるとよいとか。
https://zenn.dev/link/comments/a6c551071ed973
永続ボリューム周り
- PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
annotations:
pv.kubernetes.io/provisioned-by: file.csi.azure.com
name: azurefile
spec:
capacity:
storage: 5Gi # 確保するメモリは適宜
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: azurefile-csi
csi:
driver: file.csi.azure.com
readOnly: false
volumeHandle: unique-volumeid
volumeAttributes:
resourceGroup: ストレージアカウントを作ったリソースグループ名
shareName: ファイル共有名
nodeStageSecretRef:
name: azure-secret
namespace: git-sync-app
mountOptions:
- dir_mode=0777
- file_mode=0777
- uid=0
- gid=0
- noperm
- PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: azurefile-pvc
namespace: git-sync-app
spec:
accessModes:
- ReadWriteMany
storageClassName: azurefile-csi
volumeName: azurefile
resources:
requests:
storage: 5Gi # 確保するメモリは適宜
apiVersion: v1
kind: Secret
metadata:
name: azure-secret
namespace: git-sync-app
type: Opaque
data:
azurestorageaccountname: <base64 エンコードしたStorageアカウント名>
azurestorageaccountkey: <base64 エンコードしたStorageアカウントキー>
git-sync するとこんな感じのフォルダ構成が作成されます。
application Pod
- メインアプリケーション
一応、git-sync pod が起動してから、メインのアプリケーションも起動するようにinitContainers でチェックしてます。
※もっとエラーハンドリングする必要はありますが。
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
namespace: git-sync-app
labels:
app: app
spec:
replicas: 1
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
# config がAzure Files に置かれるのを待つ
serviceAccountName: git-sync-service-account
initContainers:
- name: wait-for-git-sync
image: bitnami/kubectl:1.27
command: ["/bin/sh"]
args: ["-c", "until [ \"$(kubectl get pods -l app='git-sync' -n 'git-sync-app' -o jsonpath='{.items[0].status.phase}')\" = 'Running' ]; do sleep 1; done"]
containers:
- name: app
image: <イメージ>
imagePullPolicy: Always
resources:
requests:
cpu: 100m
memory: 256Mi
ports:
- containerPort: 80
volumeMounts:
- name: azurefile
mountPath: /mnt/azurefiles
volumes:
- name: azurefile
persistentVolumeClaim:
claimName: azurefile-pvc # AzureFilesのCSIドライバーを使ってプロビジョニングされたファイル共有を参照するPVCの名前
- service Account
他の Pod の情報を得るためには、serviceAccount を作成する必要があります。
apiVersion: v1
kind: ServiceAccount
metadata:
name: git-sync-service-account
namespace: git-sync-app
- service Account に権限を付与する
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: git-sync-cluster-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- kind: ServiceAccount
name: git-sync-service-account
namespace: git-sync-app
ClusterRole:view 権限をつけることにより、kubectl で pod の情報が取得できるようになります。もうちょっと細かく権限をつけたい場合は自作もできるそうですが、まあ pod 起動しかたどうかを見たいだけなので、view権限で。
あとがき
このPodができるようになったら、メインアプリケーション側の Pod でも同じPVCを使用するようにすると永続ボリュームが k8s 内で共有することができます(たぶん)
git-sync はオプションで webhook とかもあるので、更新されたら通知するとかいろいろできます。
それでは引き続き k8s 沼💀に落ちていきましょう。
参考
Discussion