git cloneなどのあとにフックして処理が実行できるgit-syncが便利

git-syncご存知ですか?僕はよく社内のPreview Deploy系の仕組みでよく活用しています。

Preview Deployを実装するとなると、pushのたびに毎回イメージをビルドするのがシンプルに思いますが、我々はオンプレミスでコンテナレジストリーをメンテナンスしていることもあり、なるべくディスクの無駄を減らしたいと思っています。そんなときに便利なのがgit-syncです。

git-syncは大体のケースでsidecarとして利用しています。

    - name: example-sync
      command: ["/git-sync", "-v", "9"]
      image: registry.k8s.io/git-sync/git-sync
      env:
        - name: GITSYNC_ROOT
          value: "/repo/example"
        - name: GITSYNC_REPO
          value: git@github.com:example/example
        - name: GITSYNC_REF
          value: main
        - name: GITSYNC_EXECHOOK_COMMAND
          value: "/repo/run.sh"
        - name: GITSYNC_DEPTH
          value: "1"

使い方としては非常にシンプルで、監視しているgitリポジトリに変更があればfetchして、その後、GITSYNC_EXECHOOK_COMMANDを実行することが出来ます。例えばRailsのプロジェクトであれば、GITSYNC_EXECHOOK_COMMAND 内で bundle installnpm installl を実行して、WEBサーバをリスタートするといったような使い方ができます。

若干面倒なのが、GITSYNC_EXECHOOK_COMMAND 自体は単体の実行パスしか渡せないんので複数の処理をやろうと思うと、shellスクリプトファイルなどを別途準備する必要があります。僕はこのファイルを作成するのもinit Containerでやることが多いです。

  initContainers:
  - name: makecmd
    image: alpine:latest
    command:
      - sh
      - -c
      - |
          set -e -x
          apk --no-cache add curl jq git
          cat <<'EOF' > /repo/run.sh
          #!/bin/bash
          # somthing
          EOF
          chmod 755 /repo/run.sh
    volumeMounts:
    - name: repo-data
      mountPath: /repo

もう一つ成約になるのがgit-syncの公式イメージはscrachイメージをベースにしていてほとんど何も入ってないので、build image扱いにしてバイナリだけ取り出して他のイメージでやるか、こちら を参考に自分でイメージを作るのがいいと思います。

最後に、git-sync使うとおもしろい仕組み色々作れると思うので、やっていきましょう。