- Подготовить облачную инфраструктуру на базе облачного провайдера AWS.
- Запустить и сконфигурировать Kubernetes кластер.
- Установить и настроить систему мониторинга.
- Настроить и автоматизировать сборку тестового приложения с использованием Docker-контейнеров.
- Настроить CI для автоматической сборки и тестирования.
- Настроить CD для автоматического развёртывания приложения.
Подготовлена конфигурация Terraform для развёртывания ресурсов в AWS. Все предварительные тесты проводились на собственном тестовом аккаунте AWS. Для работы используется такая версия Terraform:
$ (master)terraform --version
Terraform v1.1.6
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v3.74.3
В ходе работы Terraform, система разворачивает 3 шт ВМ с операционной системой Ubuntu 20.04. Созданы 2 workspace с названиями prod и stage.
$ terraform workspace list
* prod
stage
В пространстве stage формируются 3 ВМ типа "t2.micro", для prod - 3 ВМ типа "t3.small".
Репозиторий этой части работы находится по ссылке
Раннее был создан ЛК в Terraform Cloud при работе над домашним заданием 7.4. К несчастью, на момент работы над диломной работой, сервис Terraform Cloud стал недоступен для пользователей из РФ. Система сообщает "This content is not currently available in your region." Фактически работа с этим сервисом на его сайте стала возможна лишь через VPN.
Использование Terraform Cloud в качестве Backend также невозможно из-за региональной блокировки доступа. Наиболее простым и уже отработанным раннее в рамках домашней работы 7.4, было использование AWS S3 + DynamoDB для хранения состояния. Изначальный вариант был заменён на конфигурацию, с использованием именно этого бекенда. Помимо этого, для возможности работы с Terraform в принципе (инициализация бэкенда, получение модулей и т.п.) было решено развернуть сервер с VPN, как наиболее быстрый способ решения.
- Была добавлена папка с файлами, которая предварительно создаёт в облаке DynamoDB и корзину S3. После отработки, в системе появляются, нужные для работы удалённого бекенда, сущности в облаке.
- Запуск планирования и применение плана, приводит к созданию нужных ресурсов.
$ (master)terraform apply "myplan"
aws_dynamodb_table.dynamodb-terraform-lock: Creating...
aws_s3_bucket.netology-diplom-bucket: Creating...
aws_dynamodb_table.dynamodb-terraform-lock: Still creating... [10s elapsed]
aws_s3_bucket.netology-diplom-bucket: Still creating... [10s elapsed]
aws_dynamodb_table.dynamodb-terraform-lock: Creation complete after 10s [id=terraform-lock]
aws_s3_bucket.netology-diplom-bucket: Creation complete after 13s [id=netology-diplom-bucket]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
region = "us-east-1"
- В основной папке проекта проводим инициализацию бекенда, делаем планирование и убеждаемся, что всё срабатывает.
$ (master)terraform apply "myplan"
Acquiring state lock. This may take a few moments...
module.vpc.aws_subnet.public[0]: Creating...
aws_instance.diplom_instance[2]: Creating...
aws_instance.diplom_instance[1]: Creating...
aws_instance.diplom_instance[0]: Creating...
.....
Releasing state lock. This may take a few moments...
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.
Тестовые подключения к ВМ выполнились успешно. В качестве примера, такая конфигурация у одной из ВМ:
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.13.0-1017-aws x86_64)
$ free -m
total used free shared buff/cache available
Mem: 1939 144 1430 0 364 1643
Swap: 0 0 0
$ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
model name : Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
processor : 1
vendor_id : GenuineIntel
model name : Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
Такой конфигурации хватит для запуска control plane и для работы с подами с приложением.
В качестве инструмента развёртывания кластера, был избран уже опробованный раннее Kubspray. В настройках инвентаря были указаны внешние IP адреса серверов (нод), с учётом того факта, что сервера имеют внутренние IP адреса. После выполнения, система сообщает о результате:
PLAY RECAP **************************************************************************************************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node1 : ok=565 changed=124 unreachable=0 failed=0 skipped=1141 rescued=0 ignored=2
node2 : ok=369 changed=76 unreachable=0 failed=0 skipped=644 rescued=0 ignored=1
node3 : ok=369 changed=76 unreachable=0 failed=0 skipped=643 rescued=0 ignored=1
Для просмотра состояния кластера, выполнен вход на первую ноду (на ней находится control plane):
~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
node1 Ready control-plane,master 25m v1.21.3
node2 Ready <none> 24m v1.21.3
node3 Ready <none> 24m v1.21.3
Просматриваем состояние активных после инсталляции подов во всех неймспейсах:
root@node1:~# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-5b4d7b4594-gkpjs 1/1 Running 1 24m
kube-system calico-node-5fd9x 1/1 Running 0 25m
kube-system calico-node-9ts7d 1/1 Running 0 25m
kube-system calico-node-g88fs 1/1 Running 0 25m
kube-system coredns-8474476ff8-7wrjd 1/1 Running 0 22m
kube-system coredns-8474476ff8-g722v 1/1 Running 0 22m
kube-system dns-autoscaler-7df78bfcfb-dwgl7 1/1 Running 0 22m
kube-system kube-apiserver-node1 1/1 Running 0 27m
kube-system kube-controller-manager-node1 1/1 Running 0 27m
kube-system kube-proxy-5zd7h 1/1 Running 0 26m
kube-system kube-proxy-j2mt8 1/1 Running 0 26m
kube-system kube-proxy-lph28 1/1 Running 0 26m
kube-system kube-scheduler-node1 1/1 Running 0 27m
kube-system nginx-proxy-node2 1/1 Running 0 26m
kube-system nginx-proxy-node3 1/1 Running 0 26m
kube-system nodelocaldns-8t8zj 1/1 Running 0 22m
kube-system nodelocaldns-lql2n 1/1 Running 0 22m
kube-system nodelocaldns-zwb6m 1/1 Running 0 22m
В качестве тестового приложения используется статическая страница, которая обрабатывается сервером Nginx. Для работы с контейнеризованным приложением был выбран официальный образ приложения, причём версия на базе наименьшего по объёму Alpine.
- Git репозиторий с тестовым приложением и Dockerfile.
- Dockerhub регистр с собранным docker image.
- Для развёртывания системы мониторинга был пакет kube-prometheus. Для возможности обращаться к веб интерфейсу Grafana, в манифест сервиса был добавлен NodePort на порт 30000. Этот порт был раннее описан и открыт в конфигурации VPC в Terraform. Выполняем последовательно команды для создания всех необходимых ресурсов:
# kubectl create -f manifests/setup/
customresourcedefinition.apiextensions.k8s.io/alertmanagerconfigs.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/alertmanagers.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/podmonitors.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/probes.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/prometheuses.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/prometheusrules.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/servicemonitors.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/thanosrulers.monitoring.coreos.com created
*namespace/monitoring created
# kubectl create -f manifests/
Можно посмотреть, что создалось в системе:
# kubectl get pods -n monitoring
NAME READY STATUS RESTARTS AGE
alertmanager-main-0 2/2 Running 0 57s
alertmanager-main-1 2/2 Running 0 57s
alertmanager-main-2 2/2 Running 0 57s
blackbox-exporter-676d976865-7ccf4 3/3 Running 0 73s
grafana-6c4c6b8fb7-k6ggk 1/1 Running 0 73s
kube-state-metrics-5d6885d89-46hbt 3/3 Running 0 72s
node-exporter-25l26 2/2 Running 0 72s
node-exporter-62cm5 2/2 Running 0 72s
node-exporter-fr9hx 2/2 Running 0 72s
prometheus-adapter-6cf5d8bfcf-4hrl8 1/1 Running 0 72s
prometheus-adapter-6cf5d8bfcf-jgwk8 1/1 Running 0 72s
prometheus-k8s-0 2/2 Running 0 56s
prometheus-k8s-1 2/2 Running 0 56s
prometheus-operator-7f58778b57-c8wk7 2/2 Running 0 71s
# kubectl get svc -n monitoring
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager-main ClusterIP 10.233.41.206 <none> 9093/TCP,8080/TCP 100s
alertmanager-operated ClusterIP None <none> 9093/TCP,9094/TCP,9094/UDP 84s
blackbox-exporter ClusterIP 10.233.62.171 <none> 9115/TCP,19115/TCP 100s
grafana NodePort 10.233.19.163 <none> 3000:30000/TCP 100s
kube-state-metrics ClusterIP None <none> 8443/TCP,9443/TCP 99s
node-exporter ClusterIP None <none> 9100/TCP 99s
prometheus-adapter ClusterIP 10.233.32.41 <none> 443/TCP 99s
prometheus-k8s ClusterIP 10.233.55.195 <none> 9090/TCP,8080/TCP 99s
prometheus-operated ClusterIP None <none> 9090/TCP 83s
prometheus-operator ClusterIP None <none> 8443/TCP 99s
Видно, что существует сервис Grafana на нужном порту, который будет доступен на внешнем IP адресе.
- Git репозиторий с конфигурационными файлами для настройки Kubernetes.
- Http доступ к web интерфейсу grafana. (вход осуществляется под учётными данными admin:admin)
- Дашборды в grafana отображающие состояние Kubernetes кластера.
- Http доступ к тестовому приложению.
Цель:
Автоматическая сборка docker образа при коммите в репозиторий с тестовым приложением.
Автоматический деплой нового docker образа.
Для работы был избран облачный Gitlab CI, как удобный и проверенный инструмент.
Работа была разбита на этапы, в ходе которых было выполнено следующее:
- создание проекта в Gitlab и репозитория
- ознакомление с возможностями Gitlab CI по соединению и управлению кластерами Kubernetes. Был избран современный способ работы совместно с Gitlab агентом. Его установка делалась по официальной документации. Агент был авторизован для работы в этом проекте, для чего были внесены нужные настройки в его конфигурацию.
- прогон тестового пайплайна для проверки связки CI/CD системы с кластером в AWS. Для работы был выбран образ Docker, который содержит установленный kubectl. Нужно было добиться получения информации от кластера, которая показывает, что связь есть между Gitlab и развёрнутым кластером.
- создание первой части пайплайна в которой производится сборка образа из Dockerfile и публикация его в докерхабе. Для связки с докерхабом, был выпущен токен, по которому Gitlab CI производит там авторизацию, что даёт возможности публиковать образы. Далее была создана переменная которая содержит токен и её можно вызывать из пайплайна.
- доработка второй части пайплайна, в которой требуется выполнять установку приложения в уже в кластере Kubernetes. Для этой части была выбрана работа с helm. Чтобы успешно выполнять команду helm, а также и kubectl был использован образ. На базе контейнера из этого образа и выполняются последующие действия. Действия по авторизации в кластере и привилегии для работы возложены на агент Gitlab.
- подготовка чарта, который делает установку deployment в кластере при установке тега. При коммите в мастер ветку, выполняется только первая часть пайплайна (сборка и публикация образа в докерхабе).
Цели задания:
- Интерфейс ci/cd сервиса доступен по http.
- При любом коммите в репозиторий с тестовым приложением происходит сборка и отправка в регистр Docker образа.
- При создании тега в репозитории происходит деплой соответствующего Docker образа.
- Репозиторий с конфигурационными файлами Terraform и готовность продемонстировать создание всех рессурсов с нуля.
- Пример pull request с комментариями созданными atlantis'ом или снимки экрана из Terraform Cloud. - для этой задачи используется связка AWS S3 backet + AWS DynamoDB по причине блокировки Terraform и Terraform Cloud в РФ
- Репозиторий с конфигурацией ansible, если был выбран способ создания Kubernetes кластера при помощи ansible.
- Репозиторий с Dockerfile тестового приложения и ссылка на собранный docker image.
- Репозиторий с конфигурацией Kubernetes кластера.
- Ссылка на тестовое приложение и веб интерфейс Grafana с данными доступа (admin:admin).