На Хабре уже не раз писали про бесплатные вычислительные ресурсы (ARM, 4 CPU, 24ГБ), которые можно развернуть в Oracle Cloud. После регистрации вы получаете $300 и 30 дней триального аккаунта, когда для развёртывания доступны все виды ресурсов. Когда эти 30 дней заканчиваются, аккаунт получает статус Always Free, и количество доступных ресурсов значительно урезается. Чтобы снова получить доступ к ним ко всем, можно сделать upgrade своего аккаунта до Pay-as-You-Go. Это односторонняя операция, переход обратно на Always Free невозможен, и после такого перехода нужно аккуратно следить и и контролировать траты. Тем не менее, Pay-as-You-Go аккаунты также могут бесплатно использовать Always Free ресурсы.

Oracle Cloud предоставляет возможность managed развёртывания K8s кластера (в документации он называется OKE – Oracle Container Engine for Kubernetes), однако он недоступен для Always Free аккаунтов (лимит установлен в 0, все упомянутые лимиты в данной статье актуальны на январь 2022 г.).

Чтобы обойти это ограничение, используем подход полностью ручного выделения облачных ресурсов (сети, виртуальных машин) и установки необходимых компонентов. На выходе получим кластер с четырьмя узлами (один control-plane и три worker'а) с установленным K8s'ом, балансировщиком нагрузки, публичным IP адресом и (бонусом) бесплатным доменом.

TL;DR: воспроизводимые Terraform скрипты (и readme по их использованию) опубликованы на github'е.

Вычислительные ресурсы

В нашем кластере будем использовать все доступные бесплатные ARM ресурсы. Используем по одному CPU для каждого узла. Узел для развёртывания K8s control-plane'а получит 3 ГБ оперативной памяти, три worker'а получат по 7 ГБ (что в сумме даёт 24 ГБ использованной памяти). Также каждая ARM VM'ка получает по 1 Gbps сетевой пропускной способности.

Помимо узлов на ARM, в Always Free аккаунте можно создать две виртуальные машины на AMD с 1 CPU и 1 ГБ RAM. Увы, это не значит, что можно выделить 4 ARM узла и 2 AMD узла, поскольку для Always Free аккаунтов доступно 200 ГБ дискового пространства, при этом минимальный блок для выделения – 47 ГБ.

При установке на узлах K8s бросает ошибку, если доступно менее двух CPU. Однако наша цель состоит в развёртывании максимального количества узлов из доступных ресурсов (возможно, ценой готовности кластера к использованию на prod'е), поэтому при собственно установке K8s агентов на узлах мы отключим эту ошибку.

Out of host capacity

Самая частая проблема, которая возникает при выделении ARM ресурсов, – это Out of host capacity.

Эта ошибка появляется из-за ограниченности вычислительных ARM ресурсов, и к сожалению, с ней не так просто бороться. Oracle заявляет, что новые ресурсы развёртываются автоматически. В некоторых случаях помогало переключиться в другой availability domain, если он доступен в выбранном регионе (Always Free аккаунты могут выделять ресурсы только в домашнем регионе, список регионов и доступных availability domain'ов можно увидеть здесь). Также получилось заметить, что если в одном регионе есть два аккаунта, но один из них Pay-as-You-Go, а другой Always Free, то первый получает больший приоритет, и у него получается выделить ARM VM'ки. Второму аккаунту пришлось ждать несколько дней, прежде чем ресурсы стали доступны.

Архитектура сети

Чтобы узлы получили возможность выхода в интернет, нам нужно развернуть для них Virtual Cloud Network (VCN). Внутри VCN можно развёртывать публичные и приватные подсети. Чтобы открыть входящий и исходящий доступ в интернет для узлов в публичной подсети, нужно: а) наличие Internet gateway'а в VCN, и б) каждый узел должен иметь публичный IP. Чтобы открыть исходящий доступ в интернет для узлов в приватной подсети, необходимо наличие NAT gateway'а (входящий доступ по умолчанию недоступен).

Таким образом, желаемая архитектура сети будет следующей: VCN с публичной и приватной подсетями, вычислительные ресурсы назначаются в приватную подсети. К сожалению, данная архитектура невозможна для Always Free аккаунтов (на январь 2022 г.). Дело в том, что Oracle установил нулевой лимит для использования NAT gateway'ев. Отсутствие NAT'а в сети приводит к тому, что ресурсы в приватных подсетях не имеют доступа в интернет.

По этой причине приходится использовать такую сетевую архитектуру: VCN с одной публичной подсетью для всех узлов, и каждый из них получает эфемерный публичный IP. Благодаря этому все узлы становятся доступными из интернета. Тем не менее, наша цель заключается в создании единой точки, из которой были бы доступны все приложения, развёрнутые в K8s кластере (в виде подов). Для достижения этого используем load balancer.

Балансировка нагрузки

В Oracle Cloud есть возможность создавать load balancer'ы двух видов. Первый работает на седьмом уровне OSI модели (и по факту является полноценным HTTP reverse proxy). Однако для его создания нам нужно выбрать shape, который определяет его пропускную способность. Для Always Free аккаунтов доступен только один load balancer на 10 Мбит/с.

Другой вид балансировщиков нагрузки называется Network Load Balancer. Этот тип работает на уровнях 3 и 4 OSI, и для балансировки в нём используются пары IP-порт. Но главная особенность таких балансировщиков заключается в том, что для них не специфицируется пропускная способность, и именно поэтому мы и будем его использовать в нашем кластере. Поместим load balancer в созданную публичную подсеть и назначаем ему зарезервированный публичный IP адрес.

Настройка load balancer'а заключается в создании следующих ресурсов:

  • Listener'ов, которые конфигурируют открытые для подключения порты;

  • Backend set'ов, которые представляют собой группы узлов, между которыми должна распределяться нагрузка (которая приходит на определённый порт);

  • Backend'ов для каждого backend set'а, которые являются ссылками на узлы.

В нашем кластере созданный Network Load Balancer будет работать на следующих TCP портах:

  • 80 – для HTTP траффика, который будет распределяться между worker'ами.

  • 443 – для HTTPS траффика для тех же worker узлов.

  • 6443 – для удалённого управления K8s кластером с помощью kubectl (например, для развёртывания новых приложений). Траффик с этого порта направляется на порт 6443 leader'а (порт для управления K8s control-plane'ом).

Наконец, сконфигурируем security правила для нашей публичной подсети. Нам необходимо открыть доступ в интернет для узлов (egress правило с маской 0.0.0.0/0), а также доступ из интернета для SSH, HTTP, HTTPS и kubectl траффика (ingress правила с маской 0.0.0.0/0).

Развёртывание K8s

Собственно развёртывание K8s кластера будем выполнять в полностью автоматическом режиме с помощью утилиты kubeadm.

В первую очередь, необходимо поднять control-plane. Чтобы поддержать автоматическое обнаружение worker'ами control-plane'а в кластере работает приватный DNS. Leader узел доступен внутри кластера по имени leader.public.vcn.oraclevcn.com. Помимо этого, перед инициализацией control-plane'а, мы генерируем discovery token, который будет использоваться и для control-plane'а (при вызове kubeadm init), и для worker'ов (при вызове kubeadm join).

Для того, чтобы control-plane имел возможность управлять агентами K8s'а на каждом узле (kubelet'ами) необходимо открыть TCP порт 10250. Помимо этого, в кластере используется flannel в качестве оверлейной сети, и для его работы необходимо открыть UDP порт 8472 (оба – ingress правила с маской 10.0.0.0/16).

После развёртывания базовой K8s инфраструктуры, мы добавим несколько полезных приложений. Во-первых, ingress-controller для роутинга по хостам и путям – в нашем кластере будем использовать ingress-nginx. Для него создадим K8s Service типа NodePort на портах 30080 и 30443 для HTTP и HTTPS траффика соответственно. Ingress controller является последним штрихом в архитектуре сети нашего кластера.

Далее, развернём приложение dashboard'а, и сделаем его доступным с помощью ingress controller'а. Dashboard будет доступен по адресу https://{cluster-public-ip}/dashboard.

Затем для поддержки HTTPS сертификатов установим cert-manager. Когда его создание завершено, создадим ресурс ClusterIssuer для поддержки LetsEncrypt. Здесь есть небольшая особенность, связанная с тем, что cert-manager'у необходимо время для завершения инициализации, и нет такого K8s API, с помощью которого мы бы об этом могли узнать. А создание ClusterIssuer'а завершается с загадочной ошибкой, если cert-manager не закончил свою инициализацию. Чтобы побороть эту проблему, будем пытаться создать ClusterIssuer до тех пор, пока это не удастся. Как правило, на это уходит около минуты.

Созданный ClusterIssuer работает в связке с ingress-controller'ом, но чтобы настоящий HTTPS сертификат был выпущен, необходим последний штрих.

Бонус: бесплатный публичный домен второго уровня

У регистратора Freenom мы можем бесплатно на год получить домен второго уровня (в зонах .tk. .ml, .ga, .cf, .gq). По истечению этого срока мы можем бесплатно же продлить его действие.

Когда домен зарегистрирован, мы можем его сконфигурировать, чтобы он указывал на зарезервированный ранее публичный IP load balancer'а. Для этого необходимо открыть страницу настройки DNS для купленного домена (Services - My Domains - Manage Domain - Manage Freenom DNS).

На скриншоте можно увидеть пример настройки: две записи (example.tk и cluster.example.tk) настроены на один и тот же публичный IP (pu.bl.ic.ip). Идея заключается в том, чтобы приложения, относящиеся к самому кластеру, были доступны под доменом cluster.example.tk, а все остальные приложения были доступны под доменом example.tk.

Когда у нас есть полноценный публичный домен, то мы можем открыть их в интернет с помощью K8s ресурса Ingress. Вот так, например, можно открыть dashboard:

Бесплатный сыр только в мышеловке, поэтому когда мы "покупаем" бесплатный домен, то гарантия, конечно же, не предоставляется. В моём случае я зарегистрировал домен в зоне .ga, и был неприятно удивлён, когда обнаружил, что мой домен (а также nameserver'ы зоны .ga) не резолвится из некоторых стран (конкретно, из Новой Зеландии, Сингапура, западного побережья США). Я написал в поддержку зоны .ga, и к счастью, через пару дней проблема разрешилась. Ответа на моё письмо я, естественно, не получил.

Такой проблемы с доменом в другой зоне не было.

a.ns.ga – такого быть НЕ должно

Именно так, пройдя через тернии, получилось развернуть ARM узлы, объединить их в сеть, установить на них K8s кластер и открыть к нему доступ через load balancer, – и всё это не выходя за пределы Always Free подписки.

Комментарии (9)


  1. Thisnickname2019
    31.01.2022 10:14

    У регистратора Freenom
    мы можем бесплатно на год получить домен второго уровня (в зонах .tk.
    .ml, .ga, .cf, .gq). По истечению этого срока мы можем бесплатно же
    продлить его действие.

    Оно вообще не рабочее. Поиск домена на главной не работает, я получал и 502 и 504 ошибки.

    Оракл может забанить, просто так без объяснения причин. В поддержке скажут это система вас забанила, мы ни при чём.

    Спасибо за статью.


  1. dvapelnik
    31.01.2022 11:28

    Как давно Вы успешно используете этот кластер?

    У меня был подобный негативный опыт: я создал always free tier, на нем два одногиговых интанса x86 и один arm с 24 Гб оперативной памяти. На последнем развернул там ноду k8s и использовал ее для ELK-стека и одного приложения, которое работало с API торговой сети не для коммерческих целей. Перешел на тарифный план Pay-as-you-go чтобы использовать минимальный бесплатный лимит и по истечению первых 30 дней мой аккаунт закрыли, ссылаясь на то, что были нарушены правила использования. Разбирательства со службой поддержки мне не смогли ответиь какой именно пункт был нарушен.


    1. egorshulga Автор
      31.01.2022 21:11

      Насколько я понимаю, при upgrade'е до Pay-as-You-Go у нас по-прежнему есть возможность использовать те же ресурсы, что и в Always Free. Отличие в том, что Always Free просто не даст использовать больше, а Pay-as-You-Go начнёт billing.

      В моём tenancy закончился месячный триал, и теперь у меня Always Free аккаунт. Compute resource я выделял уже после триала. Но да, месяц с тех пор ещё не прошёл, и мне нужно ещё последить за кластером и за аккаунтом


      1. dvapelnik
        02.02.2022 02:31

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

        бесплатный ресурс – это тот минимальный ресурс, за который не взымается плата, но Oracle расчитывает, что клиент будет использовать больше ресурса и будет платить. им невыгодно раздавать такой ресурс совсем бесплатно. догадываюсь, что система по какой-то своей логике автоматически закрывает аккаунты, которые не используют бесплатный лимит.

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

        я буду ждать как будет развиваться Ваша сага – отпишитесь, пожалуйста, в этой ветке


        1. egorshulga Автор
          02.02.2022 10:59

          Есть ещё одно point: мы как разработчики можем "подсесть" на Oracle Cloud для, например, своих личных проектов. Проинвестировать туда время, разобраться. А потом это может повлиять, например, на выбор облачного провайдера на настоящем проекте.

          Да, мне самому очень интересно, насколько живуч окажется кластер. Обязательно отвечу, когда появится новая информация (увы, снова приходится идти путём проб и ошибок, а то и просто ждать)


  1. AlexHighTower
    31.01.2022 12:54

    У регистратора Freenom мы можем бесплатно на год получить домен второго уровня (в зонах .tk. .ml, .ga, .cf, .gq).

    не знаю кому как, но уже несколько лет не даёт бесплатно зарегистрировать домен, всегда ошибка. пробовал с чистой машины создавать новый аккаунт и прописывать реальные данные, и чтоб ip со страной и городом совпадали — без результата
    но зато если тот же домен пробовать платно — вообще без проблем

    поддержка ответила пространно
    From time to time, we have to limit free domain registrations and put in place blocks.
    These blocks can be imposed for a variety of reasons including (but not limited to):
    — the country from which registrations originate;
    — the domain names themselves;
    — the IP addresses from which registrations originate;
    — the device from which registrations originate;
    — the use of measures (such as proxies and VPNs) to hide your true location from us;
    — a history of bad registrations in the account from which registrations originate.

    For reasons of security, we cannot go into the precise reasons for this block. We also cannot make any predictions on when you will be allowed to register new free domains.

    Please come back in a few days and try to register a domain again. If our systems still do not allow you to register new domains, you'll need to wait longer.

    Please do NOT register additional accounts or use any other accounts that you may already have, as this will lead to these accounts being banned, possibly indefinitely.


    вообщем надёжнее регать в другом месте…


    1. egorshulga Автор
      31.01.2022 21:03

      О как интересно. Похоже, мне повезло, что получилось зарегистрировать аж два домена. И, как и было в статье, тоже не без проблем


    1. YMakeev
      01.02.2022 09:19

      Зарегистрировал уже больше 10 доменных имён. Некоторым более 2х лет...

      Для тестовых целей очень годно.


    1. Higherous
      01.02.2022 11:08
      +1

      В аккаунте freenom,ОБЯЗАТЕЛЬНО должен быть указан такой же регион как айпи. Сам с этим сталкивался, поменял и все ок