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

Автор |  02/02/2023
 

Оскільки GitLab нещодавно змінив політику надання Free-доступу, і тепер по Free підписці буде доступно лише 5 користувачів, то вирішили ми переїжджати на self-hosted версію.

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

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

Деплоїти GitLab будемо через ArgoCD, запускати будемо в AWS Elastic Kubernetes Service, для object store використовуємо AWS S3. Але про це все потім, а для початку подивимося що GitLab є “зсередини” і як його взагалі деплоїти.

GitLab Operator vs GitLab Helm chart

Перше – GitLab Operator чи GitLab Helm chart?

Подивився на можливості – не побачив особливої різниці між Оператором та чартом, більше того, Оператор під капотом використовує той самий Helm-чарт.

За можливостями бекапа та відновлення – використовуються аналогічні утіліти та процес однаковий, див. 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 і крутити кластер PostgreSQL у Kubernetes.

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

Документація з розгортання Gitaly говорить, що до 500 користувачів достатньо однієї окремої віртуальної машини з самим Gitaly. Якщо планується 1000 і більше користувачів, то рекомендується запускати Gitaly Cluster з Praefect. Див. Gitaly > High Availability. Враховуючи кількість користувачів у нас – не бачу сенсу виносити на окремий EC2, тому будемо деплоїти разом із чартом, потім подивимося на його роботу та ресурси, можливо винесемо на окрему ноду Kubernetes.

Для роботи з 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 outstanding requests замість стандартного round-robin – треба не забути.

Корисно пройтися по всіх доступних опціях, подивитися що і як можна налаштувати, див. GitLab Helm chart deployment options, займемося цим в наступному пості.

Моніторинг GitLab – окрема тема, дійдемо до неї пізніше, поки див. Monitoring GitLab.

Запуск GitLab в Minikube

Взагалі використовується для розробників, які пиляють фічі під Kubernetes, але ми використовуємо для знайомства з чартом GitLab. Див. Developing for Kubernetes with minikube.

Запускаємо Minikube:

[simterm]

$ minikube start --cpus 4 --memory 10240

[/simterm]

Включаємо Ingress плагін:

[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
yNU***njU

[/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-defaultGitLab Rails webserver

Подивимося, що є всередині – переходимо до Адмінки:

Ммм… Смачно) І багато. З адмініструванням GitLab треба буде розбиратися окремо.

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