LL言語のWebアプリケーションなど、サーバー起動前にソースリポジトリをセットアップしておきたいケースがあります。
更新を考慮して、コンテナ作成段階でgit clone
を実行したい場合、以下のようにinitContainers
を活用できます(抜粋)。
spec:
initContainers:
- name: git-client
command: ["bash"]
args: ["-c", "cd /usr/src/app; git clone git.example.com:some-repo.git -b develop ."]
volumeMounts:
- name: temp-repo
mountPath: /usr/src/app
containers:
- name: main
volumeMounts:
- name: temp-repo
mountPath: /usr/src/app
volumes:
- name: temp-repo
emptyDir: {}
emptyDirがコンテナ作成時に空のディレクトリを供給し、initContainerでセットアップのうえ、containersが起動します。
なお、イメージの指定は環境依存であるため省略していますが、鍵配備を含め、git clone可能な環境は必要です。
かなり冗長な構成ではありますが、開発環境向けのコンテナとしてこの構成しかとれないケースがあります。
kubernetesではコンテナ間のストレージ共有に難があり、決定打となる実装がないからです。
アプリケーションサーバのホットリロードはinotifyを利用しているのだと思いますが、たとえばUnix汎用のNFSではinotifyは動作せず、コードを更新してもリロードしません。
emptyDirの場合は更新後にgit pull
するとリロードが動作します。
また、スタートアップスクリプトにセットアップ処理を書く構成も一応とれますが、セットアップに時間がかかると起動失敗と判定され、CrashLoopBackOffします。このようなケースでもinitContainerに分割すると安定します。
シングルバイナリのdeployケース
基本的な構成は完全に同一ながら、Rustのようにシングルバイナリをデプロイする場合には、initContainerでgit clone
のかわりにcurl
を実行する手があります。
ビルドキャッシュがないとコンパイルの時間がかかるようなケースでは、開発環境内のHTTPサーバ経由で実行ファイルのみ配信するとビルド時間を節約できるでしょう。
Chuma Takahiro