Как стать автором
Обновить
733.58
OTUS
Цифровые навыки от ведущих экспертов

Packer: мультисборка, пост-процессоры и пользовательские плагины

Уровень сложностиПростой
Время на прочтение6 мин
Количество просмотров2.3K

Привет, Хабр!

Packer — это open-source инструмент для создания идентичных машинных образов для множества платформ из одного исходного файла конфигурации. Т.е с пакером можно автоматизировать создание образов для Amazon EC2, VMware, Docker и т.д, используя единый процесс сборки.

Рассмотрим его возможности мультисборки, пост-процессоров и пользовательских плагинов.

Установка и конфиг. файл

Довольно интуитивная установка здесь.

Конфигурационный файл Packer в HCL2 организован в блоки, аргументы и выражения, которые вместе описывают, как должен быть создан каждый образ.

Блоки — это основные контейнеры для конфигурации в HCL2. Они имеют тип, который определяет их функцию, и тело, содержащее аргументы или даже другие блоки, есть такие блоки:

  • source определяет базовый образ и настройки для создания нового образа.

  • build содержит настройки сборки, включая источники и провайдеры.

  • variable объявляет переменные для параметризации конфигураций.

  • locals позволяет определять локальные переменные для удобства.

Аргументы внутри блоков присваивают значения определенным свойствам. Например, в блоке source аргумент ami_name может использоваться для определения имени AMI.

Выражения используются для динамического вычисления значений аргументов. HCL2 поддерживает различные типы выражений, включая использование переменных, арифметические операции и вызов функций.

Пример конфигурационного файла на HCL2 для Packer:

variable "region" {
  type    = string
  default = "us-west-2"
}

source "amazon-ebs" "example" {
  ami_name      = "packer-example-${var.region}"
  instance_type = "t2.micro"
  region        = var.region
  source_ami_filter {
    filters = {
      name                = "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    owners      = ["099720109477"]
    most_recent = true
  }
}

build {
  sources = [
    "source.amazon-ebs.example"
  ]
}

Здесь мы объявили переменную region, источник amazon-ebs с именем example, который определяет параметры для создания AMI на базе Ubuntu Xenial 16.04. Затем, в блоке build, указывается, что источником для сборки является source.amazon-ebs.example.

Краткий обзор синтаксиса

Язык HCL основной инструмент для работы в Packer.

HCL включает базовые арифм. функции add, subtract, multiply, и divide:

variable "count" {
  type = number
  default = 5
}

locals {
  count_plus_one = add(var.count, 1)
  count_double = multiply(var.count, 2)
}

format, join, split, и replace позволяют манипулировать текстовыми данными:

locals {
  formatted_string = format("This is a %s", "string")
  joined_string = join(", ", ["Hello", "World"])
  splitted_array = split(", ", "Hello, World")
  replaced_string = replace("Hello, World", "World", "Packer")
}

Для работы с коллекциями можно использовать length, element, sort, и merge:

locals {
  list_example = ["one", "two", "three"]
  list_length = length(local.list_example)
  second_element = element(local.list_example, 1)
  sorted_list = sort(local.list_example)
}

file и templatefile, позволяют включать содержимое файлов непосредственно в конфигурацию:

locals {
  user_data = file("${path.module}/user-data.sh")
  rendered_template = templatefile("${path.module}/config.tpl", { name = "world" })
}

timestamp возвращает текущую метку времени:

locals {
  current_timestamp = timestamp()
}

md5, sha1, и bcrypt позволяют исполнять криптографические операции для создания хешей строк:

locals {
  md5_hash = md5("Hello, World")
}

uuid генерирует уникальный идентификатор, а cidrsubnet и cidrhost используются для работы с сетевыми адресами:

locals {
  unique_id = uuid()
  subnet_address = cidrsubnet("10.0.0.0/16", 8, 0)
}

Мультисборка

Мультисборка осуществляется через определение нескольких источников сборки в конфиг файле Packer. Каждый источник сборки указывает на конкретную платформу и содержит необходимые параметры для создания образа для этой платформы.

В процессе сборки пакер запускает каждый источник сборки параллельно или последовательно, в зависимости от конфигурации, создавая образы для каждой целевой платформы.

Мультисборка для Amazon EC2 и Docker:

source "amazon-ebs" "amazon-linux" {
  ami_name      = "packer-example-{{timestamp}}"
  instance_type = "t2.micro"
  region        = "us-west-2"
  source_ami_filter {
    filters = {
      name                = "amzn2-ami-hvm-*-x86_64-gp2"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    owners     = ["137112412989"]
    most_recent = true
  }
}

source "docker" "ubuntu" {
  image  = "ubuntu:18.04"
  commit = true
}

build {
  sources = [
    "source.amazon-ebs.amazon-linux",
    "source.docker.ubuntu",
  ]
}

Оба образа создаются параллельно, используя общую конфигурацию сборки.

Мультисборка для VirtualBox и VMware:

source "virtualbox-iso" "windows-10" {
  iso_url      = "http://example.com/windows-10.iso"
  iso_checksum = "abc123"
  // доп. параметры для VirtualBox
}

source "vmware-iso" "windows-10" {
  iso_url      = "http://example.com/windows-10.iso"
  iso_checksum = "abc123"
  // доп. параметры для VMware
}

build {
  sources = [
    "source.virtualbox-iso.windows-10",
    "source.vmware-iso.windows-10",
  ]
}

Используя один и тот же исходный ISO-образ, Packer создает два отдельных образа, каждый из которых оптимизирован для своей платформы виртуализации.

Пост-процессоры

Пост-процессоры в Packer конфигурируются в блоке post-processors и могут быть заданы как одиночные задачи или как цепочки задач. Packer выполнит эти пост-процессоры в указанном порядке после успешного создания всех образов.

Загрузка образа в Amazon S3:

post-processors {
  type = "amazon-s3"
  only = ["amazon-ebs.ubuntu"]
  bucket = "my-packer-images"
  region = "us-west-2"
  key = "packer/{{user `version`}}/{{.BuildName}}.ami"
  acl = "private"
}

Пост-процессор amazon-s3 используется для загрузки созданного образа для Amazon EBS в заданный S3 bucket. Параметры конфигурации указывают целевой bucket, регион, путь и ключ доступа.

Создание Vagrant box:

post-processors {
  type = "vagrant"
  only = ["virtualbox-iso.ubuntu"]
  output = "builds/ubuntu-{{user `version`}}.box"
}

Пост-процессор vagrant преобразует образ, созданный для VirtualBox, в формат Vagrant box, сохраняя его в указанной директории.

Минификация образа Docker:

post-processors {
  type = "docker-tag"
  repository = "user/ubuntu"
  tag = "latest"
}
post-processors {
  type = "docker-push"
  only = ["docker.ubuntu"]
}

Пост-процессоры docker-tag и docker-push юзаются для тегирования и последующей загрузки созданного Docker образа в Docker Hub.

Использование цепочек пост-процессоров:

post-processors {
  sequence {
    post-processors {
      type = "vagrant"
    }
    post-processors {
      type = "vagrant-cloud"
      box_tag = "myusername/mybox"
      access_token = "{{user `vagrant_cloud_token`}}"
    }
  }
}

Каждый пост-процессор имеет свой набор конфигурационных параметров:

  • type: тип пост-процессора (например, vagrant, amazon-s3).

  • only: определяет, для каких сборок должен быть применен пост-процессор.

  • except: исключает определенные сборки из использования пост-процессора.

  • keep_input_artifact: указывает, следует ли сохранять исходный образ после применения пост-процессора.

Пользовательские плагины

Packer предоставляет утилиту packer-sdc для генерации шаблона кода плагина:

packer-sdc plugin new -name=my-custom-plugin -type=[builder|provisioner|post-processor]

Разработка плагина включает реализацию определенного интерфейса в зависимости от типа плагина. Например, для создания нового провайдера вы должны реализовать интерфейс Builder. Packer использует RPC для взаимодействия с плагинами, но большая часть этой работы абстрагирована, т.е можно сфокуситься на бизнес-logic:

package main

import (
    "github.com/hashicorp/packer-plugin-sdk/packer"
    "github.com/hashicorp/packer-plugin-sdk/plugin"
)

type MyCustomBuilder struct {
    // интерфейс Builder
}

func (b *MyCustomBuilder) Prepare(raws ...interface{}) ([]string, []string, error) {
    // логика подготовки
}

// остальная реализация

func main() {
    server, err := plugin.Server()
    if err != nil {
        panic(err)
    }
    server.RegisterBuilder(new(MyCustomBuilder))
    server.Serve()
}

Можно использовать стандартные инструменты Go для написания модульных тестов.

func TestMyCustomBuilder_Prepare(t *testing.T) {
    // тест метода Prepare вашего плагина
}

После разработки и тестирования плагина его нужно собрать и установить в локал директорию Packer.

go build -o packer-plugin-my-custom-plugin .
mkdir -p ~/.packer.d/plugins
mv packer-plugin-my-custom-plugin ~/.packer.d/plugins/

После установки плагина можно использовать его в своих Packer шаблонах, указав его имя в конфигурации:

{
  "builders": [
    {
      "type": "my-custom-plugin",
      "some_parameter": "value"
    }
  ]
}

my-custom-plugin - это тип плагина, а some_parameter - один из параметров, которые определили в его конфигурации.

Далее можно лить на гит свое сокровище или же оставить у себя на хранение.


С официальными плагинами пакер можно ознакомить здесь. А больше про инфраструктуру вы можете узнать в рамках практических онлайн-курсов от экспертов отрасли.

Теги:
Хабы:
Всего голосов 10: ↑7 и ↓3+6
Комментарии1

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS