コンテナ起動前にリポジトリsetup

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サーバ経由で実行ファイルのみ配信するとビルド時間を節約できるでしょう。

⁋ 2020/10/12↻ 2024/11/07
中馬崇尋
Chuma Takahiro