Cloud Run で Java ジョブをビルドして作成する

シンプルな Cloud Run ジョブを作成して、ソースからデプロイする方法を学習します。コードをコンテナ イメージに自動的にパッケージ化し、コンテナ イメージを Artifact Registry にアップロードして、Cloud Run にデプロイします。ここでは説明されていない言語を使用することもできます。

始める前に

  1. Google Cloud アカウントにログインします。 Google Cloudを初めて使用する場合は、 アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
  2. Google Cloud CLI をインストールします。

  3. 外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。

  4. gcloud CLI を初期化するには、次のコマンドを実行します。

    gcloud init
  5. Google Cloud プロジェクトを作成または選択します

    プロジェクトの選択または作成に必要なロール

    • プロジェクトを選択する: プロジェクトの選択に特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトであれば、どのプロジェクトでも選択できます。
    • プロジェクトを作成する: プロジェクトを作成するには、resourcemanager.projects.create 権限を含むプロジェクト作成者ロール(roles/resourcemanager.projectCreator)が必要です。ロールを付与する方法を確認する
    • Google Cloud プロジェクトを作成します。

      gcloud projects create PROJECT_ID

      PROJECT_ID は、作成する Google Cloud プロジェクトの名前に置き換えます。

    • 作成した Google Cloud プロジェクトを選択します。

      gcloud config set project PROJECT_ID

      PROJECT_ID は、 Google Cloud プロジェクトの名前に置き換えます。

  6. このガイドで既存のプロジェクトを使用する場合は、このガイドを完了するために必要な権限があることを確認します。新しいプロジェクトを作成した場合は、必要な権限がすでに付与されています。

  7. Google Cloud プロジェクトに対して課金が有効になっていることを確認します

  8. Google Cloud CLI をインストールします。

  9. 外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。

  10. gcloud CLI を初期化するには、次のコマンドを実行します。

    gcloud init
  11. Google Cloud プロジェクトを作成または選択します

    プロジェクトの選択または作成に必要なロール

    • プロジェクトを選択する: プロジェクトの選択に特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトであれば、どのプロジェクトでも選択できます。
    • プロジェクトを作成する: プロジェクトを作成するには、resourcemanager.projects.create 権限を含むプロジェクト作成者ロール(roles/resourcemanager.projectCreator)が必要です。ロールを付与する方法を確認する
    • Google Cloud プロジェクトを作成します。

      gcloud projects create PROJECT_ID

      PROJECT_ID は、作成する Google Cloud プロジェクトの名前に置き換えます。

    • 作成した Google Cloud プロジェクトを選択します。

      gcloud config set project PROJECT_ID

      PROJECT_ID は、 Google Cloud プロジェクトの名前に置き換えます。

  12. このガイドで既存のプロジェクトを使用する場合は、このガイドを完了するために必要な権限があることを確認します。新しいプロジェクトを作成した場合は、必要な権限がすでに付与されています。

  13. Google Cloud プロジェクトに対して課金が有効になっていることを確認します

  14. Cloud Run Admin API と Cloud Build API を有効にします。

    API を有効にするために必要なロール

    API を有効にするには、serviceusage.services.enable 権限を含む Service Usage 管理者 IAM ロール(roles/serviceusage.serviceUsageAdmin)が必要です。ロールを付与する方法を確認する

    gcloud services enable run.googleapis.com cloudbuild.googleapis.com

    Cloud Run Admin API を有効にすると、Compute Engine のデフォルトのサービス アカウントが自動的に作成されます。

  15. Cloud Run の料金を確認するか、料金計算ツールで費用を見積もります。

必要なロール

このクイックスタートを完了するために必要な権限を取得するには、管理者に次の IAM ロールを付与するよう依頼してください。

ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

Cloud Build サービス アカウントにプロジェクトへのアクセス権を付与する

この動作をオーバーライドしない限り、Cloud Build は、ソースコードと Cloud Run リソースのビルドにデフォルトの Cloud Build サービス アカウントとして Compute Engine のデフォルトのサービス アカウントを自動的に使用します。

Cloud Build がソースをビルドできるようにするには、プロジェクトの Cloud Build サービス アカウントに Cloud Run ビルダーroles/run.builder)のロールを付与します。

gcloud projects add-iam-policy-binding PROJECT_ID \
    --member=serviceAccount:SERVICE_ACCOUNT_EMAIL_ADDRESS \
    --role=roles/run.builder

PROJECT_ID は実際の Google Cloudプロジェクト ID に置き換え、SERVICE_ACCOUNT_EMAIL_ADDRESS は Cloud Build サービス アカウントのメールアドレスに置き換えます。Compute Engine のデフォルト サービス アカウントを Cloud Build サービス アカウントとして使用している場合は、サービス アカウントのメールアドレスに次の形式を使用します。

PROJECT_NUMBER-compute@developer.gserviceaccount.com

PROJECT_NUMBER は、使用する Google Cloudプロジェクト番号に置き換えます。

プロジェクト ID とプロジェクト番号を確認する方法については、プロジェクトの作成と管理をご覧ください。

Cloud Run ビルダーのロールを付与すると、反映されるまでに数分かかることがあります。

サンプルジョブの作成

Java でジョブを作成するには:

  1. jobs という名前の新しいディレクトリを作成し、そのディレクトリに移動します。

    mkdir jobs
    cd jobs
    
  2. src/main/java/com/example という名前のサブディレクトリに、実際のジョブコードを記述する JobsExample.java ファイルを作成します。ここに次のサンプル行をコピーします。

    
    package com.example;
    
    abstract class JobsExample {
      // These values are provided automatically by the Cloud Run Jobs runtime.
      private static String CLOUD_RUN_TASK_INDEX =
          System.getenv().getOrDefault("CLOUD_RUN_TASK_INDEX", "0");
      private static String CLOUD_RUN_TASK_ATTEMPT =
          System.getenv().getOrDefault("CLOUD_RUN_TASK_ATTEMPT", "0");
    
      // User-provided environment variables
      private static int SLEEP_MS = Integer.parseInt(System.getenv().getOrDefault("SLEEP_MS", "0"));
      private static float FAIL_RATE =
          Float.parseFloat(System.getenv().getOrDefault("FAIL_RATE", "0.0"));
    
      // Start script
      public static void main(String[] args) {
        System.out.println(
            String.format(
                "Starting Task #%s, Attempt #%s...", CLOUD_RUN_TASK_INDEX, CLOUD_RUN_TASK_ATTEMPT));
        try {
          runTask(SLEEP_MS, FAIL_RATE);
        } catch (RuntimeException | InterruptedException e) {
          System.err.println(
              String.format(
                  "Task #%s, Attempt #%s failed.", CLOUD_RUN_TASK_INDEX, CLOUD_RUN_TASK_ATTEMPT));
          // Catch error and denote process-level failure to retry Task
          System.exit(1);
        }
      }
    
      static void runTask(int sleepTime, float failureRate) throws InterruptedException {
        // Simulate work
        if (sleepTime > 0) {
          Thread.sleep(sleepTime);
        }
    
        // Simulate errors
        if (failureRate < 0 || failureRate > 1) {
          System.err.println(
              String.format(
                  "Invalid FAIL_RATE value: %s. Must be a float between 0 and 1 inclusive.",
                  failureRate));
          return;
        }
        if (Math.random() < failureRate) {
          throw new RuntimeException("Task Failed.");
        }
        System.out.println(String.format("Completed Task #%s", CLOUD_RUN_TASK_INDEX));
      }
    }

    Cloud Run ジョブを使用すると、実行するタスクの数を指定できます。次のサンプルコードは、組み込みの CLOUD_RUN_TASK_INDEX 環境変数を使用する方法を示しています。各タスクが、コンテナの 1 つの実行中のコピーを表します。タスクは通常、並行して実行されます。各タスクが独立してデータのサブセットを処理できる場合は、複数のタスクを使用すると便利です。

    各タスクはインデックスを認識し、CLOUD_RUN_TASK_INDEX 環境変数に格納されます。組み込みの CLOUD_RUN_TASK_COUNT 環境変数には、ジョブの実行時に --tasks パラメータを介して指定されたタスクの数が含まれています。

    このコードは、組み込みの CLOUD_RUN_TASK_ATTEMPT 環境変数を使用してタスクを再試行する方法を示しています。この変数はタスクの再試行回数を表します。最初の再試行が行われると、この変数に 0 が設定され、--max-retries になるまで再試行のたびに値が 1 ずつ増加します。

    このコードでは、再試行のテストやエラーログの生成も行うことができるため、問題の発生箇所を確認できます。

  3. pom.xml ファイルを作成し、次の内容を追加します。

    <?xml version="1.0" encoding="UTF-8"?>
    <!--
    Copyright 2021 Google LLC
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    -->
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.example.run</groupId>
      <artifactId>jobs-example</artifactId>
      <version>0.0.1</version>
      <packaging>jar</packaging>
    
      <!--  The parent pom defines common style checks and testing strategies for our samples.
    	Removing or replacing it should not affect the execution of the samples in anyway. -->
      <parent>
        <groupId>com.google.cloud.samples</groupId>
        <artifactId>shared-configuration</artifactId>
        <version>1.2.0</version>
      </parent>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.target>17</maven.compiler.target>
        <maven.compiler.source>17</maven.compiler.source>
      </properties>
    
      <dependencyManagement>
        <dependencies>
          <dependency>
            <artifactId>libraries-bom</artifactId>
            <groupId>com.google.cloud</groupId>
            <scope>import</scope>
            <type>pom</type>
            <version>26.32.0</version>
          </dependency>
        </dependencies>
      </dependencyManagement>
    
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.13.2</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>com.google.truth</groupId>
          <artifactId>truth</artifactId>
          <version>1.4.0</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>com.google.cloud</groupId>
          <artifactId>google-cloud-logging</artifactId>
          <scope>test</scope>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.3.0</version>
            <configuration>
              <archive>
                <manifest>
                  <addClasspath>true</addClasspath>
                  <mainClass>com.example.JobsExample</mainClass>
                </manifest>
              </archive>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>
    
  4. 次の内容の project.toml ファイルを作成し、Buildpack でサポートされている Java バージョンでビルドします。

    # Default version is Java 11
    #  - See https://cloud.google.com/docs/buildpacks/java#specify_a_java_version
    # Match the version required in pom.xml by setting it here
    #  - See https://cloud.google.com/docs/buildpacks/set-environment-variables#build_the_application_with_environment_variables
    
    [[build.env]]
      name = "GOOGLE_RUNTIME_VERSION"
      value = "17"
    

コードが完成し、コンテナにパッケージ化できるようになりました。

ジョブコンテナをビルドして Artifact Registry に送信し、Cloud Run にデプロイする

このクイックスタートでは、コンテナをビルドして Artifact Registry にアップロードし、ジョブを Cloud Run にデプロイするソースからのデプロイを使用します。

gcloud run jobs deploy job-quickstart \
    --source . \
    --tasks 50 \
    --set-env-vars SLEEP_MS=10000 \
    --set-env-vars FAIL_RATE=0.1 \
    --max-retries 5 \
    --region REGION \
    --project=PROJECT_ID

ここで、PROJECT_ID はプロジェクト ID、REGION はリージョンです(例: europe-west1)。パラメータの値は、テスト目的で使用する任意の値に変更できます。SLEEP_MS は作業をシミュレートし、FAIL_RATE でタスクの X% を失敗させます。これにより、並列処理をテストし、失敗したタスクを再試行できます。

Cloud Run でジョブを実行する

作成したジョブを実行するには:

gcloud run jobs execute job-quickstart --region REGION

REGION は、ジョブを作成してデプロイしたときに使用したリージョン(europe-west1 など)に置き換えます。

クリーンアップ

Google Cloud アカウントで追加料金が発生しないようにするには、このクイックスタートでデプロイしたすべてのリソースを削除します。

リポジトリを削除する

Cloud Run では、ジョブの実行時間に対してのみ料金が発生します。ただし、コンテナ イメージを Artifact Registry に保存した場合にも料金が発生する可能性があります。Artifact Registry リポジトリを削除するには、Artifact Registry ドキュメントのリポジトリを削除するの手順を行います。

ジョブを削除する

Cloud Run ジョブでは、ジョブタスクの実行時にのみ料金が発生します。Cloud Run ジョブを削除するには、次のいずれかの操作を行います。

コンソール

ジョブを削除するには:

  1. Google Cloud コンソールで Cloud Run に移動します。

    Cloud Run に移動

  2. 削除するジョブをジョブリストで探し、そのチェックボックスをクリックして選択します。

  3. [削除] をクリックします。これにより、進行中のすべてのジョブ実行と実行中のすべてのコンテナ インスタンスが終了します。

gcloud

ジョブを削除するには、次のコマンドを実行します。

gcloud run jobs delete JOB_NAME

JOB_NAME は、ジョブ名に置き換えます。

テスト プロジェクトを削除する

Google Cloud プロジェクトを削除すると、そのプロジェクト内のすべてのリソースに対する課金が停止します。プロジェクト内のすべての Google Cloud リソースを解放する手順は次のとおりです。

    Google Cloud プロジェクトを削除します。

    gcloud projects delete PROJECT_ID

次のステップ

コードソースからコンテナをビルドし、リポジトリに push する方法については、以下をご覧ください。