CFアプリ開発と管理#10 タスクの実行

このトピックでは、Cloud Foundryでタスクを実行する方法について説明します。 タスクとは、コードがデプロイされたアプリケーションの一部として含まれていても、独自のコンテナで独立して実行されるアプリケーションまたはスクリプトのことです。

シングル・ユース・オブジェクトとして、タスクの状態と成功または失敗のメッセージを確認できます。

*注意事項: この記事は、Cloud Foundry Documentaion [Running Tasks](https://docs.cloudfoundry.org/devguide/using-tasks.html) (last updated: January 19, 2017) からの独自の翻訳とコメントです。 公式なレビューを受けたものではありません。*

## タスクの使用例

タスクは、次のものを含む一回限りのジョブを実行するために使用されます。

* データベースの移行
* 電子メールを送信する
* バッチジョブの実行
* データ処理スクリプトの実行
* イメージの処理
* 検索インデックスの最適化
* データのアップロード
* バックアップデータ
* コンテンツのダウンロード



## タスクの実行方法

タスクは常に非同期に実行されます。つまり、タスクが親アプリケーションまたは同じアプリケーションで実行される他のタスクとは独立して実行されます。

タスクのライフサイクルは次のとおりです。

1. ユーザーは、次のいずれかのメカニズムを使用してCloud Foundryでタスクを開始します。
  * `cf run-task APPNAME "TASK"` コマンド。 詳細は、このトピックの「タスクの実行中」を参照してください。
  * Cloud Controller v3 API呼び出し。 詳細は、「[タスクAPIリファレンス](http://v3-apidocs.cloudfoundry.org/version/3.0.0/index.html#tasks)」を参照してください。
  * Cloud Foundry Javaクライアント。 詳細については、[Cloud Foundry Javaクライアントライブラリ](https://docs.cloudfoundry.org/buildpacks/java/java-client.html)および [Cloud Foundry Javaクライアント](https://github.com/cloudfoundry/cf-java-client) のトピックを参照してください。

2. Cloud Foundry は、タスク専用のコンテナを作成します。
3. Cloud Foundry は、cf run-taskコマンドに渡された値を使用してコンテナでタスクを実行します。
4. Cloud Foundry はコンテナを破壊します。

コンテナは、環境変数、サービスバインディング、およびアプリケーションにバインドされたセキュリティグループも継承します。

注：タスクを実行しているコンテナにSSHを実行することはできません。


## タスクのログと実行履歴
タスクが STDOUT または STDERR に出力するデータまたはメッセージは、アプリの[firehoseログ](https://docs.cloudfoundry.org/loggregator/architecture.html)にあります。 アプリケーションに接続されたsyslogドレインがタスクのログ出力を受け取ります。

タスクの実行履歴は1ヶ月間保持されます。


## タスクの管理

システムレベルでは、管理者レベルの権限を持つユーザーは、Cloud Controller v3 APIを使用して、組織内または組織内で実行中のすべてのタスクを表示できます。 詳細については、Cloud Controller v3 APIのドキュメントを参照してください。

さらに、管理者は、グローバルレベルでのタスクのデフォルトメモリとディスク使用量のクォータを設定できます。 最初は、タスクはアプリケーションと同じメモリおよびディスク使用率のデフォルトを使用します。 ただし、タスクのデフォルトメモリとディスク割り当ては、デフォルトのアプリメモリとディスク割り当てとは別に定義できます。

タスクのデフォルトメモリとディスク割り当ては、BOSH Cloud Controller Workerジョブで定義されている `cc.default_app_memory` および `cc.default_app_disk_in_mb` プロパティで指定します。 詳細については、「[構成プロパティー](http://bosh.io/jobs/cloud_controller_worker?source=github.com/cloudfoundry/cf-release&version=235)」を参照してください。


## アプリケーションでのタスクの実行

Cloud Foundry コマンドライン・インタフェース(cf CLI) を使用して、アプリケーションをアプリケーションのコンテキストで実行することができます。

注：cf CLIでタスクを実行するには、cf CLI v6.23.0以降をインストールする必要があります。 cf CLIのダウンロード、インストール、およびアンインストールについては、「[Cloud Foundry Command Line Interface のインストール](https://docs.cloudfoundry.org/cf-cli/install-go-cli.html)」を参照してください。


アプリケーションでタスクを実行するには、次の手順を実行します。

1. アプリケーションをプッシュ：

~~~
$ cf push APP-NAME
~~~


2. デプロイされたアプリケーションでタスクを実行します。

~~~
$ cf run-task APP-NAME "TASK" --name TASK-NAME
~~~


次の例では、`my-app` アプリケーションのタスクとしてデータベースの移行を実行します。

~~~
$ cf run-task my-app "bin/rails db:migrate" --name my-task
Creating task for app my-app in org jdoe-org / space development as jdoe@pivotal.io...
OK
Task 1 has been submitted successfully for execution.
~~~


注：タスクを再実行するには、上記のコマンドを使用してタスクを新しいタスクとして実行する必要があります。

`cf logs APP-NAME --recent` コマンドを使用して、アプリケーションとそのすべてのタスクの最近のログを表示します。

次の例は、正常なタスクのログを表示します。

~~~
$ cf logs my-app --recent
2017-01-03T15:58:06.57-0800 [APP/TASK/my-task/0]OUT Creating container
2017-01-03T15:58:08.45-0800 [APP/TASK/my-task/0]OUT Successfully created container
2017-01-03T15:58:13.32-0800 [APP/TASK/my-task/0]OUT D, [2017-01-03T23:58:13.322258 #7] DEBUG -- :    (15.9ms)  CREATE TABLE "schema_migrations" ("version" character varying PRIMARY KEY)
2017-01-03T15:58:13.33-0800 [APP/TASK/my-task/0]OUT D, [2017-01-03T23:58:13.337723 #7] DEBUG -- :    (11.9ms)  CREATE TABLE "ar_internal_metadata" ("key" character varying PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
2017-01-03T15:58:13.34-0800 [APP/TASK/my-task/0]OUT D, [2017-01-03T23:58:13.340234 #7] DEBUG -- :    (1.6ms)  SELECT pg_try_advisory_lock(3720865444824511725);
2017-01-03T15:58:13.35-0800 [APP/TASK/my-task/0]OUT D, [2017-01-03T23:58:13.351853 #7] DEBUG -- :   ActiveRecord::SchemaMigration Load (0.7ms)  SELECT "schema_migrations".* FROM "schema_migrations"
2017-01-03T15:58:13.35-0800 [APP/TASK/my-task/0]OUT I, [2017-01-03T23:58:13.357294 #7]  INFO -- : Migrating to CreateArticles (20161118225627)
2017-01-03T15:58:13.35-0800 [APP/TASK/my-task/0]OUT D, [2017-01-03T23:58:13.359565 #7] DEBUG -- :    (0.5ms)  BEGIN
2017-01-03T15:58:13.35-0800 [APP/TASK/my-task/0]OUT == 20161118225627 CreateArticles: migrating ===================================
2017-01-03T15:58:13.50-0800 [APP/TASK/my-task/0]OUT Exit status 0
2017-01-03T15:58:13.56-0800 [APP/TASK/my-task/0]OUT Destroying container
2017-01-03T15:58:15.65-0800 [APP/TASK/my-task/0]OUT Successfully destroyed container
~~~

次の例は、失敗したタスクのログを表示です。

~~~
$ cf logs my-app --recent
2016-12-14T11:09:26.09-0800 [APP/TASK/my-task/0]OUT Creating container
2016-12-14T11:09:28.43-0800 [APP/TASK/my-task/0]OUT Successfully created container
2016-12-14T11:09:28.85-0800 [APP/TASK/my-task/0]ERR bash: bin/rails: command not found
2016-12-14T11:09:28.85-0800 [APP/TASK/my-task/0]OUT Exit status 127
2016-12-14T11:09:28.89-0800 [APP/TASK/my-task/0]OUT Destroying container
2016-12-14T11:09:30.50-0800 [APP/TASK/my-task/0]OUT Successfully destroyed container
~~~

タスク名が一意である場合は、タスク固有のログを表示するために、タスク名の `cf logs` コマンドの出力をgrepすることができます。


## アプリケーションで実行中のタスクの一覧表示

特定のアプリケーションのタスクを一覧表示するには、`cf tasks APP-NAME` を実行します。 例えば：

~~~
$ cf tasks my-app
Getting tasks for app my-app in org jdoe-org / space development as jdoe@pivotal.io...
OK

id   name       state       start time                      command
2    339044ef   FAILED      Wed, 23 Nov 2016 21:52:52 UTC   echo foo; sleep 100; echo bar
1    8d0618cf   SUCCEEDED   Wed, 23 Nov 2016 21:37:28 UTC   bin/rails db:migrate
~~~


各タスクには、次のいずれかの状態があります。

| 状態      | 説明 |
|:--       |:-- |
|RUNNING   | タスクは現在進行中です。|
|FAILED    |タスクは完了しませんでした。 この状態は、タスクが正しく動作しない場合、またはユーザーがタスクをキャンセルした場合に発生します。|
|SUCCEEDED |タスクは正常に完了しました。|


## タスクをキャンセルする
タスクを実行した後、タスクが完了する前にタスクをキャンセルすることができます。 実行中のタスクをキャンセルするには、`cf terminate-task APP-NAME TASK-ID` コマンドを使用します。 例えば：

~~~
$ cf terminate-task my-app 2
Terminating task 2 of app my-app in org jdoe-org / space development as jdoe@pivotal.io...
OK
~~~