GCE に Gitea の環境を小さく運用するために作る
小さく運用するために
とにかく、省コストでありながらも、極力マネージド環境を使い、かつ壊れてしまってもいいという状態を作ることを目指します。
- GCE (Comupute Engine) Container-Optimized OS イメージを使ってのコンテナ運用を行います
- Gitea はほとんどインストール作業が不要ですが、それでも Linux の systemd の設定なども含めると不慣れなメンバーがいる場合に避けておきたいです
- Installation from binary - Docs
- Gitea のデータ保存用の RDB は Cloud SQL を利用します
- Git で管理するコードは Cloud Source Repositories に mirroring する
- もちろん永続ディスクでのバックアップはしますが、Gitea は多機能ではないため、CI 関係の処理を Cloud Build 等に任せたい場合、Cloud Source Repositories にコードがある方が都合もよく Gitea のリソースも圧迫しないと考えたためです
事前準備
有効化する API
上記より以下の API を有効化します
構築者に必要な役割
- Cloud SQL 管理者
- 編集者では新規インスタンスを作成できないため、最初は必要です
- Source Repository 管理者
- こちらも新規リポジトリの作成に必要です
- Compute 管理者
- Compute ネットワーク管理者
- Cloud SQL の Private IP 接続構成のために必要です
- これは、個別に
servicenetworking.services.addPeering
の権限を付与することでも代用できます - Compute ネットワーク管理者(ベータ版)の役割 - Google Cloud
- ストレージ管理者
- Gitea の Docker Image を Cloud Source Repositories に mirroring 可能にするためにカスタマイズします
- そのカスタマイズした Image を自身のプロジェクトの Container Registry に入れるために必要です
- 権限と役割 - Google Cloud
必要なサービスアカウント
Gitea から Cloud Source Repositories に mirroring するためには、Cloud Source Repositories 編集者が必要です。
Cloud Shell を起動し、以下のようにすれば作成できます。
$ export PROJECT_ID=`gcloud config list core/project --format='value(core.project)'` # サービスアカウント gitea-compute の追加 $ gcloud beta iam service-accounts create gitea-compute \ --description "Gitea サーバー用" \ --display-name "gitea" # gitea-compute に Cloud Source Repositories への push 権限を付与 $ gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:gitea-compute@$PROJECT_ID.iam.gserviceaccount.com \ --role roles/source.writer # key を作成しておく $ gcloud iam service-accounts keys create ~/gitea-key.json \ --iam-account "gitea-compute@$PROJECT_ID.iam.gserviceaccount.com"
サービス アカウント キーの作成と管理 - Google Cloud
Gitea 用の Docker Image の作成
Cloud Sourece Repositories の mirroring は上記で作成したサービスアカウントをコンテナで activate して、その権限で普通に git push --mirror
するという形にします。
そのため、サービスアカウントの activate のために gcloud
が必要です。また、Git に gcloud の helper を使わせないと Cloud Source Repositories に push ができません。
よって、以下のように gcloud を追加でインストールした Gitea のイメージを用意します。
Dockerfile
Gitea の公式イメージが alpine を利用するため google-cloud-sdk
の alpine の内容をそのまま追加した内容です。
cloud-sdk-docker/Dockerfile at master · GoogleCloudPlatform/cloud-sdk-docker · GitHub
FROM docker:17.12.0-ce as static-docker-source FROM gitea/gitea:1.10.3 # install cloud-sdk ARG CLOUD_SDK_VERSION=279.0.0 ENV CLOUD_SDK_VERSION=$CLOUD_SDK_VERSION ENV CLOUDSDK_PYTHON=python3 ENV PATH /google-cloud-sdk/bin:$PATH COPY --from=static-docker-source /usr/local/bin/docker /usr/local/bin/docker RUN apk --no-cache add \ curl \ python3 \ py3-crcmod \ bash \ libc6-compat \ openssh-client \ git \ gnupg \ && curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-${CLOUD_SDK_VERSION}-linux-x86_64.tar.gz && \ tar xzf google-cloud-sdk-${CLOUD_SDK_VERSION}-linux-x86_64.tar.gz && \ rm google-cloud-sdk-${CLOUD_SDK_VERSION}-linux-x86_64.tar.gz && \ gcloud config set core/disable_usage_reporting true && \ gcloud config set component_manager/disable_update_check true && \ gcloud config set metrics/environment github_docker_image && \ gcloud --version RUN git config --system credential.'https://source.developers.google.com'.helper gcloud.sh RUN ln -s /google-cloud-sdk/bin/gcloud /usr/local/bin/gcloud && ln -s /google-cloud-sdk/bin/git-credential-gcloud.sh /usr/local/bin/git-credential-gcloud.sh VOLUME ["/root/.config"]
Container Registry に登録
$ cd (Dockerfile のあるディレクトリ) $ docker build -t gitea-with-cloud-sdk . $ docker tag gitea-with-cloud-sdk gcr.io/$PROJECT_ID/gitea-with-cloud-sdk $ docker push gcr.io/$PROJECT_ID/gitea-with-cloud-sdk
Cloud Shell でもローカルでも実行環境は問いませんが、もし初めて Container Registry に入れる場合には以下を実行しておきます。
$ gcloud auth configure-docker
オプション: Docker イメージを実行する - Google Cloud
Cloud SQL の作成
初回はプライベート接続のための IP アドレス範囲の作成が必要になります。
プライベート IP 接続の構成 - Google Cloud
以下のような感じで VPC ネットワークピアリングとルートに追加されていれば構成が完了しています。
VPC ネットワーク ピアリング に追加される
ルートに追加される
その他の設定
ユーザーや Gitea で利用するデータベースは適宜作成しておいてください。特に規約はありません。
Gitea サーバーの構築
永続ディスク付きで Container-Optimized OS のインスタンスを作る
まずは、コンテナイメージのデプロイにチェックをし、先程 Container Registry に登録した Image を指定します。
続いて永続ディスクを作成し、 /data
をマウントします。
永続ディスクはスナップショットをとるように設定しておきます。
以下にあるように Gitea のデータは /data
を永続化しておけば問題ありません。
Installation with Docker - Gitea
永続ディスクのフォーマット
永続ディスクはフォーマットする必要があるため、上述の通りまずは作成したインスタンスに ssh で入り設定します。一度設定すれば、以降は自動でマウントされます。
Gitea コンテナ内の gcloud / Git の設定を行う
以下では、作成した Compute のインスタン名を gitea
としたとします。
まずは SCP でインスタンスにサービスアカウントの key を送ります。
$ gcloud compute scp gitea-key.json gitea:~
続いて、インスタンスに入り、Gitea のコンテナが参照出来る場所に key をコピーします。
$ sudo cp -p gitea-key.json /mnt/disks/gce-containers-mounts/gce-persistent-disks/gitea-data/
Gitea のコンテナに入り key を activate します。git
ユーザーに登録することになります。git
ユーザーは Gitea のコンテナ内に存在します。
$ docker exec -it $(docker ps -aqf "name=gitea") /bin/bash # 以降はコンテナ内 $ su - git $ cd ../ $ gcloud auth activate-service-account --key-file gitea-key.json $ gcloud config configurations list
activate したサービスアカウントの情報が出てくれば OK です。
activate の情報は /data/git/.config/gcloud
に保存されるため、一度 activate すれば、インスタンスを再起動したとしても永続ディスクに activate 情報があるため再 activate は不要です。
最後に Git helper に gcloud を登録します。
$ git config --global credential.'https://source.developers.google.com'.helper gcloud.sh
リポジトリをリモートとして追加する - Google Cloud
Gitea の初期化を行う
$ gcloud compute start-iap-tunnel arch-gitea 3000 --local-host-port=localhost:3000
上記のように TCP portforwarding をして port 3000 で見れるようにします。
Gitea は初期化画面で連携するデータベースの情報を求めてくるので、Cloud SQL の情報を入力します。Cloud SQL は private IP が割り当てられているので、それで接続できます。
続いて、Gitea にリポジトリを一つ作っておきましょう。
Cloud Source Repositories に mirroring する
まずは mirroring 先となる Cloud Source Repositories にリポジトリを作成します。
作成できたら、Gitea の作成したリポジトリの Settings -> Git Hooks に以下のように post-receive
を追加します。
上記のままだと、Gitea に git push
した際に mirroring のログも出るため、/dev/null
に捨てる等適当にアレンジしてください。
最後に
Github 等を利用できれば、Cloud Source Repositories への mirroring すら手間いらずなので、あまり自前で Git のサーバーを構築するメリットは感じないのですが、現場の制約で今回このような構成を試してみました。
現状は Cloud IAP での TCP portforwarding での接続に絞っていたりで、多少不便な点もあり、今後改善していくべき部分も多いですが、構築にあたり GCP のいくつかのサービスの知見も得られたので良い経験でした。