Note:
- Este tutorial requiere acceso a Oracle Cloud. Para registrarse en una cuenta gratuita, consulte Introducción a la capa gratuita de Oracle Cloud Infrastructure.
- Utiliza valores de ejemplo para las credenciales, el arrendamiento y los compartimentos de Oracle Cloud Infrastructure. Al finalizar el laboratorio, sustituya estos valores por otros específicos de su entorno en la nube.
Utilice Packer para crear imágenes personalizadas de Oracle Cloud Infrastructure
Introducción
Este tutorial trata sobre cómo tomar una imagen base de OCI o cualquier imagen informática que ya tenga en OCI y modificarla según las necesidades del cliente.
Por ejemplo, puede que necesite cambiar el modo de inicio de imagen de nativo a paravirtualización o cambiar la asociación de tarjeta de interfaz de red virtual (VNIC). Por ejemplo, los nodos de trabajador de OKE los necesitan. Del mismo modo, puede instalar paquetes adicionales del sistema operativo o modificar los parámetros del núcleo de instancia mediante el aprovisionador de Packer (como en Terraform).
Supongamos que necesita una imagen en la que desea tener instalada la base de datos PostgreSQL y algunos parámetros ulimit para tener otros valores. Para ello, inicie un recurso informático desde una imagen y, a continuación, cambie lo que necesite, instale los programas, la aplicación y los paquetes que necesite y, a continuación, guarde la instancia como una nueva imagen personalizada.
Ahora imagine que necesita crear varias imágenes personalizadas, para varias arquitecturas y con el tiempo necesita agregar o cambiar los programas o paquetes agregados a su imagen personalizada. Para ello, podemos utilizar Packer de HashiCorp.
Empaquetador
Packer es la herramienta de código abierto de HashiCorp que se utiliza para crear imágenes de máquinas a partir de la configuración de origen. Es ligero, se ejecuta en todos los sistemas operativos principales, de alto rendimiento. No sustituye la gestión de configuración, como Chef o Puppet. De hecho, cuando crea imágenes, Packer puede utilizar herramientas como Chef o Puppet para instalar software en la imagen. Algunas de las funciones son:
-
Automatice la creación de cualquier tipo de imagen de máquina. Personalice las imágenes para que se ajusten a los requisitos de la aplicación y la organización.
-
Cree imágenes idénticas de máquina para varias plataformas a partir de una única configuración de origen.
-
Cree imágenes de máquina para varias plataformas en paralelo.
Ventajas de Utilizar Packer
- Automatice todo el proceso.
- Cree más de una imagen personalizada a la vez.
- Cree imágenes para diferentes arquitecturas.
- Se puede ejecutar en paralelo.
- Se puede utilizar en el pipeline de compilación DevOps de OCI.
- Utiliza lenguaje HCL.
- Puede utilizar el provisionador (es decir, shell o Ansible) para ejecutar scripts y comandos personalizados en los recursos informáticos.
Autenticación de empaquetador
Puede autenticar Packer mediante las siguientes opciones.
-
Por defecto, utiliza el perfil DEFAULT del archivo
.oci/config
. -
Mediante el principal de instancia: agregue el argumento use_instance_principals en el archivo de configuración de Packer (a continuación se muestra un ejemplo).
-
Claves de firma de API.
-
Token de seguridad.
Nota: Obtenga más información sobre la autenticación de paquetes, pero la forma preferible es utilizar el archivo
.oci/config
o el principal de instancia.
Funcionamiento de Packer
En las tareas, Packer toma una imagen especificada en el parámetro base_image_ocid y despliega una instancia informática con los atributos especificados por usted en los parámetros de configuración necesarios (es decir, disponibilidad*dominio, unidad, etc.).
Después de eso, Packer intentará utilizar ssh en la instancia para ejecutar cualquier provisionador (_provisioner "shell"*) especificado en el bloque build de la imagen base después de iniciarlo. Para esta tarea, debe tener en cuenta dónde desea desplegar la instancia (los atributos subnet_ocid), por lo que Packer puede utilizar ssh en la instancia desde la máquina que ejecuta Packer. Al final de las instantáneas del empaquetador, crea una imagen personalizada reutilizable.
Aprovisionadores de empaquetado
Los aprovisionadores son componentes importantes de Packer que instalan y configuran software dentro de un equipo en ejecución antes de que ese equipo se convierta en una imagen estática. Realizan el trabajo principal de hacer que la imagen contenga software útil.
Entre los aprovisionadores de ejemplo se incluyen:
- Shell: la forma más sencilla de instalar y configurar software en un equipo.
- Archivo: para cargar archivos en máquinas creadas por Packer.
- Ansible: ejecute los cuadernos de estrategias de Ansible.
Objetivos
-
Cree una imagen personalizada a partir de una imagen existente y modifique los atributos
nic_attachment_type
yimage_launch_mode
. -
Cree una imagen personalizada a partir de una imagen existente y ejecute un cuaderno de estrategias de Ansible en la imagen recién creada.
Requisitos
-
Arrendamiento de OCI y cuenta de OCI con privilegios suficientes para gestionar la familia de instancias, utilizar red e imágenes.
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
-
Instale el paquete del empaquetador.
-
Packer requiere que haya algunos parámetros de configuración, consulte required configuration parameters.
-
Packer utilizará ssh para conectarse a los recursos informáticos aprovisionados con el fin de realizar los cambios descritos en el archivo de configuración de Packer. Haga que la instancia sea accesible en el puerto 22 (especifique normalmente un OCID de subred al que se puede acceder desde el host que ejecuta Packer, el atributo subnet_ocid).
Tarea 1: Creación del archivo de configuración del empaquetador
Packer admite formato HCL o JSON. En la siguiente tarea, es un formato HCL.
-
Asigne al archivo el nombre que desee, pero al final incluya .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 es la subred en la que se aprovisiona la instancia hasta que se crea la imagen personalizada. Se trata de una subred a la que se debe poder acceder desde el host que ejecuta Packer. Normalmente no desearía crear instancias de desarrollo con una IP pública, ya que no hay ninguna razón para que se expongan a Internet y, al hacerlo, solo se crean problemas de seguridad. Una forma de evitar el uso de IP pública es ejecutar Packer desde OCI o utilizar el servicio OCI Bastion. También puede utilizar FastConnect u otra VPN para acceder a la subred de OCI desde entornos locales sin necesidad de recorrer Internet.
Tarea 2: Inicializar empaquetador
-
Ejecute la inicialización del empaquetador.
<path to packer bin> init <packer conf file>
Por ejemplo:
<path to packer bin> init oke.pkr.hcl
Tarea 3: Crear la imagen
-
En este punto, tiene una imagen personalizada que tendrá
image_launch_mode = "NATIVE"
ynic_attachment_type = "VFIO"
. Hay otros atributos que puede cambiar. Todos se describen en el documento oficial. -
Puede ejecutar comandos personalizados o scripts (se adjuntan ejemplos).
<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..........'
Ejemplo con el provisionador:
-
En este ejemplo, se utiliza provisioner (shell y archivo).
-
Se crearían 2 imágenes (especificadas en el origen).
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}"] } }
-
Utiliza variables (como en Terraform).
image_compartment_ocid = var.deploy_in_comp
-
el método Auth es con el archivo .oci/config (valor por defecto), pero utiliza un atributo para especificar el perfil wich en el archivo que se va a utilizar.
access_cfg_file_account = var.OCI_PROFILE
-
En este caso, utilizamos provisioner "shell" y provisioner "file" y provisioner "shell-local".
-
shell Packer provisioner aprovisiona máquinas creadas por Packer mediante scripts de shell. El aprovisionamiento de shell es la forma más sencilla de instalar y configurar software en una máquina.
-
Puede ejecutar el comando shell en el equipo (utilice inline) o ejecutar una secuencia de comandos electrónica (utilice script).
-
También utilizamos el aprovisionamiento file. El provisionador de empaquetado de archivos carga archivos en máquinas creadas por Packer.
-
Puede ver más ejemplos en el archivo hcl que puede descargar prov-example.pkr.hcl.
Ejemplo con archivos de variables y aprovisionadores de Ansible:
-
Utilizamos:
- archivos de variables.
- un método Auth diferente: utilizando variables.
-
En lugar de utilizar shell para instalar paquetes, estamos utilizando la opción de ejecutar cuadernos de estrategias almacenados en una carpeta independiente.
-
Este método es para una situación más compleja que Ansible puede manejar mejor.
-
Hay dos aprovisionadores responsables:
- ansible-local: Necesita unsible instalado en el host que Packer creará (puede utilizar el shell de provisionador para instalar Ansible).
- ansible: se ejecutará ansible desde el host que ejecuta Packer, por lo que no es necesario que esté presente en la instancia que cree.
-
hay varios archivos de configuración implicados, por lo que debe especificar el nombre del directorio al crear.
packer build <directory name>
-
En este ejemplo, el archivo ansible-example.pkr.hcl. A continuación se muestra el 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" ] #} }
-
Aquí está vars.pkr.hcl. En este archivo los declaramos e inicializamos.
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......" }
-
Este es el archivo auth-vars.pkr.hcl. Utilizamos este archivo para configurar la autenticación.
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 = "...." }
-
Enlaces relacionados
Acuses de recibo
Autor: Francisc Vass (Arquitecto principal de Cloud)
Más recursos de aprendizaje
Explore otros laboratorios en docs.oracle.com/learn o acceda a más contenido de aprendizaje gratuito en el canal YouTube de Oracle Learning. Además, visite education.oracle.com/learning-explorer para convertirse en un explorador de Oracle Learning.
Para obtener documentación sobre los productos, visite Oracle Help Center.
Use Packer to create Oracle Cloud Infrastructure custom images
F87727-01
October 2023
Copyright © 2023, Oracle and/or its affiliates.