Развертывание с помощью Kustomize, FluxCD и удаленных ресурсов


Введение

Как пользователь Kubernetes, я решил использовать доступный по умолчанию инструмент под названием Kustomize для управления моими манифестами и всеми изменениями, которые мне нужно сделать в них для каждой среды, которую я хочу развернуть. Для этого Kustomize является мощным решением, основанным на концепциях наследования (resources) и композиции (components).

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

Однако Kustomize предоставляет механизм использования элементов remote, как для resources, так и для components, используя git под капотом. Это решение идеально, потому что мы можем использовать любой репозиторий git в качестве yaml реестра для наших ресурсов и компонентов 🔥.

Но, минус в том, что FluxCD не поддерживает так хорошо, по многим веским причинам (особенно если ваши репозитории приватны)… В этой статье мы рассмотрим, как обойти это ограничение и использовать удаленные ресурсы и компоненты, способом FluxCD!

Конфигурация кластера и FluxCD

В этой статье я не буду подробно описывать конфигурацию кластера и FluxCD… потому что об этом уже есть много документации и постов в блогах!

Для этой статьи я настроил кластер с помощью Google Kubernetes Engine (aka GKE), используя эту документацию, и установил FluxCD, подключенный к репозиторию GitLab с помощью следующей команды (взятой из официальной документации).

$ flux bootstrap gitlab 
  --owner=davinkevin.fr/articles/flux-and-kustomize-remote-base 
  --repository=clusters 
  --branch=gke 
  --path=fluxcd
Войти в полноэкранный режим Выйдите из полноэкранного режима

ПРИМЕЧАНИЕ: Мне не нравится использовать ветку default, поэтому я решил создать ветку для этого кластера, так что если у меня будет другой кластер, мне просто понадобится другая ветка 😉. Это что-то вроде GitLab Flow для среды.

Таким образом, у меня есть полный кластер Kubernetes, готовый для GitOps, использующий репозиторий clusters в качестве источника истины. Каждая модификация, внесенная в этот репозиторий, будет автоматически развертываться FluxCD 🤩.

Репозиторий bases

Я создал еще один репозиторий git, посвященный ресурсам и компонентам. В нем хранится то, что мы обычно называем базой, поскольку она содержит общее ядро приложения, а также множество компонентов для включения некоторых дополнительных возможностей (на уровне инфраструктуры или приложения).

Этот репозиторий доступен на GitLab и не зависит от моей среды развертывания. Опять же, я размещаю здесь только голые определения моих приложений, мы можем сравнить это с реестром helm. Поскольку он управляется в git, я могу использовать для управления теги branch & 🚀.

ПРИМЕЧАНИЕ: Обычно такой репозиторий yaml автоматически заполняется только CI из других проектов.

Публикация базы PodInfo

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

.
├── README.md
└── podinfo
    └── base
        ├── components
        │   ├── hpa
        │   │   ├── hpa.yaml
        │   │   └── kustomization.yaml
        │   ├── ingress
        │   │   ├── ingress.yaml
        │   │   └── kustomization.yaml
        │   └── redis
        │       ├── kustomization.yaml
        │       ├── redis.conf
        │       └── redis.yaml
        ├── kustomization.yaml
        └── podinfo.yaml
Вход в полноэкранный режим Выход из полноэкранного режима

Core PodInfo

Эта часть является общей для всех потенциальных развертываний. Она содержит:

  • podinfo Kubernetes Service
  • podinfo Kubernetes Deployment

И больше ничего… если вам нужно развернуть любую другую часть приложения, вы должны использовать components 👇.

Компоненты

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

Здесь мы имеем:

Интересно отметить, что компоненты могут быть любого рода, hpa и ingress сосредоточены на инфраструктуре, когда redis является функцией приложения. Без этого компонента redis приложение способно работать, просто без системы кэширования. Этот компонент redis здесь для развертывания сервера redis (конечно 😅), но также для включения кэширования на уровне podinfo.

ПРИМЕЧАНИЕ: Если вы хотите получить лучшее описание этой компонентной функции, я советую вам открыть эту статью из официальной документации.

Итак, у нас есть полный, независимый от среды resource и components, зафиксированный в нашем репозитории base. Теперь пришло время использовать их!

Публикуем PodInfo в dev

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

  • Определим компоненты Я хочу включить
  • Определите доменное имя для определения ingress.
  • Определите необходимую конфигурацию tls для ingress.
  • Определите альтернативный реестр для изображения

Итак, чтобы сделать это, мне нужно иметь один (или несколько) kustomization.yaml для определения этого:

# <clusters-repo>/podinfo-dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: podinfo-dev

images:
  - name: podinfo
    newName: ghcr.io/stefanprodan/podinfo

resources:
  - ../base
  - ingress

components:
  - ../base/components/redis
Вход в полноэкранный режим Выход из полноэкранного режима

ПРИМЕЧАНИЕ: Модификация ingress находится в собственном файле, чтобы сохранить эту модификацию достаточно простой.

Но что это за папка ../base? В репозитории cluster вообще нет base. И вы правы… мы будем использовать функцию FluxCD, доступную во flux, чтобы включить репозиторий base в нужное место во время reconciliation. Для этого нам нужно определить несколько ресурсов flux.

podinfo-base flux-репозиторий

Во-первых, нам нужно представление нашего flux.GitRepository для bases, которое материализуется во flux с:

apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
  name: podinfo-base-dev
  namespace: flux-system
spec:
  interval: 5m
  ref:
    branch: podinfo
  url: ssh://git@gitlab.com/davinkevin.fr/articles/flux-and-kustomize-remote-base/bases
  secretRef:
    name: flux-system
Войти в полноэкранный режим Выйти из полноэкранного режима

ПРИМЕЧАНИЕ: Здесь я решил определить spec.ref.branch: podinfo, чтобы следить за каждым коммитом, сделанным в этой ветке. Это, для разработки, система непрерывного развертывания 🚀.

podinfo flux repository

Теперь нам нужно создать flux.GitRepository для манифестов в репозитории clusters и манифестов из репозитория bases, созданного в предыдущем шаге. Для этого мы воспользуемся функцией include из FluxCD:

apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
  name: podinfo-dev
  namespace: flux-system
spec:
  interval: 5m
  include:
    - repository:
        name: podinfo-base-dev
      fromPath: podinfo/base
      toPath: base
  ref:
    branch: gke
  url: ssh://git@gitlab.com/davinkevin.fr/articles/flux-and-kustomize-remote-base/clusters
  secretRef:
    name: flux-system
Вход в полноэкранный режим Выйти из полноэкранного режима

Важной частью является следующее:

spec:
  include:
    - repository:
        name: podinfo-base-dev # <1>
      fromPath: podinfo/base # <2>
      toPath: base # <3>
Войти в полноэкранный режим Выйти из полноэкранного режима

Это означает, что папка podinfo/base (2), ранее определенная в podinfo-base-dev flux.GitRepository (1) будет внедрена в путь base (3) текущего podinfo-dev flux. GitRepository во время согласования FluxCD… делая доступными все ресурсы и компоненты.

podinfo-dev flux Kustomization

Это стандартная flux.Kustomization, которую вы будете использовать в любом случае. Здесь просто используется составной flux.GitRepository из предыдущего шага в качестве источника (spec.sourceRef):

apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: Kustomization
metadata:
  name: podinfo-dev
  namespace: flux-system
spec:
  suspend: false
  interval: 10m0s
  path: podinfo-dev # file path in the <clusters> repository  
  prune: true
  sourceRef:
    kind: GitRepository
    namespace: flux-system
    name: podinfo-dev
  validation: client
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Если мы развернем все эти файлы (вы можете поместить их в один и тот же), вы увидите ваше приложение, развернутое FluxCD с предоставленной вами пользовательской конфигурацией.

❯ kubectl get all -n podinfo-dev
NAME                           READY   STATUS    RESTARTS   AGE
pod/redis-869ff7c78b-jjbbk     1/1     Running   0          103m
pod/podinfo-6dbf56d6d7-ctxxr   1/1     Running   0          103m

NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
service/podinfo   ClusterIP   10.43.115.207   <none>        9898/TCP,9999/TCP   103m
service/redis     ClusterIP   10.43.192.84    <none>        6379/TCP            103m

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/redis     1/1     1            1           103m
deployment.apps/podinfo   1/1     1            1           103m

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/redis-869ff7c78b     1         1         1       103m
replicaset.apps/podinfo-6dbf56d6d7   1         1         1       103m
Войти в полноэкранный режим Выход из полноэкранного режима

Публикация PodInfo в prod

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

Поскольку нам нужно что-то относительно стабильное, мы решили определить spec.ref.tag для конкретного тега в репозитории bases (вместо ветки podinfo).

apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
  name: podinfo-base-prod
  namespace: flux-system
spec:
  interval: 5m
  ref:
    tag: podinfo-1.0
  url: ssh://git@gitlab.com/davinkevin.fr/articles/flux-and-kustomize-remote-base/bases
  secretRef:
    name: flux-system
Вход в полноэкранный режим Выйти из полноэкранного режима

Все остальные flux.Kustomization и flux.GitRepository остались прежними.

Поскольку мы работаем на производстве, мы также хотим включить различные модули, здесь HorizontalPodAutoscaler. Поэтому у нас есть другой kustomization.yaml. Благодаря полному контролю над kustomization.yaml для каждого окружения, мы можем изменить его только в production 😍.

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

❯ kubectl get all -n podinfo-prod
NAME                           READY   STATUS    RESTARTS   AGE
pod/redis-869ff7c78b-lnll5     1/1     Running   0          113m
pod/podinfo-6dbf56d6d7-k8rjl   1/1     Running   0          113m
pod/podinfo-6dbf56d6d7-qldr8   1/1     Running   0          113m

NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
service/podinfo   ClusterIP   10.43.109.213   <none>        9898/TCP,9999/TCP   113m
service/redis     ClusterIP   10.43.252.54    <none>        6379/TCP            113m

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/redis     1/1     1            1           113m
deployment.apps/podinfo   2/2     2            2           113m

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/redis-869ff7c78b     1         1         1       113m
replicaset.apps/podinfo-6dbf56d6d7   2         2         2       113m

NAME                                          REFERENCE            TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
horizontalpodautoscaler.autoscaling/podinfo   Deployment/podinfo   4%/99%    2         4         2          113m
Войти в полноэкранный режим Выйти из полноэкранного режима

Заключение

Это было трудно, с большим количеством yaml, но мы достигли нашей первоначальной цели. Возможность публиковать голые манифесты в центральном месте и позволять другим командам/людям мгновенно использовать их со всеми функциями, доступными в Kustomize.
Затем мы можем пользоваться всеми возможностями модели GitOps с выделенным (yaml) реестром, как это уже есть у helm 😇.

В будущем нас ждут некоторые последующие улучшения, например, реестры OCI (анонсированные во FluxCD 0.32), которые заменят flux.GitRepository. Нам все еще нужно решить этот вопрос, чтобы иметь возможность использовать его со всеми функциями, предоставляемыми Kustomize.

В более отдаленном будущем какое-нибудь другое решение, например, porch, может стать хорошим кандидатом для упрощения нашей стратегии развертывания… но в настоящее время оно находится на стадии alpha.

Надеюсь, вам понравилась эта статья, вы можете найти все использованные ресурсы в GitLab, и вы можете воспроизвести это в своем собственном кластере! Если у вас есть вопросы, не стесняйтесь комментировать или пишите мне в twitter @davinkevin

Оцените статью
devanswers.ru
Добавить комментарий