ノート:
- このチュートリアルではOracle Cloudへのアクセスが必要です。無料アカウントにサインアップするには、Oracle Cloud Infrastructure Free Tierの開始を参照してください。
- Oracle Cloud Infrastructure資格証明、テナンシおよびコンパートメントの値の例を使用します。演習を完了する場合は、これらの値をクラウド環境に固有の値に置き換えてください。
Packerを使用したOracle Cloud Infrastructureカスタム・イメージの作成
イントロダクション
このチュートリアルでは、OCIベース・イメージ、またはOCIにすでに存在するコンピュート・イメージを取得し、顧客のニーズに応じて変更します。
たとえば、イメージの起動モードをネイティブから準仮想化に変更したり、仮想ネットワーク・インタフェース・カード(VNIC)アタッチメントを変更する必要がある場合があります。たとえば、OKEワーカー・ノードにはこれが必要です。同様に、追加のOSパッケージをインストールしたり、Packerprovisionerを使用してインスタンス・カーネル・パラメータを変更できます(Terraformなど)。
たとえば、PostgreSQLデータベースをインストールするイメージと、他の値を持つulimitパラメータが必要なとします。これらすべてを実行するには、イメージからコンピュートを起動し、必要なものをすべて変更し、プログラム、アプリケーション、必要なパッケージをインストールしてから、インスタンスを新しいカスタム・イメージとして保存します。
複数のカスタム・イメージを作成する必要があるとします。複数のアーキテクチャに対して、カスタム・イメージに追加されたプログラムやパッケージを追加/変更する必要があります。そのためには、HashiCorpの Packerを使用できます。
パッカー
Packerは、HashiCorpのオープンソース・ツールで、ソース構成からマシン・イメージを作成するために使用されます。軽量で、すべての主要なオペレーティング・システムで実行され、高パフォーマンスです。ChefやPuppetなどの構成管理は置き換えられません。実際、イメージを構築する場合、PackerはChefやPuppetなどのツールを使用してソフトウェアをイメージにインストールできます。次のような機能があります。
-
任意のタイプのマシン・イメージの作成を自動化します。イメージをカスタマイズして、アプリケーションおよび組織の要件に一致させます。
-
単一のソース構成から複数のプラットフォームに同一のマシンイメージを作成します。
-
複数のプラットフォームのマシン・イメージを並行して作成します。
パッカーを使用する利点
- プロセス全体を自動化します。
- 一度に複数のカスタム・イメージを作成します。
- 異なるアーキテクチャのイメージを作成します。
- パラレルに実行できます。
- OCI DevOpsビルド・パイプライン内で使用できます。
- HCL言語を使用します。
- プロビジョニング・プロバイダ(シェルまたはAnsible)を使用して、コンピュートでカスタム・スクリプト/コマンドを実行できます。
パッカー認証
次のオプションを使用して、パッカーを認証できます。
-
デフォルトでは、
.oci/config
ファイルのDEFAULTプロファイルが使用されます。 -
インスタンス・プリンシパルを使用して、use_instance_principals引数をPacker構成ファイルに追加します(次に例を示します)。
-
API署名キー
-
セキュリティ・トークン。
ノート: パッカー認証についてさらに学習しますが、
.oci/config
ファイルまたはインスタンス・プリンシパルのいずれかを使用することをお薦めします。
Packerの動作
タスクでは、Packerはbase_image_ocidパラメータで指定されたイメージを取得し、必要な構成パラメータ(可用性*ドメイン、シェイプなど)でユーザーが指定した属性を持つコンピュート・インスタンスをデプロイします。
その後に、Packerは、起動後にベース・イメージのbuildブロックで指定したプロビジョナ(_provisioner "shell"*)を実行するために、インスタンスにSSHで試行します。このタスクでは、インスタンスのデプロイ場所(subnet_ocid属性)を考慮する必要があるため、Packerを実行するマシンからインスタンスにSSHを実行できます。末尾のPackerスナップショットでは、再利用可能なカスタム・イメージが作成されます。
パッカー・プロビジョナ
プロビジョニング・プロバイダは、稼働中のマシン内でソフトウェアをインストールおよび構成し、そのマシンを静的イメージに変換する重要なコンポーネントの1つです。イメージに有用なソフトウェアを含めるための主要な作業を実行します。
プロビジョナの例を次に示します。
- シェル: ソフトウェアをマシンにインストールして構成するもっとも簡単な方法です。
- ファイル: Packerによって作成されたマシンにファイルをアップロードします。
- Ansible: Ansibleプレイブックを実行します。
目的
-
既存のイメージからカスタム・イメージを作成し、
nic_attachment_type
およびimage_launch_mode
属性を変更します。 -
既存のイメージからカスタム・イメージを作成し、新しく作成したイメージに対してAnsibleプレイブックを実行します。
前提条件
-
OCIテナンシおよびOCIアカウントは、instance-familyを管理するための十分な権限を持ち、ネットワークおよびイメージを使用します。
Allow group PackerGroup to manage instance-family in compartment ${COMPARTMENT_NAME} Allow group PackerGroup to manage instance-images in compartment ${COMPARTMENT_NAME} Allow group PackerGroup to use virtual-network-family in compartment ${COMPARTMENT_NAME} Allow group PackerGroup to use compute-image-capability-schema in tenancy
-
Packer Packerをインストールします。
-
パッカーにはいくつかの構成パラメータが必要です。必要な構成パラメータを参照してください。
-
Packerは、Packer構成ファイルに記載されている変更を行うために、sshを使用してプロビジョニングされたコンピュートに接続します。インスタンスをポート22でアクセス可能にします(通常は、Packerを実行しているホスト(subnet_ocid属性)からアクセスできるサブネットOCIDを指定します)。
タスク1: Packer構成ファイルの作成
PackerはHCLまたは JSON形式をサポートしています。次のタスクでは、HCL形式です。
-
必要に応じてファイル名を指定しますが、最後に .pkr.hclを含めます。
packer { required_plugins { oracle = { source = "github.com/hashicorp/oracle" version = ">= 1.0.3" } } } source "oracle-oci" "example" { availability_domain = "GqIF:EU-FRANKFURT-1-AD-2" #you may use an OCID or use a base_image_filter #base_image_ocid = "ocid1.image.oc1.eu-frankfurt-1......" base_image_filter { #display_name = "Oracle-Linux-7.9-2023.05.24-0" display_name_search = "^Oracle-Linux-7.9*" } compartment_ocid = "ocid1.compartment.oc1......" image_name = "ExampleImage" shape = "VM.Standard1.1" ssh_username = "opc" #This is public subnet as I run packer from outside OCI VCN subnet_ocid = "ocid1.subnet.oc1.eu-frankfurt-1....." #this attribute will be changed nic_attachment_type = "VFIO" #this attribute will be changed image_launch_mode = "NATIVE" #you may skip the image creation if you are running tests #when you want to test set this as true skip_create_image = false } build { sources = ["source.oracle-oci.example"] }
-
subnet_ocidは、カスタム・イメージが構築されるまでインスタンスがプロビジョニングされるサブネットです。これは、Packerを実行しているホストから到達できる必要があるサブネットです。通常、開発インスタンスがインターネットに公開される理由がないため、パブリックIPを使用して開発インスタンスを作成することは望ましくありません。作成すると、セキュリティ上の懸念が生じます。パブリックIPの使用を回避する1つの方法は、OCI内からPackerを実行するか、OCI Bastionサービスを使用することです。FastConnectまたはその他のVPNを使用して、インターネットを経由せずに、オンプレミスからOCIサブネットにアクセスすることもできます。
タスク2: Packerの初期化
-
Packer initを実行します。
<path to packer bin> init <packer conf file>
次に例を示します:
<path to packer bin> init oke.pkr.hcl
タスク3: イメージの構築
-
この時点で、
image_launch_mode = "NATIVE"
およびnic_attachment_type = "VFIO"
を持つカスタム・イメージがあります。変更できるその他の属性があります。これらはすべて公式文書に記載されています。 -
カスタム・コマンドまたはスクリプトを実行できます(例が添付されています)。
<path to packer bin> build oke.pkr.hcl oracle-oci.example: output will be in this color. ==> oracle-oci.example: Creating temporary ssh key for instance... ==> oracle-oci.example: Creating instance... ==> oracle-oci.example: Created instance (ocid1.instance.........). ==> oracle-oci.example: Waiting for instance to enter 'RUNNING' state... ==> oracle-oci.example: Instance 'RUNNING'. ==> oracle-oci.example: Instance has IP: 130.61.X.X ==> oracle-oci.example: Using SSH communicator to connect: 130.61.X.X ==> oracle-oci.example: Waiting for SSH to become available... ==> oracle-oci.example: Connected to SSH! ==> oracle-oci.example: Creating image from instance... ==> oracle-oci.example: Updating image schema... ==> oracle-oci.example: Created image (ocid1.image........). ==> oracle-oci.example: Terminating instance (ocid1.instance.....)... ==> oracle-oci.example: Terminated instance. Build 'oracle-oci.example' finished after 4 minutes 37 seconds. ==> Wait completed after 4 minutes 37 seconds ==> Builds finished. The artifacts of successful builds are: --> oracle-oci.example: An image was created: 'ExampleImage' (OCID: ocid1.image..........'
プロビジョナを使用する例:
-
この例では、provisioner (シェルとファイル)を使用します。
-
2つのイメージが作成されます(ソースで指定)。
variable "VAREXAMPLE" { type = string default = "val Example" } variable "deploy_in_comp" { type = string default = "ocid1.compartment.oc1......." } variable "OCI_PROFILE" { type = string default = "DEFAULT" } locals { pkr_root = "${path.cwd}" #the directory from where Packer was started pkr_scripts = "${path.root}/scripts" #the directory of the input HCL file or the input folder root = path.root } source "oracle-oci" "img1" { access_cfg_file_account = var.OCI_PROFILE availability_domain = "GqIF:US-ASHBURN-AD-3" base_image_ocid = "ocid1.image.oc1.iad....." compartment_ocid = "ocid1.compartment.oc1......" image_name = "img1" shape = "VM.Standard.E4.Flex" #usage of shape config shape_config { ocpus = "1" } ssh_username = "opc" subnet_ocid = "ocid1.subnet.oc1.iad....." } source "oracle-oci" "img2" { access_cfg_file_account = var.OCI_PROFILE availability_domain = "GqIF:US-ASHBURN-AD-3" base_image_ocid = "ocid1.image.oc1.iad....." compartment_ocid = "ocid1.compartment.oc1........." image_name = "img2" shape = "VM.Standard.E4.Flex" shape_config { ocpus = "2" } ssh_username = "opc" subnet_ocid = "ocid1.subnet.oc1.iad........" image_compartment_ocid = var.deploy_in_comp } build { # here we secific both source above, img1 and img2 sources = [ "source.oracle-oci.img1", "source.oracle-oci.img2" ] provisioner "shell" { # this will run on all sources inline = [ "echo to run on all sources ${var.VAREXAMPLE}" ] } provisioner "shell" { # This provisioner only runs for img1 source. only = ["oracle-oci.img1"] inline = [ "echo To run in img1", ] } provisioner "shell" { # This provisioner runs on all but img1 source. # Mnd that there is no "source" string but only the name of the source except = ["oracle-oci.img1"] inline = [ "echo To run in all except img1", ] } provisioner "file" { only = ["oracle-oci.img2"] source = "${local.pkr_scripts}/test.txt" destination = "/tmp/test.txt" } # This will run local on the machine you run packer provisioner "shell-local" { inline = ["echo ${local.pkr_root} and ${local.pkr_scripts}"] } # This will run local on the machine you run packer provisioner "shell-local" { inline = ["echo VAR from file :${var.VAREXAMPLE}"] } }
-
変数を使用します(Terraformなど)。
image_compartment_ocid = var.deploy_in_comp
-
Authメソッドは.oci/configファイル(デフォルト)ですが、属性を使用して、使用するファイル内でwichプロファイルを指定します。
access_cfg_file_account = var.OCI_PROFILE
-
ここでは、provisioner "shell"とprovisioner "file"、provisioner "shell-local"を使用します。
-
shell Packer Provisionerは、シェル・スクリプトを使用してPackerによって構築されるマシンをプロビジョニングします。シェル・プロビジョニングは、マシンにソフトウェアをインストールして構成する最も簡単な方法です。
-
マシン上でシェルコマンドを実行(inlineを使用)するか、またはeスクリプトを実行(scriptを使用)できます。
-
fileプロセッサも使用しました。ファイルPackerプロビジョナは、Packerによって作成されたマシンにファイルをアップロードします。
-
hclファイルに、prov-example.pkr.hclをダウンロードできるその他の例が表示されることがあります。
変数ファイルおよびAnsibleプロビジョナを使用する例:
-
次を使用します。
- 変数ファイル。
- 別のAuthメソッド- 変数を使用します。
-
パッケージのインストールにシェルを使用する代わりに、別のフォルダに保存されているプレイブックを実行するためにansibleを使用します。
-
この方法は、Ansibleでより適切に処理できる、より複雑な状況を対象としています。
-
次の2つの実行可能なプロビジョナがあります。
- ansible-local : Packerが構築するホストにansibleをインストールする必要があります(プロビジョナシェルを使用して Ansibleをインストールできます)。
- ansible: Packerを実行するホストから実行できるため、ビルドするインスタンスに存在する必要はありません。
-
複数の構成ファイルが含まれているため、構築時にディレクトリ名を指定する必要があります。
packer build <directory name>
-
この例のファイル ansible-example.pkr.hcl。次に、ansible-example.pkr.hclを示します。
# mind there is a variables.pkr.hcl file where # other vars are set # so when build use: packer build <directory name> # so all the files within dir will be loaded source "oracle-oci" "img1" { #auth vars region = var.REGION tenancy_ocid = var.TENANCY_OCID user_ocid = var.USER_OCID key_file = var.KEY_FILE fingerprint = var.FINGERPRINT # availability_domain = var.AD base_image_ocid = var.BASE_IMG_OCID compartment_ocid = var.COMP_IMG_OCID image_name = var.IMG_NAME shape = var.SHAPE shape_config { ocpus = var.SHAPE_OCPUS } ssh_username = "opc" subnet_ocid = var.SUBNET_OCID # for testing and debug. remove it after skip_create_image = true } source "oracle-oci" "img2" { #auth vars region = var.REGION tenancy_ocid = var.TENANCY_OCID user_ocid = var.USER_OCID key_file = var.KEY_FILE fingerprint = var.FINGERPRINT # availability_domain = var.AD base_image_ocid = var.BASE_IMG_OCID compartment_ocid = var.COMP_IMG_OCID image_name = var.IMG_NAME1 shape = var.SHAPE shape_config { ocpus = var.SHAPE_OCPUS } ssh_username = "opc" subnet_ocid = var.SUBNET_OCID # for testing and debug. remove it after skip_create_image = true } build { sources = [ "source.oracle-oci.img1", "source.oracle-oci.img2" ] #need ansible installed on VM that packer will build #so you need to install ansible beforehand provisioner "shell" { # this will run on all sources inline = [ "sudo yum install ansible -y" ] } # this provisioner ansible-local needs ansible installed # on the host that packer will builds provisioner "ansible-local" { playbook_file = "${path.root}/ansible/pb1.yaml" } # This provisioner ansible # will run ansible playbook from host that runs packer # so you don't need to inmstall ansible on VM that packer wil create #provisioner "ansible" { # playbook_file = "${path.root}/ansible/pb-remote.yaml" # user = "opc" # # in case you need to debug ansible tasks # extra_arguments = [ "-vvvv" ] #} }
-
vars.pkr.hclを次に示します。このファイルでは、それらを宣言および初期化します。
variable "AD" { type = string default = "GqIF:US-ASHBURN-AD-3" } variable "BASE_IMG_OCID" { type = string default = "ocid1.image.oc1.iad......" } variable "COMP_IMG_OCID" { type = string default = "ocid1.compartment.oc1......." } variable "IMG_NAME" { type = string default = "img1" } variable "IMG_NAME1" { type = string default = "img2" } variable "SHAPE" { type = string default = "VM.Standard.E3.Flex" } variable "SHAPE_OCPUS" { type = string default = "1" } variable "SUBNET_OCID" { type = string default = "ocid1.subnet.oc1.iad......" }
-
次にauth-vars.pkr.hclを示します。このファイルを使用して認証を設定します。
variable "REGION" { type = string default = "us-ashburn-1" } variable "TENANCY_OCID" { type = string default = "ocid1.tenancy.oc1......." } variable "USER_OCID" { type = string default = "ocid1.user.oc1......" } variable "KEY_FILE" { type = string default = ".....oci_api_key.pem" } variable "FINGERPRINT" { type = string default = "...." }
-
関連リンク
承認
作成者 - Francisc Vass(プリンシパル・クラウド・アーキテクト)
その他の学習リソース
docs.oracle.com/learnで他のラボをご覧いただくか、Oracle Learning YouTubeチャネルでより無料のラーニング・コンテンツにアクセスしてください。また、education.oracle.com/learning-explorerにアクセスして、Oracle Learning Explorerになります。
製品ドキュメントについては、Oracle Help Centerを参照してください。
Use Packer to create Oracle Cloud Infrastructure custom images
F87727-01
October 2023
Copyright © 2023, Oracle and/or its affiliates.