はじめに
こんにちは、サイバーフィジカル融合基盤プロジェクトの郭 兆功です。主にインフラ周りを担当しています。 GitHub Actionsが昨年11月にGAになってだいぶ経ちました。すでに本番投入している方も多いのではないでしょうか。2020年6月にGitHub Actionsを組んでみたので、紹介したいと思います。
今回、GCP上に組んでいる開発中の推薦エンジンシステムをリリースするタイミングで、Blue-Green Deploymentに組み替え、GitHub Actionsを使ってCDを実現し、継続的に開発できるようにしました。
GitHub Actionsを使った1番の理由は、GitHubだけでCI/CDまで完結するからです。我々もAtlassian Confluence/JIRA、CircleCIなどを使って複数のツールを組み合わせてビルドパイプラインを組んでいますがブラウザのタブが増えてしまうのをなんとかしたいと考えていました。GitLabであれば統合的なビルドパイプラインが簡単に組めて良いのですが、使い慣れたGitHubからは離れられませんでした。そこに登場したActions、しかもFreeプランから使えるので使わないわけにはいかないですね!GitHub Marketplaceにも多くのActionsが公開されており、パブリッククラウドや各種SaaSとのインテグレーションが簡単にできることも決め手となりました。
Blue-Green Deploymentの概要
リリース前の構成
簡略化していますが、リリース前は以下のように構成で組んでいました。
夜間バッチで推薦エンジンを動かし、学習済みモデルをメモリキャッシュに反映させ、差分をDBを更新し、WebAPIから使えるようにしています。WebAPIは学習エンジンの処理時間にかかわらず動作するため、冗長構成にせずともSLI/SLOを満たせる構成になっています。 参考までに我々の推薦エンジンで設定しているSLI/SLOは以下になります。
- 可用性(HTTP Success Rate)2xx応答数/総アクセス数99.99%以上
リリース後の構成
リリース後は、並行して開発を継続して行うために、CDを任意なタイミングで実施する必要が出てきました。リリース前の構成のみで実現しようとすると、WebAPIで必要な情報が取れなくなる時間が延び結果的にSLI/SLOを満たせなくなる可能性が出てきました。そのため、Blue-Green Deploymentを採用して、開発環境を別途用意して、切り替えのタイミングで本番環境のデータと同期するように構成を変更しました。
構成は、以下のように組みました。
クライアントのエンドポイントを固定にするため、Cloud Functionsの前段にCloud Endpointsを設け、本番環境・開発環境を固定して、後段のBlue-Green環境への接続を切り替えることで実現しました。
Cloud Endpointsを二重に設けている理由は、openapi-functions.yamlのx-google-backend
でバックエンドを指定するのですが、Cloud ConsoleでCloud Runの奥深くを探さないと、バックエンドで指しているCloud Functionsがわからず、視認性が悪いためこのような方法を取りました。
Cloud EndpointsのExtensible Service Proxy(ESPv1)で、Cloud Run上に展開し、Blue-Greenの切り替えは接続先を示す環境変数ENDPOINTS_SERVICE_NAME
を切り替えることで実現しました。この方法であれば、Cloud Endpointsを再度展開する必要がなく、Cloud Runの環境変数を更新するだけで完了するため、切り替えにかかる停止時間を短くすることができます。
※ESPv2ではこのやり方はできなくなっているようですので、素直にx-google-backend
が異なるBlue/Greenのyamlを別々に用意して切り替える方が良いかもしれません。
Blueのopenapi-functions.yamlを以下に示します。
swagger: '2.0' info: title: Cloud Endpoints + GCF description: Recommend blue version: 1.0.0 host: recommend-blue-hogehoge-uc.a.run.app schemes: - https produces: - application/json paths: /spot_recommend: post: summary: recommend blue operationId: recommend_blue x-google-backend: address: https://asia-northeast1-hogehoge-project.cloudfunctions.net/recommend_blue responses: '200': description: A successful response schema: type: string
Blue/GreenのCloud EndpointsのENDPOINTS_SERVICE_NAME
は自分自身を指し、x-google-backend
に実際のCloud Functionsを指すことで実現します。
Prod/DevのCloud EndpointsのENDPOINTS_SERVICE_NAME
にBlue/Greenを指し、x-google-backend
にはダミーのアドレスを指します。
GitHub Actionsを使ってBlue-Green Deploymentの実現
GitHub Actionsは、PushやPull Requestをトリガーに自動で動かすことが一般的ですが、repository_dispatchを使うことで任意のタイミングで手動でトリガーすることができます。 CIとは異なり、CDでコケたときは人手が必要になることがあり、Blue-Greenの切り替えなどCDに関わる操作は、以下のようにGitHub ActionsでAPI化してHTTP POSTすることで手動で実現しました。
Blue-Green Deploymentに必要なワークフローは5つで、開発環境に対して推薦エンジンやWebAPIの展開を任意のタイミングで行い、切り替えのタイミングでDBの更新、キャッシュの同期を行って、最後にBlue-Greenの切り替えを行います。
Blue-Green切り替えのワークフローを以下に示します。
name: Blue/Green Dispatch on: repository_dispatch: branches: [ master ] types: [ bg-dispatch ] jobs: dispatch: runs-on: ubuntu-latest steps: - name: Checkout the repository uses: actions/checkout@v2 - name: GCP Authenticate uses: GoogleCloudPlatform/github-actions/setup-gcloud@master with: version: '298.0.0' project_id: ${{ secrets.GCP_PROJECT_ID }} service_account_email: ${{ secrets.GCP_SERVICE_ACCOUNT_EMAIL }} service_account_key: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }} - name: Dispatch Cloud Run run: | gcloud components install beta --quiet gcloud beta run services update recommend-prod --update-env-vars=ENDPOINTS_SERVICE_NAME=recommend-${{ github.event.client_payload.prod }}-hogehoge-uc.a.run.app --project ${{ secrets.GCP_PROJECT_ID }} --platform managed --region ${{ secrets.GCP_REGION }} gcloud beta run services update recommend-dev --update-env-vars=ENDPOINTS_SERVICE_NAME=recommend-${{ github.event.client_payload.dev }}-hogehoge-uc.a.run.app --project ${{ secrets.GCP_PROJECT_ID }} --platform managed --region ${{ secrets.GCP_REGION }}
client_payload
でパラメータを渡せるようになっているので、${{ github.event.client_payload.prod }}
に本番環境、${{ github.event.client_payload.dev }}
に開発環境をそれぞれBlue/Greenを指定しています。
GCPへの接続はマーケットに公開されている公式のActionsを使いました。
GitHub ActionsのSecretsはRepositoryまたはOrganizationに保存することができ、GitHub Actionsからは${{ secrets.GCP_SERVICE_ACCOUNT_EMAIL }}
のように参照することで秘匿化しています。
リクエストに{"event_type": "bg-dispatch", "client_payload": {"prod": "green", "dev": "blue"}}
を付加することで、本番環境をGreen、開発環境をBlueに切り替えることができるようになります。
終わりに
GitHub Actionsを使ってGCPで組んだ推薦エンジンをリリースに合わせてBlue-Green Deploymentを実現しました。 費用負担もなく手軽に使い始めることができ、柔軟にCDも組めるので、まだ導入をしていない方は試してみてはいかがでしょうか。