--- title: Cloud FoundryのNative Zero Downtime Updateを試す tags: ["Cloud Foundry", "PAS", "CFAR", "Pivotal Application Service"] categories: ["Dev", "PaaS", "CloudFoundry"] date: 2018-12-04T14:53:49Z updated: 2018-12-20T03:59:33Z --- [Cloud Foundry Advent Calendar 2018](https://qiita.com/advent-calendar/2018/cloudfoundry)の4日目 Cloud Foundry (Application Runtime)に[Deploying Apps with Zero Downtime (Experimental)](https://docs.cloudfoundry.org/devguide/deploy-apps/zero-downtime.html)という新機能が最近追加されました。 Platformレイヤで提供するZero Downtime Update機能あるいはRolling Updateとも呼ばれます。`cf v3-zdt-push`というコマンドが追加されました。 通常の[Blue/Green](https://docs.cloudfoundry.org/devguide/deploy-apps/blue-green.html)は2つのアプリケーションを平行でデプロイしてルーティングを切り替えます。[autopilotプラグイン](https://github.com/contraband/autopilot)を使って実現することが多いです。 これに比べてNative Zero Downtime Updateは同じアプリを少しずつ新しいバージョンに移行します。 これにより既存のBlue/Greenに比べて次の点でメリットがあります * バージョンアップ前後でアプリが同じGUIDになるのでログやメトリクスの追従で困らない * バージョンアップ前後で必要なリソースが何も設定しなくてもインスタンス数+1で済む。(Blue/Greenの場合は、工夫しなければ一時的にインスタンス数 x 2が必要) * container to container networkで必要なnetwork policyの設定を新バージョンに対して行う必要がない Native Zero Downtime Updateは * Pivotal Web Servicesでは既に利用可能です。 * Pivotal Application Service (旧Pivotal Cloud Foundry)では2.4から利用可能になります。 [[doc](https://docs.pivotal.io/pivotalcf/2-4/pcf-release-notes/runtime-rn.html#zdt-deploy)] * cf-deploymentを使っている場合は、capi-release v0.168.0以上にして[このops-file](https://github.com/cloudfoundry/cf-deployment/blob/master/operations/experimental/add-deployment-updater.yml)を追加する必要があります。 簡単なアプリケーションで試してみます。 使用するCF CLIのバージョンは次の通りです ``` $ cf -v cf バージョン 6.41.0+dd4c76cdd.2018-11-28 ``` ``` mkdir demo-zdt-push cd demo-zdt-push ``` `manifest.yml`ファイルを作成します。5インスタンスで試します。 ```yaml --- applications: - name: hello-tmaki instance: 5 buildpack: php_buildpack memory: 32m ``` 次に`index.php`を作成します。 ```php V2への切り替えで`cf v3-zdt-push`コマンドを使用します。 ``` cf v3-zdt-push hello-tmaki このコマンドは試験段階であり、通知なしに変更される可能性があります tmaki@example.com として組織 APJ / スペース development 内のアプリ hello-tmaki を更新しています... OK tmaki@example.com として組織 APJ / スペース development 内のアプリ hello-tmaki のビット・パッケージをアップロードおよび作成しています... OK tmaki@example.com として組織 APJ / スペース development 内のアプリ hello-tmaki のパッケージをステージングしています... Downloading php_buildpack... Downloaded php_buildpack Cell 56e8dd19-dacf-40d2-9458-a2e09d713ed2 creating container for instance 5da4017c-5e7d-47b7-b415-0919389363fc Cell 56e8dd19-dacf-40d2-9458-a2e09d713ed2 successfully created container for instance 5da4017c-5e7d-47b7-b415-0919389363fc Downloading app package... Downloading build artifacts cache... Downloaded app package (186B) Downloaded build artifacts cache (220B) -------> Buildpack version 4.3.64 Installing HTTPD HTTPD 2.4.37 Downloaded [file:///tmp/buildpacks/869aab15d728ede896ff849f1604920c/dependencies/https___buildpacks.cloudfoundry.org_dependencies_httpd_httpd-2.4.37-linux-x64-cflinuxfs2-303a5672.tgz] to [/tmp] Installing PHP PHP 7.2.11 Downloaded [file:///tmp/buildpacks/869aab15d728ede896ff849f1604920c/dependencies/https___buildpacks.cloudfoundry.org_dependencies_php_php7-7.2.11-linux-x64-cflinuxfs2-77151e3d.tgz] to [/tmp] Finished: [2018-12-04 14:20:28.333149] Exit status 0 Uploading droplet, build artifacts cache... Uploading build artifacts cache... Uploading droplet... Uploaded build artifacts cache (224B) Uploaded droplet (72.7M) Uploading complete Cell 56e8dd19-dacf-40d2-9458-a2e09d713ed2 stopping instance 5da4017c-5e7d-47b7-b415-0919389363fc Cell 56e8dd19-dacf-40d2-9458-a2e09d713ed2 destroying container for instance 5da4017c-5e7d-47b7-b415-0919389363fc OK 経路をマップしています... OK Starting deployment for app hello-tmaki in org APJ / space development as tmaki@example.com... OK アプリが開始するのを待機しています... ``` このタイミングで`cf app hello-tmaki`を実行すると、`web-deployment-xxxxxxxx`というタイプでアプリケーションが立ち上がり始めているのがわかります。こちらがV2のアプリです。V1の方は5インスタンスのままです。 ``` 名前: hello-tmaki 要求された状態: started 経路: hello-tmaki.cfapps.io 最終アップロード日時: Tue 04 Dec 23:20:44 JST 2018 スタック: cflinuxfs2 ビルドパック: php_buildpack タイプ: web インスタンス: 5/5 メモリー使用量: 32M 状態 開始日時 cpu メモリー ディスク 詳細 #0 実行 2018-12-04T14:16:01Z 0.7% 32M の中の 16.3M 1G の中の 220.5M #1 実行 2018-12-04T14:16:13Z 0.5% 32M の中の 16M 1G の中の 220.5M #2 実行 2018-12-04T14:16:27Z 0.6% 32M の中の 16M 1G の中の 220.5M #3 実行 2018-12-04T14:16:40Z 0.7% 32M の中の 16M 1G の中の 220.5M #4 実行 2018-12-04T14:16:54Z 0.5% 32M の中の 16.5M 1G の中の 220.5M タイプ: web-deployment-04ef4ce1-98d9-4cc1-9961-03b670986b13 インスタンス: 0/1 メモリー使用量: 32M 状態 開始日時 cpu メモリー ディスク 詳細 #0 開始中 2018-12-04T14:20:55Z 0.0% 32M の中の 0 1G の中の 0 ``` もう一度`cf app hello-tmaki`を実行すると、V2アプリの2インスタンス目が立ち上がり始めています。V1の方は4インスタンスに減りました。 ``` 名前: hello-tmaki 要求された状態: started 経路: hello-tmaki.cfapps.io 最終アップロード日時: Tue 04 Dec 23:20:44 JST 2018 スタック: cflinuxfs2 ビルドパック: php_buildpack タイプ: web インスタンス: 4/4 メモリー使用量: 32M 状態 開始日時 cpu メモリー ディスク 詳細 #0 実行 2018-12-04T14:16:00Z 0.6% 32M の中の 16.3M 1G の中の 220.5M #1 実行 2018-12-04T14:16:12Z 0.7% 32M の中の 16.1M 1G の中の 220.5M #2 実行 2018-12-04T14:16:27Z 0.5% 32M の中の 16M 1G の中の 220.5M #3 実行 2018-12-04T14:16:40Z 0.7% 32M の中の 16M 1G の中の 220.5M タイプ: web-deployment-04ef4ce1-98d9-4cc1-9961-03b670986b13 インスタンス: 1/2 メモリー使用量: 32M 状態 開始日時 cpu メモリー ディスク 詳細 #0 実行 2018-12-04T14:21:03Z 4.1% 32M の中の 15.6M 1G の中の 220.5M #1 開始中 2018-12-04T14:21:03Z 0.0% 32M の中の 0 1G の中の 0 ``` しばらくして、もう一度`cf app hello-tmaki`を実行すると、V2アプリの4インスタンス目が立ち上がり始めています。V1の方は2インスタンスに減りました。 ``` 名前: hello-tmaki 要求された状態: started 経路: hello-tmaki.cfapps.io 最終アップロード日時: Tue 04 Dec 23:20:44 JST 2018 スタック: cflinuxfs2 ビルドパック: php_buildpack タイプ: web インスタンス: 2/2 メモリー使用量: 32M 状態 開始日時 cpu メモリー ディスク 詳細 #0 実行 2018-12-04T14:16:01Z 0.6% 32M の中の 16.4M 1G の中の 220.5M #1 実行 2018-12-04T14:16:13Z 0.6% 32M の中の 16.1M 1G の中の 220.5M タイプ: web-deployment-04ef4ce1-98d9-4cc1-9961-03b670986b13 インスタンス: 3/4 メモリー使用量: 32M 状態 開始日時 cpu メモリー ディスク 詳細 #0 実行 2018-12-04T14:21:03Z 0.7% 32M の中の 15.7M 1G の中の 220.5M #1 実行 2018-12-04T14:21:14Z 0.0% 32M の中の 16.1M 1G の中の 220.5M #2 実行 2018-12-04T14:21:28Z 0.0% 32M の中の 20K 1G の中の 8K #3 開始中 2018-12-04T14:21:29Z 0.0% 32M の中の 0 1G の中の 0 ``` もう一度`cf app hello-tmaki`を実行すると、V2アプリの5インスタンス目が立ち上がり始めています。V1の方は1インスタンスに減りました。 ``` 名前: hello-tmaki 要求された状態: started 経路: hello-tmaki.cfapps.io 最終アップロード日時: Tue 04 Dec 23:20:44 JST 2018 スタック: cflinuxfs2 ビルドパック: php_buildpack タイプ: web インスタンス: 1/1 メモリー使用量: 32M 状態 開始日時 cpu メモリー ディスク 詳細 #0 実行 2018-12-04T14:16:00Z 0.6% 32M の中の 16.4M 1G の中の 220.5M タイプ: web-deployment-04ef4ce1-98d9-4cc1-9961-03b670986b13 インスタンス: 4/5 メモリー使用量: 32M 状態 開始日時 cpu メモリー ディスク 詳細 #0 実行 2018-12-04T14:21:03Z 0.7% 32M の中の 15.7M 1G の中の 220.5M #1 実行 2018-12-04T14:21:14Z 0.3% 32M の中の 17.4M 1G の中の 220.5M #2 実行 2018-12-04T14:21:27Z 0.6% 32M の中の 15.6M 1G の中の 220.5M #3 実行 2018-12-04T14:21:39Z 0.6% 32M の中の 15.4M 1G の中の 220.5M #4 開始中 2018-12-04T14:21:43Z 0.0% 32M の中の 0 1G の中の 0 ``` もう一度`cf app hello-tmaki`を実行すると、V2アプリの5インスタンス目が立ち上がり切り、V1の方は1インスタンスはなくなりました。 ``` 名前: hello-tmaki 要求された状態: started 経路: hello-tmaki.cfapps.io 最終アップロード日時: Tue 04 Dec 23:20:44 JST 2018 スタック: cflinuxfs2 ビルドパック: php_buildpack タイプ: web インスタンス: 5/5 メモリー使用量: 32M 状態 開始日時 cpu メモリー ディスク 詳細 #0 実行 2018-12-04T14:21:03Z 0.6% 32M の中の 15.8M 1G の中の 220.5M #1 実行 2018-12-04T14:21:14Z 0.6% 32M の中の 17.6M 1G の中の 220.5M #2 実行 2018-12-04T14:21:27Z 0.6% 32M の中の 15.7M 1G の中の 220.5M #3 実行 2018-12-04T14:21:39Z 0.5% 32M の中の 15.4M 1G の中の 220.5M #4 実行 2018-12-04T14:21:58Z 0.3% 32M の中の 15.6M 1G の中の 220.5M ``` 見ての通り、 V1 -> V2は1インスタンスずつ移行が行われ、同じrouteがマッピングされているので、 移行中は両方のバージョンにリクエストが行きます。インスタンス数の比率でラウンドロビンされます。 この機能が実装されるまでは同様のことをshell scriptで実装したり、[Scaleover Plugin](https://github.com/krujos/scaleover-plugin)を使って実現してましたが、`cf v3-zdt-push`コマンドが正式に導入されたらとても簡単に実行できますね。 アプリケーションの変更なしの状態で`cf v3-zdt-push`コマンドを実行すればzero down time restageになるのでbuildpackの更新をzero down timeで行えます。 また、`cf v3-zdt-restart`もあるのでこちらは環境変数変更の適用をzero down timeで行うのに使えます。 まだExperimentalという位置付けですが、かなりの便利機能です。 制約事項は[こちら](https://docs.cloudfoundry.org/devguide/deploy-apps/zero-downtime.html#limitations)