Spinnakerで Bake ステージと呼ばれる、デプロイするためのマシンイメージを作成する工程をパイプライン上に作成することができます。AWS では AMI, GCP では VM イメージ が該当します。
Spinnaker では Hashicorp 社の Pakcer というツールを使ってマシンイメージを生成します。Spinnaker で予め用意されている Packer テンプレート を使うこともできますが、カスタム Packer テンプレートを使うことも可能です。
今回はカスタム Packer テンプレートを使って Bake ステージを設定してみます。
目次
前提条件
- 本記事では Packer および Packer テンプレートについての説明は深く取り上げません。詳細を知りたい人はドキュメントを見てください
- 今回は私が取り組んでいるプロジェクトの都合上、GCP の Windows Server の VM イメージを作成しますが、AWS や Linux ユーザであったとしても、Packer テンプレートのパラメータが異なるだけでやり方は同じなので安心して読んでください
Packer テンプレート
GCP かつ Windows Server の Packer テンプレートがなかったため、自分でカスタムして作成しました。一般公開できるような形にしたのを GitHub にアップしました。
variables
セクション内の gce_xxxx
パラメータは後述の hal コマンドや Bake ステージで渡されます。指定がなければ、テンプレートにあるデフォルト値が使われます。デフォルトで外部IPアドレスを持たせずに、内部IPアドレスのみで通信させるようにしています。変更したい場合は gce_use_internal_ip
および gce_omit_external_ip
を false
に指定してください。
provisioners
セクションでは、Sysprep をGCE用にラップした GCESysprep を実行しています。
Windows Remote Management(WinRM) で接続して実行するため、起動時に専用ユーザ(packer)を起動時に作成するようにしています。
Packer テンプレートファイルの設置
上記の Packerテンプレートファイルと PowerShell スクリプトを /opt/rosco/config/packer
配下に置きます。
# Packer テンプレート /opt/rosco/config/packer/gcp-windows-2012-r2.json
実行ユーザの設定も忘れずに。
$ sudo chown spinnaker:spinnaker /opt/rosco/config/packer/gcp-windows-2012-r2.json
hal コマンドでの設定
Spinnaker の設定は hal コマンドで行います。
$ PROJECT=$(gcloud info --format='value(config.project)') # GCEのデフォルトネットワークから変更したい場合 $ hal config provider google bakery edit \ --network "sample-network" \ --network-project-id $PROJECT \ --use-internal-ip "true" \ --zone "asia-northeast1-a" # イメージの追加 $ hal config provider google bakery base-image add "windows-2012-r2" \ --source-image-family "windows-2012-r2" \ --short-description "Windows Server 2012 R2" \ --detailed-description "Windows Server 2012 R2 Datacenter Edition, x86_64" \ --package-type nupkg \ --template-file gcp-windows-2012-r2.json # 確認 $ hal config provider google bakery base-image get "windows-2012-r2" + Get current deployment Success + Get windows-2012-r2 base image Success + Settings for windows-2012-r2 ingoogle's bakery: GoogleBaseImage(baseImage=GoogleBaseImage.GoogleImageSettings(super=BaseImage.ImageSettings(id=windows-2012-r2, shortDescription=Windows Server 2012 R2, detailedDescription=Windows Server 2012 R2 Datacenter Edition, x86_64, packageType=nupkg, templateFile=gcp-windows-2012-r2.json), isImageFamily=false), virtualizationSettings=GoogleBaseImage.GoogleVirtualizationSettings(sourceImage=null, sourceImageFamily=windows-2012-r2))
hal deploy apply
で反映させます。 *1 数分程度かかります。
$ sudo hal deploy apply $ sudo systemctl daemon-reload
Pipeline での設定
Pipeline で Bake ステージの設定をします。Pipeline の作成は省略しています。
Add stage
をクリックし、 Type
を Bake
に選択します。
下図のように、 Base OS
に先ほど追加したイメージ( windows-2012-r2
)が追加されていますのでそれを選択します。
Show Advanced Options
をチェックして、Extended Attributes
で、環境変数として渡すパラメータ( gce_subnetwork
, gce_service_account_email
)を入力します。
設定できたら右下にある Save Changes
をクリックして保存します。
Pipeline の実行
Pipeline の手動実行は Start Manual Execition
をクリックします(下図①)
実行中、 Packer の実行状況やエラー調査は View Bakery Details から確認できます(上図②)
正常に完了すると、 windows-2012-r2-YYYYMMDDHHmmss
のイメージが作成されます。
正常時のログを貼っておきます。
==> googlecompute: Checking image does not exist... ==> googlecompute: Creating temporary SSH key for instance... ==> googlecompute: Using image: windows-server-2012-r2-dc-v20190225 ==> googlecompute: Creating instance... googlecompute: Loading zone: asia-northeast1-a googlecompute: Loading machine type: n1-standard-1 googlecompute: Requesting instance creation... googlecompute: Waiting for creation operation to complete... googlecompute: Instance has been created! ==> googlecompute: Creating windows user for instance... googlecompute: Waiting for windows password to complete... googlecompute: Created password. ==> googlecompute: Waiting for the instance to become running... googlecompute: IP: 10.63.6.44 ==> googlecompute: Waiting for WinRM to become available... googlecompute: WinRM connected. googlecompute: #< CLIXML googlecompute: System.Management.Automation.PSCustomObjectSystem.Object1Preparing modules for first use.0-1-1Completed-1 1Preparing modules for first use.0-1-1Completed-1 ==> googlecompute: Connected to WinRM! ==> googlecompute: Provisioning with Powershell... ==> googlecompute: Provisioning with powershell script: /tmp/packer-powershell-provisioner475077573 googlecompute: 2019/03/05 05:04:01 GCESysprep: Beginning GCESysprep. googlecompute: 2019/03/05 05:04:01 GCESysprep: No answer file was specified. Using default file. googlecompute: 2019/03/05 05:04:01 GCESysprep: Running 'schtasks' with arguments '/delete /tn GCEStartup /f' googlecompute: 2019/03/05 05:04:01 GCESysprep: --> SUCCESS: The scheduled task "GCEStartup" was successfully deleted. googlecompute: 2019/03/05 05:04:02 GCESysprep: Clearing events in EventViewer. googlecompute: 2019/03/05 05:04:06 GCESysprep: Running 'C:\Windows\System32\Sysprep\sysprep.exe' with arguments '/generalize /oobe /quit /unattend:C:\Program Files\Google\Compute Engine\sysprep\unattended.xml' googlecompute: 2019/03/05 05:05:43 GCESysprep: Waiting for sysprep to complete. googlecompute: 2019/03/05 05:05:43 GCESysprep: Setting new startup command. googlecompute: 2019/03/05 05:05:44 GCESysprep: Forgetting persistent disks. googlecompute: 2019/03/05 05:05:44 GCESysprep: Clearing self signed certs. googlecompute: 2019/03/05 05:05:44 GCESysprep: Shutting down. googlecompute: 2019/03/05 05:05:44 GCESysprep: Running 'shutdown' with arguments '/s /t 00 /d p:2:4 /f' ==> googlecompute: Deleting instance... googlecompute: Instance has been deleted! ==> googlecompute: Creating image... ==> googlecompute: Deleting disk... googlecompute: Disk has been deleted! Build 'googlecompute' finished. ==> Builds finished. The artifacts of successful builds are: --> googlecompute: A disk image was created: windows-2012-r2-20190305050100
まとめ
Spinnaker で GCE イメージを作成する、 Bake ステージの設定やカスタムイメージの設定方法を紹介しました。
参考文献
- Bake and Deploy Pipeline - Spinnaker
- Configure the Image Bakery - Spinnaker
- Packer Templates - Spinnaker
- Continuous Deployment on Compute Engine Using Ansible with Spinnaker | Solutions | Google Cloud
- rosco/rosco-web/config/packer at master · spinnaker/rosco
*1:hal config provider google bakery base-image add で更新されるはずだが反映されなかった