Remarques :
- Ce tutoriel nécessite un accès à Oracle Cloud. Pour vous inscrire à un compte gratuit, reportez-vous à Introduction au niveau gratuit d'Oracle Cloud Infrastructure.
- Il utilise des exemples de valeur pour les informations d'identification Oracle Cloud Infrastructure, la location et les compartiments. A la fin de votre atelier, remplacez ces valeurs par celles propres à votre environnement cloud.
Utiliser Packer pour créer des images personnalisées Oracle Cloud Infrastructure
Introduction
Ce tutoriel traite de la prise d'une image de base OCI, ou de toute image de calcul existante dans OCI, et de sa modification en fonction des besoins du client.
Par exemple, vous devrez peut-être changer le mode de lancement de l'image d'origine à paravirtualisation ou modifier l'attachement de carte d'interface réseau virtuelle (VNIC). Par exemple, les noeuds de processus actif OKE en ont besoin. Vous pouvez également installer des packages de système d'exploitation supplémentaires ou modifier les paramètres du noyau de l'instance à l'aide du provisionneur Packer (comme dans Terraform).
Supposons que vous ayez besoin d'une image sur laquelle vous souhaitez installer la base de données PostgreSQL et que certains paramètres ulimit aient d'autres valeurs. Pour ce faire, lancez un calcul à partir d'une image, puis modifiez ce dont vous avez besoin, installez les programmes, l'application, les packages dont vous avez besoin, puis enregistrez l'instance en tant que nouvelle image personnalisée.
Imaginez maintenant que vous devez créer plusieurs images personnalisées pour plusieurs architectures et au fil du temps, vous devez ajouter/modifier les programmes ou packages ajoutés à votre image personnalisée. Pour cela, nous pouvons utiliser Packer à partir de HashiCorp.
Emballeur
Packer est l'outil open source de HashiCorp utilisé pour créer des images de machine à partir de la configuration source. Il est léger, s'exécute sur chaque système d'exploitation majeur, hautement performant. Il ne remplace pas la gestion de configuration comme Chef ou Puppet. En fait, lorsque vous créez des images, Packer peut utiliser des outils comme Chef ou Puppet pour installer des logiciels sur l'image. Certaines fonctionnalités sont les suivantes :
-
Automatisez la création de tout type d'image de machine. Personnaliser les images en fonction des exigences de l'application et de l'organisation.
-
Créez des images de machine identiques pour plusieurs plates-formes à partir d'une configuration source unique.
-
Créez des images de machine pour plusieurs plates-formes en parallèle.
Avantages de l'utilisation de Packer
- Automatisez l'ensemble du processus.
- Créez plusieurs images personnalisées à la fois.
- Créez des images pour différentes architectures.
- Peut s'exécuter en parallèle.
- Peut être utilisé dans le pipeline de build OCI DevOps.
- Il utilise la langue HCL.
- Peut utiliser l'approvisionnement (c'est-à-dire shell ou Ansible) pour exécuter des scripts/commandes personnalisés sur le calcul.
Authentification du packer
Vous pouvez authentifier Packer à l'aide des options suivantes.
-
Par défaut, il utilise le profil DEFAULT du fichier
.oci/config
. -
En utilisant le principal d'instance : ajoutez l'argument use_instance_principals dans le fichier de configuration Packer (un exemple est ci-dessous).
-
Clés de signature d'API.
-
Jeton de sécurité.
Remarque : en savoir plus sur l'authentification de package, mais il est préférable d'utiliser le fichier
.oci/config
ou le principal d'instance.
Fonctionnement de Packer
Dans les tâches, Packer prend une image spécifiée dans le paramètre base_image_ocid et déploie une instance de calcul avec les attributs que vous avez spécifiés dans les paramètres de configuration requis (par exemple, availability*domain, shape, etc.).
Après ce Packer tentera d'exécuter ssh dans l'instance pour exécuter tout programme de provisionnement (_provisionner "shell"*) que vous avez indiqué dans le bloc build sur l'image de base après son lancement. Pour cette tâche, vous devez tenir compte de l'endroit où vous déployez l'instance (les attributs subnet_ocid), afin que Packer puisse ssh dans l'instance à partir de l'ordinateur qui exécute Packer. A la fin des instantanés Packer, il crée une image personnalisée réutilisable.
Provisionnement d'emballages
Les provisionneurs sont des composants importants de Packer qui installent et configurent des logiciels au sein d'une machine en cours d'exécution avant que cette machine ne devienne une image statique. Ils effectuent le travail majeur de faire en sorte que l'image contienne un logiciel utile.
Voici des exemples de programme de provisionnement :
- Shell : moyen le plus simple d'installer et de configurer des logiciels sur une machine.
- Fichier : permet de télécharger des fichiers vers des machines créées par Packer.
- Ansible : exécutez les livres de jeux Ansible.
Objectifs
-
Créez une image personnalisée à partir d'une image existante et modifiez les attributs
nic_attachment_type
etimage_launch_mode
. -
Créez une image personnalisée à partir d'une image existante et exécutez un livre de jeux Ansible sur l'image que vous venez de créer.
Prérequis
-
Location OCI et compte OCI disposant de privilèges suffisants pour gérer instance-family, utiliser le réseau et les images.
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
-
Installez Packer.
-
Packer requiert la présence de certains paramètres de configuration. Reportez-vous à Paramètres de configuration requis.
-
Packer utilisera ssh pour se connecter au calcul provisionné afin d'apporter les modifications décrites par le fichier de configuration Packer. Rendez l'instance accessible sur le port 22 (en général, indiquez un OCID de sous-réseau accessible à partir de l'hôte exécutant Packer, l'attribut subnet_ocid).
Tâche 1 : création du fichier de configuration Packer
Packer prend en charge le format HCL ou JSON. Dans la tâche suivante, il s'agit d'un format HCL.
-
Nommez le fichier comme vous le souhaitez, mais à la fin incluez .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 est le sous-réseau dans lequel l'instance est provisionnée jusqu'à la création de l'image personnalisée. Il s'agit d'un sous-réseau qui doit être accessible à partir de l'hôte exécutant Packer. Normalement, vous ne voulez pas créer d'instances de développement avec une adresse IP publique, car il n'y a aucune raison qu'elles soient exposées à Internet et que cela crée simplement des problèmes de sécurité. Pour éviter d'utiliser l'adresse IP publique, vous pouvez exécuter Packer à partir d'OCI ou utiliser le service OCI Bastion. Vous pouvez également utiliser FastConnect ou un autre VPN pour accéder au sous-réseau OCI sur site sans avoir à passer par Internet.
Tâche 2 : initialiser Packer
-
Exécuter l'initialisation du packer.
<path to packer bin> init <packer conf file>
Exemple :
<path to packer bin> init oke.pkr.hcl
Tâche 3 : créer l'image
-
A ce stade, vous disposez d'une image personnalisée qui contiendra
image_launch_mode = "NATIVE"
etnic_attachment_type = "VFIO"
. Il existe d'autres attributs que vous pouvez modifier. Tous sont décrits dans le document officiel. -
Vous pouvez exécuter des commandes ou des scripts personnalisés (des exemples sont joints).
<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..........'
Exemple d'utilisation de l'approvisionnement :
-
Cet exemple utilise provisioner (shell et fichier).
-
Il créerait 2 images (spécifiées dans la source).
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}"] } }
-
Il utilise des variables (comme dans Terraform).
image_compartment_ocid = var.deploy_in_comp
-
la méthode d'authentification est avec le fichier .oci/config (valeur par défaut), mais elle utilise un attribut pour spécifier le profil à utiliser dans le fichier.
access_cfg_file_account = var.OCI_PROFILE
-
Dans ce cas, nous utilisons provisionneur "shell" et provisionneur"file" et provisionneur"shell-local".
-
Le provisionneur Shell Packer provisionne les machines créées par Packer à l'aide de scripts shell. Le provisionnement de shell est le moyen le plus simple d'installer et de configurer des logiciels sur une machine.
-
Vous pouvez exécuter la commande shell sur la machine (utiliser inline) ou exécuter le script e (utiliser script).
-
Nous avons également utilisé le programme de provisionnement file. Le programme de provisionnement File Packer télécharge des fichiers vers les machines créées par Packer.
-
Vous pouvez voir plus d'exemples dans le fichier hcl que vous pouvez télécharger prov-example.pkr.hcl.
Exemple d'utilisation de fichiers variables et de provisionneurs Ansible :
-
Nous utilisons :
- Fichiers de variables.
- méthode d'authentification différente : utilisation de variables.
-
Au lieu d'utiliser shell pour installer des packages, nous utilisons ansible pour exécuter des livres de jeux stockés dans un dossier séparé.
-
Cette méthode est destinée à une situation plus complexe qui peut être mieux gérée par Ansible.
-
Le provisionnement est deux ans :
- ansible-local : doit être installé sur l'hôte que Packer va construire (vous pouvez utiliser le shell de provisionnement pour installer Ansible).
- ansible : il s'exécutera à partir de l'hôte qui exécute Packer. Il n'est donc pas nécessaire d'être présent sur l'instance que vous créez.
-
plusieurs fichiers de configuration sont impliqués. Vous devez donc indiquer le nom du répertoire lors de la création.
packer build <directory name>
-
Ici, le fichier exemple ansible-example.pkr.hcl. Voici l'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" ] #} }
-
Voici le fichier vars.pkr.hcl. Dans ce fichier, nous les déclarons et les initialisons.
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......" }
-
Voici l'authentification-vars.pkr.hcl, nous utilisons ce fichier pour configurer l'authentification.
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 = "...." }
-
Liens connexes
Remerciements
Auteur - Francisc Vass (architecte cloud principal)
Ressources de formation supplémentaires
Explorez d'autres ateliers sur docs.oracle.com/learn ou accédez à davantage de contenu de formation gratuit sur le canal Oracle Learning YouTube. En outre, accédez à education.oracle.com/learning-explorer pour devenir un explorateur Oracle Learning.
Pour consulter la documentation produit, consultez Oracle Help Center.
Use Packer to create Oracle Cloud Infrastructure custom images
F87727-01
October 2023
Copyright © 2023, Oracle and/or its affiliates.