在Kubernetes上部署Gitlab集群
背景
大多数团队都会使用 GitLab 作为代码管理平台,通常采用的都是通过单个安装包(Omnibus)进行安装,安装包内已捆绑了运行 GitLab 所需的所有服务与工具。若是你所在的团队人数比较多或者为了解决单机部署所带来的单点故障问题,那么可用的方案有以下两种:
- 多台主机安装 Omnibus 包,通过
/etc/gitlab/gitlab.rb
配置文件开启/禁用所需组件,控制组件的数量来达到高可用部署和性能需求 - 通过 Helm Chart 部署到 Kubernetes 中
现在对比一下各个方案的优劣:
单机部署
- 优点:维护简单
- 缺点:存在单点故障、不足以支撑1000+用户使用
多机部署(Omnibus 包)
- 优点:灵活配置
- 缺点:配置复杂,官方文档对此部署方式的配置没有很明确的指引
Helm Chart 部署到 Kubernetes 集群
- 优点:安装配置简单(其实不简单)、灵活扩容(其中 shell、registry、sidekiq、webservice 支持 HPA 自动扩缩容)
- 缺点:有一定的局限性,做不到非常灵活的配置;Helm Chart 没有提供的配置项,则要自行修改 Helm Chart 来实现
* 不管哪种方案,对 PostgreSQL 的高可用,都是要借助于第三方的 PostgreSQL 高可用方案,GitLab 没有集成。
我的选择
基于以上三种方案的介绍,我的需求是要求有一定的高可用性,仓库(repositories)要存储多份以满足数据的健壮性。
加上我对 Kubernetes 比较熟悉,而且现在部署应用都 All In Kubernetes 了,没有理由不用的。因此我选用 GitLab Helm Chart 的方式部署在 Kubernetes 集群上。
遇到的问题
官方提供的 Helm Chart 安装的过程中可能会遇到各种各样的问题,我这里列一下我所遇到的一些问题:
- 不支持自定义 GitLab 端口号
- Helm Chart 自带的对象存储服务 MinIO 安装的是单实例,不满足高可用需求
- minio 要求要有一个域名,我没有,所以安装完后还要做一定的修改
- PostgreSQL slave 报错
- 不会自动创建 praefect 连接 PostgreSQL 的授权账号
- Helm Chart 貌似没有 SMTP 发送邮件的相关配置
安装前提条件
- 你得有一个域名,如:git.haxi.cc
- 你得有一个 Kubernetes 集群,并配备 StorageClass,我用的是 local-path-provisioner
- 你得用 Helm3
因为用local-path,我定义了3个节点为数据节点,跑 PostgreSQL 和 Redis,因此我给节点打上标签
- 给一个节点打上标签:gitlab/workerload: db-master
- 给两个节点打上标签:gitlab/workerload: db-slave
安装步骤
我的一些配置
- 不安装 ingress,另外安装 Nginx 做反代
- GitLab 端口:8888
- shell 端口(SSH 协议):8000
- 不安装 runner,我貌似在官方文档看过 helm 部署的 runner 有问题来着,但是我已经找不到链接了
下载 GitLab Helm Chart
helm add repo gitlab https://charts.gitlab.io helm pull gitlab/gitlab --version 5.10.2
配置 GitLab Helm Chart
编写 Helm Chart 配置文件,保存为 myvalues.yaml,文件内容如下:
global: edition: ce shell: port: 8000 praefect: enabled: true hosts: domain: haxi.cc gitlab: name: git.haxi.cc port: 8888 ingress: configureCertmanager: false minio: enabled: false appConfig: object_store: enabled: true connection: secret: gitlab-rails-storage certmanager-issuer: email: [email protected] gitlab: webservice: deployment: livenessProbe: initalDelaySeconds: 60 certmanager: install: false gitlab-runner: install: false postgresql: replication: enabled: true slaveReplicas: 2 master: nodeSelector: gitlab/workerload: db-master slave: nodeSelector: gitlab/workerload: db-slave extraEnv: - name: POSTGRESQL_REPLICATION_PASSWORD value: repl_password redis: cluster: enabled: true slaveCount: 2 master: nodeSelector: gitlab/workerload: db-master slave: nodeSelector: gitlab/workerload: db-slave nginx-ingress: enabled: false registry: storage: secret: registry-storage key: config
部署 MinIO
MinIO 是一款高性能、分布式的对象存储系统。Gitlab使用它存储部分数据。
编写minio部署清单,保存为minio.yaml,内容如下:
apiVersion: apps/v1 kind: DaemonSet metadata: labels: app: minio name: minio spec: selector: matchLabels: app: minio template: metadata: labels: app: minio spec: containers: - name: minio image: quay.io/minio/minio:RELEASE.2022-05-08T23-50-31Z imagePullPolicy: IfNotPresent ports: - name: api containerPort: 9000 hostPort: 9000 protocal: TCP - name: console containerPort: 9001 hostPort: 9001 protocal: TCP env: - name: MINIO_ROOT_USER value: admin - name: MINIO_ROOT_PASSWORD value: pass@1234 args: - server - http://192.168.30.{14...17}/data/minio - http://192.168.30.{18...22}/data/minio - --address - :9000 - --console-address - :9001 volumeMounts: - name: storage mountPath: /data/minio hostNetwork: true volumes: - name: storage hostPath: path: /data/minio --- apiVersion: v1 kind: Service metadata: labels: app: minio name: minio spec: ports: - name: api port: 9000 targetPort: 9000 - name: console port: 9001 targetPort: 9001 selector: app: minio type: ClusterIP
部署 MinIO
kubectl create ns minio kubectl -n minio apply -f minio.yaml
创建buckets,登录minio webui,依次创建以下bucket:
git-lfs gitlab-artifacts gitlab-backups gitlab-ci-secure-files gitlab-dependency-proxy gitlab-mr-diffs gitlab-packages gitlab-pages gitlab-pseudo gitlab-terraform-state gitlab-uploads, registry runner-cache tmp
在Minio上创建一个ServiceAccount,并记录下来,等会配置gitlab连接到对象存储要用到。
部署 GitLab
配置minio连接信息
部署 GitLab 前,需要先配置 MinIO 的连接信息。在 examples/objectstorage 目录下有配置模板,本次部署用到的模板是rails.minio.yaml和registry.minio.yaml。
修改rails.minio.yaml模板中的aws_access_key_id、aws_secret_access_key为刚才在minio上创建的ServiceAccount对应的AccessKey和SecretKey,host为minio.minio.svc.cluster.local,endpoint为http://minio.minio.svc.cluster.local:9000。
修改registry.minio.yaml模板中的accesskey、secretkey为刚才在minio上创建的ServiceAccount对应的AccessKey和SecretKey,regionendpoint为http://minio.minio.svc.cluster.local:9000。
创建secret:
kubectl create ns gitlab kubectl -n gitlab create secret generic gitlab-rails-storage --from-file=connection=examples/objectstorage/rails.minio.yaml kubectl -n gitlab create secret generic registry-storage --from-file=config=examples/objectstorage/registry.minio.yaml
编辑gitlab helm chart模板
由于官方提供的helm charts不支持自定义gitlab的端口号,所以要对gitlab helm charts做一定的定制化修改,添加自定义端口的支持。
编辑templates/_helpers/tpl,新增:
{{- define "gitlab.gitlab.port" -}} {{- default "" .Values.global.hosts.gitlab.port -}} {{- end -}}
编辑
charts/gitlab/charts/geo-logcursor/templates/configmap.yml
,charts/gitlab/charts/toolbox/templates/configmap.yaml
,charts/gitlab/charts/webservice/templates/configmap.yml
,charts/gitlab/charts/sidekiq/templates/configmap.yaml
,charts/gitlab/charts/migrations/templates/configmap.yaml
,在gitlab.yml.erb
的host
下方新增一行,注意空格对齐上一行:port: {{ default "" (include "gitlab.gitlab.port" .) }}
部署gitlab
cd gitlab-v5.10.2 helm -n gitlab install gitlab -f values.yaml -f myvalues.yaml .
修复postgresql slave启动失败
postgresql slave启动会报错:
The POSTGRESQL_REPLICATION_PASSWORD variable is empty or not set. Set the envirable ALLOW_EMPTY_PASSWORD=yes to allow container to be started with blank passwords.
,需要修改secret gitlab-postgresql-password
,新增一个键值对:postgresql-replication-password: cmVwbF9wYXNzd29yZA==
其中
cmVwbF9wYXNzd29yZA==
为repl_password
的 base64 编码后的值。修复toolbox连接minio报错
编辑
configmap gitlab-toolbox
,修改cat <<EOF > "/${secret_dir}/.s3cfg"
下方的几个配置项的值,其中use_https
为新增项:access_key = minio的AccessKey secret_key = minio的SecretKey host_base = minio.minio.svc.cluster.local:9000 host_bucket = minio.minio.svc.cluster.local:9000/%(bucket) website_endpoint = http://minio.minio.svc.cluster.local:9000 use_https = False
配置完成后,重启 toolbox 使其加载正确的配置项。
创建praefect数据库及授权
GitLab Helm Chart 部署后,并不会自动创建 preafect 数据库及其授权,需要手动创建。
1、查询praefect的配置的数据库连接密码:
kubectl -n gitlab get secret gitlab-praefect-dbsecret -o jsonpath="{.data.secret}" | base64 -d; echo
2、进入postgresql master容器内执行命令创建数据库及授权:
kubectl -n gitlab exec -it gitlab-postgresql-master-0 -- /bin/bash
postgresql> PGPASSWORD=$(cat $POSTGRES_POSTGRES_PASSWORD_FILE) psql -U postgres postgresql> CREATE ROLE praefect WITH LOGIN; postgresql> \password praefect postgresql> 输入步骤1查询到的密码 postgresql> CREATE DATABASE praefect WITH OWNER praefect;
配置反向代理
使用nginx做反向代理。
1、安装nginx
yum install nginx -y systemctl enable --now nginx
2、配置反向代理
修改/etc/nginx/nginx.conf,内容如下:
... server { listen 8888 ssl http2; listen [::]:8888 ssl http2; server_name git.haxi.cc; root /usr/share/nginx/html; ssl_certificate "/etc/nginx/ssl/_.haxi.cc.crt" ssl_certificate_key "/etc/nginx/ssl/_.haxi.cc.key" ssl_session_cache shared:SSL:1m; ssl_ciphers HIGN:!aNULL:!MD5 ssl_prefer_server_ciphers on; client_max_body_size 512m; include /etc/nginx/default.d/*.conf; error_page 404 /404.html; location = /404.html { } error_page 500 502 503 504 /50x.html; location = 50x.html { } location / { proxy_pass http://10.43.125.236:8181; #10.43.125.236为gitlab webservice的svc ip proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-PORT $remote_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } } stream { upstream gitlabssh { server 10.43.17.193:8000 max_fails=3 fail_timeout=10s; #10.43.17.193为gitlab shell的svc ip } server { listen 8000; proxy_connect_timeout 20s; proxy_timeout 5m; proxy_pass gitlabssh; } }
3、SSL证书
证书放这里:
/etc/nginx/ssl/_.haxi.cc.crt
/etc/nginx/ssl/_.haxi.cc.key4、重载nginx使配置生效
systemctl reload nginx
5、SMTP配置
kubectl -n gitlab edit cm gitlab-sidekiq
修改email_from, smtp_setting.rb(address, user_name, password)