Продолжаем сетапить 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
основного чарта параметры разбиты на globals
(см. 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 settings,global.grafana.enabled
: включаем – посмотрим, какие там есть дашборды (нету, надо будет настраивать отдельно, см. Grafana JSON Dashboards)global.registry
: см. Using the Container Registrybucket
: надо будет создать корзину, этот параметр используется в/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
: общие параметры для работы с корзинами типа ключей доступа и 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
К именам корзин добавляем or как свой “идентификатор”, ибо имена корзин общие, что бы не было ошибки BucketAlreadyExists
, и имя окружения – 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: iinternal.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 к корзинам, надо создать 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: true
Полный 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, который указывали в конфигах:
Клонируем, подверждаем добавления сертификата в /home/setevoy/.ssh/known_hosts
:
[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
Но на всякий случай проверим в других сервисах, например из пода 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.
В общем, вроде всё.
Посмотрим, что дальше – администрирование, миграция проектов, мониторинг.