Продовжуємо зайомство з GitLab та його деплоєм у Kubernetes. Перша частина – GitLab: компоненти, архітектура, інфраструктура та запуск із Helm-чарту в Minikube, тепер давайте готуватися деплоїти в AWS Elastic Kubernetes Service.
Що робитимемо і де:
- деплоїмо в AWS з Helm-чарту, для початку якийсь “test env”
- Kubernetes – AWS EKS
- object store – AWS S3
- PostgreSQL – з operator
- Redis – поки використовуємо дефолтний, потім переїдемо на KeyDB, який теж розгортається оператором
- Gitaly – спробуємо в кластері, можливо, на окремій ноді – у нас всього 150-200 користувачів, навантаження не повинно бути великим, скейлінг і тим більше Praefik не потрібні
GitLab Operator виглядає в цілому цікаво, але в документації через слово “Experimental” і “Beta”, тому поки не чіпаємо – використовуємо чарт.
Зміст
Helm chart prerequisites
По чарту: для початку треба пройтися по доступним параметрам чарту, і подивитися, що нам взагалі треба буде із зовнішніх ресурсів (лоад-балансери, корзини S3, PostgreSQL), і що ще можна налаштувати через чарт.
Не забуваємо подивитися GitLab chart prerequisites , з якого нам поки що цікаві:
- PostgreSQL: ми будемо використовувати оператор, та розгорнемо свій кластер з блекджеком і базами
- Redis: у нас є KeyDB-оператор, потім будемо використовувати його, поки дефолтний із чарту
- Networking and DNS: використовуємо AWS ALB Contoller, створимо ACM сертифікат, DNS у Route53, записи створюються через External DNS
- Persistence: цікавий нюанс, можливо, треба буде налаштувати reclaimPolicy to Retain, див. Configuring Cluster Storage
- Prometheus: теж поінт на подумати – у нас є Kube Prometheus Stack зі своїм Prometheus та Alertmanager, треба буде подумати чи відключати вбудований у GitLab, чи залишати
- Outgoing email: поки не налаштовуватимемо, але потім треба буде подумати. У принципі є підтримка AWS SES, десь у документації зустрічав, так що нормально
- RBAC: у нас є, підтримується, тож залишаємо за замовчуванням, тобто включаємо
Враховуємо, що чарт включає цілу пачку залежностей, і корисно пройтися і подивитися що там ще деплоїться і з якими параметрами.
Структура Helm-чарту та його values.yaml
У GitLab Helm-чарту досить складна структура його values, так як чарт включає набір сабчартів і залежностей, див. GitLab Helm subcharts .
Щоб краще зрозуміти структуру його values
– можна подивитися структуру каталогу charts з дочірніми чартами:
[simterm]
$ tree -d gitlab/charts/ gitlab/charts/ |-- certmanager-issuer | `-- templates |-- gitlab | |-- charts | | |-- geo-logcursor | | | `-- templates | | |-- gitaly | | | `-- templates | | |-- gitlab-exporter | | | `-- templates | | |-- gitlab-grafana | | | `-- templates | | |-- gitlab-pages | | | `-- templates | | |-- gitlab-shell | | | `-- templates | | |-- kas | | | `-- templates | | |-- mailroom | | | `-- templates | | |-- migrations | | | `-- templates | | |-- praefect | | | `-- templates | | |-- sidekiq | | | `-- templates | | |-- spamcheck | | | `-- templates | | |-- toolbox | | | `-- templates | | `-- webservice | | `-- templates | | `-- tests | `-- templates |-- minio | `-- templates |-- nginx-ingress | `-- templates | `-- admission-webhooks | `-- job-patch `-- registry `-- templates
[/simterm]
Крім того, є набір зовнішніх залежностей, див requirements.yaml
.
Відповідно у values
основного чарту параметри розбиті на global
(див. Subcharts and Global Values), які використовуються дочірніми чартами, та параметри для конкретних чартів, див. Configure charts using globals, тобто наш values.yaml
виглядатиме так:
global: hosts: domain: hostSuffix: # використовується у ./charts/gitlab/charts/webservice, ./charts/gitlab/charts/toolbox/, ./charts/registry/, etc ... gitlab: kas: enabled: # використовується у ./charts/gitlab/charts/kas/ ... nginx-ingress: enabled: # використовується для ./gitlab/charts/nginx-ingress ... postgresql: install: # використовується при встановленні зовнішнього чарту postgresql
Тепер подивимося на самі values, і які нам можуть бути корисні.
Helm chart values
“Стартова точка” для роботи з чартом – Installing GitLab by using Helm .
Ще добре пройтися дефолтним values.yaml
– там у коментарях є посилання на сервіси/параметри.
Власне, параметри, які нам можуть бути цікаві, див. у Configure charts using globals та GitLab Helm chart deployment options :
global.hosts
:domain
: вказуємо домен, в якому будуть створюватися записи для GitLabexternalIP
: він начебто обов’язковий, але оскільки у нас буде AWS ALB, то не використовуємоhostSuffix
: test – додамо суффікс до субдоменів, що створюються, отримаємо запис виду gitlab-test.example.comhttps
: true , буде ALB із AWS Certificate Managerssh
: тут потрібно буде задати окремий субдомен для доступу до GitLab Shell
global.ingress
: так як у нас AWS ALB, то див.alb-full.yaml
annotations.*annotation-key*
: додамо аннотації для ALBconfigureCertmanager
: треба буде відключити, так як SSL термінейтимо на лоад-балансеріtls.secretName
: нам не потрібен, так як SSL термінейтимо на лоад-балансеріpath
: для ALB буде потрібен/*
provider
: для ALB == aws
global.gitlabVersion
: думав тут задати версію Gitlab, яку будемо деплоїти, але виявилося, що ні – правильніше через версію чарту, див. GitLab Versionglobal.psql
: параметри для підключення до PostgreSQL сервісами GitLab, див. Configure PostgreSQL settingshost
: адреса PosgtreSQL Servicedatabase
,username
: зрозумілоpassword
:useSecret
: пароль зберігатимемо в Secretsecret
: ім’я секретуkey
: ключ/поле у Секреті, за яким отримуємо пароль
global.redis
: взагалі буде зовнішній, KeyDB, і тут треба буде вказати параметри доступу до нього, але спочатку залишимо дефолтний, див. Configure Redis settingsglobal.grafana.enabled
: включаємо – подивимося, які там є дашборди (таки треба буде налаштовувати окремо, див. Grafana JSON Dashboards )global.registry
: див. Using the Container Registrybucket
: треба буде створити S3 бакет, цей параметр використовується/charts/gitlab/charts/toolbox/
для бекапів, сам GitLab Registry налаштовується через окремі параметри, розглянемо нижче
global.gitaly
: поки використовуємо з чарту, незважаючи на рекомендації – будемо деплоїти у вигляді Kubernetes Pod в кластер, залишаємо за замовчуванням, але маємо на увазіglobal.minio
: відключимо – використовуємо відразу AWS S3global.appConfig
: ось тут прям багато всього, див. Configure appConfig settings – містить загальні параметри для чартів Webservice, Sidekiq та GitalycdnHost
: взагалі-то корисна начебто річ, але подивимося, як його використовувати, поки не чіпаємоcontentSecurityPolicy
: теж корисна штука, але налаштуємо потім, див. Content Security PolicyenableUsagePing
: “телеметрія” для самого GitLab Inc, не бачу сенсу, відключимоenableSeatLink
: не зрозумів, що це, посилання seat link support веде в “нікуди” – на сторінці інформації про seat не знайшов, але мабуть це щось пов’язане з кількістю користувачів в ліцензії, а оскільки ми її не купуємо – то можна вимкнутиobject_store
: загальні параметри для роботи з S3 типу ключів доступу та proxy, див. Consolidated object storage
-
connection
: тут потрібно буде створити секрет, в якому описуються налаштування підключення до корзин, у тому числі ACCESS/SECRET ключі, але ми замість ключів використовуємо ServiceAccount та IAM role
- Specify buckets : які корзини потрібні, є набір дефолтних імен типу gitlab-artifacts , але для dev- та test- має сенс перевизначити
storage_options
: шифрування для бакетів, має сенс змінювати якщо використовується AWS KMS, але ми швидше за все залишимо дефолтне шифрування
- LFS, Artifacts, Uploads, Packages, External MR diffs, and Dependency Proxy – налаштування корзин для різних сервісів, поки не чіпатимемо, подивимося по ходу використання
gitlab_kas
: налаштування для GitLab Agent for Kubernetes, поки залишимо за замовчуванням, не впевнений, що він нам знадобитьсяomniauth
: налаштування для SSO, якось потім, взагалі будемо підключати аутентифікацію через Google, див. OmniAuth
global.serviceAccounts
: замість ACCESS/SECRET будемо використовувати Kubernetes ServiceAccounts з IAM Role для подів:create
: включаємо створення SA для сервісівannotations
: а тут вкажемо ARN IAM-ролі
global.nodeSelector
: корисно, потім будемо на виділених нодахglobal.affinity
&&global.antiAffinity
: плюс можна налаштувати Affinityglobal.common.labels
: задамо тут всякі environment , team , etcglobal.tracing
: поки не чіпаємо, але маємо на увазі на майбутнє – потім додамо якийсь Jaeger/Grafana Tempoglobal.priorityClassName
: можливо корисно або навіть потрібно, потім потикаємо, див. Pod Priority and Preemption
З глобальних змінних це начебто все, крім них нам треба буде:
- вимкнути
certmanager
– використуємо AWS Certificate Manager на AWS LoadBalncer - вимкнути
postgresql
– використуємо зовнішній - відключити
gitlab-runner
– у нас вже є запущені раннери, потім спробуємо прикрутити їх до цього інстансу GitLab - відключити
nginx-ingress
– у нас AWS ALB Controller та AWS ALB балансери - налаштувати Services для
webservice
таgitlab-shell
- налаштувати
registry
Тепер перед деплоєм чарту треба підготувати зовнішні сервіси:
- кластер та база PostgreSQL
- бакети AWS S3
- сертифікат в AWS Certificate Manager для лоад-балансеру
Підготовка – створення зовнішніх ресурсів
PostgreSQL
У нас використовується PostgreSQL Operator – описуємо створення кластера.
Параметри по коннектам, пам’яті, диску та реквестам-лімітам поки що дефолтні – подивимося по ходу діла, як сильно навантажуватиметься база.
Описуємо створення бази gitlabhq_test та дефолтних юзерів – defaultUsers=true
:
kind: postgresql apiVersion: acid.zalan.do/v1 metadata: name: gitlab-cluster-test-psql namespace: gitlab-cluster-test labels: team: devops environment: test spec: teamId: devops postgresql: version: "14" parameters: max_connections: '100' shared_buffers: 256MB work_mem: 32MB numberOfInstances: 3 preparedDatabases: gitlabhq_test: defaultUsers: true schemas: public: defaultRoles: false enableMasterLoadBalancer: false enableReplicaLoadBalancer: false enableConnectionPooler: false enableReplicaConnectionPooler: false volume: size: 10Gi storageClass: encrypted resources: requests: cpu: "100m" memory: 100Mi limits: memory: 1024Mi enableLogicalBackup: true logicalBackupSchedule: "0 1 * * *" sidecars: - name: exporter image: quay.io/prometheuscommunity/postgres-exporter:v0.11.1 ports: - name: exporter containerPort: 9187 protocol: TCP resources: limits: memory: 50M requests: cpu: 50m memory: 50M env: - name: DATA_SOURCE_URI value: localhost/postgres?sslmode=disable - name: DATA_SOURCE_USER value: "$(POSTGRES_USER)" - name: DATA_SOURCE_PASS value: "$(POSTGRES_PASSWORD)" - name: PG_EXPORTER_AUTO_DISCOVER_DATABASES value: "true"
Створюємо неймспейс:
[simterm]
$ kk create ns gitlab-cluster-test
[/simterm]
Деплоїмо кластер:
[simterm]
$ kk apply -f postgresql.yaml postgresql.acid.zalan.do/gitlab-cluster-test-psql created
[/simterm]
Перевіряємо поди:
[simterm]
$ kk -n gitlab-cluster-test get pod NAME READY STATUS RESTARTS AGE devops-gitlab-cluster-test-psql-0 2/2 Running 0 24s devops-gitlab-cluster-test-psql-1 0/2 ContainerCreating 0 4s
[/simterm]
Окей, створюються.
Перевіряємо Секрети – потім використуємо секрет юзера postgres у конфігах GitLab:
[simterm]
$ kk -n gitlab-cluster-test get secret NAME TYPE DATA AGE default-token-2z2ct kubernetes.io/service-account-token 3 4m12s gitlabhq-test-owner-user.devops-gitlab-cluster-test-psql.credentials.postgresql.acid.zalan.do Opaque 2 65s gitlabhq-test-reader-user.devops-gitlab-cluster-test-psql.credentials.postgresql.acid.zalan.do Opaque 2 65s gitlabhq-test-writer-user.devops-gitlab-cluster-test-psql.credentials.postgresql.acid.zalan.do Opaque 2 66s postgres-pod-token-p7b4g kubernetes.io/service-account-token 3 66s postgres.devops-gitlab-cluster-test-psql.credentials.postgresql.acid.zalan.do Opaque 2 66s standby.devops-gitlab-cluster-test-psql.credentials.postgresql.acid.zalan.do Opaque 2 66s
[/simterm]
Наче ОК.
AWS S3
Тепер створимо корзини.
Нам будуть потрібні:
- для registry – Configure Registry settings
- для бекапів – Backups to S3
- і пачка всяких для LFS, Artifacts, Uploads, Packages, External MR diffs, and Dependency Proxy
Щоб уникнути помилки BucketAlreadyExists
, до імен корзин додаємо or як власний “ідентифікатор”, бо імена загальні, і ім’я оточення – test , тобто список виходить такий:
- or-gitlab-registry-test
- or-gitlab-artifacts-test
- or-git-lfs-test
- or-gitlab-packages-test
- or-gitlab-uploads-test
- or-gitlab-mr-diffs-test
- or-gitlab-terraform-state-test
- or-gitlab-ci-secure-files-test
- or-gitlab-dependency-proxy-test
- or-gitlab-pages-test
- or-gitlab-backups-test
- or-gitlab-tmp-test
Не факт, що знадобляться всі, подивимося по ходу налаштування GitLab та його фіч, але поки що створимо.
Створюємо з AWS CLI:
[simterm]
$ aws --profile internal s3 mb s3://or-gitlab-registry-test make_bucket: or-gitlab-registry-test
[/simterm]
Повторюємо для решти корзин.
AWS Certificate Manager
Для Ingress нам потрібен TLS-сертифікат, див. Requesting a public certificate, а для отримання сертифіката – вочевидь, що домен.
У нашому випадку використовуємо internal.example.com, для якого створимо wildcard-сертифікат в ACM:
У FQDN вказуємо *.internal.example.com, щоб включити всі субдомени. Потім для GitLab використуємо параметри global.hosts.domain=internal.example.com
та hostSuffix=test
, що в результаті створить кілька Ingress та Services, які через ExternalDNS створять необхідні записи у Route53.
У Validation Method вибираємо DNS – найпростіший, тим більш що доменна зона хоститься в Route53 – все створюється в пару кліків:
Переходимо до сертифікату – він зараз у Pending validation, клікаємо Create records in Route53 :
Тепер статус Issued, запам’ятовуємо його ARN – він нам знадобиться у values:
AWS IAM Policy та IAM Role для ServiceAccount
Для ServiceAccount, який повинен буде давати доступ до AWS S3, потрібно створити IAM Policy та IAM Role. Детально див. Kubernetes ServiceAccounts з IAM Role для подів, тут швиденько.
Створюємо поліси:
{ "Statement": [ { "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:ListMultipartUploadParts", "s3:AbortMultipartUpload" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::or-gitlab-registry-test/*", "arn:aws:s3:::or-gitlab-artifacts-test/*", "arn:aws:s3:::or-git-lfs-test/*", "arn:aws:s3:::or-gitlab-packages-test/*", "arn:aws:s3:::or-gitlab-uploads-test/*", "arn:aws:s3:::or-gitlab-mr-diffs-test/*", "arn:aws:s3:::or-gitlab-terraform-state-test/*", "arn:aws:s3:::or-gitlab-ci-secure-files-test/*", "arn:aws:s3:::or-gitlab-dependency-proxy-test/*", "arn:aws:s3:::or-gitlab-backups-test/*", "arn:aws:s3:::or-gitlab-tmp-test/*" ] }, { "Action": [ "s3:ListBucket", "s3:ListAllMyBuckets", "s3:GetBucketLocation", "s3:ListBucketMultipartUploads" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::or-gitlab-registry-test", "arn:aws:s3:::or-gitlab-artifacts-test", "arn:aws:s3:::or-git-lfs-test", "arn:aws:s3:::or-gitlab-packages-test", "arn:aws:s3:::or-gitlab-uploads-test", "arn:aws:s3:::or-gitlab-mr-diffs-test", "arn:aws:s3:::or-gitlab-terraform-state-test", "arn:aws:s3:::or-gitlab-ci-secure-files-test", "arn:aws:s3:::or-gitlab-dependency-proxy-test", "arn:aws:s3:::or-gitlab-backups-test", "arn:aws:s3:::or-gitlab-tmp-test" ] } ], "Version": "2012-10-17" }
Створюємо IAM Role – вибираємо Web identity:
Підключаємо створену вище Policy:
Наче все? Можна писати values.
Деплой Gitlab Helm
Створення values.yaml
Всі дефолтні values тут>>>, можна використати як приклад, але не варто повністю копіювати – у свій values пишемо тільки те, що у нас відрізняється від дефолтного.
global
hosts
Вказуємо домен, використовуючи який чарт пропише значення для Ingress та Services які буде створювати – отримаємо набір доменів виду gitlab.internal.example.com, registry.internal.example.com і т.д.
Для SSH у прикладі для Ingress вказаний окремий субдомен, оскільки під SSH буде створюватися окремий Service з Network Load Balancer для доступу до 22 TCP.
hostSuffix
додасть суфікс до створюваних записів, тобто в результаті будуть субдомени виду gitlab-test.internal.example.com та registry-test.internal.example.com .
Але для SSH hostSuffix
не застосовується, тому вказуємо відразу з суфіксом.
Виходить так:
global: hosts: domain: internal.example.com hostSuffix: test ssh: gitlab-shell-test.internal.example.com
ingress
Беремо для прикладу alb-full.yaml
, від себе додамо тільки load_balancing.algorithm.type=least_outstanding_requests
:
ingress: # Common annotations used by kas, registry, and webservice annotations: alb.ingress.kubernetes.io/backend-protocol: HTTP alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:eu-central-1:514***799:certificate/7227a8fa-1124-441c-81d7-ec168180190d alb.ingress.kubernetes.io/group.name: gitlab alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]' alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-group-attributes: load_balancing.algorithm.type=least_outstanding_request alb.ingress.kubernetes.io/target-type: ip kubernetes.io/ingress.class: alb nginx.ingress.kubernetes.io/connection-proxy-header: "keep-alive" class: none configureCertmanager: false enabled: true path: /* pathType: ImplementationSpecific provider: aws tls: enabled: false
Якщо використовувати KAS, йому потрібен буде окремий LoadBalancer, налаштуємо його трохи пізніше в блоці gitlab.kas
.
psql
Знаходимо ім’я Service, який був створений під час деплою PostgreSQL кластеру:
[simterm]
$ kk -n gitlab-cluster-test get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE devops-gitlab-cluster-test-psql ClusterIP 172.20.67.135 <none> 5432/TCP 63m devops-gitlab-cluster-test-psql-config ClusterIP None <none> <none> 63m devops-gitlab-cluster-test-psql-repl ClusterIP 172.20.165.249 <none> 5432/TCP 63m
[/simterm]
Користувача поки що візьмемо дефолтного postgress, з готового секрету:
[simterm]
$ kk -n gitlab-cluster-test get secret postgres.devops-gitlab-cluster-test-psql.credentials.postgresql.acid.zalan.do NAME TYPE DATA AGE postgres.devops-gitlab-cluster-test-psql.credentials.postgresql.acid.zalan.do Opaque 2 67m
[/simterm]
Для production таки треба буде робити окремого, бо postgress == root .
Готуємо конфіг:
psql: host: devops-gitlab-cluster-test-psql database: gitlabhq_test username: postgres password: useSecret: true secret: postgres.devops-gitlab-cluster-test-psql.credentials.postgresql.acid.zalan.do key: password
redis
Configure Redis chart-specific settings
Configure the GitLab chart with an external Redis
Поки залишимо все за замовчуванням – Redis використовується тільки для кешування, подивимося, як він працюватиме і що по ресурсам.
registry
В globals
для registry
вказуємо тільки корзину:
registry: bucket: or-gitlab-registry-test
gitaly
Поки що залишимо, як є. Потім подумаємо, може винесемо на окрему ноду.
Треба буде моніторити як він ресурси використовує, але у випадку з нашими 150-200 користувачів навряд чи там буде необхідність сильно допилювати його або тим більше розгортати кластер Praefect .
minio
Відключаємо, ходитимемо відразу в AWS S3:
minio: enabled: false
grafana
Включимо, подивимося, що в ній є (нічого 🙂):
grafana: enabled: true
appConfig
Список корзин є у values.
object_store
таки треба налаштовувати – додати секрет, в якому буде вказано провайдер і регіон бакетів. Ключі не використовуємо – буде ServiceAccount.
Приклад візьмемо з , rails.s3.yaml
, див. connection:
provider: AWS region: eu-central-1
Створюємо Secret:
[simterm]
$ kk -n gitlab-cluster-test create secret generic gitlab-rails-storage --from-file=connection=rails.s3.yaml
[/simterm]
І описуємо appConfig
, виходить так:
appConfig: enableUsagePing: false enableSeatLink: true # disable? object_store: enabled: true proxy_download: true connection: secret: gitlab-rails-storage key: connection artifacts: bucket: or-gitlab-artifacts-test lfs: bucket: or-git-lfs-test packages: bucket: or-gitlab-packages-test uploads: bucket: or-gitlab-uploads-test externalDiffs: bucket: or-gitlab-mr-diffs-test terraformState: bucket: or-gitlab-terraform-state-test ciSecureFiles: bucket: or-gitlab-ci-secure-files-test dependencyProxy: bucket: or-gitlab-dependency-proxy-test backups: bucket: or-gitlab-backups-test tmpBucket: or-gitlab-tmp-test
serviceAccount
Див. Kubernetes: ServiceAccount з AWS IAM Role для Kubernetes Pod.
Начебто можна без створення ServiceAccount, просто через анотації до сервісів – IAM roles for AWS when using the GitLab chart.
Але ми будемо використовувати ServiceAccount, роль із політикою вже робили – додаємо:
serviceAccount: enabled: true create: true annotations: eks.amazonaws.com/role-arn: arn:aws:iam::514***799:role/S3GitlabClusterTest
Так, з globals
начебто все.
registry
Defining the Registry Configuration
Тут треба налаштувати storage
, який зберігається в Secret, і в якому теж необхідно вказати ім’я корзини: параметр globals.registry
буде використовуватися для бекапів, а параметр тут – самим сервісом Registry, див Docker Registry images .
Для прикладу візьмемо файл registry.s3.yaml
, але без ключів, тому що для Registry буде створено свій ServiceAccoumt з IAM Role:
s3: bucket: or-gitlab-registry-test region: eu-central-1 v4auth: true
Створюємо секрет:
[simterm]
$ kk -n gitlab-cluster-test create secret generic registry-storage --from-file=config=registry.s3.yaml
[/simterm]
Описуємо конфіг:
registry: enabled: true service: type: NodePort storage: secret: registry-storage key: config
gitlab
– Services
Окремо описуємо Services для kas
, webservice
та gitlab-shell
, з того ж прикладу alb-full.yaml
.
Для gitlab-shell
Service в аннотації external-dns.alpha.kubernetes.io/hostname
вказуємо ім’я хоста:
gitlab: kas: enabled: true ingress: # Specific annotations needed for kas service to support websockets annotations: alb.ingress.kubernetes.io/healthcheck-path: /liveness alb.ingress.kubernetes.io/healthcheck-port: "8151" alb.ingress.kubernetes.io/healthcheck-protocol: HTTP alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=4000,routing.http2.enabled=false alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=86400 alb.ingress.kubernetes.io/target-type: ip kubernetes.io/tls-acme: "true" nginx.ingress.kubernetes.io/connection-proxy-header: "keep-alive" nginx.ingress.kubernetes.io/x-forwarded-prefix: "/path" # k8s services exposed via an ingress rule to an ELB need to be of type NodePort service: type: NodePort webservice: enabled: true service: type: NodePort # gitlab-shell (ssh) needs an NLB gitlab-shell: enabled: true service: annotations: external-dns.alpha.kubernetes.io/hostname: "gitlab-shell-test.internal.example.com" service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip" service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing" service.beta.kubernetes.io/aws-load-balancer-type: "external" type: LoadBalancer
Інше
Відключаємо непотрібні нам сервіси:
certmanager: install: false postgresql: install: false gitlab-runner: install: false nginx-ingress: enabled: false
Повний values.yaml
В результаті отримуємо такий конфіг:
global: hosts: domain: internal.example.com hostSuffix: test ssh: gitlab-shell-test.internal.example.com ingress: # Common annotations used by kas, registry, and webservice annotations: alb.ingress.kubernetes.io/backend-protocol: HTTP alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:eu-central-1:514***799:certificate/7227a8fa-1124-441c-81d7-ec168180190d alb.ingress.kubernetes.io/group.name: gitlab alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]' alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-group-attributes: load_balancing.algorithm.type=least_outstanding_requests alb.ingress.kubernetes.io/target-type: ip kubernetes.io/ingress.class: alb nginx.ingress.kubernetes.io/connection-proxy-header: "keep-alive" class: none configureCertmanager: false enabled: true path: /* pathType: ImplementationSpecific provider: aws tls: enabled: false psql: host: devops-gitlab-cluster-test-psql database: gitlabhq_test username: postgres password: useSecret: true secret: postgres.devops-gitlab-cluster-test-psql.credentials.postgresql.acid.zalan.do key: password registry: bucket: or-gitlab-registry-test minio: enabled: false grafana: enabled: true appConfig: enableUsagePing: false enableSeatLink: true # disable? object_store: enabled: true proxy_download: true connection: secret: gitlab-rails-storage key: connection artifacts: bucket: or-gitlab-artifacts-test lfs: bucket: or-git-lfs-test packages: bucket: or-gitlab-packages-test uploads: bucket: or-gitlab-uploads-test externalDiffs: bucket: or-gitlab-mr-diffs-test terraformState: bucket: or-gitlab-terraform-state-test ciSecureFiles: bucket: or-gitlab-ci-secure-files-test dependencyProxy: bucket: or-gitlab-dependency-proxy-test backups: bucket: or-gitlab-backups-test tmpBucket: or-gitlab-tmp-test serviceAccount: enabled: true create: true annotations: eks.amazonaws.com/role-arn: arn:aws:iam::514***799:role/S3GitlabClusterTest common: labels: environment: test gitlab: kas: enabled: true ingress: # Specific annotations needed for kas service to support websockets annotations: alb.ingress.kubernetes.io/healthcheck-path: /liveness alb.ingress.kubernetes.io/healthcheck-port: "8151" alb.ingress.kubernetes.io/healthcheck-protocol: HTTP alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=4000,routing.http2.enabled=false alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=86400 alb.ingress.kubernetes.io/target-type: ip kubernetes.io/tls-acme: "true" nginx.ingress.kubernetes.io/connection-proxy-header: "keep-alive" nginx.ingress.kubernetes.io/x-forwarded-prefix: "/path" # k8s services exposed via an ingress rule to an ELB need to be of type NodePort service: type: NodePort webservice: enabled: true service: type: NodePort # gitlab-shell (ssh) needs an NLB gitlab-shell: enabled: true service: annotations: external-dns.alpha.kubernetes.io/hostname: "gitlab-shell-test.internal.example.com" service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip" service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing" service.beta.kubernetes.io/aws-load-balancer-type: "external" type: LoadBalancer registry: enabled: true service: type: NodePort storage: secret: registry-storage key: config certmanager: install: false postgresql: install: false gitlab-runner: install: false nginx-ingress: enabled: false
Gitlab deploy
Ну і начебто все? Давайте деплоїти:
[simterm]
$ helm repo add gitlab https://charts.gitlab.io/ $ helm repo update $ helm upgrade --install --namespace gitlab-cluster-test gitlab gitlab/gitlab --timeout 600s -f gitlab-cluster-test-values.yaml
[/simterm]
Перевіряємо Ingresses:
[simterm]
$ kk -n gitlab-cluster-test get ingress NAME CLASS HOSTS ADDRESS PORTS AGE gitlab-grafana-app <none> gitlab-test.internal.example.com k8s-***.eu-central-1.elb.amazonaws.com 80 117s gitlab-kas <none> kas-test.internal.example.com k8s-***.eu-central-1.elb.amazonaws.com 80 117s gitlab-registry <none> registry-test.internal.example.com k8s-***.eu-central-1.elb.amazonaws.com 80 117s gitlab-webservice-default <none> gitlab-test.internal.example.com k8s-***.eu-central-1.elb.amazonaws.com 80 117s
[/simterm]
Відкриваємо URL https://gitlab-test.internal.example.com:
Отримуємо рутовий пароль:
[simterm]
$ kubectl -n gitlab-cluster-test get secret gitlab-gitlab-initial-root-password -ojsonpath='{.data.password}' | base64 --decode ; echo cV6***y1t
[/simterm]
Логінимося під root:
Перевірка деплою
Не віриться мені, що з першого разу все завелося.
Repository
Перевіряємо роботу з репозиторієм, тобто роботу сервісів Gitaly та GitLab Shell.
Створюємо тестовий репозиторій:
Копіюємо адресу – з субдоменом gitlab-shell-test.internal.example.com, який вказували в конфігах:
Клонуємо:
[simterm]
$ git clone [email protected]:gitlab-instance-da4355a9/test-repo.git Cloning into 'test-repo'... The authenticity of host 'gitlab-shell-test.internal.example.com (3.***.***.79)' can't be established. ED25519 key fingerprint is SHA256:xhC1Q/lduNbg49kGljYUb21YlBBsxrG89xE+iCHD+xc. This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added 'gitlab-shell-test.internal.example.com' (ED25519) to the list of known hosts. remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (3/3), done.
[/simterm]
І зміст:
[simterm]
$ ll test-repo/ total 8 -rw-r--r-- 1 setevoy setevoy 6274 Feb 4 13:24 README.md
[/simterm]
Спробуємо пушнути якісь зміни назад:
[simterm]
$ cd test-repo/ $ echo test > test.txt $ git add test.txt $ git commit -m "test" $ git push Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Delta compression using up to 16 threads Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 285 bytes | 285.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 To gitlab-shell-test.internal.example.com:gitlab-instance-da4355a9/test-repo.git 7217947..4eb84db main -> main
[/simterm]
І в WebUI:
Окей, працює.
Container Registry
Далі перевіримо Registry – приклади команд є у веб-інтерфейсі > Container Registry :
Логінимося з тим же логіном:паролем, які використовували для логіна в веб-інтерфейс GitLab (користувач root, пароль з секрету gitlab-gitlab-initial-root-password
):
[simterm]
$ docker login registry-test.internal.example.com Username: root Password: ... Login Succeeded
[/simterm]
Створюємо Dockerfile
:
FROM busybox RUN echo "hello world"
Збираємо образ, тегаємо з ім’ям нашого Registry:
[simterm]
$ docker build -t registry-test.internal.example.com/gitlab-instance-da4355a9/test-repo:1 .
[/simterm]
І пушимо:
[simterm]
$ docker push registry-test.internal.example.com/gitlab-instance-da4355a9/test-repo:1 The push refers to repository [registry-test.internal.example.com/gitlab-instance-da4355a9/test-repo] b64792c17e4a: Mounted from gitlab-instance-da4355a9/test 1: digest: sha256:eb45a54c2c0e3edbd6732b454c8f8691ad412b56dd10d777142ca4624e223c69 size: 528
[/simterm]
Перевіряємо корзину or-gitlab-registry-test
:
[simterm]
$ aws --profile internal s3 ls or-gitlab-registry-test/docker/registry/v2/repositories/gitlab-instance-da4355a9/test-repo/_manifests/tags/1/ PRE current/ PRE index/
[/simterm]
Окей – Registry працює, доступ до S3 є, з ServiceAccounts проблем начебто немає.
ServiceAccounts та S3 access
Але про всяк випадок перевіримо ServiceAccounts та доступ до S3 в інших сервісах, наприклад з поду Toolbox:
[simterm]
$ kk -n gitlab-cluster-test exec -ti gitlab-toolbox-565889b874-vgqcb -- bash git@gitlab-toolbox-565889b874-vgqcb:/$ aws s3 ls or-gitlab-registry-test PRE docker/
[/simterm]
Окей – тут також все працює.
Grafana
Перевіряємо Grafana – https://gitlab-test.internal.example.com/-/grafana/.
Логін root, пароль беремо із секрету:
[simterm]
$ kubectl -n gitlab-cluster-test get secret gitlab-grafana-initial-password -ojsonpath='{.data.password}' | base64 --decode ; echo Cqc***wFS
Працює. Дашборди треба підключати окремо, потім займемося, як дійдемо до моніторингу взагалі, поки див. Grafana JSON Dashboards .
Загалом, начебто все.
Подивимося, що далі – адміністрування, міграція проектів, моніторинг, секьюріті.