はじめに

Google Cloud Next Tokyo の「Google Cloud Next Tokyo ’24 セッションレポート 進化するコンテナ環境: Google Kubernetes Engine と Cloud Run の最新アップデートと使い所を徹底解説」にて説明されていた、Cloud Run の自動セキュリティアップデート機能が 2024/08/21 でパブリックプレビューとなりました。
セッションでも聞いていた内容なので、どういった形で導入可能か、メリットなどについて考えていきます。

セキュリティ自動アップデートとは

ドキュメントの言葉を引用すると

Configuring automatic base image updates for Cloud Run enables Google to make security patches to the operating system and runtime components of the application image automatically. You don’t have to rebuild or redeploy your service

とのことで、Cloud Run のベースイメージの自動更新を構成すると、Google は OS とコンポーネントに対してパッチを自動的に適用でき、しかも、再デプロイ、再構築が不要らしい!

Cloud Run の自動ベースイメージ更新機能メリデメ

メリット

  • セキュリティの向上
  • 運用コストの削減
  • ダウンタイム無しでの更新

単純に固定バージョンで運用していたイメージは、イメージの更新が必要だったものが不要となります。
セキュリティ運用自体が不要になりませんが、ある程度マネージドに任せられる部分が出てくるかと思います。
最大のメリットはアップデートに伴いダウンタイムが発生しないことです。すご!!

デメリット

  • 意図しないアップデートが行われる

事前に検証環境や開発環境でアップデートテストを行いたいような場合、Build 方法や CI/CD で考慮する必要があると思います。
プレビュー中で実績が無いのでなんともいえませんが、自動更新を無効化することも可能なので、必要なアップデートがあった際に、運用で有効化するなど、必要なタイミングで設定することも可能なのではないか、と思いました。ダウンタイムなくできるのがいいかな、と思うので。

実行条件

ベースイメージを利用して、恩恵を受ける方法としては以下の2つがあります。

  • ソースから Cloud Run のデプロイを使用する
  • マルチステージビルドを使用して、ベースイメージと互換性のあるアプリケーションイメージを作成する

ベースイメージの種類はこちらを参照ください。

それぞれのサンプルは、ドキュメントベースの内容となりますが、以下に記載します。

ソースから Cloud Run のデプロイを使用する

ソースから Cloud Run へデプロイする方法は以前からありましたが、アップデート機能を適用するには、--base-image=XXXXXを明記し、ベースイメージを指定する必要があります。
※以下サンプルとしてドキュメントに掲載されたデプロイ方法となります。
※この記事記載時点で最新のsdkで行わないとエラーになるかと思うので、事前に確認ください

gcloud beta run deploy サービス名 \
  --source . \
  --base-image=ランタイムベースイメージ

こちらについて、クイックスタートベースで自動アップデート対象となったことを確認できましたので、詳細を後述します。

マルチステージビルドを使用して、ベースイメージと互換性のあるアプリケーションイメージを作成する

アプリケーションに必要なビルドをビルダーイメージ内で行い、スクラッチイメージに対象をコピーするような内容となります。

FROM node:18-slim as builder

# Create and change to the app directory.
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image and install
# production dependencies.
COPY package*.json ./
RUN npm install --only=production

# Copy local code to the container image.
COPY . ./

# Copy the application source code and depenencies onto a scratch image.
FROM scratch
COPY --from=builder --chown=33:33 /usr/src/app/ ./

# Run the web service on container startup.
CMD [ "node", "index.js" ]

こちらで作成した Dockerfile をビルドし、ArtifactRegistry にアップロードします。

そして Cloud Run にデプロイします。

gcloud beta run deploy サービス名 \
  --image=先ほど保存したイメージ \
  --base-image=ランタイムベースイメージ

ソースからのデプロイによる自動セキュリティアップデート有効化

※参考:クイックスタート(python)

1.必要ファイル作成

app.py

import os

from flask import Flask

app = Flask(__name__)


@app.route("/")
def hello_world():
    """Example Hello World route."""
    name = os.environ.get("NAME", "World")
    return f"Hello {name}!"


if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

Procfile

web: gunicorn app:app

requirements.txt

Flask==2.2.2
gunicorn==20.1.0
Werkzeug==3.0.3

2.デプロイ
以下のコマンドを実行します。

gcloud beta run deploy サービス名 --source . --base-image=python310

リージョンは us-central1 で行う必要があります。

3.自動更新が対象であることの確認
デプロイされた Cloud Run の Yaml を確認すると以下のように annotations に2箇所記載があると思いますが、その場合対象です。

annotations:
    ...
    run.googleapis.com/build-base-image: BASE_IMAGE_URL
    run.googleapis.com/launch-stage: BETA
    ...

試してみた結果、以下のように確認できました。よくみたら enable-auto-updates の記載もありますね。

まとめ

マネージドサービスのメンテナンス対応や、Cloud SQL のマイナーバージョンアップなど、マネージドサービスで自動アップデートする仕組みは多くありましたが、コンテナのイメージ内の更新はなかなかないのでは?と思い、今後推し機能になる気がしています。今の時点で以下のような部分もアップデートされるといいな、と思いました。期待したいです。

  • 自動ではなく承認が含まれるようなアップデートをコントロールする仕組み
  • アップデートされた内容がわかるような仕組み
     →今だとベースイメージのドキュメントベースで確認する形になるかな、と思いました。