Используйте Terraform для развертывания высокодоступного кластера K3s с использованием спотовых инстансов AWS EC2.

Обратите внимание: в этом руководстве используются ресурсы AWS, которые за пределами уровня бесплатного пользования AWS, поэтому будьте осторожны!

Введение

K3s — это сертифицированный дистрибутив Kubernetes с высокой доступностью, предназначенный для производственных рабочих нагрузок в автоматических, ограниченных по ресурсам, удаленных местах или внутри устройств IoT.

С K3s вы можете развернуть производственную среду всего за несколько минут.

Основные особенности K3s:

  • Упакован как один двоичный файл.
  • Облегченный сервер хранения на основе sqlite3 в качестве механизма хранения по умолчанию. etcd3, MySQL, Postgres также все еще доступны.
  • Обернутый в простой лаунчер, который справляется со многими сложностями TLS и опций.
  • Безопасность по умолчанию с разумными значениями по умолчанию для облегченных сред.
  • Были добавлены простые, но мощные функции «с батарейным питанием», такие как: локальный поставщик хранилища, балансировщик нагрузки службы, контроллер Helm и входной контроллер Traefik.
  • Работа всех компонентов плоскости управления Kubernetes инкапсулирована в один двоичный файл и процесс. Это позволяет K3 автоматизировать и управлять сложными кластерными операциями, такими как распространение сертификатов.
  • Внешние зависимости сведены к минимуму (требуется только современное ядро ​​и монтирование cgroup).

Пакеты K3s требуют зависимостей, в том числе:

  • контейнерd
  • Фланель
  • CoreDNS
  • CNI
  • Хост-утилиты (iptables, socat и т. д.)
  • Входной контроллер (traefik)
  • Встроенный балансировщик нагрузки службы
  • Встроенный контроллер сетевой политики

Требования

Для этого урока вам нужно:

  • Terraform: Terraform — это инфраструктура с открытым исходным кодом как программный инструмент, который обеспечивает согласованный рабочий процесс CLI для управления сотнями облачных сервисов. Terraform кодирует облачные API в декларативные файлы конфигурации.
  • Учетная запись Amazon AWS: учетная запись Amazon AWS с включенным выставлением счетов.
  • kubectl: инструмент командной строки Kubernetes (необязательно)
  • aws cli: инструмент командной строки AWS (необязательно)

Структура проекта

Первый шаг — клонировать этот репозиторий.

git clone https://github.com/garutilorenzo/k3s-aws-terraform-cluster.git

Структура выглядит следующим образом:

«Волшебные» части репозитория — это файлы .sh в каталоге файлов.

Эти файлы автоматически установят и настроят наш кластер K3s, давайте взглянем на k3s-install-server.sh.

Первая часть скрипта устанавливает двоичный файл распаковки и обновляет нашу систему, затем скрипт устанавливает инструмент AWS CLI.

Затем скрипт устанавливает некоторые переменные:

  • Частный IP-адрес экземпляра EC2
  • Фланелевой интерфейс машины (если экземпляр EC2 имеет более одного интерфейса, мы получаем интерфейс по умолчанию как фланельный интерфейс)
  • Создайте идентификатор поставщика (необходим для инструмента автомасштабирования кластера).
  • Запустите первый экземпляр k3s-сервера
  • Получить идентификатор экземпляра

Теперь волшебная часть: скрипт проверяет, является ли этот экземпляр самым первым запущенным экземпляром k3s-сервера. В этом случае скрипт запускает «инициализацию кластера», так как в данный момент кластера нет.

Если инстанс не является первым запущенным инстансом k3-serverа, он присоединяется к кластеру.

После установки скрипт ждет, пока станет доступна команда kubectl, и получит ответ от сервера kube-api.

Последним шагом является установка обработчика завершения узла, поскольку мы работаем на спотовых инстансах EC2. Дополнительные сведения см. в разделе «Ресурс кластера развернут» выше.

k3s-install-agent.sh следует той же логике, но для «инициализации кластера» нет никакой логики, поскольку экземпляры запускаются как агент.

Оба k3s-install-server.sh и k3s-install-agent.sh отображаются при создании шаблона запуска. Затем эти файлы используются в качестве пользовательских данных для всех будущих экземпляров EC2, которые будут запущены. Подробнее см. здесь.

Другой основной частью репозитория является файл vars.tf, подробности описаны выше в разделе «Настройка среды».

Все остальные файлы используют Terraform AWS api, подробнее смотрите в документации.

Настройка среды

Если вы впервые используете Terraform, вам необходимо создать новый ключ доступа для использования с Terraform. Поскольку первоначальная настройка Terraform выходит за рамки этого руководства, вы можете выполнить шаг Предварительные требования по этой ссылке.

Получив ключ доступа, создайте в корне только что загруженного репозитория файл с именем terraform.tfvars. Файл будет выглядеть так:

AWS_ACCESS_KEY = "xxxxxxxxxxxxxxxxx"
AWS_SECRET_KEY = "xxxxxxxxxxxxxxxxx"

В файле vars.tf измените следующие переменные:

  • AWS_REGION, установите правильный регион AWS в соответствии с вашими потребностями.
  • PATH_TO_PUBLIC_KEY и PATH_TO_PRIVATE_KEY, эти переменные должны указывать на ваш открытый ключ ssh и ваш закрытый ключ ssh
  • vpc_id, установите свой vpc-id. Вы можете найти свой vpc_id в консоли AWS (пример: vpc-xxxxx)
  • vpc_subnets задайте список ваших подсетей VPC. Вы можете найти список своих подсетей vpc в консоли AWS (пример: subnet-xxxxxx)
  • vpc_subnet_cidr, установите cidr вашей подсети vcp. Вы можете найти CIDR подсети VPC в консоли AWS (пример: 172.31.0.0/16).
  • my_public_ip_cidr, ваш общедоступный IP-адрес в формате cidr (пример: 195.102.xxx.xxx/32)

Вы также можете изменить эти необязательные переменные:

  • k3s_token, токен вашего кластера K3s
  • cluster_name, имя вашего кластера K3s
  • AMIS, установите идентификатор amis, который вы будете использовать (обратите внимание, что это руководство было протестировано с использованием Ubuntu 20.04)

Вам необходимо вручную создать роль AWS IAM с именем «AWSEC2ReadOnlyAccess». Вы можете использовать собственное имя для этой роли, затем имя должно быть установлено в vars.tf в переменной instance_profile_name.

Роль исполняют:

  • AmazonEC2ReadOnlyAccess — это политика, управляемая AWS.
  • Пользовательская встроенная политика для автомасштабирования кластера (необязательно)

Встроенная политика выглядит следующим образом (в формате JSON):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "autoscaling:DescribeAutoScalingGroups",
                "autoscaling:DescribeAutoScalingInstances",
                "autoscaling:DescribeLaunchConfigurations",
                "autoscaling:SetDesiredCapacity",
                "autoscaling:TerminateInstanceInAutoScalingGroup",
                "autoscaling:DescribeTags",
                "ec2:DescribeLaunchTemplateVersions"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

Более подробную информацию о политике автомасштабирования кластера вы можете найти здесь. Полная документация по автомасштабированию кластера доступна здесь.

Примечания по настройке K3s

В этом руководстве высокая доступность кластера K3s обеспечивается с помощью встроенной базы данных. Подробнее здесь

Окончательный обзор инфраструктуры

Окончательную инфраструктуру сделают:

  • Две группы автомасштабирования: одна группа автомасштабирования для серверных узлов с именем «k3s_servers» и одна группа автомасштабирования для рабочих узлов с именем «k3s_workers».
  • Один внутренний балансировщик нагрузки, который будет направлять трафик на серверы K3s.
  • Одна целевая группа, которая будет проверять работоспособность нашего сервера K3s на порту 6433.

Другие ресурсы, созданные terraform:

  • Два шаблона запуска (один для серверов и один для рабочих), используемые группами автомасштабирования.
  • Пара ключей ssh, связанная с каждым экземпляром EC2.

При такой настройке будет создана группа безопасности, которая позволит:

  • Входящий трафик только с вашего публичного IP-адреса на порт 22 (ssh)
  • Входящий трафик внутри подсети VPC на порт 6443 (сервер kube-api)
  • Исходящий трафик в интернет

Примечания о группе автомасштабирования:

  • Каждая группа автомасштабирования будет состоять из 3 инстансов EC2.
  • Автомасштабирование настроено на использование комбинации спотовых инстансов и инстансов по запросу.
  • Общее количество инстансов по требованию составляет 20%, поэтому, например, если мы запустим в общей сложности 10 инстансов, 2 инстанса будут инстансами по запросу.
  • Группа автоматического масштабирования настроена для максимального успеха спотового запроса с использованием различных типов экземпляров EC2 (см. Используемый экземпляр выше).

Вы можете изменить этот параметр, изменив значение on_demand_percentage_above_base_capacity в asg.tf. Вы можете потребовать, чтобы все EC2 запускались с использованием инстансов по требованию, установив on_demand_percentage_above_base_capacity на 100. Подробнее читайте здесь.

Вот схема нашей инфраструктуры:

Примечание. на этой диаграмме только две зоны доступности, в нашей настройке мы развернем нашу инфраструктуру в трех зонах доступности. Количество зон доступности зависит от того, в какой зоне вы развертываете стек.

Используемые экземпляры

В этом руководстве используются следующие типы экземпляров:

  • t3.large (по умолчанию), определенный в файле launchtemplate.tf

Другие типы инстансов EC2 определены/переопределены в файле asg.tf, а именно:

  • t3.large, как по умолчанию
  • т2.большой
  • м4.большой
  • t3a.большой

С этими настройками вероятность того, что наш запрос спотового инстанса будет выполнен, выше. Также очень важным параметром для проверки является стратегия распределения. В этих конфигурациях определяется как «оптимизированный по емкости» в asg.tf.

Вы можете изменить тип используемого экземпляра, отредактировав asg.tf и launchtemplate.tf.

Очень важное примечание: поскольку мы развертываем кластер Kubernetes, очень важно, чтобы все экземпляры имели одинаковый объем памяти (ОЗУ) и одинаковое количество ЦП!

Развертывать

Сначала нам нужно загрузить файлы провайдера Terraform.

terraform init

Теперь мы готовы развернуть нашу инфраструктуру. Сначала мы просим terraform спланировать выполнение с помощью:

terraform plan

Если все работает нормально, вывод должен быть примерно таким:

...
      + name                   = "allow-strict"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags                   = {
          + "Name" = "allow-strict"
        }
      + tags_all               = {
          + "Name" = "allow-strict"
        }
      + vpc_id                 = "vpc-xxxx"
    }

Plan: 10 to add, 0 to change, 0 to destroy.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

Теперь мы можем развернуть наши ресурсы с помощью:

terraform apply

Примерно через пять минут наша инфраструктура будет готова. Теперь вы можете подключиться по ssh к одному мастеру (вы можете найти IPS в консоли AWS или использовать командную строку AWS, чтобы найти IPS).

Если у вас установлен интерфейс командной строки AWS, вы можете найти IPS главных узлов с помощью:

aws ec2 describe-instances --filters Name=tag-value,Values=k3s-server Name=instance-state-name,Values=running --query "Reservations[*].Instances[*].[PublicIpAddress, Tags[?Key=='Name'].Value|[0]]"

На одном главном узле вы можете проверить состояние кластера с помощью:

kubectl get nodes

Примечание. После подготовки экземпляров может пройти до пяти минут, прежде чем станет доступна команда kubectl.

Совет. Чтобы проверить состояние установки K3s, проверьте файл /var/log/cloud-init-output.log в каталоге /var/log.

Ресурс кластера развернут

В этой настройке на каждом узле кластера будет автоматически установлен Node Termination Handler. Подробнее читайте здесь. Если по какой-то причине обработчик завершения узла вам не нужен, вы можете отредактировать k3s-install-server.sh и закомментировать строки с 40 по 44.

Дополнительные ресурсы кластера

Вы можете развернуть инструмент автомасштабирования кластера, подробнее здесь. Чтобы развернуть средство автомасштабирования кластера, выполните следующие действия.

wget https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml

Отредактируйте cluster-autoscaler-autodiscover.yaml и измените команду развертывания cluster-autoscaler. Команда следующая:

command:
            - ./cluster-autoscaler
            - --v=4
            - --stderrthreshold=info
            - --cloud-provider=aws
            - --skip-nodes-with-local-storage=false
            - --skip-nodes-with-system-pods=false
            - --balance-similar-node-groups
            - --expander=random
            - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/k3s-cluster

Нам также нужно отредактировать том ssl-certs. Обновленный том будет:

volumes:
        - name: ssl-certs
          hostPath:
            path: "/etc/ssl/certs/ca-certificates.crt"

Примечание. путь к сертификату может меняться от дистрибутива к дистрибутиву, поэтому настройте значение в соответствии с вашими потребностями.

Теперь мы можем развернуть автомасштабирование кластера с помощью:

kubectl apply -f cluster-autoscaler-autodiscover.yaml

Очистить

Не забудьте очистить все ранее созданные ресурсы, когда закончите! Нам не нужны сюрпризы от команды биллинга AWS:

terraform destroy

Вывод

И вот оно! Я надеюсь, что вы нашли этот урок полезным. Если это так, обязательно дайте мне знать ваши мысли в комментариях. Спасибо за чтение.

Дополнительные материалы на plainenglish.io