🐋

GitHub Container Registry で公開されているコンテナイメージを Cloud Run で動かす

2024/04/29に公開

Cloud Run では GitHub Container Registry で配布されているコンテナイメージを直接参照して実行することはできません。
Google Artifact Registry (GAR)[1] もしくは Docker Hub[2] にイメージを置いて参照する必要があります。

これまでは、Cloud Run で直接参照できないリポジトリで公開されているイメージを動かす場合、GAR にリポジトリを作成しイメージをコピーする必要がありました。
しかし、半年前 (記事執筆時点) に GA となった機能を利用することで、イメージのコピーを明示的に行う手間が省けるようになっていましたので、その方法をご紹介します。

前提

  • ここで言う Cloud Run はフルマネージドのコンテナ実行環境を指します

  • 今回は GitHub Container Registry (ghcr.io) を外部のリポジトリとする場合の手順を紹介します

    • Quay.io で公開されているイメージを利用したい場合も、今回紹介する手順が参考になります
    • Docker Hub の非公開イメージを利用したい場合は Google Cloud 公式のドキュメントをご参照ください

TL;DR

  • 2023年10月27日に GA になったArtifact Registry remote repositories を利用します
  • 認証が不要な場合はアップストリームの検証に必ず失敗するので、検証を無効にします
  • Cloud Run で指定するイメージを ghcr.io/* の代わりに、今回作成する Remote repository (${region}-docker.pkg.dev/${project}/${repository}/*) を使用します

手順

GitHub Container Registry で配布されているイメージとして、ghcr.io/openzipkin/zipkin を例にします。
一般公開されていて、Cloud Run で起動し Web ブラウザで確認できるものであれば何でも構いません。

この先、Google Cloud の Project ID とロケーション (リージョン) は、それぞれ ${PROJECT_ID}${LOCATION} で表記します。
環境変数 PROJECT_IDLOCATION を事前に定義しておいてください。

PROJECT_ID=#環境に合わせて置き換える#
LOCATION=asia-northeast1

GAR リモートリポジトリの作成

2023年10月27日に GA になったArtifact Registry remote repositories を利用します。

リモートリポジトリは外部のリポジトリのプロキシとなって動作し、Cloud Run から参照することができます。

https://cloud.google.com/artifact-registry/docs/repositories/remote-repo?hl=ja

gcloud CLI を用いて、次のように作成します。

gcloud artifacts repositories create ghcr \
    --project=${PROJECT_ID} \
    --repository-format=docker \
    --location=${LOCATION} \
    --description="Remote docker repository for GitHub Container Registry" \
    --mode=remote-repository \
    --remote-repo-config-desc="GitHub Container Registry" \
    --remote-docker-repo="https://ghcr.io" \
    --disable-remote-validation

手元で pull してみる

Cloud Run を起動する前に、作成したリモートリポジトリを利用して手元から pull できることを確認します。

docker pull ${LOCATION}-docker.pkg.dev/${PROJECT_ID}/ghcr/openzipkin/zipkin

pull できて、コンソールから次のように確認できたら成功です。

Cloud Run で動かす

先ほど pull した際に指定したイメージで Cloud Run を起動します。

Service Account の作成

Cloud Run Service の実行に使用する Service Account (SA) を作成します。
Cloud Run Service の作成時に SA を指定しない場合デフォルトの SA (Compute Engine のデフォルトのサービスアカウント) が使用されますが、権限が強く推奨されません。最小権限の原則に従い、新規に SA を作成します。

https://cloud.google.com/blog/ja/products/identity-security/securing-cloud-run-deployments-with-least-privilege-access

gcloud iam service-accounts create zipkin \
    --display-name="Zipkin" \
    --description="Service Account for Zipkin on Cloud Run"

Cloud Run Service の作成

gcloud run deploy zipkin \
    --image=${LOCATION}-docker.pkg.dev/${PROJECT_ID}/ghcr/openzipkin/zipkin \
    --region=${LOCATION} \
    --service-account=zipkin@${PROJECT_ID}.iam.gserviceaccount.com \
    --no-allow-unauthenticated \
    --execution-environment=gen1 \
    --cpu=1 \
    --memory=512Mi \
    --max-instances=1 \
    --port=9411

※ 第2世代で動かす場合は --execution-environmentgen2 を指定します。

ターミナルに表示された URL は認証が必要でそのまま開けないため、次のように Cloud Run proxy を使用して開きます。

gcloud run services proxy zipkin --region $LOCATION

成功した場合は以下のようにターミナルに表示されるので、ブラウザで http://127.0.0.1:8080 を開きます。

http://127.0.0.1:8080 proxies to ...

次のように Zipkin の画面が開いたら成功です 🎉

Cloud Run proxy は Ctrl + C で終了します。

今回の手順を Terraform で

Terraform で書くと以下のようになります。

locals {
  project_id = "#環境に合わせて置き換える#"
  location   = "asia-northeast1"
}

terraform {
  required_version = "~> 1.8.2"

  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 5.26.0"
    }
  }
}

resource "google_artifact_registry_repository" "ghcr" {
  location      = local.location
  repository_id = "ghcr"
  description   = "Remote docker repository for GitHub Container Registry"
  format        = "DOCKER"
  mode          = "REMOTE_REPOSITORY"

  remote_repository_config {
    description                 = "GitHub Container Registry"
    disable_upstream_validation = true
    docker_repository {
      custom_repository {
        uri = "https://ghcr.io"
      }
    }
  }
}

resource "google_service_account" "zipkin" {
  account_id   = "zipkin"
  display_name = "Zipkin"
  description  = "Service Account for Zipkin on Cloud Run"
}

resource "google_cloud_run_v2_service" "zipkin" {
  name     = "zipkin"
  location = local.location
  ingress  = "INGRESS_TRAFFIC_ALL"

  template {
    execution_environment = "EXECUTION_ENVIRONMENT_GEN1"
    service_account       = google_service_account.zipkin.email

    scaling {
      max_instance_count = 1
    }

    containers {
      image = "${local.location}-docker.pkg.dev/${local.project_id}/${google_artifact_registry_repository.ghcr.name}/openzipkin/zipkin"
      ports {
        container_port = 9411
      }
      resources {
        limits = {
          cpu    = "1"
          memory = "512Mi"
        }
        cpu_idle          = true
        startup_cpu_boost = true
      }
    }
  }
}

さいごに

Artifact Registry remote repositories のお陰で、GAR や Docker Hub で提供されていないイメージを GAR にコピーする手間が省けるようになりました。
リモートリポジトリを作成する手間はありますが、GitHub Container Registry、Quay.io といった単位で作成するだけなので頻度は少なく大したコストではないでしょう。

地味ではありますが、Cloud Run が捗る Tips でした 🐳

脚注
  1. Google Container Registry (GCR) に置くこともできますが、サービス終了予定なのでここでは言及しません。 ↩︎

  2. Docker Hub で公開されているイメージは2023年2月26日から利用できるようになりました。 ↩︎

Discussion