用于大规模 DevOps 的 GitLab 和 MinIO

用于大规模 DevOps 的 GitLab 和 MinIO

GitLab 是一个基于 Web 的 Git 存储库管理器,提供源代码管理 (SCM)、持续集成/持续部署 (CI/CD) 和问题跟踪。它可以用作自托管平台或基于云的平台。

GitLab 的自托管版本希望完全控制其源代码管理和部署过程的组织使用。他们还需要能够自定义 GitLab 以满足他们的特定需求,例如更好地保护他们的 IP 和代码库。特定的安全性、合规性或法规要求也将在 GitLab 的云版本或本地部署之间做出选择。

GitLab 可以使用 MinIO 作为其对象存储后端来存储大型文件,例如工件、Docker 图像和 Git LFS 文件。鉴于合适的底层硬件,MinIO 提供了支持任何现代工作负载(包括 GitLab)的性能和规模。我们之前写过关于MinIO 和 GitHub Enterprise 的文章,并提供了一个教程,向您展示了如何使用 MinIO 使用 GitHub Actions 和 GitHub Packages。

要将 MinIO 用作 GitLab 的对象存储后端,您需要将 GitLab 配置为使用 MinIO 端点作为对象存储 URL。这可以在 GitLab 配置文件中或通过 GitLab 用户界面完成。一旦完成,GitLab 将在 MinIO 而不是本地文件系统中存储工件、Docker 图像和 Git LFS 文件。

使用 MinIO 可以在许多不同的场景中提供性能、高可用性、可扩展性和卓越的经济性。例如,当您有两个运行 GitLab 的不同区域或数据中心时,但您需要相同的基础资产集来构建最终版本。MinIO 将处理多站点复制并确保这些资产在两个站点都可用。如果其中一个站点出现故障,您也可以在 DR 场景中使用它,因为站点到站点的复制,您可以简单地指向另一侧并使一切恢复正常。所有这些数据都需要一个复杂的云原生存储系统。该系统理想地兼容 S3、高性能、可无缝扩展到数百个 PB、软件定义、多云、安全且有弹性。

换句话说,GitLab 需要 MinIO,而 MinIO 通过以下方式增强了 GitLab:

  • S3 兼容— 开发人员现在使用 RESTful API。这就是 S3——RESTful。用于对象存储的 S3 API 是事实上的标准。MinIO 是部署最广泛的 Amazon S3 替代方案,并且有超过 10 亿次 Docker 拉取来证明这一点。没有比 MinIO 运行在更多架构、更多类型硬件和更多用例中的 S3 兼容对象存储。这就是为什么它“适用于”数十万个应用程序的原因。

  • 高性能——MinIO 是世界上最快的对象存储,GET/PUT 速度分别超过 325 GB/s 和 165 GB/s。存储和检索速度很快——无论对象大小如何。MinIO 的所有基准测试均已发布——请随时在此处查看

  • 多云——GitLab 无处不它的存储解决方案也需要。MinIO 在每个公共云、私有云和边缘运行。

  • 安全——GitLab 负责企业最重要的软件资产,因此它需要像它一样重视安全性的存储。MinIO 的加密方案支持使用现代行业标准加密算法(例如 AES-256-GCM、ChaCha20-Poly1305 和 AES-CBC)进行粒度对象级加密。MinIO 与 S3 加密语义完全兼容,还通过包括对非 AWS 密钥管理服务(例如 Hashicorp Vault、Gemalto KeySecure 和 Google Secrets Manager)的支持来扩展 S3。当加密打开时,MinIO 仍然保持高性能。

  • 无缝可扩展——MinIO 通过称为服务器池的概念进行扩展,该概念专为硬件异构性而设计。GitLab 实例正在快速增长,变得非常大并且寿命很长。MinIO 非常适合这些用例。

  • 集成——MinIO 支持使用外部密钥管理系统(KMS)。如果客户端请求 SSE-S3,或者启用了自动加密,则 MinIO 服务器使用唯一的对象密钥加密每个对象,该对象密钥由 KMS 管理的主密钥保护。

  • 弹性——保护数据不仅仅是加密。不变性是对象存储框架的核心,MinIO 支持完整的对象锁定/保留框架,提供合法持有和保留(具有治理和合规模式)。

此外,MinIO 具有一些对 GitLab 很重要的关键功能。

  • MinIO 支持同步和异步复制如果两个集群之间的链路出现故障,那么即使是同步复制也会暂时自动恢复为异步复制。MinIO 提供了管理集中更新和升级的机制。生命周期管理是集群控制台的一部分,策略是集中管理的。这使架构师能够设计出能够承受整个云的故障的系统。这是有意义的,因为在启用了复制和负载均衡器的双集群 HA 设置中,如果一个集群完全失败,GitLab 将通过将所有请求发送到另一个集群来继续运行。这意味着开发人员无需停机。

  • 集群级别的身份管理是使用 AD/LDAP 或 OpenID 单点登录 (SSO) 执行的。属于一个组的用户和用户受到基于策略的访问控制的限制,这些访问控制指示可以对特定资源采取的操作。控制台上启用了策略创作,管理员可以为用户、组和服务帐户创建策略。集群、池、策略和桶的集中管理易于管理。

  • 管理很简单,联合解决方案可以通过 Ansible 等技术实现自动化。同时管理 MinIO 和 GitLab——无论是裸机还是 Kubernetes——都是一个明显的优势。



gitlab-cache-100.jpeg



您可以通过在 MinIO 控制台或 MinIO 客户端(mc)中检查您的存储桶来浏览当前存储的缓存。这提供了一种检查磁盘利用率和删除旧缓存以释放空间的便捷方法。GitLab 为您的每个项目 ID 创建一个存储桶前缀。在该文件夹中,您会找到包含您的缓存的 ZIP 存档,每个缓存都由分支命名,缓存名称在您的.gitlab-ci.yml.



gitlab-pipeline-100.jpeg






gitlab-buckets1-100.jpeg
gitlab-buckets2-100.jpeg



安装 MinIO 和 GitLab Runner

在我们深入研究之前,让我们看看基本架构是如何工作的。我们将有 2 个 Docker 容器。一个运行 GitLab,另一个运行 MinIO。我们将在 MinIO 中为我们的 Docker 运行实例设置与对象存储相关的配置。正如您将看到的,您可以在 GitLab 中配置大量的细节来存储在 MinIO 对象存储上。当您在生产环境中设置这些时,您将能够在存储数据时利用站点到站点复制、传输中加密和静态加密等 MinIO 功能,以确保满足合规性要求并确保数据安全。

让我们向您展示它是如何工作的。

Gitlab 中的对象存储可用于分布式运行器缓存以及存储构建的 Docker 容器。

安装 Gitlab runner

% brew install gitlab-runner

启动 Gitlab runner

% brew services start gitlab-runner

为 Gitlab 卷创建本地目录

$ export GITLAB_HOME=$HOME//gitlab

$ mkdir $GITLAB_HOME/config \
  $GITLAB_HOME/logs\
  $GITLAB_HOME/data

在 Docker 中安装 Gitlab

% sudo docker run --detach \
  --hostname gitlab.aj.local \
  --publish 20443:443 --publish 20080:80 --publish 20022:22 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/etc/gitlab \
  --volume $GITLAB_HOME/logs:/var/log/gitlab \
  --volume $GITLAB_HOME/data:/var/opt/gitlab \
  --shm-size 256m \
  gitlab/gitlab-ee:latest
Password:
Unable to find image 'gitlab/gitlab-ee:latest' locally
2023/03/16 11:56:08 must use ASL logging (which requires CGO) if running as root
latest: Pulling from gitlab/gitlab-ee
df6635ed1257: Pull complete
5573b794eacb: Pull complete
135ee811700c: Pull complete
598ac1898ca6: Pull complete
0df27cb51362: Pull complete
1272afc2ac37: Pull complete
0b65f427ccb7: Pull complete
69fe2f4d73da: Downloading  1.362GB/1.368GB

创建/etc/hosts条目

% cat /etc/hosts
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1   localhost
127.0.0.1   gitlab.aj.local

从以下命令获取初始 root 密码

docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password

转到http://localhost:20080



Screen Shot 2023-03-16 at 12.43.28 PM.png




将凭据更新为以下内容

用户:根

密码:minio123

转到项目,在这种情况下Administrator / ajtest -> Settings -> CI/CD



Screen Shot 2023-03-16 at 9.56.50 AM.png




展开跑步者



Screen Shot 2023-03-16 at 9.58.01 AM.png




转到 Project Runners 并单击“show runner installation instructions”。运行以下命令

gitlab-runner register --url http://localhost:20080/ --registration-token TOKEN

当它要求“输入执行者”时,选择“shell”,如下所示

% gitlab-runner register --url http://localhost:20080/ --registration-token TOKEN
Runtime platform                                arch=arm64 os=darwin pid=96356 revision=d540b510 version=15.9.1
WARNING: Running in user-mode.
WARNING: Use sudo for system-mode:                                                            WARNING: $ sudo gitlab-runner...

Created missing unique system ID                system_id=s_f78578411376
Enter the GitLab instance URL (for example, https://gitlab.com/):
[https://gitlab.com/]:
Enter the registration token:
[TOKEN]:
Enter a description for the runner:
[AJs-MacBook-Pro.local]: AJ-MinIO-Pro
Enter tags for the runner (comma-separated):
aj,gitlab,minio
Enter optional maintenance note for the runner:
maintain gently
WARNING: Support for registration tokens and runner parameters in the 'register' command has been deprecated in GitLab Runner 15.6 and will be replaced with support for authentication tokens. For more information, see https://gitlab.com/gitlab-org/gitlab/-/issues/380872
Registering runner... succeeded                 runner=GR1348941ez_t9dip
Enter an executor: docker-ssh, virtualbox, docker-ssh+machine, custom, parallels, shell, ssh, docker+machine, instance, kubernetes, docker:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

Configuration (with the authentication token) was saved in "/Users/aj/.gitlab-runner/config.toml"

几分钟后,您应该会在 Assigned project runners 下的 Project runners 仪表板中看到本地安装的运行器



Screen Shot 2023-03-16 at 9.46.24 AM.png




您还可以在 http://localhost:20080 项目设置中远程更新运行器设置。



Screen Shot 2023-03-16 at 9.53.35 AM.png



要 git clone 项目 repo,将部署的 SSH 端口设置gitlab.aj.local为 20022 以匹配 Docker 容器主机名和外部暴露的端口

% cat ~/.ssh/config

host gitlab.aj.local
Port 20022
User git


Git 克隆项目仓库

% git clone git@gitlab.aj.local:root/ajtest.git                      Cloning into 'ajtest'...
The authenticity of host '[gitlab.aj.local]:20022 ([127.0.0.1]:20022)' can't be established.
ED25519 key fingerprint is SHA256:awJM6jOapg/NI0bFin0F4xRHkdBupyiRIy3tos0j90I.
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.aj.local]:20022' (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.

启动 MinIO Docker 容器并公开 API 和控制台端口。确保-v卷路径存在于本地,如果需要更改路径。

docker run -d \
  -p 20092:9001 \
  -p 20090:9000 \
  -v /Users/aj/Mime/minio/disk:/mnt/disk \
  --name minio \
  --hostname minio \
  minio/minio server /mnt/disk/minio --console-address ":9001"

安装 MinIO 客户端 (mc)

% brew install minio-mc

配置 MinIO 别名。如果你使用上面的 Docker 命令,端口应该是 20090

% mc alias set myminio http://localhost:20090 minioadmin minioadmin

Added `myminio` successfully.

% mc admin info myminio
●  localhost:20090
  Uptime: 17 hours
  Version: 2023-03-13T19:46:17Z
  Network: 1/1 OK
  Drives: 1/1 OK
  Pool: 1

Pools:
  1st, Erasure sets: 1, Drives per erasure set: 1

1 drive online, 0 drives offline

打开 GitLab Runner 配置文件

$ vi /Users/aj/.gitlab-runner/config.toml

Gitlab 运行器配置

[[runners]]
  name = "AJ-MinIO-Pro"
  url = "https://gitlab.com/"
  id = 21903271
  token = "<token>
  token_obtained_at = 2023-03-16T13:41:51Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "shell"
  [runners.cache]
Type = "s3"
Shared = true
[runners.cache.s3]
  AccessKey = "minioadmin"
  SecretKey = "minioadmin"
  BucketName = "gitlab"
  Insecure = true
  ServerAddress = "http://localhost:20090"


为了使用 MinIO 作为 S3 兼容后端,让我们设置一些默认的 GitLab 对象存储连接信息,例如 MinIO 端点、访问密钥和密钥。

gitlab_rails['object_store']['enabled'] = true
gitlab_rails['object_store']['connection'] = {
      'provider' => 'AWS',
      'region' => 'us-east-1',
      'endpoint' => 'http://minio:9000',
      'aws_access_key_id' => 'minioadmin',
      'aws_secret_access_key' => 'minioadmin'
    }
# gitlab_rails['object_store']['storage_options'] = {}
gitlab_rails['object_store']['proxy_download'] = true
gitlab_rails['object_store']['objects']['artifacts']['bucket'] = 'gitlab'
gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = 'gitlab'
gitlab_rails['object_store']['objects']['lfs']['bucket'] = 'gitlab'
gitlab_rails['object_store']['objects']['uploads']['bucket'] = 'gitlab'
gitlab_rails['object_store']['objects']['packages']['bucket'] = 'gitlab'
gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = 'gitlab'
gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = 'gitlab'
gitlab_rails['object_store']['objects']['ci_secure_files']['bucket'] = 'gitlab'
gitlab_rails['object_store']['objects']['pages']['bucket'] = 'gitlab'

以下是您可以将 MinIO 与 GitLab 集成的几种不同方式。

工件: GitLab 允许您管理工件并将它们存储在 MinIO 上,释放本地资源并提高开发人员效率。当作业运行时,它们可能会输出工件,例如存储在本地磁盘上的二进制文件或 tar.gz 文件。您可以将这些作业工件保存在 MinIO 中以启用数据复制并将它们存储在多个磁盘上以防出现故障。

永恒的合并请求:出于性能优化的目的,您可以从存储在 MinIO 存储桶中的副本中获取这些差异,而不是从源中获取合并请求的差异。

LFS:超过一定磁盘大小的对象不能像普通文件一样提交到 git 仓库中,git 将不允许并拒绝。在这种情况下,您需要LFS git 协议将这些大对象保存在 git 存储库中。

上传:除了 git 相关数据,GitLab还需要一个地方来存储头像上传、评论和描述的附件等数据。这些也可以存储在 MinIO 对象存储中。

页面:当你想向 GitLab 添加核心示例的额外文档时,你不需要单独的网站来添加此信息,然后从 GitLab 存储库链接到它。存储在 MinIO 对象存储中的Wiki页面在呈现给最终用户时可以直接访问。

工件配置

gitlab_rails['artifacts_object_store_enabled'] = true
gitlab_rails['artifacts_object_store_proxy_download'] = true
gitlab_rails['artifacts_object_store_remote_directory'] = "artifacts"
gitlab_rails['artifacts_object_store_connection'] = {
  'provider' => 'AWS',
  'region' => 'us-east-1',
  'aws_access_key_id' => 'minioadmin',
  'aws_secret_access_key' => 'minioadmin',
  # # The below options configure an S3 compatible host instead of AWS
  # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4.
  'endpoint' => 'http://minio:9000', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces
  # 'host' => 's3.amazonaws.com',
  # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object'
}

外部合并请求

gitlab_rails['external_diffs_enabled'] = true
# gitlab_rails['external_diffs_when'] = nil
# gitlab_rails['external_diffs_storage_path'] = "/var/opt/gitlab/gitlab-rails/shared/external-diffs"
gitlab_rails['external_diffs_object_store_enabled'] = true
gitlab_rails['external_diffs_object_store_proxy_download'] = true
# gitlab_rails['external_diffs_object_store_remote_directory'] = "external-diffs"
gitlab_rails['external_diffs_object_store_connection'] = {
  'provider' => 'AWS',
  'region' => 'us-east-1',
  'aws_access_key_id' => 'minioadmin',
  'aws_secret_access_key' => 'minioadmin',
  # # The below options configure an S3 compatible host instead of AWS
  # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4.
  'endpoint' => 'http://minio:9000', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces
  # 'host' => 's3.amazonaws.com',
  # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object'
}

LFS 配置

### Git LFS
gitlab_rails['lfs_enabled'] = true
# gitlab_rails['lfs_storage_path'] = "/var/opt/gitlab/gitlab-rails/shared/lfs-objects"
gitlab_rails['lfs_object_store_enabled'] = true
gitlab_rails['lfs_object_store_proxy_download'] = true
# gitlab_rails['lfs_object_store_remote_directory'] = "lfs-objects"
gitlab_rails['lfs_object_store_connection'] = {
  'provider' => 'AWS',
  'region' => 'us-east-1',
  'aws_access_key_id' => 'minioadmin',
  'aws_secret_access_key' => 'minioadmin',
  # # The below options configure an S3 compatible host instead of AWS
  # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4.
  'endpoint' => 'http://minio:9000', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces
  # 'host' => 's3.amazonaws.com',
  # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object'
}

上传配置

# gitlab_rails['uploads_directory'] = "/var/opt/gitlab/gitlab-rails/uploads"
# gitlab_rails['uploads_storage_path'] = "/opt/gitlab/embedded/service/gitlab-rails/public"
# gitlab_rails['uploads_base_dir'] = "uploads/-/system"
gitlab_rails['uploads_object_store_enabled'] = true
gitlab_rails['uploads_object_store_proxy_download'] = true
# gitlab_rails['uploads_object_store_remote_directory'] = "uploads"
gitlab_rails['uploads_object_store_connection'] = {
  'provider' => 'AWS',
  'region' => 'us-east-1',
  'aws_access_key_id' => 'minioadmin',
  'aws_secret_access_key' => 'minioadmin',
  # # The below options configure an S3 compatible host instead of AWS
  # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4.
  'endpoint' => 'http://minio:9000', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces
  # 'host' => 's3.amazonaws.com',
  # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object'
}

页面配置

### GitLab Pages
gitlab_rails['pages_object_store_enabled'] = true
# gitlab_rails['pages_object_store_remote_directory'] = "pages"
gitlab_rails['pages_object_store_connection'] = {
  'provider' => 'AWS',
  'region' => 'us-east-1',
  'aws_access_key_id' => 'minioadmin',
  'aws_secret_access_key' => 'minioadmin',
  # # The below options configure an S3 compatible host instead of AWS
  # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4.
  'endpoint' => 'http://minio:9000', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces
  # 'host' => 's3.amazonaws.com',
  # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object'
}

结论

开发人员喜欢 MinIO,也喜欢 GitLab。MinIO 很容易配置为基本安装,作为 GitLab Runner 的共享缓存。这可确保在多个作业并发运行时可靠地使用缓存。我们相信,任何运行自托管 GitLab 安装的人都会因添加 MinIO 而受益。

为什么?因为两者都是简单但功能强大的工具,可以提高编码效率。基于 GitLab 的 CI/CD 会产生大量数据,所有这些数据都需要一个复杂的云原生存储系统,以便企业可以充分利用这些数据。MinIO 通过对象存储补充 GitLab,对象存储兼容 S3 API、高性能、可无缝扩展到数百个 PB、软件定义、多云、安全且有弹性。将 MinIO 添加到 GitLab 可以将 DevOps 团队从苦差事中解放出来,这样他们就可以开发您的业务需求,而不是管理缓存并等待他们上传/下载。

在这篇文章中,我们了解了如何配置 GitLab,不仅将其缓存存储在 MinIO 中,还包括其他功能,如 LFS、Pages 等,以确保您可以将它们放在 MinIO 上,并使用 MinIO 附带的底层功能,例如复制、加密、分层等。如果您对 GitLab 集成有任何疑问,请随时在Slack上与我们联系



上一篇 下一篇