从 GitLab 开始的全新 DevOps 之旅

  1. 1. 选择 GitLab 的原因
  2. 2. 准备资源
    1. 2.1. 服务器
    2. 2.2. CDN
  3. 3. 开始搭建
    1. 3.1. 部署 GitLab
      1. 3.1.1. 安装 docker 与 docker-compose
      2. 3.1.2. 编写 docker-compose.yml 文件
      3. 3.1.3. 编写 config.rb 配置文件
        1. 3.1.3.1. 主要配置
        2. 3.1.3.2. 默认主题色
        3. 3.1.3.3. Gravatar 相关反向代理
        4. 3.1.3.4. SMTP 设置
        5. 3.1.3.5. 接收邮件设置
        6. 3.1.3.6. S3 外部存储设置
        7. 3.1.3.7. Impersonation 功能
        8. 3.1.3.8. 备份设置
        9. 3.1.3.9. Matomo 与 Sentry
        10. 3.1.3.10. 容器镜像仓库
        11. 3.1.3.11. 内置 nginx 代理
        12. 3.1.3.12. GitLab Pages
        13. 3.1.3.13. GitLab KAS
        14. 3.1.3.14. Mattermost
        15. 3.1.3.15. Service Desk 服务台
        16. 3.1.3.16. 禁用数据上报
        17. 3.1.3.17. 开启节点监控
      4. 3.1.4. 放置需要使用的 SSL 证书
      5. 3.1.5. 启动 GitLab
    2. 3.2. 防火墙规则
      1. 3.2.1. 安装 ipset
      2. 3.2.2. 创建 IP 集
      3. 3.2.3. 创建防火墙规则
    3. 3.3. 部署 GitLab Runner
  4. 4. 成本核算
  5. 5. 参考资料
  6. 6. 附件

GitHub 终究还是个 Hub ——中心化的服务。即使它是全球最大的代码托管平台,无论是出于 DMCA 之类的法律原因导致自己辛苦编制的代码被删除(参见 GitHub DMCA Repository ),抑或是因为些许其他不可描述的因素导致心血资源的消失,这些都是将代码部署在如 GitHub 这样的公共平台上可能发生的恶性事件。

如果本地有原始代码,那尚且还有一救,利用其他的平台重新开始;如果备份已然丢失,那么将宣告的是代码的完全湮灭。前有 youtube-dl 被封导致的群情激愤(虽然已经恢复),后有 ncmdump 被一纸 DMCA 摧毁带来的生态进一步封闭、矛盾进一步激化,中心化的服务,面临着的不光是各地法律的约束,更有各种敌对势力可能借助平台运营行为带来的打击。本着数据无价、自建为王的原则,在经过多方比对 Bitbucket 、 Gitea 与 GitLab 等平台的相关优缺点后,我决定自建一个 GitLab 实例,成为自己最信任的代码托管平台。

选择 GitLab 的原因

Bitbucket 自建的方案称为 Bitbucket Server ,但已经于 2021 年 2 月 2 日停止销售,并将于 2024 年 2 月 2 日停止支持,因而直接不纳入考虑范围。其他的一些开源平台,则因为有些 UI 过于古早,存在审美和逻辑交互上的障碍,所以不予考虑。最终的目光聚集在了 GitLab 和 Gitea 上,并基于多方的资料收集、比较,确定了 GitLab CE (Community Edition) 作为搭建的基础。

选择 GitLab 并不是因为 Gitea 不完美,正相反:使用 go 编写的 Gitea 更轻量、更快速、也更符合“搭建一个代码托管平台”最初的愿景;但正是因为它的轻量,导致它并不是一个一应俱全的产品,更多的需要依靠其他产品的结合:比如 TeamCity 提供 CI/CD 流水线,比如手搓容器镜像管理平台,比如暂时不知道能不能配置的外部存储和 Git LFS 存储支持等等。

虽然作为一名 JetBrains 全家桶用户对 TeamCity 这个方便实用的 CI/CD 平台有种天然的好感,但由于它是专有软件,免费使用的版本有严格的限制(3 个 Agent , 100 个构建配置),因而并不是一个足够打动人的产品。而没有 GitLFS 和外部存储的支持,也意味着并不能存储可能出现的大文件,也许未必会使用到——但当有所需要的时候,这些种种为了轻便而舍弃的功能会成为一块块前期埋下的绊脚石。而容器镜像的管理,一个直观的界面能带来的效率提升是再多的命令行调用都无法带来的。 Docker 官方没有提供管理面板,而一些第三方的管理面板也大多古老陈旧,所以也就并没有太多的选择余地。 Docker Hub 也存在 Hub 的问题,并且由于它是一款商业产品,免费版的体验,不能说所有人都会很糟糕吧——只能说是见仁见智了。

对应的,使用 Ruby on Rails 编写的经典代码托管平台 GitLab 则是一系列服务应有尽有,代价是更高的资源消耗—— Ruby 本身内存管理就受到诟病,而 Rails 使用 Ruby 的方式更是让内存成倍上涨,随手一搜「gitlab memory」就会有大量关于 GitLab 内存处理与优化相关的资料。

但这并不能阻挡 GitLab 成为一个优秀的产品。如同那句经典的自嘲:“贵不是商品的错,而是我穷的错”类似的道(歪)理,只要经过精心调整配置、在准备充足资源的环境下,相信 GitLab 能发挥出完美的水平,成为一位忠实可靠的 DevOps 伴侣。

之所以选择 CE 而不是 EE (Enterprise Edition) 进行搭建,是因为 GitLab EE 为专有软件,而基于 MIT 协议开源的 GitLab CE 已经足够满足我的需求,因而可以算是一种开源爱好者的精神追求吧——总觉得大差不差情况下,开放的比闭源的会更好一点。

「极狐」是 GitLab 中国大陆和港澳地区的特供版,所以在国际开发环境的内容部署上,还是不要沾染这些地区特供的版本了吧。

准备资源

服务器

根据 GitLab installation minimum requirements ,对于 GitLab 服务器需要的资源,以承载 500 名用户为例,官方的推荐是 4 核处理器、 4GB 内存与 至少 20GB 硬盘存储空间( GitLab Omnibus 本体 + PostgreSQL 数据库 + 一些其他的存储需要)。

对于 GitLab Runner (CI/CD 执行时使用的容器) 所需的服务器资源,由于不同的项目有不同的消耗,所以并没有一个统一的规格。作为参考, GitLab 提供的 SaaS 服务上使用的 Runner 规格为 1 核 CPU 与 3.75GB 内存。

由于 Runner 的运行具有突发性和不确定性,在生产环境中请一定避免将 Runner 与 GitLab 安装在同一环境下。

我为 GitLab 本体准备的是一台 6 核 AMD EPYC 7282 处理器, 16GB 内存, 600GB SSD (500+GB 可用)的 VPS 。为 GitLab Runner 准备的是一台 4 核处理器, 8 GB 内存的 VPS 。

CDN

为了进一步优化站点的使用体验并提升站点安全性,我为站点启用了 CloudFlare 提供的 CDN 服务。

其中, CloudFlare 有一款名为 Spectrum 的产品可以提供针对 SSH 的保护,但仅在 Pro 及以上的方案中提供。因而我为即将用于代码部署的域名订购了 CloudFlare Pro 。但有一点需要注意的是, CloudFlare Spectrum 与一般的域名代理功能是有冲突的,它们不能运行在同一个具体域名下;因而对于 SSH 连接需要使用一个子域名,此处我选择的是 ssh

为进一步保护源站安全、避免绕过 CloudFlare 直接对源站进行访问的流量经过,我在 CloudFlare 上配置 SSL/TLS 加密模式为 完整(严格) ,并开启了 Authenticated Origin Pull 功能。其中使用到的服务端证书可以在 Zone-Level — Cloudflare certificate 获得,在文后的附件部分也会附上该证书文件。我还为源站服务器设置了防火墙规则,具体的内容在后面的部分会有涉及。

另外,为了避免防火墙阻挡 Runner 与 GitLab 的通信,需要在 防火墙 -> 防火墙规则 中为 GitLab Runner 设置允许绕行的策略。我的设置方案为 UserAgent 包含 gitlab-runner 字样的请求 允许 通过。

开始搭建

部署 GitLab

为了尽可能简化部署过程、减少系统不同导致的部署细节差异,我使用了 root 权限下的 Debian 11 作为主操作系统,使用 GitLab 官方提供的 CE 版镜像,配合 Docker + Docker Compose 方案进行部署。

安装 docker 与 docker-compose

首先安装 docker 。使用以下的指令需要您已经准备好 curl 命令行。如果没有,您可以先安装它。

1
bash <(curl -L -s https://get.docker.com)

安装完成后,下载使用二进制预先构建的 docker-compose 可执行文件

1
2
3
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

编写 docker-compose.yml 文件

我参照的是官方的 Install GitLab using Docker Compose 提供的参考配置,并结合 swarm mode 的配置进行了一定的修改,以方便使用,并能进一步优化后续可能出现的升级、更新等操作时的流程。我使用了外置配置文件并映射进入容器的方案,这样当有配置更新时,直接在容器内执行 gitlab-ctl reconfigure 即可。

gitlab 的 docker 镜像使用的是 Omnibus 搭建方案,已经集成 PostgreSQL 与 Redis 数据库(尽管版本比较老旧,如 GitLab 14.7.3 的内置 PostgreSQL 为 12.7 ),因而无需像传统的原子应用程序那样手动配置外置的数据库。而在正式的企业生产环境中,更为推荐的做法是使用 kubernetes 部署 GitLab 的各个组件,并单独设定外接的 PostgreSQL 与 Redis 数据库。

最终获得的 docker-compose.yml 文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: '3.6'
services:
gitlab:
image: gitlab/gitlab-ce
ports:
- '443:443'
- '22:22'
volumes:
- './ssl:/etc/ssl:ro'
- './config:/etc/gitlab'
- './logs:/var/log/gitlab'
- './data:/var/opt/gitlab'
- './config.rb:/omnibus_config.rb:ro'
- '/proc:/host/proc:ro'
- '/sys:/host/sys:ro'
- '/:/rootfs:ro'
shm_size: '4g'
environment:
GITLAB_OMNIBUS_CONFIG: "from_file('/omnibus_config.rb')"

需要注意的除了 gitlab-ce 外,由于需要使用的是 HTTPS 协议,因而此处没有暴露容器的 80 端口;并且将固定使用的 SSL 证书单独存放到一个只读的目录下。

GitLab 官方文档中推荐的共享内存大小为 256MB ,在此我设置为了 4GB ,以便更好地利用系统资源,优化使用体验。

编写 config.rb 配置文件

毋庸置疑,这是所有步骤中最为关键的一步,也因此我花了一整个周末的时间来仔细研读每一块配置内容的含义。此处的配置文件,也将以脱敏后分块的方式呈现,以方便您更好的阅读和理解。完整的配置文件将会附在文章末尾,您可以直接以此为模板进行修改。

此处先附上官方配置样例的链接: gitlab.rb.template

主要配置

此处标注了 GitLab 运行实例的外部主域名,和 SSH 使用的主机名(在项目内提示 SSH 连接时使用)。由于 CloudFlare Spectrum 与直接 HTTPS 代理并不兼容,因此只能无奈让 SSH 使用 ssh 子域名进行连接。

1
2
3
4
5
## Main URL
external_url 'https://<gitlab.instance>'

## SSH Host
gitlab_rails['gitlab_ssh_host'] = '<ssh.gitlab.instance>'
默认主题色

我使用了亮蓝色作为默认主题色。

1
2
## Default theme
gitlab_rails['gitlab_default_theme'] = 7 # Light Blue

附上具体的颜色列表:

ID 英文原名 中文名
1 Indigo 靛蓝色
2 Dark 深色
3 Light 亮色
4 Blue 蓝色
5 Green 绿色
6 Light Indigo 亮靛蓝色
7 Light Blue 亮蓝色
8 Light Green 亮绿色
9 Red 红色
10 Light Red 亮红色
Gravatar 相关反向代理

由于 Gravatar 在大陆的访问速度不佳,因此我们需要使用反向代理,以便让用户能正确加载头像。当然,此处的设置也可为兼容的其他服务,如 Libavatar ,或是自建的 邮箱 - 头像 映射服务等。

如果您没有反向代理或是其他服务的需要,请不要添加这些行,使用默认的 Gravatar 即可。

1
2
3
## Gravatar
gitlab_rails['gravatar_plain_url'] = 'http://<gravatar.reverse.proxy>/avatar/%{hash}?s=%{size}&d=identicon'
gitlab_rails['gravatar_ssl_url'] = 'https://<gravatar.reverse.proxy>/avatar/%{hash}?s=%{size}&d=identicon'
SMTP 设置

我使用的是自建的 mailcow: dockerized 邮局服务,因而使用的是以下的配置方案。 GitLab 官方根据不同的主流邮局系统给出了对应的配置选项,可以参考官方文档中的 SMTP settings 部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
## SMTP settings
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "<mail.server>"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "info@<gitlab.instance>"
gitlab_rails['smtp_password'] = "<PASSWORD>"
gitlab_rails['smtp_domain'] = "<mail.server>"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['smtp_openssl_verify_mode'] = 'none'
gitlab_rails['gitlab_email_from'] = 'info@<gitlab.instance>'
gitlab_rails['smtp_pool'] = true
接收邮件设置

GitLab 使用接收邮箱来方便用户进行一些流程,例如 使用邮件回复 issue 、使用邮件开启 issue 、使用邮件开启新的合并请求、通过邮件提供帮助 等。

此处我设置的是使用 mailcow 的 IMAP 协议进行邮件处理的方案,您也可以根据官方文档中的 Incoming email 部分配置参考来设置您的邮件服务器。

1
2
3
4
5
6
7
8
9
10
## Incoming settings
gitlab_rails['incoming_email_enabled'] = true
gitlab_rails['incoming_email_address'] = "incoming+%{key}@<gitlab.instance>"
gitlab_rails['incoming_email_email'] = "incoming@<gitlab.instance>"
gitlab_rails['incoming_email_password'] = "<PASSWORD>"
gitlab_rails['incoming_email_host'] = "<mail.server>"
gitlab_rails['incoming_email_port'] = 993
gitlab_rails['incoming_email_ssl'] = true
gitlab_rails['incoming_email_start_tls'] = false
gitlab_rails['incoming_email_expunge_deleted'] = true
S3 外部存储设置

使用外部存储能有效控制在 GitLab 服务器上的文件大小,并能提升其运行的稳定性,在升级和迁移时都会变得更加方便。

我使用的是 Wasabi 提供的服务,不同的服务商的配置可能会有所不同,请根据您的服务商的相关配置方案进行配置。

注意这些模块的存储细节可以在后续单独的字段中被单独配置,此处只是提供了一个整合管理的方案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## S3 Storage settings
gitlab_rails['object_store']['enabled'] = true
gitlab_rails['object_store']['connection'] = {
'provider' => 'AWS',
'region' => '<BUCKET_REGION>',
'aws_access_key_id' => '<ACCESS_KEY>',
'aws_secret_access_key' => '<SECRET_KEY>',
'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4.
'endpoint' => 'https://s3.<BUCKET_REGION>.wasabisys.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces
'host' => 's3.<BUCKET_REGION>.wasabisys.com',
'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object'
}
gitlab_rails['object_store']['storage_options'] = {}
gitlab_rails['object_store']['proxy_download'] = true
gitlab_rails['object_store']['objects']['artifacts']['bucket'] = 'artifacts-bucket-name'
gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = 'external-diffs-bucket-name'
gitlab_rails['object_store']['objects']['lfs']['bucket'] = 'lfs-bucket-name'
gitlab_rails['object_store']['objects']['uploads']['bucket'] = 'uploads-bucket-name'
gitlab_rails['object_store']['objects']['packages']['bucket'] = 'packages-bucket-name'
gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = 'dependency-proxy-bucket-name'
gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = 'terraform-state-bucket-name'
gitlab_rails['object_store']['objects']['ci_secure_files']['bucket'] = 'ci-secure-files-bucket-name'
gitlab_rails['object_store']['objects']['pages']['bucket'] = 'pages-bucket-name'

Wasabi 虽然能提供全网最便宜的 S3 兼容存储解决方案 ($7/1TB/1月) ,但它有最小计费起始,并在文件删除后仍会持续计费 3 个月,所以见仁见智吧。

Impersonation 功能

这个功能可以让管理员暂借用户身份,从管理的角度讲保持开启也许能更方便,但从安全的角度来讲还是关闭比较好。

1
2
## Impersonation settings
gitlab_rails['impersonation_enabled'] = false
备份设置

备份是最重要的,所以这一块在全部设置完后可以使用 gitlab-backup create 指令创建一个备份文件进行调试测试。我使用了与之前同样的 S3 存储方案,因而设置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
## Backup Settings
gitlab_rails['backup_upload_connection'] = {
'provider' => 'AWS',
'region' => '<BUCKET_REGION>',
'aws_access_key_id' => '<ACCESS_KEY>',
'aws_secret_access_key' => '<SECRET_KEY>',
'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4.
'endpoint' => 'https://s3.<BUCKET_REGION>.wasabisys.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces
'host' => 's3.<BUCKET_REGION>.wasabisys.com',
'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object'
}
gitlab_rails['backup_upload_remote_directory'] = 'backup-bucket-name'
gitlab_rails['env'] = {
"SKIP" => "uploads,builds,artifacts,lfs,pages,terraform_state,packages"
}
gitlab_rails['backup_encryption'] = 'AES256'
gitlab_rails['backup_encryption_key'] = '<YOUR 32-BYTE KEY HERE>'

请注意 "SKIP" 的内容,默认设置中会跳过对数据库代码仓库的备份,但在本文所述的配置环境中这样做可能会有安全隐患;而 terraform_state 和 packages 已经存储到外部存储中,所以不需要备份,因而进行了如上文的修改。

完整的备份列表可以参见 Excluding specific directories from the backup

Matomo 与 Sentry

Matomo (原名 Piwik )是用于统计站点访问量信息的一个开源可自建的 Google Analytics 替代方案,而 Sentry 是一个用于收集错误信息的开源可自建项目。如果您有对应的需求,您可以在这里配置 Matomo 和 Sentry 。

1
2
3
4
5
6
7
8
9
10
## Matomo
gitlab_rails['extra_matomo_url'] = 'matomo.server'
gitlab_rails['extra_matomo_site_id'] = '0'
gitlab_rails['extra_matomo_disable_cookies'] = false

## Sentry
gitlab_rails['sentry_enabled'] = true
gitlab_rails['sentry_dsn'] = 'https://<key>@sentry.io/<project>'
gitlab_rails['sentry_clientside_dsn'] = 'https://<key>@sentry.io/<project>'
gitlab_rails['sentry_environment'] = 'production'
容器镜像仓库

Docker 模式下部署的 GitLab 容器镜像仓库使用外部存储(S3)一定会失败、无法工作的,具体的解决方案还有待进一步的研究调试。

GitLab Omnibus 部署方案集成了容器镜像仓库的功能,可以通过类似如下的配置来启用它:

1
2
3
4
5
## Container Registry settings
registry_external_url 'https://reg.<gitlab.instance>'
registry_nginx['ssl_certificate'] = "/etc/ssl/<gitlab.instance>/cert.pem"
registry_nginx['ssl_certificate_key'] = "/etc/ssl/<gitlab.instance>/key.pem"
gitlab_rails['registry_enabled'] = true
内置 nginx 代理

GitLab Omnibus 部署方案会使用一个 nginx 作为整体的反向代理整合,以保证统一管理所有的流量出入,并提供了一系列较为精细的配置选项,因而没必要再在前端追加一个 nginx 作为反向代理,我是直接让容器直接监听在 443 端口上的。

因而需要使用系列的参数来配置 nginx 。不同部分的需求已经分散在不同的模块中,此处仅指出一些与 CloudFlare 最紧密关联的配置:

1
2
3
4
5
6
## Built-in NGINX settings
letsencrypt['enable'] = false
nginx['ssl_verify_client'] = "on"
nginx['ssl_client_certificate'] = "/etc/ssl/cloudflare.crt"
nginx['ssl_certificate'] = "/etc/ssl/<gitlab.instance>/cert.pem"
nginx['ssl_certificate_key'] = "/etc/ssl/<gitlab.instance>/key.pem"

由于前面加了一层 CloudFlare 的 CDN 作为反向代理,因而此处关闭了使用 Let’s Encrypt 获取证书的功能,而是使用了 CloudFlare 签发的供源站使用的证书;并且开启了 Verify Client 功能,以避免绕过 CloudFlare 的请求(比如端口扫描)成功访问。后面还有一节是配置防火墙规则的。

开启 ssl_verify_client 会导致容器本地健康请求失败变成 unhealthy ,这是正常现象,可以通过公开的健康状态请求端口(可以在 管理中心 -> 监控 -> 运行状况检查 (/admin/health_check) 看到)获取最真实的信息。

GitLab Pages

GitLab Pages 是一个静态页面提供服务,但是在我们现在这样的配置下第三方的域名如果不经由 CloudFlare 估计不是太好访问,因为它不知道服务器的真实地址因而无法解析,而且会被防火墙规则拦截请求。但依旧可以提供这项服务的配置,方便加入了代理的域名经由的请求(我还没试过):

1
2
3
4
5
## GitLab Pages
pages_external_url "https://pages.<gitlab.instance>/"
gitlab_pages['enable'] = true
pages_nginx['ssl_certificate'] = "/etc/ssl/<gitlab.instance>/cert.pem"
pages_nginx['ssl_certificate_key'] = "/etc/ssl/<gitlab.instance>/key.pem"
GitLab KAS

全称 Kubernetes Agent Server ,这是用于将一个 k8s 集群连接到 GitLab 进行 CI/CD 的服务。虽然不太明白,但还是将其配置好:

1
2
3
4
5
6
7
## GitLab Kubernetes Agent Server
gitlab_rails['gitlab_kas_enabled'] = true
gitlab_rails['gitlab_kas_external_url'] = 'ws://<gitlab.instance>/-/kubernetes-agent/'
gitlab_rails['gitlab_kas_external_k8s_proxy_url'] = 'https://<gitlab.instance>/-/kubernetes-agent/'
gitlab_kas['enable'] = true
gitlab_kas['sentry_dsn'] = 'https://<key>@sentry.io/<project>'
gitlab_kas['sentry_environment'] = 'production'
Mattermost

Mattermost 是一个开源可自建的在线聊天服务,主要用作 Slack 与 Microsoft Teams 的开源替代品。 GitLab Omnibus 集成了 Mattermost 的服务端,并支持让 Mattermost 通过 OAuth2 授权来获取用户的信息,实现 SSO ( Single Sign On ,单点登录 )的功能。

Mattermost 需要的应用 ID 和 私钥 并不会像 Grafana 那样在 GitLab 初始化的过程中被自动创建,因而需要在初始化完成后去 GitLab 管理员控制台手动设置,再在加入配置文件后重新生成 GitLab 配置。估计是一个 bug 。
并且 Mattermost 需要访问 user API 端点,因而需要授权 read_user 权限,而不是像官方文档描述的那样不需要授予任何权限(其实是因为不授予任何权限会报错不让创建应用)。

1
2
3
4
5
6
7
8
9
10
11
12
13
## GitLab Mattermost
mattermost_external_url 'https://mm.<gitlab.instance>'
mattermost['enable'] = true
mattermost['team_site_name'] = "GitLab.MM"
mattermost_nginx['ssl_certificate'] = "/etc/ssl/<gitlab.instance>/cert.pem"
mattermost_nginx['ssl_certificate_key'] = "/etc/ssl/<gitlab.instance>/key.pem"
mattermost['gitlab_enable'] = true
mattermost['gitlab_id'] = "<OAuth Application ID from GitLab>"
mattermost['gitlab_secret'] = "<OAuth Application Secret from GitLab>"
mattermost['gitlab_scope'] = "read_user"
mattermost['gitlab_auth_endpoint'] = "https://<gitlab.instance>/oauth/authorize"
mattermost['gitlab_token_endpoint'] = "https://<gitlab.instance>/oauth/token"
mattermost['gitlab_user_api_endpoint'] = "https://<gitlab.instance>/api/v4/user"
Service Desk 服务台

这个功能让团队可以不用其他任何工具,通过邮件直接与外接进行沟通交流。可以这样配置:

1
2
3
4
5
6
7
8
9
## Service Desk
gitlab_rails['service_desk_email_enabled'] = true
gitlab_rails['service_desk_email_address'] = "contact_project+%{key}@<gitlab.instance>"
gitlab_rails['service_desk_email_email'] = "contact_project@<gitlab.instance>"
gitlab_rails['service_desk_email_password'] = "<PASSWORD>"
gitlab_rails['service_desk_email_host'] = "<mail.server>"
gitlab_rails['service_desk_email_port'] = 993
gitlab_rails['service_desk_email_ssl'] = true
gitlab_rails['service_desk_email_start_tls'] = false
禁用数据上报

GitLab 默认会定期将实例的数据上报给官方的开发团队,以便于数据分析和用户体验优化。但是考虑到这种数据上报的行为可能会影响到开发者代码的隐秘性与安全性,所以在此处关闭了这个功能。

如果您没有关闭这个功能,您可以在 管理中心 -> 设置 -> 指标与分析 (/admin/application_settings/metrics_and_profiling) 中的 使用情况统计 展开栏下选择 “启用注册功能” ,以免费享受一些稍微进阶的功能。

1
2
## Disable Service Ping
gitlab_rails['usage_ping_enabled'] = false
开启节点监控

默认情况下, 由于监控的数据采集点为容器,默认的配置参数并非宿主机因而没有意义,因而 docker 运行环境时会默认关闭节点数据采集功能(参见 commit/891444 ),因而导致失去对节点状态的感知, grafana 中也一片空白。但可以通过指定 node_exporter 监听路径的方式来实现节点监控,其中映射所需的路径已经在 docker-compose.yml 中完成了只读模式的映射,以下是启动该功能并指定正确的 node-exporter 运行参数相关的配置:

1
2
3
4
5
6
7
8
9
## Enable node_exporter
node_exporter['enable'] = true
node_exporter['flags'] = {
'collector.textfile.directory' => "/var/opt/gitlab/node-exporter/textfile_collector",
'path.procfs' => "/host/proc",
'path.sysfs' => "/host/sys",
'path.rootfs' => "/rootfs",
'collector.filesystem.ignored-mount-points' => "'^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)'"
}

放置需要使用的 SSL 证书

根据配置文件中的描述,将所需的 SSL 证书放置到了 ./ssl 目录下。

  1. CloudFlare 客户端认证证书:可以从 Zone-Level — Cloudflare certificate 处获得,在文后的附件部分也会附上该证书文件。
  2. CloudFlare 提供的用于部署到服务端的证书:可以从具体域名的 SSL/TLS -> Origin Server -> Origin Certificates 处签发。

如果您使用和我一样的配置方案策略,那么放置完证书后的目录结构应该像这样:

tree
1
2
3
4
5
6
7
8
9
.
├── config.rb
├── docker-compose.yml
└── ssl
   ├── cloudflare.crt
   └── <gitlab.instance>
   ├── cert.pem
   └── key.pem

启动 GitLab

到此, GitLab 应该已基本配置完成,您可以使用 docker-compose pull 拉取最新的镜像,并使用 docker-compose up -d 启动它。

GitLab 由于体系庞大、组件繁多,且初次启动会进行大量初始化操作,因而启动起来比较缓慢;当启动完成后,您即可进入系统进行体验。

默认的账号为 root ,默认的密码由初始化时生成,您可以通过 docker-compose exec gitlab grep 'Password:' /etc/gitlab/initial_root_password 命令获得。请在 24 小时内获得您的密码,出于安全因素考虑,它将在启动 24 小时后被删除。

防火墙规则

到此 GitLab 主体的安装与配置部分基本接近尾声,我们使用防火墙为服务器的安全进行进一步的加固处理。我的习惯是使用 iptables (尽管它已经被 nftables 取代)。

安装 ipset

我使用的这个服务器上默认没有安装 ipset 软件包,所以需要安装一份。

1
apt install ipset -y

创建 IP 集

然后是创建 IP 集规则,以便用于管理来自 CloudFlare 的 IP 。

1
2
3
ipset create cfv4 hash:net
curl -sS https://www.cloudflare.com/ips-v4/ | xargs -I {} ipset add cfv4 {}
ipset save cfv4 -f cfv4.txt # 可以使用 ipset restore -f cfv4.txt 来恢复

其中第一条指令创建了一个名为 cfv4 ,类型为 hash:net 的 IP 集。名称可以随意,类型推荐为 hash:net ,因为 CloudFlare 提供的 IP 信息是以 CIDR 格式列出的。

第二条指令从 CloudFlare 提供的 IPv4 地址列表中提取出 IP 地址,并将其添加到上一步创建的规则集中。

第三条指令将规则集保存到文件中。因为 ipset 是一个运行在内存中的记录列表,默认情况下会在开机时自动丢失,因而需要手动执行一次保存动作,以便在重新启动系统时能够手动执行恢复。

对 IPv6 也是一样的处理流程,只是需要进行一些显式的指定:

1
2
3
ipset create cfv6 hash:net family inet6
curl -sS https://www.cloudflare.com/ips-v6/ | xargs -I {} ipset add cfv6 {}
ipset save cfv6 -f cfv6.txt # 可以使用 ipset restore -f cfv6.txt 来恢复

创建防火墙规则

如果您使用的是直接部署的方案,您可以使用以下的代码:

1
2
iptables -I INPUT -p tcp -m multiport --dports ssh,http,https -m set ! --match-set cfv4 src -j DROP
iptables -I INPUT -p udp -m multiport --dports https -m set ! --match-set cfv4 src -j DROP
1
2
ip6tables -I INPUT -p tcp -m multiport --dports ssh,http,https -m set ! --match-set cfv6 src -j DROP
ip6tables -I INPUT -p udp -m multiport --dports https -m set ! --match-set cfv6 src -j DROP

如果您像我一样使用的是 Docker 进行部署的方式,请注意 Docker 容器暴露到宿主机的流量是不经由 INPUT 表的。 Docker 自己会管理一张 DOCKER 表,而对于我们用户所需要的配置,需要手动在 DOCKER-USER 表中指定具体流量的通信与拦截规则:

1
2
iptables -I DOCKER-USER -i ext_if -p tcp -m multiport --dports ssh,http,https -m set ! --match-set cfv4 src -j DROP
iptables -I DOCKER-USER -i ext_if -p udp -m multiport --dports https -m set ! --match-set cfv4 src -j DROP

ext_if 的意思是外部网卡( external interface ),例如您的外部网卡是 eth0 ,那么您需要将这个值替换为 eth0 ,否则防火墙规则不会生效。
如果不加 -i 选项,那么防火墙规则会对所有网卡生效,在此处的表现为容器的出站连接( HTTPS 、 SSH )也会失败,导致外部存储失效等一系列疑难杂症(表现状况为连接超时)。

Docker 默认不带有 IPv6 支持,因而此处略过了对 IPv6 规则集的配置。如果您有相关的需要,您可以使用类似的命令自行修改。

iptables 同样默认不带有持久化,因而需要显式执行备份命令,以便在重新启动系统时能够手动执行恢复。

1
2
iptables-save > ip4tables.txt # 可以使用 iptables-restore ip4tables.txt 来恢复
ip6tables-save > ip6tables.txt # 可以使用 ip6tables-restore ip6tables.txt 来恢复

部署 GitLab Runner

这一个部分其实我也不是太明白,主要记录一下我的方案:使用 k3s 部署本地 k8s 环境,使用 helm 管理镜像,让 GitLab Runner 在 k8s 环境中运行。

这里的指令因为调试了好几天已经混乱了,可能有误,仅供参考。

k3s 和 helm 的环境可以这样安装:

1
2
3
4
5
bash <(curl -L -s https://get.docker.com) # 安装 docker
curl -sfL https://get.k3s.io | sh - # 安装 k3s
nano /etc/profile # 在末尾加上 `export KUBECONFIG=/etc/rancher/k3s/k3s.yaml` 这一行,这样 kubectl 命令就可以使用了
source /etc/profile # 应用变更
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash # 安装 helm

官方文档可以参见 GitLab Runner Helm Chart ,主要的配置文件 values.yaml 可以从 values.yaml 获取。

为了避免我比较时候有什么疏漏,我会将完整的配置文件作为附件附在文章末尾(当然也有可能就是错的)。需要修改的部分有:

  1. 第 46 行 gitlabUrl 部分,请取消注释并设置为您的 GitLab URL 。
  2. 第 52 行 runnerRegistrationToken 部分,请取消注释并设置为您的 GitLab Runner 的注册令牌 (可以从 GitLab 的 管理中心 -> 概览 -> Runner -> 注册一个实例 runner (右上角) 获取)
  3. 第 67 行 unregisterRunners 部分可以取消注释,这一个选项的意思是当一个 runner 结束时,会自动从 GitLab 中注销,这样就不会出现 GitLab 中有多个过时的失效 runner 的情况。
  4. 第 87 行 concurrent 部分,根据您的实际服务器配置调整最大并发运行的任务数量。
  5. 第 107 行 sentryDsn 部分,如果您需要为 Runner 启用 Sentry ,请取消注释并设置为您的 Sentry DSN 。
  6. 第 132 行的 create 部分需要设置为 true ,否则会出现 Runner CI/CD 容器没有权限导致运行失败的问题。
  7. 删除第 145 行 rules 后面的方括号(使用下面的数组规则)
  8. 解除第 146 行 ~ 第 150 行的注释并调整内容,请参考文末的附件 (这个权限问题官方样例里配置的根本跑不起来,真是服了)
  9. 如果是出于兼容性考虑,为了保证使用套娃容器 (docker-in-docker, did) 的旧流水线能够运行,第 374 行 privileged 部分,请取消注释并设置为 true 。但出于安全性考虑,建议这里保持 false ,并使用上述标注中提到的文档中介绍的使用 Kaniko 进行优化权限构建的方案(参见 Best practices for building containers without privileged mode )。

然后这样启动 Runner :

1
2
3
helm repo add gitlab https://charts.gitlab.io # add gitlab charts
kubectl create namespace gitlab-runner # create namespace
helm upgrade --install -f ./values.yaml --namespace gitlab-runner gitlab-runner gitlab/gitlab-runner # start gitlab-runner

如果一切正常,那么您将可以在 GitLab 的控制台中看到一个 Runner 实例。如果不正常,那应该是我记错了什么。

到此,所有的基础配置与安装工作已经完成。

成本核算

产品 规格 功能 价格(按年付计算)
域名 - 服务域名解析 $37.05
CloudFlare Pro CDN 与 SSH 保护 $240.00
GitLab CE 代码托管 $0.00
服务器 6C16G GitLab 服务器 $143.88
服务器 4C8G Runner 服务器 $83.88
Wasabi 按 1TB 计算 S3 静态资源存储服务 $84.00

年预计运行总开销为 $588.81 ,约合人民币 ¥3740.36 元(汇率按照截稿时的 6.3524 计算)。

当然,这是一个出于生产环境稳定性考虑的比较大规模的部署模式,需要相对高昂的各项服务费用;如果仅是使用小服务器 + 直接连接的方案,那么在只有服务器费用的情况下,将年开销控制在千元以内是完全没有问题的。而如果是个人纯代码托管、无其他需要的方案,使用 Gitea 甚至能将成本控制在百元以内。

参考资料

  1. Gitea vs GitLab
  2. GitLab Docs
  3. Docker and iptables

附件

CloudFlare 中间证书
cloudflare.crt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
-----BEGIN CERTIFICATE-----
MIIGCjCCA/KgAwIBAgIIV5G6lVbCLmEwDQYJKoZIhvcNAQENBQAwgZAxCzAJBgNV
BAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMRQwEgYDVQQLEwtPcmln
aW4gUHVsbDEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv
cm5pYTEjMCEGA1UEAxMab3JpZ2luLXB1bGwuY2xvdWRmbGFyZS5uZXQwHhcNMTkx
MDEwMTg0NTAwWhcNMjkxMTAxMTcwMDAwWjCBkDELMAkGA1UEBhMCVVMxGTAXBgNV
BAoTEENsb3VkRmxhcmUsIEluYy4xFDASBgNVBAsTC09yaWdpbiBQdWxsMRYwFAYD
VQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMSMwIQYDVQQD
ExpvcmlnaW4tcHVsbC5jbG91ZGZsYXJlLm5ldDCCAiIwDQYJKoZIhvcNAQEBBQAD
ggIPADCCAgoCggIBAN2y2zojYfl0bKfhp0AJBFeV+jQqbCw3sHmvEPwLmqDLqynI
42tZXR5y914ZB9ZrwbL/K5O46exd/LujJnV2b3dzcx5rtiQzso0xzljqbnbQT20e
ihx/WrF4OkZKydZzsdaJsWAPuplDH5P7J82q3re88jQdgE5hqjqFZ3clCG7lxoBw
hLaazm3NJJlUfzdk97ouRvnFGAuXd5cQVx8jYOOeU60sWqmMe4QHdOvpqB91bJoY
QSKVFjUgHeTpN8tNpKJfb9LIn3pun3bC9NKNHtRKMNX3Kl/sAPq7q/AlndvA2Kw3
Dkum2mHQUGdzVHqcOgea9BGjLK2h7SuX93zTWL02u799dr6Xkrad/WShHchfjjRn
aL35niJUDr02YJtPgxWObsrfOU63B8juLUphW/4BOjjJyAG5l9j1//aUGEi/sEe5
lqVv0P78QrxoxR+MMXiJwQab5FB8TG/ac6mRHgF9CmkX90uaRh+OC07XjTdfSKGR
PpM9hB2ZhLol/nf8qmoLdoD5HvODZuKu2+muKeVHXgw2/A6wM7OwrinxZiyBk5Hh
CvaADH7PZpU6z/zv5NU5HSvXiKtCzFuDu4/Zfi34RfHXeCUfHAb4KfNRXJwMsxUa
+4ZpSAX2G6RnGU5meuXpU5/V+DQJp/e69XyyY6RXDoMywaEFlIlXBqjRRA2pAgMB
AAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgECMB0GA1Ud
DgQWBBRDWUsraYuA4REzalfNVzjann3F6zAfBgNVHSMEGDAWgBRDWUsraYuA4REz
alfNVzjann3F6zANBgkqhkiG9w0BAQ0FAAOCAgEAkQ+T9nqcSlAuW/90DeYmQOW1
QhqOor5psBEGvxbNGV2hdLJY8h6QUq48BCevcMChg/L1CkznBNI40i3/6heDn3IS
zVEwXKf34pPFCACWVMZxbQjkNRTiH8iRur9EsaNQ5oXCPJkhwg2+IFyoPAAYURoX
VcI9SCDUa45clmYHJ/XYwV1icGVI8/9b2JUqklnOTa5tugwIUi5sTfipNcJXHhgz
6BKYDl0/UP0lLKbsUETXeTGDiDpxZYIgbcFrRDDkHC6BSvdWVEiH5b9mH2BON60z
0O0j8EEKTwi9jnafVtZQXP/D8yoVowdFDjXcKkOPF/1gIh9qrFR6GdoPVgB3SkLc
5ulBqZaCHm563jsvWb/kXJnlFxW+1bsO9BDD6DweBcGdNurgmH625wBXksSdD7y/
fakk8DagjbjKShYlPEFOAqEcliwjF45eabL0t27MJV61O/jHzHL3dknXeE4BDa2j
bA+JbyJeUMtU7KMsxvx82RmhqBEJJDBCJ3scVptvhDMRrtqDBW5JShxoAOcpFQGm
iYWicn46nPDjgTU0bX1ZPpTpryXbvciVL5RkVBuyX2ntcOLDPlZWgxZCBp96x07F
AnOzKgZk4RzZPNAxCXERVxajn/FLcOhglVAKo5H0ac+AitlQ0ip55D2/mf8o72tM
fVQ6VpyjEXdiIXWUq/o=
-----END CERTIFICATE-----

GitLab 配置文件
config.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#########################################
# Gitlab setttings #
#########################################
##! Use `gitlab-ctl reconfigure` to restart services
##! after editing this file

## Main URL
external_url 'https://<gitlab.instance>'

## SSH Host
gitlab_rails['gitlab_ssh_host'] = '<ssh.gitlab.instance>' # With CloudFlare Spectrum enabled

## Default theme
gitlab_rails['gitlab_default_theme'] = 7 # Light Blue

## Gravatar
gitlab_rails['gravatar_plain_url'] = 'http://<gravatar.reverse.proxy>/avatar/%{hash}?s=%{size}&d=identicon'
gitlab_rails['gravatar_ssl_url'] = 'https://<gravatar.reverse.proxy>/avatar/%{hash}?s=%{size}&d=identicon'

## SMTP settings
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "<mail.server>"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "info@<gitlab.instance>"
gitlab_rails['smtp_password'] = "<PASSWORD>"
gitlab_rails['smtp_domain'] = "<mail.server>"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['smtp_openssl_verify_mode'] = 'none'
gitlab_rails['gitlab_email_from'] = 'info@<gitlab.instance>'
gitlab_rails['smtp_pool'] = true

## Incoming settings
gitlab_rails['incoming_email_enabled'] = true
gitlab_rails['incoming_email_address'] = "incoming+%{key}@<gitlab.instance>"
gitlab_rails['incoming_email_email'] = "incoming@<gitlab.instance>"
gitlab_rails['incoming_email_password'] = "<PASSWORD>"
gitlab_rails['incoming_email_host'] = "<mail.server>"
gitlab_rails['incoming_email_port'] = 993
gitlab_rails['incoming_email_ssl'] = true
gitlab_rails['incoming_email_start_tls'] = false
gitlab_rails['incoming_email_expunge_deleted'] = true

## S3 Storage settings
gitlab_rails['object_store']['enabled'] = true
gitlab_rails['object_store']['connection'] = {
'provider' => 'AWS',
'region' => '<BUCKET_REGION>',
'aws_access_key_id' => '<ACCESS_KEY>',
'aws_secret_access_key' => '<SECRET_KEY>',
'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4.
'endpoint' => 'https://s3.<BUCKET_REGION>.wasabisys.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces
'host' => 's3.<BUCKET_REGION>.wasabisys.com',
'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object'
}
gitlab_rails['object_store']['storage_options'] = {}
gitlab_rails['object_store']['proxy_download'] = true
gitlab_rails['object_store']['objects']['artifacts']['bucket'] = 'artifacts-bucket-name'
gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = 'external-diffs-bucket-name'
gitlab_rails['object_store']['objects']['lfs']['bucket'] = 'lfs-bucket-name'
gitlab_rails['object_store']['objects']['uploads']['bucket'] = 'uploads-bucket-name'
gitlab_rails['object_store']['objects']['packages']['bucket'] = 'packages-bucket-name'
gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = 'dependency-proxy-bucket-name'
gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = 'terraform-state-bucket-name'
gitlab_rails['object_store']['objects']['ci_secure_files']['bucket'] = 'ci-secure-files-bucket-name'
gitlab_rails['object_store']['objects']['pages']['bucket'] = 'pages-bucket-name'

## Impersonation settings
gitlab_rails['impersonation_enabled'] = false

## Backup Settings
gitlab_rails['backup_upload_connection'] = {
'provider' => 'AWS',
'region' => '<BUCKET_REGION>',
'aws_access_key_id' => '<ACCESS_KEY>',
'aws_secret_access_key' => '<SECRET_KEY>',
'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4.
'endpoint' => 'https://s3.<BUCKET_REGION>.wasabisys.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces
'host' => 's3.<BUCKET_REGION>.wasabisys.com',
'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object'
}
gitlab_rails['backup_upload_remote_directory'] = 'backup-bucket-name'
gitlab_rails['env'] = {
"SKIP" => "uploads,builds,artifacts,lfs,pages,terraform_state,packages"
}
gitlab_rails['backup_encryption'] = 'AES256'
gitlab_rails['backup_encryption_key'] = '<YOUR 32-BYTE KEY HERE>'

## Matomo
gitlab_rails['extra_matomo_url'] = 'matomo.server'
gitlab_rails['extra_matomo_site_id'] = '0'
gitlab_rails['extra_matomo_disable_cookies'] = false

## Sentry
gitlab_rails['sentry_enabled'] = true
gitlab_rails['sentry_dsn'] = 'https://<key>@sentry.io/<project>'
gitlab_rails['sentry_clientside_dsn'] = 'https://<key>@sentry.io/<project>'
gitlab_rails['sentry_environment'] = 'production'

## Container Registry settings
registry_external_url 'https://reg.<gitlab.instance>'
registry_nginx['ssl_certificate'] = "/etc/ssl/<gitlab.instance>/cert.pem"
registry_nginx['ssl_certificate_key'] = "/etc/ssl/<gitlab.instance>/key.pem"
gitlab_rails['registry_enabled'] = true

## Built-in NGINX settings
letsencrypt['enable'] = false
nginx['ssl_verify_client'] = "on"
nginx['ssl_client_certificate'] = "/etc/ssl/cloudflare.crt"
nginx['ssl_certificate'] = "/etc/ssl/<gitlab.instance>/cert.pem"
nginx['ssl_certificate_key'] = "/etc/ssl/<gitlab.instance>/key.pem"

## GitLab Pages
pages_external_url "https://pages.<gitlab.instance>/"
gitlab_pages['enable'] = true
pages_nginx['ssl_certificate'] = "/etc/ssl/<gitlab.instance>/cert.pem"
pages_nginx['ssl_certificate_key'] = "/etc/ssl/<gitlab.instance>/key.pem"

## GitLab Kubernetes Agent Server
gitlab_rails['gitlab_kas_enabled'] = true
gitlab_rails['gitlab_kas_external_url'] = 'ws://<gitlab.instance>/-/kubernetes-agent/'
gitlab_rails['gitlab_kas_external_k8s_proxy_url'] = 'https://<gitlab.instance>/-/kubernetes-agent/'
gitlab_kas['enable'] = true
gitlab_kas['sentry_dsn'] = 'https://<key>@sentry.io/<project>'
gitlab_kas['sentry_environment'] = 'production'

## GitLab Mattermost
mattermost_external_url 'https://mm.<gitlab.instance>'
mattermost['enable'] = true
mattermost['team_site_name'] = "GitLab.MM"
mattermost_nginx['ssl_certificate'] = "/etc/ssl/<gitlab.instance>/cert.pem"
mattermost_nginx['ssl_certificate_key'] = "/etc/ssl/<gitlab.instance>/key.pem"
mattermost['gitlab_enable'] = true
mattermost['gitlab_id'] = "<OAuth Application ID from GitLab>"
mattermost['gitlab_secret'] = "<OAuth Application Secret from GitLab>"
mattermost['gitlab_scope'] = "read_user"
mattermost['gitlab_auth_endpoint'] = "https://<gitlab.instance>/oauth/authorize"
mattermost['gitlab_token_endpoint'] = "https://<gitlab.instance>/oauth/token"
mattermost['gitlab_user_api_endpoint'] = "https://<gitlab.instance>/api/v4/user"

## Service Desk
gitlab_rails['service_desk_email_enabled'] = true
gitlab_rails['service_desk_email_address'] = "contact_project+%{key}@<gitlab.instance>"
gitlab_rails['service_desk_email_email'] = "contact_project@<gitlab.instance>"
gitlab_rails['service_desk_email_password'] = "<PASSWORD>"
gitlab_rails['service_desk_email_host'] = "<mail.server>"
gitlab_rails['service_desk_email_port'] = 993
gitlab_rails['service_desk_email_ssl'] = true
gitlab_rails['service_desk_email_start_tls'] = false

## Disable Service Ping
gitlab_rails['usage_ping_enabled'] = false

## Enable node_exporter
node_exporter['enable'] = true
node_exporter['flags'] = {
'collector.textfile.directory' => "/var/opt/gitlab/node-exporter/textfile_collector",
'path.procfs' => "/host/proc",
'path.sysfs' => "/host/sys",
'path.rootfs' => "/rootfs",
'collector.filesystem.ignored-mount-points' => "'^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)'"
}

GitLab Runner 配置文件
values.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
## GitLab Runner Image
##
## By default it's using gitlab/gitlab-runner:alpine-v{VERSION}
## where {VERSION} is taken from Chart.yaml from appVersion field
##
## ref: https://hub.docker.com/r/gitlab/gitlab-runner/tags/
##
## Note: If you change the image to the ubuntu release
## don't forget to change the securityContext;
## these images run on different user IDs.
##
# image: gitlab/gitlab-runner:alpine-v14.6.0

## Specify a imagePullPolicy for the main runner deployment
## 'Always' if imageTag is 'latest', else set to 'IfNotPresent'
##
## Note: it does not apply to job containers launched by this executor.
## Use `pull_policy` in [runners.kubernetes] to change it.
##
## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images
##
imagePullPolicy: IfNotPresent

## Specifying ImagePullSecrets on a Pod
## Kubernetes supports specifying container image registry keys on a Pod.
## ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
##
# imagePullSecrets:
# - name: "image-pull-secret"

## Timeout, in seconds, for liveness and readiness probes of a runner pod.
# probeTimeoutSeconds: 1

## How many runner pods to launch.
##
## Note: Using more than one replica is not supported with a runnerToken. Use a runnerRegistrationToken
## to create multiple runner replicas.
# replicas: 1

## How many old ReplicaSets for this Deployment you want to retain
# revisionHistoryLimit: 10

## The GitLab Server URL (with protocol) that want to register the runner against
## ref: https://docs.gitlab.com/runner/commands/README.html#gitlab-runner-register
##
gitlabUrl: https://<gitlab.instance>/

## The Registration Token for adding new Runners to the GitLab Server. This must
## be retrieved from your GitLab Instance.
## ref: https://docs.gitlab.com/ce/ci/runners/README.html
##
runnerRegistrationToken: "<runner_registration_token>"

## The Runner Token for adding new Runners to the GitLab Server. This must
## be retrieved from your GitLab Instance. It is token of already registered runner.
## ref: (we don't yet have docs for that, but we want to use existing token)
##
# runnerToken: ""
#
## Unregister all runners before termination
##
## Updating the runner's chart version or configuration will cause the runner container
## to be terminated and created again. This may cause your Gitlab instance to reference
## non-existant runners. Un-registering the runner before termination mitigates this issue.
## ref: https://docs.gitlab.com/runner/commands/README.html#gitlab-runner-unregister
##
unregisterRunners: true

## When stopping the runner, give it time to wait for its jobs to terminate.
##
## Updating the runner's chart version or configuration will cause the runner container
## to be terminated with a graceful stop request. terminationGracePeriodSeconds
## instructs Kubernetes to wait long enough for the runner pod to terminate gracefully.
## ref: https://docs.gitlab.com/runner/commands/#signals
terminationGracePeriodSeconds: 3600

## Set the certsSecretName in order to pass custom certficates for GitLab Runner to use
## Provide resource name for a Kubernetes Secret Object in the same namespace,
## this is used to populate the /home/gitlab-runner/.gitlab-runner/certs/ directory
## ref: https://docs.gitlab.com/runner/configuration/tls-self-signed.html#supported-options-for-self-signed-certificates
##
# certsSecretName:

## Configure the maximum number of concurrent jobs
## ref: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section
##
concurrent: 4

## Defines in seconds how often to check GitLab for a new builds
## ref: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section
##
checkInterval: 30

## Configure GitLab Runner's logging level. Available values are: debug, info, warn, error, fatal, panic
## ref: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section
##
# logLevel:

## Configure GitLab Runner's logging format. Available values are: runner, text, json
## ref: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section
##
# logFormat:

## Configure GitLab Runner's Sentry DSN.
## ref https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section
##
sentryDsn: "https://<key>@sentry.io/<project>"

## A custom bash script that will be executed prior to the invocation
## gitlab-runner process
#
#preEntrypointScript: |
# echo "hello"

## Specify whether the runner should start the session server.
## Defaults to false
## ref:
##
## When sessionServer is enabled, the user can either provide a public publicIP
## or either rely on the external IP auto discovery
## When a serviceAccountName is used with the automounting to the pod disable,
## we recommend the usage of the publicIP
sessionServer:
enabled: false
# timeout: 1800
# internalPort: 8093
# externalPort: 9000
# publicIP: ""

## For RBAC support:
rbac:
create: true

## Define specific rbac permissions.
## DEPRECATED: see .Values.rbac.rules
# resources: ["pods", "pods/exec", "secrets"]
# verbs: ["get", "list", "watch", "create", "patch", "delete"]
# resources: ["pods", "pods/exec", "secrets", "configmaps", "pods/attach"]
# verbs: ["get", "list", "watch", "create", "patch", "delete", "update"]


## Define list of rules to be added to the rbac role permissions.
## Each rule supports the keys:
## - apiGroups: default "" (indicates the core API group) if missing or empty.
## - resources: default "*" if missing or empty.
## - verbs: default "*" if missing or empty.
rules:
- resources: ["configmaps", "pods", "pods/attach", "secrets", "services"]
verbs: ["get", "list", "watch", "create", "patch", "delete", "update"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create", "patch", "delete"]

## Run the gitlab-bastion container with the ability to deploy/manage containers of jobs
## cluster-wide or only within namespace
clusterWideAccess: false

## Use the following Kubernetes Service Account name if RBAC is disabled in this Helm chart (see rbac.create)
##
# serviceAccountName: default

## Specify annotations for Service Accounts, useful for annotations such as eks.amazonaws.com/role-arn
##
## ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html
##
# serviceAccountAnnotations: {}

## Use podSecurity Policy
## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/
podSecurityPolicy:
enabled: false
resourceNames:
- gitlab-runner

## Specify one or more imagePullSecrets used for pulling the runner image
##
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account
##
# imagePullSecrets: []

## Configure integrated Prometheus metrics exporter
##
## ref: https://docs.gitlab.com/runner/monitoring/#configuration-of-the-metrics-http-server
##
metrics:
enabled: true

## Define a name for the metrics port
##
portName: metrics

## Provide a port number for the integrated Prometheus metrics exporter
##
port: 9252

## Configure a prometheus-operator serviceMonitor to allow autodetection of
## the scraping target. Requires enabling the service resource below.
##
serviceMonitor:
enabled: false

## Provide additional labels to the service monitor ressource
##
## labels: {}

## Define a scrape interval (otherwise prometheus default is used)
##
## ref: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config
##
# interval: ""

## Specify the scrape protocol scheme e.g., https or http
##
# scheme: "http"

## Supply a tls configuration for the service monitor
##
## ref: https://github.com/helm/charts/blob/master/stable/prometheus-operator/crds/crd-servicemonitor.yaml
##
# tlsConfig: {}

## The URI path where prometheus metrics can be scraped from
##
# path: "/metrics"

## A list of MetricRelabelConfigs to apply to samples before ingestion
##
## ref: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs
##
# metricRelabelings: []

## A list of RelabelConfigs to apply to samples before scraping
##
## ref: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
##
## relabelings: []

## Configure a service resource e.g., to allow scraping metrics via
## prometheus-operator serviceMonitor
service:
enabled: false

## Provide additonal labels for the service
##
# labels: {}

## Provide additonal annotations for the service
##
# annotations: {}

## Define a specific ClusterIP if you do not want a dynamic one
##
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#choosing-your-own-ip-address
##
# clusterIP: ""

## Define a list of one or more external IPs for this service
##
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips
##
# externalIPs: []

## Provide a specific loadbalancerIP e.g., of an external Loadbalancer
##
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer
##
# loadBalancerIP: ""

## Provide a list of source IP ranges to have access to this service
##
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#aws-nlb-support
##
# loadBalancerSourceRanges: []

## Specify the service type e.g., ClusterIP, NodePort, Loadbalancer or ExternalName
##
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
##
type: ClusterIP

## Specify the services metrics nodeport if you use a service of type nodePort
##
# metrics:

## Specify the node port under which the prometheus metrics of the runner are made
## available.
##
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#nodeport
##
# nodePort: ""

## Provide a list of additional ports to be exposed by this service
##
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service
##
# additionalPorts: []

## Configuration for the Pods that the runner launches for each new job
##
runners:
# runner configuration, where the multi line strings is evaluated as
# template so you can specify helm values inside of it.
#
# tpl: https://helm.sh/docs/howto/charts_tips_and_tricks/#using-the-tpl-function
# runner configuration: https://docs.gitlab.com/runner/configuration/advanced-configuration.html
config: |
[[runners]]
[runners.kubernetes]
namespace = "{{.Release.Namespace}}"
image = "ubuntu:16.04"

## Which executor should be used
##
# executor: kubernetes

## Default container image to use for builds when none is specified
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# image: ubuntu:16.04

## Specify one or more imagePullSecrets
##
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# imagePullSecrets: []

## Specify the image pull policy: never, if-not-present, always. The cluster default will be used if not set.
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# imagePullPolicy: ""

## Defines number of concurrent requests for new job from GitLab
## ref: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# requestConcurrency: 1

## Specify whether the runner should be locked to a specific project: true, false. Defaults to true.
##
# locked: true

## Specify the tags associated with the runner. Comma-separated list of tags.
##
## ref: https://docs.gitlab.com/ce/ci/runners/#use-tags-to-limit-the-number-of-jobs-using-the-runner
##
# tags: ""

## Specify the name for the runner.
##
# name: ""

## Specify if jobs without tags should be run.
## If not specified, Runner will default to true if no tags were specified. In other case it will
## default to false.
##
## ref: https://docs.gitlab.com/ce/ci/runners/#runner-is-allowed-to-run-untagged-jobs
##
# runUntagged: true

## Specify whether the runner should only run protected branches.
## Defaults to false.
##
## ref: https://docs.gitlab.com/ee/ci/runners/#prevent-runners-from-revealing-sensitive-information
##
# protected: true

## Run all containers with the privileged flag enabled
## This will allow the docker:dind image to run if you need to run Docker
## commands. Please read the docs before turning this on:
## ref: https://docs.gitlab.com/runner/executors/kubernetes.html#using-dockerdind
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
privileged: true

## The name of the secret containing runner-token and runner-registration-token
# secret: gitlab-runner

## Namespace to run Kubernetes jobs in (defaults to the same namespace of this release)
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# namespace:

## The amount of time, in seconds, that needs to pass before the runner will
## timeout attempting to connect to the container it has just created.
## ref: https://docs.gitlab.com/runner/executors/kubernetes.html
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# pollTimeout: 180

## Set maximum build log size in kilobytes, by default set to 4096 (4MB)
## ref: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# outputLimit: 4096

## Distributed runners caching
## ref: https://docs.gitlab.com/runner/configuration/autoscale.html#distributed-runners-caching
##
## If you want to use s3 based distributing caching:
## First of all you need to uncomment General settings and S3 settings sections.
##
## Create a secret 's3access' containing 'accesskey' & 'secretkey'
## ref: https://aws.amazon.com/blogs/security/wheres-my-secret-access-key/
##
## $ kubectl create secret generic s3access \
## --from-literal=accesskey="YourAccessKey" \
## --from-literal=secretkey="YourSecretKey"
## ref: https://kubernetes.io/docs/concepts/configuration/secret/
##
## If you want to use gcs based distributing caching:
## First of all you need to uncomment General settings and GCS settings sections.
##
## Access using credentials file:
## Create a secret 'google-application-credentials' containing your application credentials file.
## ref: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnerscachegcs-section
## You could configure
## $ kubectl create secret generic google-application-credentials \
## --from-file=gcs-application-credentials-file=./path-to-your-google-application-credentials-file.json
## ref: https://kubernetes.io/docs/concepts/configuration/secret/
##
## Access using access-id and private-key:
## Create a secret 'gcsaccess' containing 'gcs-access-id' & 'gcs-private-key'.
## ref: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnerscachegcs-section
## You could configure
## $ kubectl create secret generic gcsaccess \
## --from-literal=gcs-access-id="YourAccessID" \
## --from-literal=gcs-private-key="YourPrivateKey"
## ref: https://kubernetes.io/docs/concepts/configuration/secret/
##
## If you want to use Azure-based distributed caching:
## First, uncomment General settings.
##
## Create a secret 'azureaccess' containing 'azure-account-name' & 'azure-account-key'
## ref: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction
##
## $ kubectl create secret generic azureaccess \
## --from-literal=azure-account-name="YourAccountName" \
## --from-literal=azure-account-key="YourAccountKey"
## ref: https://kubernetes.io/docs/concepts/configuration/secret/

cache: {}
## General settings
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration and https://docs.gitlab.com/runner/install/kubernetes.html#using-cache-with-configuration-template
# cacheType: s3
# cachePath: "gitlab_runner"
# cacheShared: true

## S3 settings
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration and https://docs.gitlab.com/runner/install/kubernetes.html#using-cache-with-configuration-template
# s3ServerAddress: s3.amazonaws.com
# s3BucketName:
# s3BucketLocation:
# s3CacheInsecure: false

## GCS settings
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration and https://docs.gitlab.com/runner/install/kubernetes.html#using-cache-with-configuration-template
# gcsBucketName:

## S3 the name of the secret.
# secretName: s3access
## Use this line for access using gcs-access-id and gcs-private-key
# secretName: gcsaccess
## Use this line for access using google-application-credentials file
# secretName: google-application-credentials
## Use this line for access using Azure with azure-account-name and azure-account-key
# secretName: azureaccess


## Build Container specific configuration
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
builds: {}
# cpuLimit: 200m
# cpuLimitOverwriteMaxAllowed: 400m
# memoryLimit: 256Mi
# memoryLimitOverwriteMaxAllowed: 512Mi
# cpuRequests: 100m
# cpuRequestsOverwriteMaxAllowed: 200m
# memoryRequests: 128Mi
# memoryRequestsOverwriteMaxAllowed: 256Mi

## Service Container specific configuration
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
services: {}
# cpuLimit: 200m
# memoryLimit: 256Mi
# cpuRequests: 100m
# memoryRequests: 128Mi

## Helper Container specific configuration
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
helpers: {}
# cpuLimit: 200m
# memoryLimit: 256Mi
# cpuRequests: 100m
# memoryRequests: 128Mi
# image: "gitlab/gitlab-runner-helper:x86_64-${CI_RUNNER_REVISION}"

## Helper container security context configuration
## Refer to https://docs.gitlab.com/runner/executors/kubernetes.html#using-security-context
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# pod_security_context:
# run_as_non_root: true
# run_as_user: 100
# run_as_group: 100
# fs_group: 65533
# supplemental_groups: [101, 102]

## Service Account to be used for runners
##
# serviceAccountName:

## If Gitlab is not reachable through $CI_SERVER_URL
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# cloneUrl:

## Specify node labels for CI job pods assignment
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# nodeSelector: {}

## Specify node tolerations for CI job pods assignment
## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# nodeTolerations: {}

## Specify pod labels for CI job pods
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# podLabels: {}

## Specify annotations for job pods, useful for annotations such as iam.amazonaws.com/role
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# podAnnotations: {}

## Configure environment variables that will be injected to the pods that are created while
## the build is running. These variables are passed as parameters, i.e. `--env "NAME=VALUE"`,
## to `gitlab-runner register` command.
##
## Note that `envVars` (see below) are only present in the runner pod, not the pods that are
## created for each build.
##
## ref: https://docs.gitlab.com/runner/commands/#gitlab-runner-register
##
## DEPRECATED: See https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration
# env:
# NAME: VALUE


## Specify the name of the scheduler which used to schedule runner pods.
## Kubernetes supports multiple scheduler configurations.
## ref: https://kubernetes.io/docs/reference/scheduling
# schedulerName: "my-custom-scheduler"

## Configure securitycontext
## ref: http://kubernetes.io/docs/user-guide/security-context/
##
securityContext:
runAsUser: 100
# runAsGroup: 65533
fsGroup: 65533
# supplementalGroups: [65533]

## Note: values for the ubuntu image:
# runAsUser: 999
# fsGroup: 999

## Configure resource requests and limits
## ref: http://kubernetes.io/docs/user-guide/compute-resources/
##
resources: {}
# limits:
# memory: 256Mi
# cpu: 200m
# requests:
# memory: 128Mi
# cpu: 100m

## Affinity for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
##
affinity: {}

## Node labels for pod assignment
## Ref: https://kubernetes.io/docs/user-guide/node-selection/
##
nodeSelector: {}
# Example: The gitlab runner manager should not run on spot instances so you can assign
# them to the regular worker nodes only.
# node-role.kubernetes.io/worker: "true"

## List of node taints to tolerate (requires Kubernetes >= 1.6)
## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
##
tolerations: []
# Example: Regular worker nodes may have a taint, thus you need to tolerate the taint
# when you assign the gitlab runner manager with nodeSelector or affinity to the nodes.
# - key: "node-role.kubernetes.io/worker"
# operator: "Exists"

## Configure environment variables that will be present when the registration command runs
## This provides further control over the registration process and the config.toml file
## ref: `gitlab-runner register --help`
## ref: https://docs.gitlab.com/runner/configuration/advanced-configuration.html
##
# envVars:
# - name: RUNNER_EXECUTOR
# value: kubernetes

## list of hosts and IPs that will be injected into the pod's hosts file
hostAliases: []
# Example:
# - ip: "127.0.0.1"
# hostnames:
# - "foo.local"
# - "bar.local"
# - ip: "10.1.2.3"
# hostnames:
# - "foo.remote"
# - "bar.remote"

## Annotations to be added to manager pod
##
podAnnotations: {}
# Example:
# iam.amazonaws.com/role: <my_role_arn>

## Labels to be added to manager pod
##
podLabels: {}
# Example:
# owner.team: <my_cool_team>

## HPA support for custom metrics:
## This section enables runners to autoscale based on defined custom metrics.
## In order to use this functionality, Need to enable a custom metrics API server by
## implementing "custom.metrics.k8s.io" using supported third party adapter
## Example: https://github.com/directxman12/k8s-prometheus-adapter
##
#hpa: {}
# minReplicas: 1
# maxReplicas: 10
# metrics:
# - type: Pods
# pods:
# metricName: gitlab_runner_jobs
# targetAverageValue: 400m

## Secrets to be additionally mounted to the containers.
## All secrets are mounted through init-runner-secrets volume
## and placed as readonly at /init-secrets in the init container
## and finally copied to an in-memory volume runner-secrets that is
## mounted at /secrets.
secrets: []
# Example:
# - name: my-secret
# - name: myOtherSecret
# items:
# - key: key_one
# path: path_one

## Additional config files to mount in the containers in `/configmaps`.
##
## Please note that a number of keys are reserved by the runner.
## See https://gitlab.com/gitlab-org/charts/gitlab-runner/-/blob/main/templates/configmap.yaml
## for a current list.
configMaps: {}