Введение
Как пользователь 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 Servicepodinfo
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