paint-brush
Практический курс CI/CD: простой, но функциональный рабочий процесс непрерывного развертывания [Часть 2]к@j04n
515 чтения
515 чтения

Практический курс CI/CD: простой, но функциональный рабочий процесс непрерывного развертывания [Часть 2]

к Joan Flotats14m2023/10/10
Read on Terminal Reader

Слишком долго; Читать

Развертывания вручную не подвержены ошибкам. Более того, они состоят из множества повторяющихся и сложных задач. В этой статье рассматривается автоматизация процессов развертывания для преобразования их в процессы непрерывного развертывания с использованием FluxCD, Flagger и Grafana.
featured image - Практический курс CI/CD: простой, но функциональный рабочий процесс непрерывного развертывания [Часть 2]
Joan Flotats HackerNoon profile picture
0-item
1-item


Развертывания вручную не подвержены ошибкам. Более того, они состоят из множества повторяющихся и сложных задач. Команды разработчиков боятся сложности развертывания новой версии приложения и головной боли, которую это приносит. Иногда для развертывания приложения требуются продвинутые навыки работы с платформой. Отладка проблем развертывания — утомительный процесс.


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


В этой статье рассматривается автоматизация процессов развертывания для преобразования их в процессы непрерывного развертывания с помощью FluxCD , Flagger и Grafana .


Прочтите первую статью, чтобы узнать больше о непрерывной доставке приложения:

Практический курс CI/CD: простой, но функциональный рабочий процесс непрерывной интеграции [Часть 1] .



Введение

Используйте KinD и Terraform для настройки кластера Kubernetes. Прежде всего создайте кластер и экспортируйте конфигурацию Kubernetes, чтобы установить поставщика Kubernetes:


 $ kind create cluster --name develop $ kind export kubeconfig --name develop --kubeconfig kubeconfig


Создайте новый репозиторий GitHub и токен разработчика с разрешениями репозитория. Terrafom требует его для настройки FluxCD. Инициализируйте Terraform и примените изменения:


 $ terraform init $ terraform apply -var="github_owner=owner_name" -var="github_repository=repo_name" # Introduce your GitHub token


Как только Terraform завершит процесс установки, у вас должен быть запущен FluxCD в вашем кластере Kind и новая папка с именем кластер в вашем репозитории.


Терраформировать

Terraform устанавливает MetalLB и настраивает диапазон IP-адресов. Подробнее о настройке MetalLB вы можете прочитать в первой части статьи :


 resource "helm_release" "metallb" { name = "metallb" repository = "https://metallb.github.io/metallb" chart = "metallb" } data "docker_network" "kind" { name = "kind" } resource "kubectl_manifest" "kind-address-pool" { yaml_body = yamlencode({ "apiVersion" : "metallb.io/v1beta1", "kind" : "IPAddressPool", "metadata" : { "name" : "kind-address-pool" }, "spec" : { "addresses" : [replace(tolist(data.docker_network.kind.ipam_config)[0].subnet, ".0.0/16", ".255.0/24")] } }) depends_on = [helm_release.metallb] } resource "kubectl_manifest" "kind-advertisement" { yaml_body = <<YAML apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: kind-advertisement YAML depends_on = [helm_release.metallb] }


Затем он устанавливает FLuxCD Helm Chart и настраивает репозиторий GitHub для использования FluxCD:


 resource "helm_release" "flux" { repository = "https://fluxcd-community.github.io/helm-charts" chart = "flux2" name = "flux2" namespace = "flux-system" create_namespace = true version = "2.9.2" } resource "tls_private_key" "flux" { depends_on = [helm_release.flux] algorithm = "ECDSA" ecdsa_curve = "P256" } resource "github_repository_deploy_key" "flux" { depends_on = [tls_private_key.flux] title = "Flux" repository = var.github_repository key = tls_private_key.flux.public_key_openssh read_only = "false" } resource "flux_bootstrap_git" "this" { depends_on = [github_repository_deploy_key.flux] path = "clusters/develop" }


Предложения по хукам перед фиксацией:

  1. Терраформ ( https://github.com/antonbabенко/pre-commit-terraform ):
    • TFSec: статический анализ Terraform для выявления потенциальных неправильных конфигураций.
    • TFLint: средство проверки статического формата для Terraform.
  2. Обнаружение секретов ( https://github.com/Yelp/detect-secrets ): предотвращение попадания новых секретов в базу кода.


FluxCD

FluxCD — это инструмент GitOps, позволяющий поддерживать в кластере Kubernetes последние изменения системы контроля версий (например, репозитории Git). Flux автоматизирует развертывание нового кода.


Как только Flux заработает в кластере, давайте посмотрим, как он работает. Мы развернем ingress-nginx в качестве входного провайдера. Flux не обеспечивает соблюдение структуры папок проекта. Вы можете настроить его по своему желанию или следовать предпочитаемому стандарту.


Создайте папку с именем base внутри папки с именеминфраструктура . Базовая папка содержит базовую конфигурацию инфраструктуры для всех ваших кластеров. Затем создайте папку с именем ingress-nginx . Используйте имя пространства имен в качестве имени папки.


 --- apiVersion: v1 kind: Namespace metadata: name: ingress-ngnix --- apiVersion: source.toolkit.fluxcd.io/v1beta1 kind: HelmRepository metadata: name: ingress-nginx spec: interval: 2h url: https://kubernetes.github.io/ingress-nginx --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: ingress-nginx spec: interval: 15m chart: spec: chart: ingress-nginx version: 4.7.1 sourceRef: kind: HelmRepository name: ingress-nginx interval: 15m --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: ingress-ngnix resources: - namespace.yaml - helmrepository.yaml - helmrelease.yaml


Используйте несколько файлов для определения ваших объектов: helmrelease.yaml , helmrepository.yaml , namespace.yaml , kustomization.yaml и т. д.


Настройка считывает и обрабатывает ресурсы для их применения. И последнее, но не менее важное: вам необходимо создать объект настройки для синхронизации конфигурации вашего кластера. Создайте файл YAML с именеминфраструктура.yaml внутри папкикластер /имя_кластера :


 --- apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: infra-base namespace: flux-system spec: interval: 1h retryInterval: 1m timeout: 5m sourceRef: kind: GitRepository name: flux-system path: ./infrastructure/base prune: true wait: true


После фиксации и отправки изменений в репозиторий Flux согласует состояние кластера для установки Helm Chart ingress-nginx.


Флаггер

Flagger — это оператор Kubernetes, который постепенно доставляет ваше приложение с помощью синего/зеленого развертывания, канареечного выпуска или A/B-тестирования.


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


Создайте новую папку, используя имя вашего кластера, внутри папки инфраструктуры . Затем создайте файл с именем i nfrastructure.yaml в вашем кластере/имя_кластера :


 --- apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: infra-cluster-name namespace: flux-system spec: dependsOn: - name: infra-base interval: 1h retryInterval: 1m timeout: 5m sourceRef: kind: GitRepository name: flux-system path: ./infrastructure/cluster_name prune: true


FluxCD синхронизирует состояние кластера после применения инфрабазовой настройки. Установите Flagger, создав следующий файл YAML в папке Infrastructure/cluster_name/flagger-system :


 --- apiVersion: v1 kind: Namespace metadata: name: flagger-system --- apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: HelmRepository metadata: name: flagger spec: interval: 1h url: https://flagger.app --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: flagger spec: interval: 1h install: crds: CreateReplace upgrade: crds: CreateReplace chart: spec: chart: flagger version: 1.xx interval: 6h sourceRef: kind: HelmRepository name: flagger --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: flagger-loadtester spec: interval: 1h chart: spec: chart: loadtester version: 0.xx interval: 6h sourceRef: kind: HelmRepository name: flagger --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: flagger-system resources: - namespace.yaml - helmrepository.yaml - helmrelease.yaml


Непрерывное развертывание

Чтобы создать конвейер непрерывного развертывания приложения Podinfo , создайте установочный YAML-файл в папке apps/cluster_name/podinfo *:*.


 --- apiVersion: v1 kind: Namespace metadata: name: podinfo --- apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: HelmRepository metadata: name: podinfo spec: interval: 5m url: https://stefanprodan.github.io/podinfo --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: podinfo spec: releaseName: podinfo chart: spec: chart: podinfo version: 6.5.0 sourceRef: kind: HelmRepository name: podinfo interval: 50m install: remediation: retries: 3 values: ingress: enabled: true className: nginx hpa: enabled: true --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: podinfo resources: - namespace.yaml - helmrepository.yaml - helmrelease.yaml


Вы можете использовать скрипт Python update hosts для обновления хостов локальной среды, как описано в первой части статьи .


Затем создайте файл настройки в папке «кластер/имя_кластера» , чтобы синхронизировать ваши приложения:


 --- apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: apps namespace: flux-system spec: interval: 10m0s dependsOn: - name: infra-cluster-name sourceRef: kind: GitRepository name: flux-system path: ./apps/cluster_name prune: true wait: true timeout: 5m0s


Далее мы можем настроить FluxCD для автоматического обновления версии Helm Chart образа Podinfo. Чтобы настроить автоматическое обновление образа, нам необходимо создать репозиторий изображений для сканирования новых тегов изображений, политику обновления изображений для определения шаблона версии для обновления и автоматическое обновление образа для настройки репозитория для отправки изменений.


 --- apiVersion: image.toolkit.fluxcd.io/v1beta2 kind: ImageRepository metadata: name: podinfo-chart spec: image: ghcr.io/stefanprodan/charts/podinfo interval: 5m --- apiVersion: image.toolkit.fluxcd.io/v1beta2 kind: ImagePolicy metadata: name: podinfo-chart spec: imageRepositoryRef: name: podinfo-chart policy: semver: range: 6.xx --- apiVersion: image.toolkit.fluxcd.io/v1beta1 kind: ImageUpdateAutomation metadata: name: podinfo-chart spec: interval: 30m sourceRef: kind: GitRepository name: flux-system namespace: flux-system git: checkout: ref: branch: main commit: author: email: [email protected] name: fluxcdbot messageTemplate: 'chore(develop): update podinfo chart to {{range .Updated.Images}}{{println .}}{{end}}' push: branch: main update: path: ./apps/cluster_name/podinfo strategy: Setters --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: podinfo resources: [...] - imagepolicy.yaml - imagerepository.yaml - imageautoupdate.yaml


Наконец, примените политику обновления изображения к изображению или тегу, который вы хотите обновить:


 apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: podinfo spec: releaseName: podinfo chart: spec: chart: podinfo version: 6.5.0 # {"$imagepolicy": "podinfo:podinfo-chart:tag"} sourceRef: kind: HelmRepository name: podinfo interval: 50m install: remediation: retries: 3


Всякий раз, когда у Podinfo Chart появляется новая версия в диапазоне 6.xx, FluxCD отправляет фиксацию в репозиторий, обновляя текущую версию более новой.


FluxCD. https://fluxcd.io/flux/comComponents/image


Канарский релиз

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

Flagger постепенно доставляет новую версию приложения определенной группе пользователей и отслеживает состояние приложения. Он создает новое развертывание для новых версий приложения и постепенно перенаправляет входящий трафик в новое развертывание. Это будет способствовать развертыванию canary после успешного анализа показателей. В случае сбоя Flagger удаляет новое развертывание и восстанавливает поток трафика к старому развертыванию. Этот процесс делает вид, что обнаруживает дефекты, проблемы и ошибки перед доставкой приложения всем пользователям.



Флаггер. https://docs.flagger.app/tutorials/nginx-progressive-delivery


Сначала создайте шаблон метрики, чтобы сообщить Flagger, какой статус у приложения. Мы используем Prometheus для измерения вероятности успеха запроса:


 --- apiVersion: flagger.app/v1beta1 kind: MetricTemplate metadata: name: podinfo-request-success-rate spec: provider: type: prometheus address: http://loki-stack-prometheus-server.loki-stack:80 query: | 100 - sum( rate( http_requests_total{ app_kubernetes_io_name="podinfo", namespace="{{ namespace }}", status!~"5.*" }[{{ interval }}] ) ) / sum( rate( http_requests_total{ app_kubernetes_io_name="podinfo", namespace="{{ namespace }}", }[{{ interval }}] ) ) * 100 --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: podinfo resources: [...] - metrictemplate.yaml


Затем определите процесс выпуска Canary. Мы используем nginx в качестве провайдера для формирования входящего трафика. Flagger предлагает множество способов и инструментов для настройки ваших выпусков.


 --- apiVersion: flagger.app/v1beta1 kind: Canary metadata: name: podinfo spec: provider: nginx targetRef: apiVersion: apps/v1 kind: Deployment name: podinfo ingressRef: apiVersion: networking.k8s.io/v1 kind: Ingress name: podinfo autoscalerRef: apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler name: podinfo progressDeadlineSeconds: 60 service: port: 9898 targetPort: 9898 analysis: interval: 10s threshold: 10 maxWeight: 50 stepWeight: 5 metrics: - name: podinfo-request-success-rate thresholdRange: min: 99 interval: 1m webhooks: - name: acceptance-test type: pre-rollout url: http://flagger-loadtester.flagger-system/ timeout: 30s metadata: type: bash cmd: curl -sd 'test' http://podinfo-canary.podinfo:9898/token | grep token - name: load-test url: http://flagger-loadtester.flagger-system/ timeout: 5s metadata: cmd: hey -z 1m -q 10 -c 2 http://podinfo-canary.podinfo:9898/healthz --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: podinfo resources: [...] - canary.yaml


Флаггеру требуются ссылки на ваше развертывание, вход и автомасштабирование модулей. Всякий раз, когда Flagger обнаруживает новую версию, он масштабирует развертывание, создает основной и дополнительный сервисы и настраивает nginx для отправки входящего трафика соответствующему сервису. Используйте свойства maxWeight и StepWeight, чтобы настроить максимальный процент перенаправления трафика и процент добавочного шага.

Выполните нагрузочное тестирование вашего приложения с помощью перехватчиков Flagger. Имеет несколько крючков. Перехватчики приема проверяют готовность к развертыванию canary, а перехватчик нагрузочного теста генерирует постоянный входящий трафик.

Флаггер будет отслеживать статус выпуска Canary, используя заранее определенную метрику успеха, чтобы принять решение о продвижении развертывания Canary. Флаггер ожидает, что 99% запросов будут успешными для продвижения канареечного развертывания. Используйте свойство порога, чтобы настроить максимальное количество неудачных проверок метрики перед откатом.


Мониторинг

Используйте стек Loki для мониторинга состояния ресурсов кластера с помощью Grafana + Loki + Prometheus. Установите стек Loki, создав следующий файл YAML в папке Infrastructure/имя_кластера/loki-stack :


 --- apiVersion: v1 kind: Namespace metadata: name: loki-stack --- apiVersion: source.toolkit.fluxcd.io/v1beta1 kind: HelmRepository metadata: name: grafana spec: interval: 2h url: https://grafana.github.io/helm-charts --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: loki-stack spec: interval: 1h chart: spec: chart: loki-stack version: v2.9.11 sourceRef: kind: HelmRepository name: grafana interval: 1h values: grafana: enabled: true ingress: enabled: true annotations: kubernetes.io/ingress.class: nginx hosts: - grafana.local prometheus: enabled: true nodeExporter: enabled: true --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: loki-stack resources: - namespace.yaml - helmrepository.yaml - helmrelease.yaml


Установка стека Loki позволяет Grafana Ingress получать доступ к Grafana, Prometheus — для сбора показателей вашей среды, а Node Exporter — для экспорта показателей вашего узла.


Вы можете использовать скрипт Python update hosts для обновления хостов локальной среды, как описано в первой части статьи.


Войдите в Grafana, используя имя пользователя и пароль администратора. Вы можете определить пароль администратора, используя установочные значения. По умолчанию Chart создает секрет Kubernetes для хранения случайного пароля. Опишите секрет, как получить значение пароля в формате Base64 и расшифровать его.


Вы можете импортировать свою любимую панель мониторинга, используя ее идентификатор или скопировав необработанный JSON:


Grafana - Панель управления Prometheus K8s


Grafana - Панель инструментов Prometheus FluxCD


Графана - Журналы Локи


Заключение

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


FluxCD и Flagger предлагают множество функций для непрерывного тестирования, развертывания и мониторинга состояния вашего приложения. В этой статье используются некоторые из них, но мы не увидели веб-перехватчиков и функций уведомлений. Используйте функции уведомлений, чтобы узнать, когда развертывание завершилось неудачно, или функцию веб-перехватчиков, чтобы перенести развертывание в новую среду или запустить тесты для новых версий. Интегрируйте FluxCD вместе с другими инструментами, чтобы обогатить ваш конвейер развертывания.

Избегайте развертываний вручную. Они сложны и не подвержены ошибкам. Поощряйте команды разработчиков поддерживать свои приложения, что упрощает процесс развертывания. Автоматическое развертывание сокращает время выполнения заказа, цикл обратной связи и общие затраты. Разработчики могут сосредоточиться на том, что действительно важно.