Oracle Cloud: бесплатный VPS 4 ядра ARM/24ГБ памяти: решаем проблему большого спроса (OCI CLI)

Очень заманчивая конфигурация была недавно анонсирована в рамках доступа «Всегда бесплатно». К сожалению, «очень быстро разбирают», а именно — сложно запустить экземпляр, постоянно вылазит ошибка «Out of Capacity». Здесь мы решаем эту проблему, так как Oracle время от времени наращивает ёмкость.

Каждый арендатор получает бесплатно первые 3000 часов условных ЦП и 18 000 ГБ-часов в месяц для создания экземпляров Ampere A1 Compute с использованием конфигурации VM.Standard.A1.Flex (эквивалентно 4 условным ЦП и 24 ГБ памяти).

Начнем с установки консольной утилиты

https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm

Если вы предпочитаете использовать PHP вместо консольной утилиты, соответствующая статья в процессе написания и уже почти готова к публикации. Для особо нетерпеливых: https://github.com/hitrov/oci-arm-host-capacity

Генерируем ключи доступа к API

После логина в веб-консоль кликаем иконку с профилем и затем User Settings

image-loader.svg

Далее идём по пути Resources → API keys, жмём кнопку «Add API Key»

image-loader.svg

Копируем содержимое текстового поля, сохраняем в файле с именем config. Я поместил его в новую директорию /home/ubuntu/.oci вместе со скачанным приватным ключом *.pem

image-loader.svg

Настраиваем CLI

Устанавливаем путь к файлу конфигурации

OCI_CLI_RC_FILE=/home/ubuntu/.oci/config

Если вы не добавили бинарник OCI CLI себе в PATH, выполните

alias oci='/home/ubuntu/bin/oci'

(только замените путь на тот, куда утилита была установлена в самом начале).

Установите политику доступ к приватному ключу

oci setup repair-file-permissions --file /home/ubuntu/.oci/oracleidentitycloudservice***.pem

Протестируем аутентификацию, выполнив следующую команду (значение user берём из текстового поля во время генерации)

oci iam user get --user-id ocid1.user.oc1..aaaaaaaax72***d3q

image-loader.svg

Получаем параметры для запуска экземпляра

Нам нужно знать, который из доменов доступности (Availability Domain) бесплатен. Жмём меню Oracle Cloud → Compute → Instances

image-loader.svg

Жмём «Create Instance» и смотрим, где Availability Domain помечен как »Always Free Eligible». В нашем случае видим, что это AD-2.

image-loader.svg

Почти каждая команда требует установленный параметр compartment-id. Давайте временно сохраним его в переменную окружения (замените на своё значение tenancy из config файла)

export C=ocid1.tenancy.oc1..aaaaaaaakpx***mpa

Наконец, соберём значения для запуска экземпляра:

  • availability-domain

  • shape

  • subnet-id

  • image-id

oci iam availability-domain list - all - compartment-id=$C

Пример вывода

{
  "data": [
    ...
    {
      "compartment-id": "ocid1.tenancy.oc1..aaaaaaaakpx***mpa",
      "id": "ocid1.availabilitydomain.oc1..aaaaaaaalcd***m2q",
      "name": "FeVO:EU-FRANKFURT-1-AD-2"
    },
    ...
  ]
}

Помните, нам нужен бесплатный (у меня это AD-2). Устанавливаем значение еще одной переменной окружения

export A=FeVO:EU-FRANKFURT-1-AD-2

Выберем тип (shape)

oci compute shape list --compartment-id=$C

Нас интересует  VM.Standard.A1.Flex:

{
  "data": [
    ...
    {
      "baseline-ocpu-utilizations": null,
      "gpu-description": null,
      "gpus": 0,
      "is-live-migration-supported": false,
      "local-disk-description": null,
      "local-disks": 0,
      "local-disks-total-size-in-gbs": null,
      "max-vnic-attachment-options": {
        "default-per-ocpu": 1.0,
        "max": 24.0,
        "min": 2
      },
      "max-vnic-attachments": 2,
      "memory-in-gbs": 6.0,
      "memory-options": {
        "default-per-ocpu-in-g-bs": 6.0,
        "max-in-g-bs": 512.0,
        "max-per-ocpu-in-gbs": 64.0,
        "min-in-g-bs": 1.0,
        "min-per-ocpu-in-gbs": 1.0
      },
      "min-total-baseline-ocpus-required": null,
      "networking-bandwidth-in-gbps": 1.0,
      "networking-bandwidth-options": {
        "default-per-ocpu-in-gbps": 1.0,
        "max-in-gbps": 40.0,
        "min-in-gbps": 1.0
      },
      "ocpu-options": {
        "max": 80.0,
        "min": 1.0
      },
      "ocpus": 1.0,
      "processor-description": "3.0 GHz Ampere\u00ae Altra\u2122",
      "shape": "VM.Standard.A1.Flex"
    },
    ...
  ]
}

Надеюсь, вы ранее уже создавали VM.Standard.E2.1.Micro (с процессором AMD) из консоли — два таких экземпляра являются бесплатными. Если нет, сделайте это прежде — нам нужны существующие VNC, subnet, route table, security list и т.д.

oci network subnet list --compartment-id=$C

Обратите внимание на id

{
  "data": [
    {
      "availability-domain": null,
      "cidr-block": "10.0.0.0/24",
      "compartment-id": "ocid1.tenancy.oc1..aaaaaaaakpx***mpa",
      "defined-tags": {
        "Oracle-Tags": {
          "CreatedBy": "***",
          "CreatedOn": "2021-01-26T13:51:31.332Z"
        }
      },
      "dhcp-options-id": "ocid1.dhcpoptions.oc1.eu-frankfurt-1.aaaaaaaafh4***cvq",
      "display-name": "subnet-20210126-1549",
      "dns-label": "subnet01261551",
      "freeform-tags": {},
      "id": "ocid1.subnet.oc1.eu-frankfurt-1.aaaaaaaaahbb***faq",
      "ipv6-cidr-block": null,
      "ipv6-virtual-router-ip": null,
      "lifecycle-state": "AVAILABLE",
      "prohibit-internet-ingress": false,
      "prohibit-public-ip-on-vnic": false,
      "route-table-id": "ocid1.routetable.oc1.eu-frankfurt-1.aaaaaaaaqwe***p76q",
      "security-list-ids": [
        "ocid1.securitylist.oc1.eu-frankfurt-1.aaaaaaaaagnn***tca"
      ],
      "subnet-domain-name": "subnet***.vcn***.oraclevcn.com",
      "time-created": "2021-01-26T13:51:31.534000+00:00",
      "vcn-id": "ocid1.vcn.oc1.eu-frankfurt-1.amaaaaaalox***y4a",
      "virtual-router-ip": "10.0.0.1",
      "virtual-router-mac": "00:00:17:***"
    }
  ]
}

…и сохраните его в переменную

export S=ocid1.subnet.oc1.eu-frankfurt-1.aaaaaaaaahbb***faq

Смотрим список образов

oci compute image list  --compartment-id=$C --shape=VM.Standard.A1.Flex

Я предпочитаю иметь весь установленный софт для разработки сразу из коробки — мой выбор — это »Oracle Linux Cloud Developer»

{
  "data": [
    ...
    {
      "agent-features": null,
      "base-image-id": null,
      "billable-size-in-gbs": 14,
      "compartment-id": null,
      "create-image-allowed": true,
      "defined-tags": {},
      "display-name": "Oracle-Linux-Cloud-Developer-8.4-aarch64-2021.06.18-0",
      "freeform-tags": {},
      "id": "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaa23zlxgcvdgb2zn4ffik6rda4g5daa5wa42svsgp4enljv4ywv6wa",
      "launch-mode": "NATIVE",
      "launch-options": {
        "boot-volume-type": "PARAVIRTUALIZED",
        "firmware": "UEFI_64",
        "is-consistent-volume-naming-enabled": true,
        "is-pv-encryption-in-transit-enabled": true,
        "network-type": "PARAVIRTUALIZED",
        "remote-data-volume-type": "PARAVIRTUALIZED"
      },
      "lifecycle-state": "AVAILABLE",
      "listing-type": null,
      "operating-system": "Oracle Linux Cloud Developer",
      "operating-system-version": "8",
      "size-in-mbs": 51200,
      "time-created": "2021-06-24T20:36:22.659000+00:00"
    },
    ...
  ]
}

Сохраняем image id

export I=ocid1.image.oc1.eu-frankfurt-1.aaaaaaaa23zlxgcvdgb2zn4ffik6rda4g5daa5wa42svsgp4enljv4ywv6wa

Также нам нужно создать несколько маленьких JSON файлов

  • instanceOptions.json

{
    "areLegacyImdsEndpointsDisabled": false
}
  • shapeConfig.json (можете изменить значения количества процессоров или ОЗУ). Возможные значения 1/6, 2/12, 3/18 and 2/24 соответственно. Обратите внимание, что образ «Oracle Linux Cloud Developer» требует минимум 8ГБ ОЗУ (таким образом, валидное для него значение — это как минимум 1/8)

{
    "ocpus": 4,
    "memoryInGBs": 24
}
  • availabilityConfig.json

{
    "recoveryAction": "RESTORE_INSTANCE"
}

Чтобы иметь безопасный зашифрованный доступ к экземпляру, нужно иметь сгенерированную пару ключей ~/.ssh/id_rsa и ~/.ssh/id_rsa.pub. Имя файла второго из них (публичного) должно быть передано в команду ниже. В сети достаточно инструкций, чтобы выполнить их генерацию, здесь мы опустим эту часть.

Наконец,

oci compute instance launch \
 --availability-domain $A \
 --compartment-id $C \
 --shape VM.Standard.A1.Flex \
 --subnet-id $S \
 --assign-private-dns-record true \
 --assign-public-ip false \
 --availability-config file:///home/ubuntu/availabilityConfig.json \
 --display-name my-new-instance \
 --image-id $I \
 --instance-options file:///home/ubuntu/instanceOptions.json \
 --shape-config file:///home/ubuntu/shapeConfig.json \
 --ssh-authorized-keys-file /home/ubuntu/.ssh/id_rsa.pub


Теперь вы можете настроить crontab для запуска этой команды, например, раз в минуту. Создайте .sh файл («экспортируйте» переменные окружения до запуска) и убедитесь, что пользователь cron имеет доступ к приватному ключу. Опять же, здесь мы опустим эту часть.

Вывод команды (я тестировал с типом VM.Standard.E2.1.Micro, чтобы не уничтожать существующие экземпляры ARM)

image-loader.svgimage-loader.svg

Я полагаю, что достаточно безопасно оставить скрипт работать и проверять Cloud Console в браузере раз в несколько дней, поскольку когда экземпляр будет, наконец, создан, вы (API, CLI) не сможете создать их больше, чем разрешено, и станете получать в ответ что-то вроде

{
    "code": "LimitExceeded",
    "message": "The following service limits were exceeded: standard-a1-memory-count, standard-a1-core-count. Request a service limit increase from the service limits page in the console. "
}

или же снова

{
    "code": "InternalError",
    "message": "Out of host capacity."
}

Во всяком случае, именно так и есть в моем случае.

Назначаем публичный IP адрес

Мы не делаем это нарочно во время запуска команды, поскольку существует ограничение на два «недолговечных» (ephemeral) бесплатных IP адреса. Когда вы преуспеете в создании экземрляра, открываем консоль в веб-браузере, идём по пути Instance Details → Resources → Attached VNICs, выбирая его имя

image-loader.svg

Затем, Resources → IPv4 Addresses →… → Edit

image-loader.svg

Выбираем ephemeral и кликаем по кнопке «Update»

image-loader.svg

Заключение

Вот, как вы будете логиниться в экземпляр после его создания (обратите внимание на имя пользователя — opc)

ssh -i ~/.ssh/id_rsa opc@ip.add.re.ss

Если же вы не назначили внешний (публичный) IP адрес, вы всё равно можете подключиться, используя его внутреннее доменное имя (internal FQDN) или частный (private) IP адрес (10.x.x.x) со страницы Instance Details, если экземпляр находится в той же сети VNIC, например,

ssh -i ~/.ssh/id_rsa opc@instance-20210714-xxxx.subnet.vcn.oraclevcn.com

Спасибо, что прочли!

© Habrahabr.ru