GitLab: компоненты, архитектура, инфраструктура и запуск из Helm-чарта в Minikube

Автор: | 02/02/2023
 

Так как GitLab недавно изменил политику предоставления Free-доступа, и теперь по Free подписке будет доступно только 5 пользователей, то решили мы переезжать на self-hosted версию.

Вообще с лицензией у них интересно: цена зависит от количества пользователей, купить можно минимум на год, и после покупки уменьшить количество пользователей в лицензии нельзя (но можно увеличить).

Крутить будем в Kubernetes, и вопросов перед запуском вагон и тележка, тем более раньше GitLab вообще не особо пользовался.

Деплоить GitLab будем через ArgoCD, запускать будем в AWS Elastic Kubernetes Service, для object store используем AWS S3. Но об этом всё потом, а для начала посмотрим что GitLab представляет из себя “изнутри”.

GitLab Operator vs GitLab Helm chart

Первое – GitLab Operator или GitLab Helm chart?

Посмотрел на возможности – не увидел особой разницы между Оператором и чартом, более того, Оператор под капотом просто выкатывает тот же хельм-чарт.

По возможностям бекапа и восстановления – используются аналогичные тулы и процесс одинаков, см. General backup and restore guidance.

А вот в обновлении версии GitLab-инстанса документация Оператора выглядит попроще. См. Upgrade the GitLab chart vs How the Operator handles GitLab upgrades.

И даже сам Gitlab.com деплоится их чартом:

The largest known GitLab instance is on GitLab.com, which is deployed using our official GitLab Helm chart

Но в документации прям через слово “Experimental” и “Beta”, поэтому пока наверно без него.

Да и в любом случае всё завязано на чарт, так что знакомиться будем в основном с ним и его опциями.

Архитектура и компоненты GitLab

Для ознакомления:

Упрощённая схема из документации:

Тут:

  • NGINX: принимаем входящие соединения
  • GitLab Workhorse: является реверс-прокси для загрузки и выгрузки файлов, Git push/pull и т.д.
  • Puma: веб-сервер на Ruby, используется GitLab для API и своих веб-страниц
  • Sidekiq: для создания и управления очередями задач
    • использует Redis для хранения информации о джобах
  • PostgreSQL: хранение информации о пользователях, правах доступа, метаданных и т.д.
  • GitLab Shell: работает с репозиториями по SSH и управляет ключами доступов
    • обращается к Gitaly для обработки Git-объектов
    • отправляет информацию в Redis для создания задач в Sidekiq
  • Gitaly: Git RPC server, занимается задачами в репозиториях, которые получает от GitLab Shell и GitLab веб-приложения

Инфраструктура

Для работы GitLab требуются PostgreSQL, Redis, корзины AWS S3 и почтовый сервис для получения и отправки писем.

Helm-чарт по-умолчанию устанавливает PostgreSQL и Redis, но для production PostgreSQL рекомендуется устанавливать отдельно, см. Configure the GitLab chart with an external database и Configure PostgreSQL, хотя мы будем использовать PostgreSQL Operator и крутить кластер в Kubernetes.

Аналогичные требования Redis и Gitaly – их тоже желательно запускать не из чарта и не в Kubernetes-кластере. См. Installing GitLab by using Helm. У нас вместо Redis скорее всего будет KeyDB, тоже через оператор, тоже в Kubernetes.

Документация по развёртыванию Gitaly говорит, что до 500 юзеров достаточно 1 отдельной виртуальной машины с самим Gitaly. Если планируется 1000 и больше пользователей – то рекомендуется запускать Gitaly Cluster с Praefect. См. Gitaly > High Availability. Учитывая количество пользователей у нас – не вижу смысла выносить на отдельный EC2, поэтому будем деплоить вместе с чартом, потом посмотрим на его работу и ресурсы.

Для работы с object store в чарте устанавливается Minio, для production рекомендуется внешний сервис, такой как AWS S3. См. Configure the GitLab chart with an external object storage.

Так как мы в AWS и используем AWS ALB Controller, есть смысл отключить установку NGINX Controller, см. Customize the GitLab Ingress options.

Есть хороший пример инфрастуктуры в GitLab on AWS Partner Solution Deployment Guide, но это для прям совсем серьёзных масштабов, мы будем делать попроще. Тем не менее, сама схема интересная и полезная для понимания общей концепции при планировании инфрастуктуры:

Кроме того, есть Reference architectures, в которых описаны варианты запуска GitLab под различные нагрузки. Из них нам могут быть особо интересны Cloud native hybrid, которые описывают запуск в Kubernetes (hybrid – потому что часть сервисов таки рекомендуется запускать не в кластере):

Для LoadBalancer рекомендуется least-connection вместо стандартного round-robin – надо не забыть.

Полезно пройтись по всем доступным опциям, посмотреть что и как можно настроить, см. GitLab Helm chart deployment options, будем обсуждать в следующем посте.

Мониторинг GitLab – отдельная тема, дойдём и до неё, пока см. Monitoring GitLab.

Запуск GitLab в Minikube

Вообще используется для разработчиков которые пилят фичи под Кубер, но мы используем для общего знакомства. См. Developing for Kubernetes with minikube.

Из ограничений:

  • не будет nginx-ingress
  • не будет certmanager

Запускаем Миникуб:

[simterm]

$ minikube start --cpus 4 --memory 10240

[/simterm]

Включаем Ингресы:

[simterm]

$ minikube addons enable ingress

[/simterm]

Клонируем репозиторий и устанавливаем зависимости – полезно на них посмотреть, хотя они описаны в документации к чарту:

[simterm]

$ git clone https://gitlab.com/gitlab-org/charts/gitlab.git
$ cd gitlab
$ helm dependency update
...
Dependency gitlab did not declare a repository. Assuming it exists in the charts directory
Dependency certmanager-issuer did not declare a repository. Assuming it exists in the charts directory
Dependency minio did not declare a repository. Assuming it exists in the charts directory
Dependency registry did not declare a repository. Assuming it exists in the charts directory
Downloading cert-manager from repo https://charts.jetstack.io/
Downloading prometheus from repo https://prometheus-community.github.io/helm-charts
Downloading postgresql from repo https://raw.githubusercontent.com/bitnami/charts/eb5f9a9513d987b519f0ecd732e7031241c50328/bitnami
Downloading gitlab-runner from repo https://charts.gitlab.io/
Downloading grafana from repo https://grafana.github.io/helm-charts
Downloading redis from repo https://raw.githubusercontent.com/bitnami/charts/eb5f9a9513d987b519f0ecd732e7031241c50328/bitnami
Dependency nginx-ingress did not declare a repository. Assuming it exists in the charts directory
...

[/simterm]

Проверяем IP Миникуба:

[simterm]

$ minikube ip
192.168.49.2

[/simterm]

И устанавливаем с values-minikube.yaml:

[simterm]

$ helm upgrade --install gitlab . --timeout 600s -f https://gitlab.com/gitlab-org/charts/gitlab/raw/master/examples/values-minikube.yaml --set global.hosts.domain=$(minikube ip).nip.io --set global.hosts.externalIP=$(minikube ip)

[/simterm]

Проверяем поды – тут прям много всего:

[simterm]

$ kubectl get pod
NAME                                          READY   STATUS      RESTARTS      AGE
gitlab-gitaly-0                               1/1     Running     0             11m
gitlab-gitlab-exporter-5c8dbdc954-hr7jj       1/1     Running     0             11m
gitlab-gitlab-runner-7c4488ff58-bg8f5         0/1     Running     3 (39s ago)   8m30s
gitlab-gitlab-shell-7f9f5bb9ff-qlpxr          1/1     Running     0             11m
gitlab-gitlab-shell-7f9f5bb9ff-wc9rx          1/1     Running     0             11m
gitlab-kas-84cb5c548b-jbp69                   1/1     Running     0             11m
gitlab-kas-84cb5c548b-jxqqr                   1/1     Running     0             11m
gitlab-migrations-2-vw5jd                     0/1     Completed   0             8m30s
gitlab-minio-74467697bb-z8nms                 1/1     Running     0             11m
gitlab-minio-create-buckets-2-b6zl6           0/1     Completed   0             8m30s
gitlab-postgresql-0                           2/2     Running     0             11m
gitlab-prometheus-server-6bf4fffc55-6xpfm     2/2     Running     0             11m
gitlab-redis-master-0                         2/2     Running     0             11m
gitlab-registry-cd64f65dc-frsmt               1/1     Running     0             8m30s
gitlab-registry-cd64f65dc-nvfv2               1/1     Running     0             8m10s
gitlab-sidekiq-all-in-1-v2-59ccd7d6b9-9mpmz   1/1     Running     0             8m30s
gitlab-toolbox-6586c478f5-ktj5x               1/1     Running     0             7m58s
gitlab-webservice-default-6787f4b5db-kfp9h    2/2     Running     0             6m55s
gitlab-webservice-default-6787f4b5db-q62f9    2/2     Running     0             8m30s

[/simterm]

Сервисы:

[simterm]

$ kubectl get svc
NAME                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                               AGE
gitlab-gitaly                ClusterIP   None             <none>        8075/TCP,9236/TCP                     11m
gitlab-gitlab-exporter       ClusterIP   10.110.108.219   <none>        9168/TCP                              11m
gitlab-gitlab-shell          NodePort    10.110.231.31    <none>        32022:32022/TCP                       11m
gitlab-kas                   ClusterIP   10.102.124.129   <none>        8150/TCP,8153/TCP,8154/TCP,8151/TCP   11m
gitlab-minio-svc             ClusterIP   10.99.213.94     <none>        9000/TCP                              11m
gitlab-postgresql            ClusterIP   10.102.38.18     <none>        5432/TCP                              11m
gitlab-postgresql-headless   ClusterIP   None             <none>        5432/TCP                              11m
gitlab-postgresql-metrics    ClusterIP   10.107.123.35    <none>        9187/TCP                              11m
gitlab-prometheus-server     ClusterIP   10.104.133.44    <none>        80/TCP                                11m
gitlab-redis-headless        ClusterIP   None             <none>        6379/TCP                              11m
gitlab-redis-master          ClusterIP   10.96.133.252    <none>        6379/TCP                              11m
gitlab-redis-metrics         ClusterIP   10.105.193.58    <none>        9121/TCP                              11m
gitlab-registry              ClusterIP   10.109.96.193    <none>        5000/TCP                              11m
gitlab-webservice-default    ClusterIP   10.108.231.229   <none>        8080/TCP,8181/TCP,8083/TCP            11m
kubernetes                   ClusterIP   10.96.0.1        <none>        443/TCP                               23m

[/simterm]

Заходим на https://gitlab.192.168.49.2.nip.io:

Находим пароль:

[simterm]

$ kubectl get secret gitlab-gitlab-initial-root-password -ojsonpath='{.data.password}' | base64 --decode ; echo
yNUJLhQrGNdFqAX3UsZjcgkAwd7bf6nPRbVUYKUyWI6Z15qjiXE15kCPZhnAqnjU

[/simterm]

И логинимся под пользователем root:

Давайте посмотрим, что мы тут надеплоили:

  • gitaly – знаем
  • gitlab-exporter – сбор метрик GitLab для его Prometheus
  • gitlab-runner – воркеры для CI/CD
  • gitlab-shell – уже читали выше
  • kas – Kubernetes agent server для Gitlab Agent, “GitLab Agent for Kubernetes is an active in-cluster component for solving any GitLab<->Kubernetes integration tasks
  • migrations – джоба для работы с миграциями базы данных
  • minioHigh Performance Object Storage, API compatible with Amazon S3 – используется, когда нет S3
  • postgresql – база данных, читали
  • prometheus-server – мониторинг GitLab
  • redis-master – ясно-понятно
  • registry – Container Registry для хранения образов
  • sidekiq – уже читали
  • toolbox – бекапы и прочие задачи
  • webservice-default – GitLab Rails webserver

Окей. Можно с этим жить.

Посмотрим, что есть внутри – переходим в Админку:

Ммм… Вкусно) И много. С администрированием GitLab надо будет разбираться отдельно.

Пока можно приступать к изучению чарта, и пробовать его деплоить в Kubernetes – см. GitLab: Helm-чарт values, зависимости и деплой в Kubernetes с AWS S3.