APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

Azure PipelinesのエージェントとしてVMSSを使う

はじめに

こんにちは、ACS事業部の吉川です。
Azure DevOpsでPipelineを実行する際、エージェント(ジョブを実行するマシン)には大別して以下の3種類があります。

最近はAzure virtual machine scale set agent(以下、VMSS agentと呼びます)を利用する機会が多いので、利用方法についてご紹介します。

利用シーン

Microsoft-hosted AgentはジョブごとにMicrosoftのデータセンター内で稼働しているマシンがランダムに割り当てられます。
そのため、ジョブを実行するマシンのIPアドレスが特定できません
例えばAKSにアプリをデプロイするジョブを実行したい場合、AKSのAPIサーバーに対しアクセス元IPアドレス制限を掛けることができなくなります。

一方、Self-hosted agentやVMSS agentを使えば、IPアドレスを固定化することが可能なため、そのIPアドレスからのアクセスのみに制限することができます。

Self-hosted agentと比べたVMSS agentのメリットとしては、利用状況に応じた柔軟なスケール性 が挙げられます。
大量のジョブを実行するときにノード数を増やすといったことが簡単に実現できます。
また、利用していないときには 0台までスケールイン できるため、夜間や休日などの利用しない期間のコストを抑えることができます。

エージェントマシンのカスタマイズ

ビルドやデプロイのジョブを実行するためには、必要なツールをエージェントマシンにインストールする必要があります。
参考までにMicrosoft-hosted agentのubuntu-20.04イメージにインストールされているソフトウェアは以下にて公開されています。

github.com

Microsoft-hosted agentのVMイメージは残念ながら公開されていないため、VMSS agentを利用する上では、

  • 必要なソフトウェアをインストールしたカスタムイメージを作成してそれを利用する
  • 標準のVMイメージを利用して、起動後にソフトウェアのインストールを行う

のどちらかの対応が必要です。

個人的に前者のカスタムイメージ作成方式は、作成したイメージの管理をしていかなければならないのが手間であまり使用しません。
よって本記事では後者の 起動後にソフトウェアのインストールを行う 方式の解説を行います。

カスタマイズ方法その1 - cloud-init

起動後にソフトウェアのインストールを行う方法もいくつか存在しますが、1つ目として cloud-init を紹介します。
以下のようなYAMLファイルで起動時に実行する処理を定義します。

#cloud-config
bootcmd:
  - mkdir -p /etc/systemd/system/walinuxagent.service.d
  - echo "[Unit]\nAfter=cloud-final.service" > /etc/systemd/system/walinuxagent.service.d/override.conf
  - sed "s/After=multi-user.target//g" /lib/systemd/system/cloud-final.service > /etc/systemd/system/cloud-final.service
  - systemctl daemon-reload
package_upgrade: true
packages:
  - docker.io
  - unzip
users:
  - name: AzDevOps
    groups: docker
runcmd:
  - curl -sL https://aka.ms/InstallAzureCLIDeb | bash
  - az extension add --name azure-devops --system

それぞれのセクションの解説は以下のとおりです。

  • bootcmd : 最初に実行するコマンドを記述します。cloud-initをそのまま実行するとソフトウェアのインストール処理が完了する前にPipelineジョブが起動してしまう場合があります。それを防ぐために、systemdのサービスの順序を変更しcloud-initの終了後にPipelineジョブが実行されるようにしています。こちら を参考にさせていただきました。
  • package_upgrade : パッケージの最新化を行います。(apt upgradeと同等)
  • packages : 指定したパッケージのインストールを行います。ここでは Docker と unzip のインストールを行っています。
  • users : OSのユーザーに関する設定を行います。ここでは Azure DevOpsユーザーをdockerグループに追加しています。
  • runcmd : 最後に実行するコマンドを記述します。ここではAzure CLIのインストールとAzure DevOps拡張機能を有効化しています。

上記のとおり、比較的平易な書き方でカスタマイズ内容を記述できます。
パッケージのインストールなど、root権限が必要な作業はこちらの方法で行うのがよいでしょう。

カスタマイズ方法その2 - Pipeline内でインストールする

もう1つのソフトウェアインストール方法として、Pipeline内でインストールする 方法があります。

例として、kubectlをインストールするタスクは以下のように記述します。

- task: KubectlInstaller@0
  displayName: Kubectl installer
  inputs: 
    kubectlVersion: 1.23.8

kubectl以外にも、

などをインストールするタスクが提供されています。
ビルド環境のバージョンはアプリケーションのコードと密接に関連するので、PipelineのYAMLファイルの中で定義してリポジトリで管理できると使い勝手がよいのではと思います。

VMSS agentの作成

それでは、実際にVMSS agentを作成し利用する手順を紹介したいと思います。

まずVMSSを作成します。

# リソースグループの作成
az group create -l japaneast -n vmssagents

# VMSSの作成
az vmss create \
--name vmssagentspool \
--resource-group vmssagents \
--image UbuntuLTS \
--vm-sku Standard_D2_v3 \
--storage-sku StandardSSD_LRS \
--instance-count 0 \
--lb-sku Standard \
--custom-data cloud-init.yaml \
--disable-overprovision \
--upgrade-policy-mode manual

VMSS agentとして利用する場合、--disable-overprovision--upgrade-policy-mode manual の指定が必須です。
--custom-data オプションにYAMLファイルを指定することでcloud-initでのカスタマイズを実現しています。 また、利用シーン の項で述べたIPアドレス固定化のためにAzure Load Balancerを同時作成しています。(--lb-sku Standard

続いて、作成したVMSSをAzure DevOpsに登録します。 Azure DevOpsのProject Settingsにて Agent pools を選択、

Add pool ボタンをクリックし、Poolの情報を入力します。
Pool to linkは New、Pool typeは Azure virtual machine scale set agent を選択し、サブスクリプションを指定し作成したVMSSを選びます。上記のコマンドではVMSSの名前を vmssagentspool としています。
Name欄でPipelineから呼び出す際の名前を付けます。ここでは vmssagent としました。

入力画面の下部では以下の項目を入力します。

  • Automatically tear down virtual machines after every use : ジョブの実行毎にVMを落としたい場合にチェックを付ける。
  • Maximum number of virtual machines in the scale set : VMSSの最大ノード数を指定する。
  • Number of agents to keep on standby : アイドル時にスケールインする最小ノード数を指定する。この値を0にすると利用していないときにノードが全て削除される。
  • Delay in minutes before deleting excess idle agents : スケールインが発動するまでの猶予時間を分単位で指定する。

入力が終わったら下部の Create ボタンをクリックします。

登録したVMSS agentを利用するには、PipelineのYAML内で以下のようにAgent Poolを指定します。

pool:
  name: vmssagent

Pipelineジョブを起動するとVMSSのノードが新規で作成され、cloud-initの処理が完了後にジョブが実行されます。

おわりに

VMSS agentを利用するとVMを常時起動しておく必要がなくなり、コスト面・管理面でのメリットがあります。
また、VMSSの作成やPipelineの組み方を工夫することでVMSSベースイメージの管理からも解放されます。 特に小規模なプロジェクトに対して有効な策だと思います。ぜひ使ってみてください。

私達はAzure・AKSを活用した内製化のご支援をしております。ご相談等ありましたらぜひご連絡ください。

www.ap-com.co.jp

また、一緒に働いていただける仲間も募集中ですので、ご興味ある方はぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: 吉川 俊甫
AKSをメインにインフラ系のご支援を担当しています。趣味は資格取得です。
Shunsuke Yoshikawa - Credly