Help us learn about your current experience with the documentation. Take the survey.

在亚马逊网络服务(AWS)上安装GitLab概念验证(POC)

  • 层级:免费版、高级版、旗舰版
  • 版本:GitLab 自托管版

本页提供了使用官方Linux包在AWS上配置GitLab的常见步骤指南。您应根据自身需求进行调整。

对于拥有1000名用户或以下的组织,推荐的AWS安装方法是启动一个EC2单机Linux包安装并实施快照策略备份数据。有关更多信息,请参阅20 RPS或1000用户参考架构

开始生产级GitLab配置

本文档是概念验证(POC)实例的安装指南。它不是参考架构,也不会生成高可用配置。强烈建议改用GitLab Environment Toolkit (GET)

严格遵循此指南将得到一个概念验证(POC)实例,大致相当于缩减版两个可用区实现非高可用40 RPS或2000用户参考架构。2000用户参考架构并非高可用,因为它主要用于在降低成本和复杂性的前提下提供一定扩展性。60 RPS或3000用户参考架构是GitLab高可用的最小规模。它具有额外的服务角色以实现高可用,最显著的是使用Gitaly Cluster (Praefect) 实现Git仓库存储的高可用,并指定三重冗余。

GitLab维护和测试两种主要的参考架构。Linux包架构基于实例计算实现,而云原生混合架构则最大化利用Kubernetes集群。云原生混合参考架构规范是参考架构大小页面中的附录章节,这些页面先描述Linux包架构。例如,60 RPS或3000用户云原生参考架构位于60 RPS或3000用户参考架构页面的子章节使用Helm Charts的云原生混合参考架构(替代方案)中。

开始生产级Linux包安装

基础设施即代码工具GitLab Environment Tool (GET) 是开始在AWS上使用Linux包构建的最佳起点,尤其是如果您计划搭建高可用配置。虽然它不能自动化一切,但它会为您完成复杂的设置,如Gitaly Cluster (Praefect)。GET是开源的,任何人都可以在其基础上构建并贡献改进。

开始生产级云原生混合GitLab

GitLab Environment Toolkit (GET) 是一组有观点的Terraform和Ansible脚本。这些脚本帮助在选定的云提供商上部署Linux包或云原生混合环境,并被GitLab开发者用于GitLab Dedicated(例如)。您可以使用GitLab Environment Toolkit在AWS上部署云原生混合环境。不过这不是必需的,也可能不支持所有有效组合。也就是说,这些脚本按原样提供,您可以相应地调整它们。

引言

在很大程度上,我们在设置中主要使用Linux包,但也利用AWS原生服务。我们不使用Linux包捆绑的PostgreSQL和Redis,而是使用Amazon RDS和ElastiCache。

在本指南中,我们将经历一个多节点设置过程:首先配置虚拟私有云(VPC)和子网,以便后续集成数据库服务器所需的RDS服务和作为Redis集群的ElastiCache,最终通过带有自定义扩展策略的自动伸缩组来管理它们。

要求

除对 AWSAmazon EC2 有基本了解外,您还需:

通过 ACM 提供的证书验证可能需要数小时。为避免后续延迟,请尽早申请证书。

架构

下图概述了推荐架构。

缩小的 2 可用区与非高可用 AWS 架构示意图。

AWS 成本

GitLab 使用以下 AWS 服务,附价格信息链接:

  • EC2:GitLab 部署在共享硬件上,适用 按需定价。若您希望在专用或预留实例上运行 GitLab,请参阅 EC2 定价页面 了解成本。
  • S3:GitLab 使用 S3 (定价页面) 存储备份、工件及 LFS 对象。
  • NLB:网络负载均衡器 (定价页面),用于将请求路由至 GitLab 实例。
  • RDS:使用 PostgreSQL 的亚马逊关系数据库服务 (定价页面)。
  • ElastiCache:内存缓存环境 (定价页面),用于提供 Redis 配置。

创建 IAM EC2 实例角色与配置文件

因我们使用 Amazon S3 对象存储,EC2 实例需对我们的 S3 桶具备读、写及列出权限。为避免在 GitLab 配置中嵌入 AWS 密钥,我们借助 IAM Role 授予 GitLab 实例该权限。需创建 IAM 策略以附加至 IAM 角色:

创建 IAM 策略

  1. 进入 IAM 仪表板,选择左侧菜单中的 策略

  2. 选择 创建策略,切换至 JSON 选项卡,添加策略。我们需 遵循安全最佳实践并授予最小特权,仅赋予角色执行必要操作的权限。

    1. 若您按图示以 gl- 作为 S3 桶名前缀,添加以下策略:
    {   "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "s3:PutObject",
                    "s3:GetObject",
                    "s3:DeleteObject",
                    "s3:PutObjectAcl"
                ],
                "Resource": "arn:aws:s3:::gl-*/*"
            },
            {
                "Effect": "Allow",
                "Action": [
                    "s3:ListBucket",
                    "s3:AbortMultipartUpload",
                    "s3:ListMultipartUploadParts",
                    "s3:ListBucketMultipartUploads"
                ],
                "Resource": "arn:aws:s3:::gl-*"
            }
        ]
    }
  3. 选择 下一步 查看策略。为策略命名(我们使用 gl-s3-policy),然后选择 创建策略

创建 IAM 角色

  1. 仍在 IAM 仪表板,选择左侧菜单中的 角色,再选择 创建角色
  2. 对于 可信实体类型,选择 AWS 服务;对于 用例,下拉列表与单选按钮均选 EC2,然后选择 下一步
  3. 在策略筛选器中搜索此前创建的 gl-s3-policy,选中后选择 下一步
  4. 为角色命名(我们使用 GitLabS3Access),若需可添加标签,最后选择 创建角色

我们将在后续 创建启动模板 时使用此角色。

配置网络

我们先为 GitLab 云基础设施创建 VPC,随后可在至少两个 可用区 (AZs) 中创建子网,容纳公有与私有实例。公有子网需配备 Route Table 及关联的 Internet Gateway。

创建虚拟私有云(VPC)

我们现在创建一个VPC,这是一个由你控制的虚拟网络环境:

  1. 登录到Amazon Web Services

  2. 从左侧菜单中选择“您的VPC”,然后选择“创建VPC”。 在“名称标签”中输入gitlab-vpc,在“IPv4 CIDR块”中输入10.0.0.0/16。如果不需要专用硬件,可以将“租期”保留为默认值。准备就绪后选择“创建VPC”。

    为GitLab云基础设施创建VPC。

  3. 选择该VPC,选择“操作”,选择“编辑VPC设置”,并勾选“启用DNS解析”。完成后选择“保存”。

子网

现在,让我们在不同可用区创建一些子网。确保每个子网都与我们刚刚创建的VPC相关联,并且CIDR块不重叠。这还允许我们启用多AZ以实现冗余。

我们创建公共和私有子网来匹配负载均衡器和RDS实例:

  1. 从左侧菜单中选择“子网”。

  2. 选择“创建子网”。根据IP给它一个描述性名称标签,例如gitlab-public-10.0.0.0,选择我们之前创建的VPC,选择一个可用区(我们使用us-west-2a),并在IPv4 CIDR块中给它一个24位子网10.0.0.0/24

    创建子网。

  3. 按照相同步骤创建所有子网:

    名称标签 类型 可用区 CIDR块
    gitlab-public-10.0.0.0 公共 us-west-2a 10.0.0.0/24
    gitlab-private-10.0.1.0 私有 us-west-2a 10.0.1.0/24
    gitlab-public-10.0.2.0 公共 us-west-2b 10.0.2.0/24
    gitlab-private-10.0.3.0 私有 us-west-2b 10.0.3.0/24
  4. 所有子网创建完成后,为两个公共子网启用“自动分配IPv4”:

    1. 依次选择每个公共子网,选择“操作”,然后选择“编辑子网设置”。勾选“启用自动分配公有IPv4地址”选项并保存。

互联网网关

现在,仍在同一仪表板中,进入互联网网关并创建一个新的:

  1. 从左侧菜单中选择“互联网网关”。

  2. 选择“创建互联网网关”,将其命名为gitlab-gateway,然后选择“创建”。

  3. 从表格中选择它,然后在“操作”下拉列表中选择“附加到VPC”。

    创建互联网网关。

  4. 从列表中选择gitlab-vpc并点击“附加”。

创建NAT网关

部署在我们私有子网中的实例必须连接到互联网进行更新,但不应该可以从公共互联网访问。为此,我们在每个公共子网中使用NAT网关

  1. 进入VPC仪表板,从左侧菜单栏中选择“NAT网关”。
  2. 选择“创建NAT网关”并完成以下操作:
    1. 子网:从下拉列表中选择gitlab-public-10.0.0.0
    2. 弹性IP分配ID:输入现有的弹性IP或选择“分配弹性IP地址”为新网关分配新IP。
    3. 如需添加标签则添加。
    4. 选择“创建NAT网关”。

创建第二个NAT网关,但这次将其放置在第二个公共子网gitlab-public-10.0.2.0中。

路由表

公共路由表

我们必须创建一个路由表,使我们的公共子网能够通过上一步创建的互联网网关访问互联网。

在VPC仪表板上:

  1. 从左侧菜单中选择“路由表”。
  2. 选择“创建路由表”。
  3. 在“名称标签”中输入gitlab-public,并在“VPC”下选择gitlab-vpc
  4. 选择“创建”。

现在我们必须添加互联网网关作为新的目标,让它接收来自任何目的地的流量。

  1. 从左侧菜单中选择“路由表”,然后选择gitlab-public路由表以显示底部的选项。
  2. 选择“路由”选项卡,选择“编辑路由 > 添加路由”,并将0.0.0.0/0设置为目的地。在目标列中,选择“互联网网关”并选择我们之前创建的gitlab-gateway。完成后选择“保存更改”。

接下来,我们必须将公共子网与路由表关联:

  1. 选择“子网关联”选项卡,然后选择“编辑子网关联”。
  2. 仅勾选公共子网,然后选择“保存关联”。

私有路由表

我们还需要创建两个私有路由表,以便每个私有子网中的实例可以通过同一可用区中对应公有子网内的NAT网关访问互联网。

  1. 按照之前的步骤创建两个私有路由表。将它们命名为 gitlab-private-agitlab-private-b
  2. 接下来,向每个私有路由表中添加一条新路由,其中目标地址为 0.0.0.0/0,目标是之前创建的一个NAT网关。
    1. 将我们在 gitlab-public-10.0.0.0 中创建的NAT网关作为 gitlab-private-a 路由表中新路由的目标。
    2. 同样地,将 gitlab-public-10.0.2.0 中的NAT网关作为 gitlab-private-b 路由表中新路由的目标。
  3. 最后,将每个私有子网与一个私有路由表关联。
    1. gitlab-private-10.0.1.0gitlab-private-a 关联。
    2. gitlab-private-10.0.3.0gitlab-private-b 关联。

负载均衡器

我们创建一个负载均衡器,以在端口 80443 上均匀分配传入流量到我们的 GitLab 应用服务器。根据我们稍后创建的缩放策略,实例会按需添加或从负载均衡器中移除。此外,负载均衡器会对我们的实例执行健康检查。虽然在我们的环境中处理 SSL/TLS 有different ways(不同方式),但对于这个POC,我们在负载均衡器中终止SSL,而不使用后端SSL。

在EC2控制台中,在左侧导航栏查找负载均衡器

  1. 选择创建负载均衡器

  2. 选择网络负载均衡器并点击创建

  3. 将负载均衡器名称设为 gitlab-loadbalancer。设置以下附加选项:

    • 方案:选择Internet-facing
    • IP地址类型:选择IPv4
    • VPC:从下拉列表中选择 gitlab-vpc
    • 映射:从列表中选择两个公有子网,以便负载均衡器可以将流量路由到两个可用区。
  4. 我们为负载均衡器添加一个安全组,作为防火墙来控制允许通过的流量。在“安全组”部分,选择创建新安全组,为其命名(我们使用 gitlab-loadbalancer-sec-group)并添加描述,允许来自任何地方(0.0.0.0/0, ::/0)的HTTP和HTTPS流量。同时允许SSH流量,选择自定义源,并添加单个可信IP地址或CIDR表示法的IP地址范围。这允许用户通过SSH执行Git操作。

  5. 监听器和路由部分,设置端口 2280443 的监听器,考虑以下目标组。

    协议 端口 目标组
    TCP 22 gitlab-loadbalancer-ssh-target
    TCP 80 gitlab-loadbalancer-http-target
    TLS 443 gitlab-loadbalancer-http-target
    1. 对于端口 443 的TLS监听器,在安全策略设置下:
      1. 策略名称:从下拉列表中选择预定义的安全策略。你可以在AWS文档中查看网络负载均衡器的预定义SSL安全策略的详细说明。检查GitLab代码库中支持的SSL密码套件和协议列表
      2. 默认SSL/TLS服务器证书:从ACM选择SSL/TLS证书或上传证书到IAM。
  6. 对于我们创建的每个监听器,我们需要创建一个目标组并根据之前的表格分配它们。我们尚未创建任何EC2实例,因此无需注册目标。EC2实例将在后续自动缩放组设置过程中创建并分配。

    1. 选择创建目标组。选择实例作为目标类型。
    2. 为每个监听器选择适当的目标组名称:
      • gitlab-loadbalancer-http-target - 用于端口80的TCP协议
      • gitlab-loadbalancer-ssh-target - 用于端口22的TCP协议
    3. 选择IPv4作为IP地址类型。
    4. 从VPC下拉列表中选择 gitlab-vpc
    5. 对于 gitlab-loadbalancer-http-target 的健康检查,你应该使用就绪检查端点。你必须将VPC IP地址范围(CIDR)添加到健康检查端点的IP允许列表中。
    6. 对于 gitlab-loadbalancer-ssh-target 的健康检查,选择TCP
      • gitlab-loadbalancer-http-target 分配给端口80和443监听器。
      • gitlab-loadbalancer-ssh-target 分配给端口22监听器。
    7. 有些属性只能在目标组创建后配置。以下是你可以根据需求配置的一些功能。
      • 客户端IP保留 默认为目标组启用。这让连接到负载均衡器的客户端IP能在GitLab应用中保留。你可以根据需求启用或禁用它。

Proxy Protocol (https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#proxy-protocol) 默认对目标组禁用。这允许负载均衡器在代理协议头中发送额外信息。若想启用该功能,需确保内部负载均衡器、NGINX 等其他环境组件也完成相应配置。对本 POC 来说,仅需在后续的 GitLab 节点中启用即可。

  1. 选择 Create load balancer

负载均衡器启动并运行后,你可重新查看安全组,以仅通过 NLB 细化访问权限及其他潜在需求。

配置负载均衡器的 DNS

在 Route 53 仪表板中,选择左侧导航栏中的 Hosted zones(托管区域):

  1. 选择现有的托管区域,或者如果你的域名还没有托管区域,请选择 Create Hosted Zone(创建托管区域),输入你的域名,然后选择 Create(创建)。
  2. 选择 Create record(创建记录)并填写以下值:
    1. Name(名称):使用域名(默认值)或输入子域。
    2. Type(类型):选择 A - IPv4 address(A - IPv4 地址)。
    3. Alias(别名):默认为 disabled(禁用)。启用此选项。
    4. Route traffic to(路由流量至):选择 Alias to Network Load Balancer(别名为网络负载均衡器)。
    5. Region(区域):选择网络负载均衡器所在的区域。
    6. Choose network load balancer(选择网络负载均衡器):选择我们之前创建的网络负载均衡器。
    7. Routing Policy(路由策略):我们使用 Simple(简单)策略,但你也可以根据用例选择不同的策略。
    8. Evaluate Target Health(评估目标健康状态):我们将其设置为 No(否),但你可以选择让负载均衡器基于目标健康状态路由流量。
    9. 选择 Create(创建)。
  3. 如果你是通过 Route 53 注册的域名,那么就完成了。如果你使用了其他域名注册商,你必须通过域名注册商更新 DNS 记录。你需要:
    1. 选择 Hosted zones(托管区域)并选择你之前添加的域名。
    2. 你会看到一组 NS 记录。从你的域名注册商管理面板中,将这些记录作为 NS 记录添加到你域名的 DNS 记录中。不同域名注册商的操作步骤可能有所不同。如果你遇到困难,可以谷歌搜索 “your registrar’s name add DNS records”(你的注册商名称 添加 DNS 记录),你应该能找到针对你域名注册商的帮助文章。

具体操作步骤因使用的注册商而异,超出了本指南的范围。

使用 RDS 的 PostgreSQL

我们的数据库服务器使用 Amazon RDS for PostgreSQL,它提供 Multi AZ 冗余(Aurora 不受支持)。首先我们创建一个安全组和子网组,然后再创建实际的 RDS 实例。

RDS 安全组

我们需要一个允许来自后续部署的 gitlab-loadbalancer-sec-group 实例入站流量的数据库安全组:

  1. 从 EC2 仪表板中,选择左侧菜单栏中的 Security Groups(安全组)。
  2. 选择 Create security group(创建安全组)。
  3. 为其命名(我们使用 gitlab-rds-sec-group),添加描述,并从 VPC 下拉列表中选择 gitlab-vpc
  4. Inbound rules(入站规则)部分,选择 Add rule(添加规则)并设置以下内容:
    1. Type(类型):搜索并选择 PostgreSQL 规则。
    2. Source type(源类型):设置为 “Custom”(自定义)。
    3. Source(源):选择我们之前创建的 gitlab-loadbalancer-sec-group
  5. 完成后,选择 Create security group(创建安全组)。

RDS 子网组

  1. 进入 RDS 仪表板并从左侧选择 Subnet Groups(子网组)。
  2. 选择 Create DB Subnet Group(创建数据库子网组)。
  3. Subnet group details(子网组详情)下,输入名称(我们使用 gitlab-rds-group)、描述,并从 VPC 下拉列表中选择 gitlab-vpc
  4. Availability Zones(可用区)下拉列表中,选择包含你已配置子网的可用区。在我们的例子中,我们添加了 eu-west-2aeu-west-2b
  5. Subnets(子网)下拉列表中,选择我们定义的两个私有子网(10.0.1.0/2410.0.3.0/24),就像我们在 子网部分 中所做的那样。
  6. 准备好后选择 Create(创建)。

创建数据库

避免为数据库使用突发实例(t类实例),因为这可能导致在高负载持续期间因CPU积分耗尽而出现性能问题。

现在是时候创建数据库了:

  1. 前往RDS仪表板,从左侧菜单中选择“数据库”,并选择“创建数据库”。

  2. 选择“标准创建”作为数据库创建方式。

  3. 选择“PostgreSQL”作为数据库引擎,并选择与您的GitLab版本对应的最低PostgreSQL版本(可在我们的数据库要求中找到)。

  4. 由于这是生产环境,让我们在“模板”部分选择“生产”。

  5. 在“可用性与持久性”下,选择“多可用区DB实例”,以便在不同可用区中配置备用RDS实例。

  6. 在“设置”下,使用:

    • 数据库实例标识符为gitlab-db-ha
    • 主用户名为gitlab
    • 主密码为非常安全的密码。

    请记录这些信息,因为我们后续会用到。

  7. 对于数据库实例规格,选择“标准类”,并从下拉列表中选择满足您需求的实例规格。我们使用db.m5.large实例。

  8. 在“存储”下,配置以下内容:

    1. 从存储类型下拉列表中选择“预置IOPS SSD”。预置IOPS SSD存储最适合此场景(不过您也可以选择通用型SSD来降低成本)。更多信息请参阅AWS RDS存储
    2. 分配存储容量并设置预置IOPS。我们使用最小值1001000
    3. (可选)启用存储自动扩容,并设置最大存储阈值。
  9. 在“连接性”下,配置以下内容:

    1. 在“虚拟私有云(VPC)”下拉列表中选择我们之前创建的VPC(gitlab-vpc)。
    2. 在“DB子网组”下选择我们之前创建的子网组(gitlab-rds-group)。
    3. 将公共访问设置为“否”。
    4. 在“VPC安全组”下,选择“选择现有”,并从下拉列表中选择我们之前创建的gitlab-rds-sec-group
    5. 在“其他配置”下,将数据库端口保留为默认的5432
  10. 对于“数据库身份验证”,选择“密码身份验证”。

  11. 展开并完成“其他配置”部分的以下操作:

    1. 初始数据库名称。我们使用gitlabhq_production
    2. 配置您偏好的备份设置。
    3. 我们在此处唯一的额外修改是:在“维护”下禁用自动次要版本更新。
    4. 其他所有设置保持默认或按需调整。
    5. 如无问题,选择“创建数据库”。

现在数据库已创建,让我们继续设置带有ElastiCache的Redis。

Redis with ElastiCache

ElastiCache是一种内存托管的缓存解决方案。Redis自身维护持久化,用于存储GitLab应用的会话数据、临时缓存信息和后台任务队列。

创建Redis安全组

  1. 前往EC2仪表板。
  2. 从左侧菜单中选择“安全组”。
  3. 选择“创建安全组”并填写详情。为其命名(我们使用gitlab-redis-sec-group),添加描述,并选择我们之前创建的VPC(gitlab-vpc)。
  4. 在“入站规则”部分,选择“添加规则”,添加“自定义TCP”规则,设置端口6379,并将“自定义”源设置为之前创建的gitlab-loadbalancer-sec-group
  5. 完成后,选择“创建安全组”。

Redis子网组

  1. 从AWS控制台前往ElastiCache仪表板。

  2. 转到左侧菜单中的“子网组”,创建新子网组(我们命名为gitlab-redis-group)。选择我们之前创建的VPC(gitlab-vpc),并确保所选子网表中仅包含私有子网

  3. 准备就绪后选择“创建”。

    为GitLab Redis组创建子网组。

创建 Redis 集群

  1. 返回 ElastiCache 控制台。

  2. 在左侧菜单中选择「Redis 缓存」,然后选择「创建 Redis 缓存」以新建一个 Redis 集群。

  3. 在「部署选项」下选择「自定义缓存」。

  4. 在「创建方式」下选择「集群缓存」。

  5. 在「集群模式」下选择「禁用」,因为它不受支持。即使未开启集群模式,你仍有机会在多个可用区部署 Redis。

  6. 在「集群信息」中为集群命名(gitlab-redis)并添加描述。

  7. 在「位置」下选择「AWS 云」并启用「多可用区」选项。

  8. 在集群设置部分:

    1. 对于引擎版本,请选择与我们 Redis 要求 中针对你的 GitLab 版本定义一致的 Redis 版本。
    2. 端口保持为 6379,因为我们此前在 Redis 安全组中使用过此端口。
    3. 选择节点类型(至少 cache.t3.medium,可根据需求调整)以及副本数量。
  9. 在连接设置部分:

    1. 「网络类型」:IPv4
    2. 「子网组」:选择「选择现有子网组」并选择我们先前创建的 gitlab-redis-group
  10. 在可用区放置部分:

    1. 手动选择首选可用区,并在「副本 2」下选择与其他两个不同的可用区。

      选择 Redis 组的可用区。

  11. 选择「下一步」。

  12. 在安全设置中,编辑安全组并选择我们先前创建的 gitlab-redis-sec-group。选择「下一步」。

  13. 其余设置保持默认值或根据喜好修改。

  14. 完成后,选择「创建」。

设置堡垒主机

由于我们的 GitLab 实例位于私有子网中,我们需要一种通过 SSH 连接这些实例的方式,以便执行包括配置更改和升级在内的操作。一种方法是使用 堡垒主机,有时也被称为跳板机。

如果你不想维护堡垒主机,可以设置 AWS Systems Manager Session Manager 来访问实例。这超出了本文档的范围。

创建堡垒主机 A

  1. 前往 EC2 控制台并选择「启动实例」。
  2. 在「名称和标签」部分,将「名称」设置为 Bastion Host A
  3. 选择最新的「Ubuntu Server LTS (HVM)」AMI。查看 GitLab 文档了解 最新支持的操作系统版本
  4. 选择实例类型。我们使用 t2.micro,因为我们仅用堡垒主机通过 SSH 连接到其他实例。
  5. 在「密钥对」部分,选择「创建新密钥对」。
    1. 为密钥对命名(我们使用 bastion-host-a),并保存 bastion-host-a.pem 文件以备后续使用。
  6. 编辑网络设置部分:
    1. 在「VPC」下,从下拉列表中选择 gitlab-vpc
    2. 在「子网」下,选择我们先前创建的公共子网(gitlab-public-10.0.0.0)。
    3. 确保「自动分配公网 IP」下选择了「禁用」。稍后在 下一节 中会为该主机分配弹性 IP 地址。
    4. 在「防火墙」下选择「创建安全组」,输入「安全组名称」(我们使用 bastion-sec-group),并添加描述。
    5. 我们启用来自任意位置的 SSH 访问(0.0.0.0/0)。如果需要更严格的安全策略,可指定单个 IP 地址或 CIDR 表示法的 IP 地址范围。
  7. 存储方面,我们保留所有默认设置,仅添加一个 8 GB 的根卷。我们不在此实例上存储任何数据。
  8. 检查所有设置,若满意则选择「启动实例」。

为堡垒主机 A 分配弹性 IP

  1. 前往 EC2 控制台并选择「网络与安全」。
  2. 选择「弹性 IP」并将「网络边界组」设置为 us-west-2
  3. 选择「分配」。
  4. 选择已创建的弹性 IP 地址。
  5. 选择「操作」并选择「关联弹性 IP 地址」。
  6. 在「资源类型」下选择「实例」,然后在「实例」下拉列表中选择 Bastion Host A 主机。
  7. 选择「关联」。

确认可 SSH 连接到实例

  1. 在 EC2 控制台中,选择左侧菜单中的「实例」。
  2. 从实例列表中选择「Bastion Host A」。
  3. 选择「连接」并遵循连接说明。
  4. 如果能成功连接,让我们继续设置第二个堡垒主机以实现冗余。

创建堡垒主机 B

  1. 创建一个 EC2 实例,按照之前相同的步骤操作,但做如下更改:
    1. 对于 Subnet(子网),选择我们之前创建的第二个公共子网(gitlab-public-10.0.2.0)。
    2. Add Tags(添加标签)部分,设置 Key: NameValue: Bastion Host B,这样我们可以轻松识别两个实例。
    3. 对于安全组,选择我们之前创建的现有 bastion-sec-group

使用 SSH 代理转发

运行 Linux 的 EC2 实例使用私钥文件进行 SSH 身份验证。你通过 SSH 客户端连接到堡垒主机,使用存储在客户端上的私钥文件。由于私钥文件不在堡垒主机上,因此无法连接到私有子网中的实例。

在堡垒主机上存储私钥文件是个坏主意。为了解决这个问题,请在客户端上使用 SSH 代理转发。

例如,命令行 ssh 客户端使用带有 -A 开关的代理转发,如下所示:

ssh -A user@<bastion-public-IP-address>

有关如何为其他客户端使用 SSH 代理转发的分步指南,请参阅安全连接到在私有 Amazon VPC 中运行的 Linux 实例

安装 GitLab 并创建自定义 AMI

我们需要一个预配置的自定义 GitLab AMI,以便稍后在启动配置中使用。作为起点,我们使用官方 GitLab AMI 来创建 GitLab 实例。然后,我们为 PostgreSQL、Redis 和 Gitaly 添加自定义配置。如果你愿意,也可以不使用官方 GitLab AMI,而是自行启动一个 EC2 实例并手动安装 GitLab

安装 GitLab

从 EC2 控制台:

  1. 使用以下标题为“在 AWS 上查找官方 GitLab 创建的 AMI ID”的部分找到正确的 AMI,然后选择 Launch(启动)。
  2. Name and tags(名称和标签)部分,将 Name(名称)设置为 GitLab
  3. Instance type(实例类型)下拉列表中,根据你的工作负载选择一个实例类型。参考硬件要求选择适合你需求的一个(至少 c5.2xlarge,足以容纳 100 个用户)。
  4. Key pair(密钥对)部分,选择 Create new key pair(创建新密钥对)。
    1. 给密钥对命名(我们使用 gitlab),并保存 gitlab.pem 文件以备后用。
  5. Network settings(网络设置)部分:
    1. VPC:选择我们之前创建的 gitlab-vpc
    2. Subnet:从我们之前创建的子网列表中选择 gitlab-private-10.0.1.0
    3. Auto-assign Public IP(自动分配公有 IP):选择 Disable(禁用)。
    4. Firewall(防火墙):选择 Select existing security group(选择现有安全组),然后选择我们之前创建的 gitlab-loadbalancer-sec-group
  6. 对于存储,根卷默认为 8 GiB,鉴于我们不在此处存储任何数据,这应该足够了。
  7. 检查所有设置,如果满意,选择 Launch Instance(启动实例)。

添加自定义配置

通过 Bastion Host A 使用SSH 代理转发 连接到你的 GitLab 实例。连接后,添加以下自定义配置:

禁用 Let’s Encrypt

因为我们将在负载均衡器上添加 SSL 证书,所以不需要 GitLab 内置的 Let’s Encrypt 支持。当使用 https 域时,Let’s Encrypt默认启用,因此我们必须显式禁用它:

  1. 打开 /etc/gitlab/gitlab.rb 并禁用它:

    letsencrypt['enable'] = false
  2. 保存文件并重新配置以使更改生效:

    sudo gitlab-ctl reconfigure

为 PostgreSQL 安装所需扩展

从你的 GitLab 实例,连接到 RDS 实例以验证访问并安装所需的 pg_trgmbtree_gist 扩展。

要找到主机或端点,请转到 Amazon RDS > Databases(数据库),然后选择你之前创建的数据库。在 Connectivity & security(连接与安全性)选项卡下查找端点。

不要包含冒号和端口号:

sudo /opt/gitlab/embedded/bin/psql -U gitlab -h <rds-endpoint> -d gitlabhq_production

psql 提示符下创建扩展,然后退出会话:

psql (10.9)
Type "help" for help.

gitlab=# CREATE EXTENSION pg_trgm;
gitlab=# CREATE EXTENSION btree_gist;
gitlab=# \q

配置 GitLab 连接 PostgreSQL 和 Redis

  1. 编辑 /etc/gitlab/gitlab.rb,找到 external_url 'http://<domain>' 选项,将其更改为您使用的 https 域名。

  2. 查找 GitLab 数据库设置并按需取消注释。在我们的当前示例中,我们指定了数据库适配器、编码、主机、数据库名称、用户名和密码:

    # 禁用内置的 PostgreSQL
     postgresql['enable'] = false
    
    # 填充连接详情
    gitlab_rails['db_adapter'] = "postgresql"
    gitlab_rails['db_encoding'] = "unicode"
    gitlab_rails['db_database'] = "gitlabhq_production"
    gitlab_rails['db_username'] = "gitlab"
    gitlab_rails['db_password'] = "mypassword"
    gitlab_rails['db_host'] = "<rds-endpoint>"
  3. 接下来,我们必须通过添加主机并取消注释端口来配置 Redis 部分:

    # 禁用内置的 Redis
    redis['enable'] = false
    
    # 填充连接详情
    gitlab_rails['redis_host'] = "<redis-endpoint>"
    gitlab_rails['redis_port'] = 6379
  4. 最后,重新配置 GitLab 以使更改生效:

    sudo gitlab-ctl reconfigure
  5. 您还可以运行检查和服务状态以确保一切设置正确:

    sudo gitlab-rake gitlab:check
    sudo gitlab-ctl status

设置 Gitaly

在此架构中,单个 Gitaly 服务器会造成单点故障。使用 Gitaly Cluster (Praefect) 可消除此限制。

Gitaly 是一个提供服务以通过高级 RPC 访问 Git 仓库的服务。它应在其中一个我们先前配置的 私有子网 中的独立 EC2 实例上启用和配置。

让我们创建一个用于安装 Gitaly 的 EC2 实例:

  1. 从 EC2 仪表板中选择 启动实例

  2. 名称和标签 部分,将 名称 设为 Gitaly

  3. 选择 AMI。在本示例中,我们选择最新的 Ubuntu Server LTS (HVM), SSD Volume Type。查看 GitLab 文档了解 最新支持的操作系统版本

  4. 选择实例类型。我们选择 m5.xlarge

  5. 密钥对 部分,选择 创建新密钥对

    1. 为密钥对命名(我们使用 gitaly)并保存 gitaly.pem 文件以备后用。
  6. 在网络设置部分:

    1. VPC 下,从下拉列表中选择 gitlab-vpc
    2. 子网 下,选择我们之前创建的私有子网(gitlab-private-10.0.1.0)。
    3. 确保 自动分配公网 IP 选择了 禁用
    4. 防火墙 下选择 创建安全组,输入 安全组名称(我们使用 gitlab-gitaly-sec-group),并添加描述。
      1. 创建一条 自定义 TCP 规则 并将端口 8075 添加到 端口范围。对于 来源,选择 gitlab-loadbalancer-sec-group
      2. 还需添加来自 bastion-sec-group 的入站规则以便我们可以使用 SSH Agent Forwarding 从 Bastion 主机连接。
  7. 将根卷大小增加到 20 GiB 并将 卷类型 更改为 Provisioned IOPS SSD (io1)。(卷大小是任意值。创建足够大的卷以满足您的仓库存储需求。)

    1. 对于 IOPS,设置为 1000(20 GiB × 50 IOPS)。您可以每 GiB 预配最多 50 IOPS。如果选择更大的卷,请相应增加 IOPS。像 git 这样以串行方式写入许多小文件的工作负载需要高性能存储,因此选择 Provisioned IOPS SSD (io1)
  8. 检查所有设置,若满意则选择 启动实例

除了将配置和仓库数据存储在根卷上,您也可以选择添加额外的 EBS 卷用于仓库存储。遵循之前提到的相同指导原则。参见 Amazon EBS 定价页面

现在我们的 EC2 实例已准备就绪,请按照 文档安装 GitLab 并在其自己的服务器上设置 Gitaly。在该文档中执行客户端设置步骤,针对我们之前创建的 GitLab 实例

弹性文件系统 (EFS)

我们不推荐使用 EFS,因为它可能会对 GitLab 的性能产生负面影响。有关更多信息,请参阅避免使用基于云的文件系统的文档

如果你决定使用 EFS,请确保 PosixUser 属性被省略或正确指定了 Gitaly 所在系统上 git 用户的 UID 和 GID。可以通过以下命令获取 UID 和 GID:

# UID
$ id -u git

# GID
$ id -g git

此外,你不应配置多个 访问点,尤其是当它们指定不同凭据时。除 Gitaly 外的应用程序可能会以某种方式操纵 Gitaly 存储目录的权限,导致 Gitaly 无法正常运行。有关此问题的示例,请参见 omnibus-gitlab 问题 8893

添加对代理 SSL 的支持

由于我们在 负载均衡器 处终止 SSL,请按照支持代理 SSL中的步骤在 /etc/gitlab/gitlab.rb 中进行配置。

保存对 gitlab.rb 文件的更改后,记得运行 sudo gitlab-ctl reconfigure

快速查找授权 SSH 密钥

允许访问 GitLab 的用户的公钥存储在 /var/opt/gitlab/.ssh/authorized_keys 中。通常我们会使用共享存储,以便所有实例在用户执行 Git 操作时都能访问该文件。由于我们的设置中没有共享存储,我们将配置更新为通过 GitLab 数据库中的索引查找来授权 SSH 用户。

按照设置快速 SSH 密钥查找中的说明,从使用 authorized_keys 文件切换到数据库。

如果不配置快速查找,SSH 执行 Git 操作会出现以下错误:

Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

配置主机密钥

通常我们会手动将主应用服务器上 /etc/ssh/ 的内容(主密钥和公钥)复制到所有辅助服务器的 /etc/ssh 中。这可以防止在负载均衡器后访问集群中的服务器时出现虚假中间人攻击警报。

我们通过在自定义 AMI 中创建静态主机密钥来自动完成此操作。由于这些主机密钥每次 EC2 实例启动时都会轮换,“硬编码”到我们的自定义 AMI 中是一种变通方法。

在你的 GitLab 实例上运行以下命令:

sudo mkdir /etc/ssh_static
sudo cp -R /etc/ssh/* /etc/ssh_static

/etc/ssh/sshd_config 中更新以下内容:

# 协议版本 2 的 HostKeys
HostKey /etc/ssh_static/ssh_host_rsa_key
HostKey /etc/ssh_static/ssh_host_dsa_key
HostKey /etc/ssh_static/ssh_host_ecdsa_key
HostKey /etc/ssh_static/ssh_host_ed25519_key

Amazon S3 对象存储

由于我们没有使用 NFS 作为共享存储,因此我们使用 Amazon S3 存储桶来存储备份、构件、LFS 对象、上传内容、合并请求差异、容器注册表镜像等。我们的文档包含如何为每种数据类型配置对象存储的说明,以及其他关于在 GitLab 中使用对象存储的信息。

因为我们使用了之前创建的 AWS IAM profile,所以在配置对象存储时,请务必省略 AWS 访问密钥和秘密访问密钥/值对。相反,请在配置中使用 'use_iam_profile' => true,如之前链接的对象存储文档中所示。

保存对 gitlab.rb 文件的更改后,记得运行 sudo gitlab-ctl reconfigure


至此,我们的 GitLab 实例配置变更已完成。接下来,我们将基于此实例创建一个自定义 AMI,用于启动配置和自动伸缩组。

IP 允许列表

我们必须将之前创建的 gitlab-vpcVPC IP 地址范围(CIDR) 添加到 IP 允许列表 中,用于 健康检查端点

  1. 编辑 /etc/gitlab/gitlab.rb
    gitlab_rails['monitoring_whitelist'] = ['127.0.0.0/8', '10.0.0.0/16']
  2. 重新配置 GitLab:
    sudo gitlab-ctl reconfigure

代理协议

如果在之前创建的 负载均衡器 中启用了代理协议,我们也必须在 gitlab.rb 文件中 启用 该功能。

  1. 编辑 /etc/gitlab/gitlab.rb
    nginx['proxy_protocol'] = true
    nginx['real_ip_trusted_addresses'] = [ "127.0.0.0/8", "IP_OF_THE_PROXY/32"]
  2. 重新配置 GitLab:
    sudo gitlab-ctl reconfigure

首次登录

使用设置 负载均衡器的 DNS 时使用的域名,你现在应该能够在浏览器中访问 GitLab。

根据你安装 GitLab 的方式以及是否通过其他方式更改了密码,默认密码可能是:

  • 如果你使用了官方 GitLab AMI,则是你的实例 ID。
  • 一个随机生成的密码,存储在 /etc/gitlab/initial_root_password 中,有效期为 24 小时。

若要更改默认密码,请以 root 用户身份使用默认密码登录,并 在用户资料中修改

当我们的 自动伸缩组 启动新实例时,我们可以使用用户名 root 和新生成的密码登录。

创建自定义 AMI

在 EC2 控制台:

  1. 选择我们 之前创建GitLab 实例。
  2. 选择 Actions,向下滚动至 Image and templates 并选择 Create image
  3. 为镜像命名并添加描述(我们同时使用 GitLab-Source 作为名称和描述)。
  4. 其他选项保持默认,选择 Create Image

现在我们拥有一个自定义 AMI,可用于下一步创建启动配置。

在自动伸缩组中部署 GitLab

创建启动模板

从 EC2 控制台:

  1. 从左侧菜单中选择 Launch Templates,然后选择 create launch template
  2. 输入启动模板的名称(我们使用 gitlab-launch-template)。
  3. 选择 Launch template contents,然后选择 My AMIs 标签页。
  4. 选择 Owned by me,然后选择我们之前创建的 GitLab-Source 自定义 AMI。
  5. 选择最适合你需求的实例类型(至少为 c5.2xlarge)。
  6. Key pair 部分,选择 Create new key pair
    1. 为密钥对命名(我们使用 gitlab-launch-template),并保存 gitlab-launch-template.pem 文件以备后用。
  7. 根目录卷默认为 8 GiB,由于我们不在此处存储任何数据,这足够了。选择 Configure Security Group
  8. 勾选 Select an existing security group,然后选择我们之前创建的 gitlab-loadbalancer-sec-group
  9. Network settings 部分:
    1. 防火墙:选择 Select existing security group,然后选择我们之前创建的 gitlab-loadbalancer-sec-group
  10. Advanced details 部分:
    1. IAM instance profile:选择我们 之前创建GitLabS3Access 角色。
  11. 检查所有设置,如果满意,选择 Create launch template

创建自动伸缩组

从EC2仪表板:

  1. 从左侧菜单中选择自动伸缩组,然后选择创建自动伸缩组

  2. 输入组名(我们使用gitlab-auto-scaling-group)。

  3. 启动模板下,选择之前创建的启动模板。选择下一步

  4. 在网络设置部分:

    1. VPC下,从下拉列表中选择gitlab-vpc
    2. 可用区和子网下,选择之前创建的私有子网gitlab-private-10.0.1.0gitlab-private-10.0.3.0)。
    3. 选择下一步
  5. 在负载均衡设置部分:

    1. 选择附加到现有负载均衡器
    2. 现有负载均衡器目标组下拉列表中选择之前创建的目标组。
    3. 对于健康检查类型,勾选开启弹性负载均衡健康检查选项。我们将健康检查宽限期保留为默认值300秒。
    4. 选择下一步
  6. 对于组大小,将所需容量设置为2

  7. 在扩展设置部分:

    1. 选择无扩展策略。这些策略稍后配置。
    2. 最小所需容量:设置为2
    3. 最大所需容量:设置为4
    4. 选择下一步
  8. 最后,根据需要配置通知和标签,查看更改,并创建自动伸缩组。

  9. 自动伸缩组创建完成后,我们需要在Cloudwatch中创建扩展升级和降级策略并分配它们。

    1. 为之前创建的按自动伸缩组划分的EC2实例CPUUtilization指标创建警报。
    2. 使用以下条件创建扩展升级策略
      1. CPUUtilization大于或等于60%时,添加1个容量单位。
      2. 扩展策略名称设置为Scale Up Policy

    配置扩展升级策略。

    1. 使用以下条件创建扩展降级策略
      1. CPUUtilization小于或等于45%时,移除1个容量单位。
      2. 扩展策略名称设置为Scale Down Policy

    配置扩展降级策略。

    1. 将新的动态扩展策略分配给之前创建的自动伸缩组。

自动伸缩组创建后,您会在EC2仪表板中看到新实例正在启动。您还会看到新实例已添加到负载均衡器。实例通过健康检查后,即可开始接收来自负载均衡器的流量。

由于我们的实例是由自动伸缩组创建的,请返回您的实例并终止之前手动创建的实例。我们只需要这个实例来创建自定义AMI。

健康检查与Prometheus监控

除了可以在各种服务上启用的Amazon CloudWatch外,GitLab还提供了基于Prometheus的自身集成监控解决方案。有关如何设置的更多信息,请参阅GitLab Prometheus

GitLab还有各种健康检查端点,您可以对其进行ping操作并获得报告。

GitLab Runner

如果您想利用GitLab CI/CD,则必须至少设置一个runner

有关如何在AWS上配置自动伸缩GitLab Runner的信息,请参阅配置AWS上的自动伸缩GitLab Runner

备份与恢复

GitLab提供用于备份的工具,以恢复其Git数据、数据库、附件、LFS对象等。

一些重要事项:

备份GitLab

要备份GitLab:

  1. 通过SSH连接到您的实例。

  2. 进行备份:

    sudo gitlab-backup create

从备份恢复GitLab

要恢复GitLab,请先查看恢复文档,并重点了解恢复前提条件。然后,按照Linux包安装部分下的步骤操作。

更新GitLab

GitLab每月在发布日期发布新版本。每当有新版本发布时,您可以更新您的GitLab实例:

  1. 通过SSH连接到您的实例

  2. 备份数据:

    sudo gitlab-backup create
  3. 更新仓库并安装GitLab:

    sudo apt update
    sudo apt install gitlab-ee

几分钟后,新版本应该就能正常运行了。

在AWS上查找官方GitLab创建的AMI ID

阅读有关如何使用GitLab发布作为AMI的更多信息。

结论

在本指南中,我们主要介绍了扩展和一些冗余选项,具体情况因人而异。

请记住,所有解决方案都存在成本/复杂性与可用性之间的权衡。您想要的可用性越高,解决方案就越复杂。而解决方案越复杂,设置和维护所需的工作量就越大。

请阅读这些其他资源,并随时通过提交问题请求额外材料:

  • 扩展GitLab:GitLab支持多种不同类型的集群。
  • 地理复制:Geo是为广泛分布的开发团队提供的解决方案。
  • Linux包 - 关于管理您的GitLab实例的所有必备知识。
  • 添加许可证:通过许可证激活所有GitLab企业版功能。
  • 定价:不同层级的定价。

故障排除

实例健康检查失败

如果您的实例未通过负载均衡器的健康检查,请验证它们是否从我们之前配置的健康检查端点返回状态码200。任何其他状态码,包括重定向如状态码302,都会导致健康检查失败。

您可能需要为root用户设置密码,以防止在健康检查通过前登录端点的自动重定向。

“您请求的更改被拒绝(422)”

如果您在尝试通过网页界面设置密码时看到此页面,请确保gitlab.rb中的external_url与您发出请求的域名匹配,并在对其做出任何更改后运行sudo gitlab-ctl reconfigure

部分作业日志未上传到对象存储

当GitLab部署扩展到多个节点时,部分作业日志可能无法正确上传到对象存储。CI使用对象存储需要启用增量日志记录

如果尚未启用,请启用增量日志记录