Сборка образа ВМ с набором инфраструктурных инструментов с помощью Packer
Yandex Compute Cloud можно использовать для создания образа дисков виртуальных машин с набором дополнительных инфраструктурных инструментов с помощью утилиты Packer
Соберите с помощью утилиты Packer образ ВМ на основе Ubuntu Linux 20.04 LTS с заданными в конфигурационном файле параметрами. Добавьте в образ часто используемые при работе с Yandex Cloud инструменты:
- Yandex Cloud CLI версии 0.91.0 или выше.
- Terraform
версии 1.1.9. - kubectl
версии 1.23. - Docker
версии 20.10.16 или выше. - Git
версии 2.25.1 или выше. - Helm
версии 3.9.0. - jq
версии 1.6 или выше. - tree
версии 1.8.0 или выше. - gRPCurl
версии 1.8.6. - Pulumi
версии 3.33.2. - tmux
версии 3.0a или выше.
С помощью Packer будет создана и запущена вспомогательная ВМ, на которую будет установлено необходимое ПО. Затем на основе ее загрузочного диска будет собран образ. После этого вспомогательная ВМ и загрузочный диск будут удалены.
Аналогично вы можете создать собственный образ с необходимым набором ПО.
Чтобы собрать образ и создать на его основе ВМ:
- Подготовьте облако к работе.
- Подготовьте рабочее окружение.
- Подготовьте конфигурацию образа.
- Соберите образ.
- Создайте ВМ из образа.
Если созданные ресурсы вам больше не нужны, удалите их.
Подготовьте облако к работе
Зарегистрируйтесь в Yandex Cloud и создайте платежный аккаунт:
- Перейдите в консоль управления
, затем войдите в Yandex Cloud или зарегистрируйтесь. - На странице Yandex Cloud Billing
убедитесь, что у вас подключен платежный аккаунт, и он находится в статусеACTIVE
илиTRIAL_ACTIVE
. Если платежного аккаунта нет, создайте его и привяжите к нему облако.
Если у вас есть активный платежный аккаунт, вы можете создать или выбрать каталог, в котором будет работать ваша инфраструктура, на странице облака
Подробнее об облаках и каталогах.
Необходимые платные ресурсы
В стоимость сборки образа ВМ с последующим созданием ВМ входит:
- плата за хранение собранных образов (см. тарифы Yandex Compute Cloud);
- плата за вычислительные ресурсы ВМ (см. тарифы Yandex Compute Cloud).
Подготовьте рабочее окружение
-
Установите Packer:
-
Скачайте дистрибутив Packer и установите его по инструкции на официальном сайте
.Также вы можете скачать дистрибутив Packer для вашей платформы из зеркала Yandex Cloud
. -
После загрузки добавьте путь к папке, в которой находится исполняемый файл, в переменную
PATH
. Для этого выполните команду:export PATH=$PATH:<путь_к_папке_с_исполняемым_файлом_Packer>
Примечание
Для работы с Yandex Cloud требуется Packer версии не ниже 1.5.
-
-
Настройте плагин Yandex Compute Builder
:-
Создайте файл
config.pkr.hcl
со следующим содержанием:packer { required_plugins { yandex = { version = ">= 1.1.2" source = "github.com/hashicorp/yandex" } } }
-
Установите плагин:
packer init <путь_к_файлу_config.pkr.hcl>
Результат:
Installed plugin github.com/hashicorp/yandex v1.1.2 in ...
-
-
Установите Yandex Cloud CLI и создайте профиль.
-
Получите информацию о доступных подсетях и зонах доступности. Если у вас нет подсетей — создайте новую.
CLIAPI-
Выполните команду:
yc vpc subnet list
Результат:
+----------------------+----------------------+----------------------+----------------+---------------+-----------------+ | ID | NAME | NETWORK ID | ROUTE TABLE ID | ZONE | RANGE | +----------------------+----------------------+----------------------+----------------+---------------+-----------------+ | b0c29k6anelk******** | intro2-ru-central1-d | enp45glgitd6******** | | ru-central1-d | [10.130.0.0/24] | | e2ltcj4urgpb******** | intro2-ru-central1-b | enp45glgitd6******** | | ru-central1-b | [10.129.0.0/24] | | e9bn57jvjnbu******** | intro2-ru-central1-a | enp45glgitd6******** | | ru-central1-a | [10.128.0.0/24] | +----------------------+----------------------+----------------------+----------------+---------------+-----------------+
-
Запишите идентификатор подсети (столбец
ID
), в которой будет размещаться вспомогательная ВМ, на основе которой создается образ, а также соответствующую зону доступности (столбецZONE
). Эти параметры потребуются в дальнейшем.
Воспользуйтесь методом REST API list для ресурса Subnet или вызовом gRPC API SubnetService/List.
-
-
Задайте в командной строке значения переменных, используемых в процессе сборки образа.
export YC_FOLDER_ID=$(yc config get folder-id) export YC_ZONE="<зона_доступности>" export YC_SUBNET_ID="<идентификатор_подсети>" export YC_TOKEN=$(yc iam create-token)
Где:
YC_FOLDER_ID
— идентификатор каталога, в котором будет размещена вспомогательная ВМ, на основе которой создается образ. Заполняется автоматически.YC_ZONE
— зона доступности, в которой будет размещена вспомогательная ВМ, на основе которой создается образ. Получена ранее.YC_SUBNET_ID
— идентификатор подсети, в которой будет размещена вспомогательная ВМ, на основе которой создается образ. Получен ранее.YC_TOKEN
— IAM-токен. Нужен для создания образа ВМ, заполняется автоматически.
-
Сгенерируйте пару SSH-ключей. Они понадобятся при создании и подключении к ВМ.
Подготовьте конфигурацию образа
-
Создайте конфигурационный файл в формате HCL
, напримерtoolbox.pkr.hcl
. -
Опишите в конфигурационном файле параметры образа, который необходимо создать:
# Yandex Cloud Toolbox VM Image based on Ubuntu 20.04 LTS # # Provisioner docs: # https://www.packer.io/docs/builders/yandex # variable "YC_FOLDER_ID" { type = string default = env("YC_FOLDER_ID") } variable "YC_ZONE" { type = string default = env("YC_ZONE") } variable "YC_SUBNET_ID" { type = string default = env("YC_SUBNET_ID") } variable "TF_VER" { type = string default = "1.1.9" } variable "KCTL_VER" { type = string default = "1.23.0" } variable "HELM_VER" { type = string default = "3.9.0" } variable "GRPCURL_VER" { type = string default = "1.8.6" } variable "GOLANG_VER" { type = string default = "1.17.2" } variable "PULUMI_VER" { type = string default = "3.33.2" } source "yandex" "yc-toolbox" { folder_id = "${var.YC_FOLDER_ID}" source_image_family = "ubuntu-2004-lts" ssh_username = "ubuntu" use_ipv4_nat = "true" image_description = "Yandex Cloud Ubuntu Toolbox image" image_family = "my-images" image_name = "yc-toolbox" subnet_id = "${var.YC_SUBNET_ID}" disk_type = "network-hdd" zone = "${var.YC_ZONE}" } build { sources = ["source.yandex.yc-toolbox"] provisioner "shell" { inline = [ # Global Ubuntu things "sudo apt-get update", "echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections", "sudo apt-get install -y unzip python3-pip python3.8-venv", # Yandex Cloud CLI tool "curl --silent --remote-name https://storage.yandexcloud.net/yandexcloud-yc/install.sh", "chmod u+x install.sh", "sudo ./install.sh -a -i /usr/local/ 2>/dev/null", "rm -rf install.sh", "sudo sed -i '$ a source /usr/local/completion.bash.inc' /etc/profile", # Docker "curl --fail --silent --show-error --location https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-keyring.gpg", "echo \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null", "sudo apt-get update", "sudo apt-get install -y docker-ce containerd.io", "sudo usermod -aG docker $USER", "sudo chmod 666 /var/run/docker.sock", "sudo useradd -m -s /bin/bash -G docker yc-user", # Docker Artifacts "docker pull hello-world", "docker pull -q amazon/aws-cli", "docker pull -q golang:${var.GOLANG_VER}", # Terraform (classic way) #"curl --fail --silent --show-error --location https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-keyring.gpg", #"echo \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main\" | sudo tee /etc/apt/sources.list.d/hashicorp.list > /dev/null", #"sudo apt-get update", #"sudo apt-get install -y terraform", # # Alternative Option "curl --silent --location https://hashicorp-releases.yandexcloud.net/terraform/${var.TF_VER}/terraform_${var.TF_VER}_linux_amd64.zip --output terraform.zip", "unzip terraform.zip", "sudo install -o root -g root -m 0755 terraform /usr/local/bin/terraform", "rm -rf terraform terraform.zip", # Terraform configuration file ? #"cat <<EOF > ~/.terraformrc \n provider_installation { network_mirror { url = \"https://terraform-mirror.yandexcloud.net/\" include = [\"registry.terraform.io/*/*\"] } direct { exclude = [\"registry.terraform.io/*/*\"] } } \n EOF", # kubectl "curl --silent --location --remote-name https://dl.k8s.io/release/v${var.KCTL_VER}/bin/linux/amd64/kubectl", "sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl", "rm -rf kubectl", # Helm "curl --silent --show-error --location --remote-name https://get.helm.sh/helm-v${var.HELM_VER}-linux-amd64.tar.gz", "tar zxf helm-v${var.HELM_VER}-linux-amd64.tar.gz", "sudo install -o root -g root -m 0755 linux-amd64/helm /usr/local/bin/helm", "rm -rf helm-v${var.HELM_VER}-linux-amd64.tar.gz", "rm -rf linux-amd64", # User can add own repo after login like this: # helm repo add stable https://charts.helm.sh/stable ## grpccurl "curl --silent --show-error --location --remote-name https://github.com/fullstorydev/grpcurl/releases/download/v${var.GRPCURL_VER}/grpcurl_${var.GRPCURL_VER}_linux_x86_64.tar.gz", "tar zxf grpcurl_${var.GRPCURL_VER}_linux_x86_64.tar.gz", "sudo install -o root -g root -m 0755 grpcurl /usr/local/bin/grpcurl", "rm -rf grpcurl_${var.GRPCURL_VER}_linux_x86_64.tar.gz", "rm -rf grpcurl", # Pulumi "curl --silent --show-error --location --remote-name https://get.pulumi.com/releases/sdk/pulumi-v${var.PULUMI_VER}-linux-x64.tar.gz", "tar zxf pulumi-v${var.PULUMI_VER}-linux-x64.tar.gz", "sudo cp pulumi/* /usr/local/bin/", "rm -rf pulumi-v${var.PULUMI_VER}-linux-x64.tar.gz", "rm -rf pulumi", # Other packages "sudo apt-get install -y git jq tree tmux", # Clean "rm -rf .sudo_as_admin_successful", # Test - Check versions for installed components "echo '=== Tests Start ==='", "yc version", "terraform version", "docker version", "kubectl version --client=true", "helm version", "grpcurl --version", "git --version", "jq --version", "tree --version", "pulumi version", "echo '=== Tests End ==='" ] } }
Важно
В конфигурационном файле нельзя одновременно использовать параметры provisioner "shell"
и metadata
.
Соберите образ
-
В командной строке перейдите в папку с конфигурационным файлом образа:
cd <путь_к_папке_с_конфигурационным_файлом>
-
Проверьте корректность конфигурационного файла образа с помощью команды:
packer validate yc-toolbox.pkr.hcl
Где
yc-toolbox.pkr.hcl
— имя конфигурационного файла.Если конфигурация является корректной, появится сообщение:
The configuration is valid.
-
Запустите сборку образа с помощью команды:
packer build yc-toolbox.pkr.hcl
Где
yc-toolbox.pkr.hcl
— имя конфигурационного файла. -
После завершения сборки будет выведено сообщение о том, что образ успешно создан:
... ==> Builds finished. The artifacts of successful builds are: --> yandex.yc-toolbox: A disk image was created: yc-toolbox (id: fd83j475posv********) with family name infra-images
Запишите идентификатор собранного образа — параметр
id
. Используйте этот идентификатор в дальнейшем, чтобы создать ВМ. -
Проверьте наличие собранного образа в Yandex Cloud.
CLIAPIВыполните команду:
yc compute image list
Результат:
+----------------------+------------+-----------+----------------------+--------+ | ID | NAME | FAMILY | PRODUCT IDS | STATUS | +----------------------+------------+-----------+----------------------+--------+ | fd83j475posv******** | yc-toolbox | my-images | f2ek1vhoppg2******** | READY | +----------------------+------------+-----------+----------------------+--------+
Воспользуйтесь методом REST API list для ресурса Image или вызовом gRPC API ImageService/List.
Создайте виртуальную машину из образа
-
Задайте значения переменных, используемых в процессе создания ВМ. Для этого выполните команду:
export VM_NAME="<имя_ВМ>" export YC_IMAGE_ID="<идентификатор_образа>" export YC_SUBNET_ID="<идентификатор_подсети>" export YC_ZONE="<зона_доступности>"
Где:
VM_NAME
— имя создаваемой ВМ.YC_IMAGE_ID
— идентификатор образа, из которого будет создана ВМ. Получен ранее.YC_SUBNET_ID
— идентификатор подсети, в которой будет размещена ВМ. Получен ранее.YC_ZONE
— зона доступности, в которой будет размещена ВМ. Получена ранее.
-
Создайте ВМ из собранного образа.
CLIAPIВыполните команду:
yc compute instance create \ --name $VM_NAME \ --hostname $VM_NAME \ --zone=$YC_ZONE \ --create-boot-disk size=20GB,image-id=$YC_IMAGE_ID \ --cores=2 \ --memory=8G \ --core-fraction=100 \ --network-interface subnet-id=$YC_SUBNET_ID,ipv4-address=auto,nat-ip-version=ipv4 \ --ssh-key <путь_к_публичной_части_SSH-ключа>
Где:
--name
— имя создаваемой ВМ.--hostname
— имя хоста ВМ.--zone
— зона доступности.--create-boot-disk
— параметры загрузочного диска:size
— размер,image-id
— идентификатор используемого образа.--cores
— количество vCPU.--memory
— объем RAM.--core-fraction
— базовая производительность vCPU в %.--network-interface
— параметры сетевого интерфейса:subnet-id
— идентификатор подсети,ipv4-address
— внутренний IPv4-адрес,nat-ip-version
— спецификация IP для NAT в интернет.--ssh-key
— публичная часть SSH-ключа.
После выполнения команды будет выведена информация о созданной ВМ. Запишите публичный IP-адрес ВМ:
... one_to_one_nat: address: 62.84.122.151 ...
Подробнее о создании ВМ из пользовательского образа.
Воспользуйтесь методом REST API create для ресурса Instance или вызовом gRPC API InstanceService/Create.
-
Подключитесь к ВМ по протоколу SSH:
ssh -i <путь_к_закрытой_части_SSH-ключа> yc-user@<публичный_IP-адрес_ВМ>
Как удалить созданные ресурсы
Чтобы перестать платить за созданные ресурсы: