Используйте 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