はじめに
Azure Virtual Machine Scale Sets (VMSS) は、VM イメージからオートスケール可能な VM 群を作成し、管理してくれる便利なサービスです。
VMSS を運用していくに当たって、更新したアプリケーションを VMSS にデプロイしたい、オートスケールで新たに起動した VM で最新のアプリケーションが稼働することを保証したい、OS やミドルウェアのバージョンを定期的に更新したい、といったニーズが出てくると思います。
本記事では、こういったニーズに応えるための VMSS の更新方法について整理します。
VMSS の更新方法の一覧
大まかに以下の 4 つの方法があります。各方法の詳細は後述します。
- カスタム VM イメージを用いた新規 VMSS の作成
- カスタム VM イメージを用いた既存 VMSS の更新
- 共有イメージギャラリーを用いた既存 VMSS の更新
- スクリプト主体の方法 (カスタムスクリプト拡張機能 / cloud-init / Run command)
方法 1 から 3 は VM イメージ主体の方法で、いずれもカスタム VM イメージを利用します。カスタム VM イメージとは、ユーザー自身が、必要なミドルウェア類のインストール、OS 及びミドルウェアの設定、アプリケーションの同梱などを行った VM のイメージを指します。この方法は、アプリケーションの更新だけでなく OS やミドルウェアの構成や設定を大きく変更したい場合にも使えます。
一方、スクリプト主体の方法では、VM 内で任意のスクリプトを実行します。VM にスクリプトを実行させるための仕組みが複数あるため、それらを簡単に紹介します。
使い分けのアイディア
結局気になるのは「どの方法を使うべきか」という点だと思います。いずれも良し悪しがあるのでケースバイケースで使い分ける形になりますが、各方法の詳細を紹介する前に、使い分けのアイディアになる情報をまとめたいと思います。
カスタム VM イメージを用いた新規 VMSS の作成
更新後のイメージで新しい VMSS を作成して VMSS のフロントにある負荷分散サービスで切り替える Blue-Green デプロイ的な方法です。アプリケーションのダウンタイムが許容されない、タイミングを決めてリリースしたい、リリース失敗のリスクは極力減らしたいといった要件にマッチすると思います。
- 特長
- アプリケーションのダウンタイムが発生しない
- 異なるバージョンのアプリケーションが混在しない
- 問題が起きたときに前のバージョンにすぐに切り戻せる
- イメージ自体を更新する方式のため、アプリケーションの更新だけでなく OS やミドルウェアの構成や設定を大きく変えたい場合にも使える
- 考慮事項
- 一時的に VMSS が 2 セットできるなどやや大がかり & 準備から完了までにやや時間が掛かるため 1 日に何度もリリースするようなスピード感には合わないかもしれない
カスタム VM イメージを用いた既存 VMSS の更新
既存の VMSS を新しいイメージで差し替えて手動または自動で VM 群を更新する方法です。リリースのためにサービスを停止する時間が確保可能、更新中にアプリケーションがオフラインになる or バージョンが混在しても問題ない、なるべく手軽に更新したい等の要件にマッチすると思います。
- 特長
- VM イメージ主体の方法の中では最もシンプルで分かりやすい
- イメージ自体を更新する方式のため、アプリケーションの更新だけでなく OS やミドルウェアの構成や設定を大きく変えたい場合にも使える
- 考慮事項
- アップグレードモード: 自動の場合、更新中にアプリケーションがオフラインになる
- アップグレードモード: ローリングの場合、更新中に異なるバージョンのアプリケーションが混在する
- 前のバージョンへの切り戻しは古いバージョンのイメージへの更新によって行うため、やや時間が掛かる可能性がある
共有イメージギャラリーを用いた既存 VMSS の更新
新しいイメージを**共有イメージギャラリー** (Shared Image Gallery) のイメージ定義に新しいバージョンとして登録し、既存の VMSS を自動または手動で更新する方法です。この方法は、あるカスタム VM イメージから複数のリージョンまたはサブスクリプションに複数の VMSS を展開するなど、大規模な利用シーンにマッチする可能性があります。
共有イメージギャラリーは、イメージのバージョン管理や異なるリージョン・サブスクリプションへの複製等が行える便利なサービスです。ただ使うサービスが増えるということはその分、設計・運用時の考慮事項が増えることにもなります。
そのため、単一リージョンで数台規模の単一の VMSS を運用するような場合は、共有イメージギャラリーを使わない構成でも問題ないと思います。もちろん利用しても OK ですが、その場合は VMSS の更新をワンサイクル回してみて、共有イメージギャラリー & VMSS がどういう挙動をするかを検証して把握することをオススメします。
スクリプト主体の方法 (カスタムスクリプト拡張機能 / cloud-init / Run command)
方法 | 概要 |
---|---|
カスタムスクリプト拡張機能 (Linux) (Windows) |
Blob Storage や GitHub などに格納した Bash / PowerShell スクリプトを VM がダウンロードして実行するという機能です。 カスタムスクリプトの登録・更新時、または VM が新規作成されるタイミングで、スクリプトのダウンロード & 実行が行われます。 |
cloud-init (Linux) |
Linux VM を初回起動時にカスタマイズするために広く使用されている手法で、任意の Bash スクリプトを実行することができます。 |
Run command (Linux) (Windows) |
az vm run-command invoke コマンド (Azure CLI) / Invoke-AzVMRunCommand コマンドレット (Azure PowerShell) で送信した Bash / PowerShell スクリプトを VM で実行することができます。 |
上記の中では、カスタムスクリプト拡張機能がアプリケーションの更新と相性が良いと思います。例えば、更新したアプリケーションをビルド & パッケージングして Blob Storage の所定のパスに格納しておき、カスタムスクリプト拡張機能を登録 / 更新して VM にアプリケーションをダウンロードさせて再起動させるというのは、スマートな方法だと思います。
カスタムスクリプトは VM の新規作成時にも実行されるため、上記の処理を仕込んでおけば、新規作成時に最新のアプリケーションが VM に配備されることになります。
上記のどの方法もスクリプトを実行するのでやろうと思えば何でもできるのですが、処理が失敗した場合のデバッグが面倒なので、処理内容はあまり複雑にせずに、シンプル & 確実に動く処理だけを実行するのが良いと思います。
ですので、OS やミドルウェアの構成や設定を大きく変更したい場合には、前述のカスタム VM イメージを利用する方法の方がマッチすると思います。
以降は各方法の詳細についてまとめています。かなり文量が多いので興味のある方法をピックアップして見て頂くのが良いと思います。
方法 1: カスタム VM イメージを用いた新規 VMSS の作成
Blue-Green 的なデプロイ手法です。大体以下のような流れになると思います。
# | タスク |
---|---|
1 | 更新したアプリケーションのビルド & パッケージング |
2 | アプリケーションを VM に配置してイメージを作成 |
3 | イメージから新規 VMSS を作成 |
4 | Application Gateway などの負荷分散を行うサービスでリクエストの向き先を既存 VMSS から新規 VMSS に変更 |
5 | 新規 VMSS でリクエストが問題なく捌けることを確認して既存 VMSS を削除 |
上記を手動で実施しても OK ですが、Azure DevOps や GitHub Actions などを組み合わせることで効率化することもできます。以下の記事は英語ですが、Azure DevOps での CI/CD パイプラインの具体的な流れが丁寧にまとめられていますので、ぜひご一読されるのをオススメします。
アプリケーションのビルド & パッケージング
利用しているプログラミング言語やビルドツールなどにもよりますが、迷ったら Azure DevOps の 1 サービスである Azure Pipelines で実現できそうか見てみるのが良いと思います。
カスタム VM イメージの作成
以下のような方法がありますので、お好みのものをお使い頂くのが良いと思います。
方法 | 参考リンク |
---|---|
Azure ポータル | 本記事末尾の Appendix を参照 |
Azure CLI | Azure CLI を使用して Linux VM のマネージド イメージをキャプチャする - Azure Linux Virtual Machines |
Azure PowerShell | Azure で管理対象イメージを作成する - Azure Windows Virtual Machines |
Packer * イメージ作成の自動化用 OSS ツール |
|
Azure Image Builder (プレビュー) * イメージ作成用の Azure サービス、Packer ベース |
(Tips) 効率化のアイディア
- Azure DevOps や GitHub Actions で CI/CD パイプラインを組んである程度自動化しておくと運用負荷が下げられると思います
- OS やミドルウェアの設定の自動化 (いわゆるプロビジョニング) のツールである「Ansible」、VM イメージ作成の自動化用のツールである「Packer」などを用いて Infrastrcture as Code (IaC) を CI/CD に組み合わせるのも良いアイディアだと思います
- アプリケーションのビルドの度に OS & ミドルウェア等のプロビジョニングを行うと時間が掛かるため、プロビジョニング済みの「ゴールデンイメージ」をあらかじめ作っておき、それを再利用するのも良いアイディアだと思います
方法 2: カスタム VM イメージを用いた既存 VMSS の更新
この方法は、カスタム VM イメージから作成した VMSS が対象です。
# | タスク |
---|---|
1 | 更新したアプリケーションのビルド & パッケージング |
2 | アプリケーションを VM に配置してイメージを作成 |
3 | 既存 VMSS のイメージ参照 ID を新しいイメージの ID に更新 |
4 | VM を選択してアップグレード (アップグレードモード: 手動の場合のみ) |
アップグレードポリシー & アップグレードモードについて
VMSS ではカスタム VM イメージの更新後の挙動を制御するための機能としてアップグレードポリシーというものが用意されており、以下の 3 つのアップグレードモードが選択できます。選択したアップグレードモードによって、VMSS のイメージ参照 ID の更新後の挙動が変わってきます。
- 手動 - 既存のインスタンスは手動でアップグレードする必要があります
- 自動 - インスタンスはランダムな順序ですぐにアップグレードを開始します
- ローリング - 一時停止を任意で指定し、アップグレードをバッチでロールアウトします
アップグレードモード: 手動
VMSS のイメージ参照 ID 更新後、既存の VM について手動でアップグレードする必要があります。具体的な方法については後述します。
アップグレードモード: 自動
VMSS のイメージ参照 ID 更新をトリガーとして、VMSS 配下の全 VM の更新が開始されます。そのため、アプリケーションがオフラインになる時間が発生します。
アップグレードモード: ローリング
VMSS のイメージ参照 ID 更新をトリガーとして、[ローリング アップグレードのバッチ サイズ %] に応じた割合の VM が順次更新されます。例えば VM 台数が 5 台、バッチサイズが 20% の場合、1 台ずつ更新されます。
VMSS のイメージ参照 ID 更新
Azure PowerShell か Azure CLI で行う必要があります。以下はコマンド例です。詳細は以下のドキュメントをご覧ください。
Azure 仮想マシン スケール セットを変更する - Azure Virtual Machine Scale Sets | Microsoft Docs
Update-AzVmss `
-ResourceGroupName "myResourceGroup" `
-VMScaleSetName "myScaleSet" `
-ImageReferenceId /subscriptions/{subscriptionID}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/images/myNewImage
az vmss update \
--resource-group myResourceGroup \
--name myScaleSet \
--set virtualMachineProfile.storageProfile.imageReference.id=/subscriptions/{subscriptionID}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/images/myNewImage
VM を選択してアップグレード (アップグレードモード: 手動の場合のみ)
Azure ポータル、Azure PowerShell (Update-AzureRmVmssInstance)、Azure CLI (az vmss update-instances) で実行できます。
以下はポータルで実施する場合のキャプチャです。イメージ参照 ID を新しいイメージのものに更新すると、以下のように [最新のモデル] が [いいえ] と表示されます。これらの VM について 1 台または複数台にチェックを入れて [アップグレード] を押します。
アップグレード中に再起動の可能性がある旨表示されるので問題なければ [はい] をクリックします。
アップグレードが完了すると以下のように [最新のモデル] が [はい] に変わります。
(Tips) イメージ参照 ID 更新後にスケールアウトした場合
この場合、新しいイメージから VM が作成されます。既存の VM をアップグレードする前にスケールアウトした場合、古いイメージの VM と新しいイメージの VM が混在することになります。
(Tips) 各 VM のイメージ参照 ID の確認方法
以下の Azure CLI コマンドで各 VM のイメージ参照 ID を確認できます。--query
で出力対象を絞り込み、-o tsv
で結果を TSV 形式で出力するようにしています。フルの結果が見たい場合はこれらのオプションは外して実行ください。
az vmss list-instances --resource-group ${resource_group_name} --name ${vmss_name} --query '[].{vmName:name, vmId:id, imageId:storageProfile.imageReference.id, imageVersion:storageProfile.imageReference.exactVersion}' -o tsv
vmss-hinakaza-iw-image_0 /subscriptions/(subscription_id)/resourceGroups/rg-hinakaza-iw-sig/providers/Microsoft.Compute/images/ubuntu1804image-20200823-3 None
vmss-hinakaza-iw-image_2 /subscriptions/(subscription_id)/resourceGroups/rg-hinakaza-iw-sig/providers/Microsoft.Compute/images/ubuntu1804image-20200823-4 None
vmss-hinakaza-iw-image_3 /subscriptions/(subscription_id)/resourceGroups/rg-hinakaza-iw-sig/providers/Microsoft.Compute/images/ubuntu1804image-20200823-4 None
vmss-hinakaza-iw-image_4 /subscriptions/(subscription_id)/resourceGroups/rg-hinakaza-iw-sig/providers/Microsoft.Compute/images/ubuntu1804image-20200823-4 None
vmss-hinakaza-iw-image_6 /subscriptions/(subscription_id)/resourceGroups/rg-hinakaza-iw-sig/providers/Microsoft.Compute/images/ubuntu1804image-20200823-4 None
方法 3: 共有イメージギャラリーを用いた既存 VMSS の更新
共有イメージギャラリー と VMSS の自動 OS イメージアップグレードを利用することで既存の VMSS を更新する方法です。
共有イメージギャラリーの概要
共有イメージギャラリー (Share Image Gallery) は Azure のサービスで、自組織内で共有可能な VM イメージのギャラリーになります。共有イメージギャラリーのリソースを作成し、その配下に複数のイメージ定義、さらに複数のイメージバージョンを登録して管理することができます。
イメージは複数のリージョンに複製して配置でき、複製先のリージョンで VM / VMSS を作成できます。また、RBAC を設定することで同一の Azure AD テナントの別のサブスクリプションでも共有イメージギャラリーから VM / VMSS を作成できます。
(こちらの手順を参考に別の Azure AD テナントに共有することも可能です)
VMSS 作成 (初回のみ)
この方法を利用する場合、VMSS が共有イメージギャラリーに登録されたイメージを参照する必要があります。
# | タスク |
---|---|
1 | アプリケーションのビルド & パッケージング |
2 | アプリケーションを VM に配置して VM イメージを作成 |
3 | 共有イメージギャラリー & イメージ定義を作成 |
4 | 2 で作成した VM イメージを共有イメージギャラリーのイメージ定義の新しいバージョンとして登録 (共有イメージギャラリーと VMSS のリージョンが異なる場合は VMSS のリージョンにイメージバージョンをレプリケーションする) |
5 | 共有イメージギャラリーのイメージ定義から VMSS を作成 (作成時に [アップグレードモード] で [自動 / 手動 / ローリング] のいずれかを選択、[OS の自動アップグレード] で [オン] を指定) |
1 ~ 2 について前述のカスタム VM イメージの作成と同様です。
3 ~ 4 については Azure 共有イメージギャラリーをデプロイしてみた │ Ether-Zone などを参考にすれば Azure ポータル上で迷うことなく実施できると思います。
5 の VMSS 作成について Azure ポータルから実施する場合、「イメージバージョン」ではなく「イメージ定義」の画面から VMSS を作成する必要がある点に注意が必要です。
こうすることで VMSS は個別のイメージバージョンではなく最新 (latest) のイメージバージョンを参照するようになります。
適切なアップグレードモードを選択し、OS の自動アップグレードをオンにします。選択するアップグレードモードによって更新時の挙動が異なりますので、要件に合うモードを選択ください。
スケールアウト時の挙動
共有イメージギャラリーのイメージ定義の最新イメージバージョンを使って VM が起動されます。
VMSS 更新の流れ
共有イメージギャラリーのイメージ定義に新しいバージョンのイメージが発行され、VMSS の存在するリージョンにレプリケートされたことをトリガーとして VMSS の更新が実行されます。
# | タスク |
---|---|
1 | 更新したアプリケーションのビルド & パッケージング |
2 | アプリケーションを VM に配置して VM イメージを作成 |
3 | 2 で作成した VM イメージを共有イメージギャラリーのイメージ定義の新しいバージョンとして登録 (共有イメージギャラリーと VMSS のリージョンが異なる場合は VMSS のリージョンにイメージバージョンをレプリケーションする) |
4 | VM を選択してアップグレード (アップグレードモード: 手動の場合のみ) |
初回更新時の注意事項
Azure 仮想マシン スケール セットを使用した OS イメージの自動アップグレード - Azure Virtual Machine Scale Sets | Microsoft Docs に以下の記述があります。
スケール セットが OS の自動アップグレードに向けて初めて構成された後、スケール セットが最初のイメージのアップグレード ロールアウトをトリガーするまで、最大 3 時間かかることがあります。これは、スケール セットごとに 1 回限りの遅延です。 それ以降のイメージのロールアウトは、30 分から 60 分以内にスケール セットでトリガーされます。
実際に試してみたところ、共有イメージギャラリーへの新バージョン登録後、アップグレードが開始されるまでに初回は 3 時間程度掛かり、2 回目以降は 30-60 分程度掛かっていました。
アップグレードモード: 自動
前述のカスタム VM イメージの更新では一斉に VM 全台が更新されていましたが、検証したところ、こちらの方式では 1 台ずつ順番に更新が行われました。
アップグレードモード: ローリング
[ローリング アップグレードのバッチ サイズ %] に応じた割合の VM が順次更新されます。
本編は以上です。以降は参考情報になります。
Appendix 1: Azure ポータルでのカスタム VM イメージ作成
イメージ化対象の VM の [概要] > [キャプチャ] をクリックします。
イメージの名前などを入力し [作成] をクリックするとイメージ作成の一連の処理 (VM の停止、一般化、イメージの作成) が実行されます。イメージ作成後、イメージ化対象の VM は起動できなくなることに留意が必要です。
指定したリソースグループにイメージが作成されます。
作成したイメージの概要です。
以上です。