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

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

始める前に

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Install the Google Cloud CLI.

  5. 外部 ID プロバイダ(IdP)を使用している場合は、まずフェデレーション ID を使用して gcloud CLI にログインする必要があります。

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

    gcloud init
  7. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  8. Verify that billing is enabled for your Google Cloud project.

  9. Install the Google Cloud CLI.

  10. 外部 ID プロバイダ(IdP)を使用している場合は、まずフェデレーション ID を使用して gcloud CLI にログインする必要があります。

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

    gcloud init
  12. Cloud Run Admin API と Cloud Build API を有効にします。

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

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

  13. ここをクリックして Cloud Build サービス アカウントに必要なロールを表示

    この動作をオーバーライドしない限り、Cloud Build は、ソースコードと Cloud Run リソースのビルドにデフォルトの Cloud Build サービス アカウントとして Compute Engine のデフォルトのサービス アカウントを自動的に使用します。Cloud Build がソースをビルドできるようにするには、プロジェクトの Compute Engine のデフォルトのサービス アカウントに Cloud Run ビルダーroles/run.builder)を付与するよう管理者に依頼します。

      gcloud projects add-iam-policy-binding PROJECT_ID \
          --member=serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com \
          --role=roles/run.builder
      

    PROJECT_NUMBER は Google Cloudプロジェクト番号に、PROJECT_ID は Google Cloudプロジェクト ID に置き換えます。プロジェクト ID とプロジェクト番号を確認する方法については、プロジェクトの作成と管理をご覧ください。

    Compute Engine のデフォルト サービス アカウントに Cloud Run ビルダーのロールを付与すると、反映されるまでに数分かかることがあります。

  14. Cloud Run の料金を確認するか、料金計算ツールで費用を見積もります。
  15. サンプルジョブを作成する

    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 にデプロイする

    重要: 以下の説明では、このクイックスタートで使用するプロジェクトのオーナーロールまたは編集者ロールが付与されていることを前提としています。ロールが付与されていない場合は、Cloud Run ソース デベロッパー ロールで、ソースから 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 リソースを解放する手順は次のとおりです。

    1. In the Google Cloud console, go to the Manage resources page.

      Go to Manage resources

    2. In the project list, select the project that you want to delete, and then click Delete.
    3. In the dialog, type the project ID, and then click Shut down to delete the project.

    次のステップ

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