GitLab教程(16): 高可用架构与扩展

当GitLab需要支持大量用户或要求高可用性时,需要进行架构扩展。本文将介绍GitLab的高可用部署方案。

GitLab架构组件

# GitLab核心组件

┌─────────────────────────────────────────────────────────────┐
│                        GitLab Stack                         │
├─────────────────────────────────────────────────────────────┤
│  Web层                                                      │
│  ├── Nginx (反向代理)                                       │
│  ├── Puma (Rails应用服务器)                                 │
│  └── GitLab Workhorse (Git HTTP处理)                        │
│                                                             │
│  后台处理                                                   │
│  ├── Sidekiq (异步任务)                                     │
│  └── Gitaly (Git仓库访问)                                   │
│                                                             │
│  数据存储                                                   │
│  ├── PostgreSQL (数据库)                                    │
│  ├── Redis (缓存/队列)                                      │
│  └── Object Storage (文件存储)                              │
│                                                             │
│  其他服务                                                   │
│  ├── GitLab Shell (SSH访问)                                 │
│  ├── GitLab Pages                                           │
│  ├── Container Registry                                     │
│  └── GitLab Runner                                          │
└─────────────────────────────────────────────────────────────┘

参考架构

# GitLab提供的参考架构(按用户数)

# 1k用户 (单节点)
CPU: 4核
内存: 8GB
存储: 100GB

# 2k用户
应用节点: 2个
数据库: 1个 (PostgreSQL)
Redis: 1个
Gitaly: 1个

# 3k用户
应用节点: 2个
数据库: 1个 (主)
Redis: 3个 (Sentinel)
Gitaly: 2个

# 5k用户
应用节点: 3个
数据库: 1个主 + 2个从
Redis: 3个 (Sentinel)
Gitaly: 3个
PgBouncer: 2个

# 10k+用户
完整HA配置
Consul集群
Praefect (Gitaly集群)
多区域部署

负载均衡配置

# HAProxy配置示例
# /etc/haproxy/haproxy.cfg

global
    maxconn 10000

defaults
    mode http
    timeout connect 5s
    timeout client 30s
    timeout server 30s

frontend gitlab_frontend
    bind *:80
    bind *:443 ssl crt /etc/ssl/gitlab.pem
    default_backend gitlab_backend

backend gitlab_backend
    balance roundrobin
    option httpchk GET /-/health
    http-check expect status 200
    server gitlab1 192.168.1.10:80 check
    server gitlab2 192.168.1.11:80 check
    server gitlab3 192.168.1.12:80 check

frontend gitlab_ssh
    bind *:22
    mode tcp
    default_backend gitlab_ssh_backend

backend gitlab_ssh_backend
    mode tcp
    balance roundrobin
    server gitlab1 192.168.1.10:22 check
    server gitlab2 192.168.1.11:22 check
    server gitlab3 192.168.1.12:22 check

# 健康检查端点
# /-/health       基本健康检查
# /-/readiness    就绪检查
# /-/liveness     存活检查

PostgreSQL高可用

# PostgreSQL主从复制配置

# 主节点 /etc/gitlab/gitlab.rb
postgresql['enable'] = true
postgresql['listen_address'] = '0.0.0.0'
postgresql['sql_replication_user'] = 'gitlab_replicator'
postgresql['sql_replication_password'] = 'replication_password'
postgresql['trust_auth_cidr_addresses'] = ['192.168.1.0/24']

# 从节点 /etc/gitlab/gitlab.rb
postgresql['enable'] = true
postgresql['listen_address'] = '0.0.0.0'
postgresql['sql_user_password'] = 'password_hash'

# 配置复制
postgresql['hot_standby'] = 'on'

# 使用Patroni管理PostgreSQL集群
# 提供自动故障转移

# PgBouncer连接池
# /etc/gitlab/gitlab.rb (应用节点)
gitlab_rails['db_host'] = 'pgbouncer.internal'
gitlab_rails['db_port'] = 6432
gitlab_rails['db_pool'] = 10

pgbouncer['enable'] = true
pgbouncer['listen_address'] = '0.0.0.0'
pgbouncer['auth_type'] = 'md5'
pgbouncer['databases'] = {
  'gitlabhq_production' => {
    'host' => 'primary.postgres.internal',
    'port' => 5432
  }
}

Redis高可用

# Redis Sentinel配置

# Redis主节点 /etc/gitlab/gitlab.rb
redis_master_role['enable'] = true
redis['bind'] = '0.0.0.0'
redis['port'] = 6379
redis['password'] = 'redis_password'

# Redis从节点 /etc/gitlab/gitlab.rb
redis_replica_role['enable'] = true
redis['bind'] = '0.0.0.0'
redis['port'] = 6379
redis['password'] = 'redis_password'
redis['master_name'] = 'gitlab-redis'
redis['master_ip'] = '192.168.1.20'
redis['master_port'] = 6379
redis['master_password'] = 'redis_password'

# Sentinel配置
sentinel['enable'] = true
sentinel['bind'] = '0.0.0.0'
sentinel['port'] = 26379
sentinel['quorum'] = 2
sentinel['master_name'] = 'gitlab-redis'
sentinel['master_ip'] = '192.168.1.20'
sentinel['master_port'] = 6379
sentinel['master_password'] = 'redis_password'

# 应用节点连接Sentinel
# /etc/gitlab/gitlab.rb
gitlab_rails['redis_sentinels'] = [
  {'host' => '192.168.1.20', 'port' => 26379},
  {'host' => '192.168.1.21', 'port' => 26379},
  {'host' => '192.168.1.22', 'port' => 26379}
]
gitlab_rails['redis_sentinels_master'] = 'gitlab-redis'
gitlab_rails['redis_sentinels_password'] = 'redis_password'

Gitaly集群

# Gitaly集群使用Praefect实现

# Praefect节点 /etc/gitlab/gitlab.rb
praefect['enable'] = true
praefect['listen_addr'] = '0.0.0.0:2305'
praefect['prometheus_listen_addr'] = '0.0.0.0:9652'

praefect['database_host'] = 'praefect-db.internal'
praefect['database_port'] = 5432
praefect['database_user'] = 'praefect'
praefect['database_password'] = 'praefect_password'
praefect['database_dbname'] = 'praefect_production'

praefect['virtual_storages'] = {
  'default' => {
    'nodes' => {
      'gitaly-1' => {
        'address' => 'tcp://192.168.1.30:8075',
        'token' => 'gitaly_token'
      },
      'gitaly-2' => {
        'address' => 'tcp://192.168.1.31:8075',
        'token' => 'gitaly_token'
      },
      'gitaly-3' => {
        'address' => 'tcp://192.168.1.32:8075',
        'token' => 'gitaly_token'
      }
    }
  }
}

# Gitaly节点 /etc/gitlab/gitlab.rb
gitaly['enable'] = true
gitaly['listen_addr'] = '0.0.0.0:8075'
gitaly['auth_token'] = 'gitaly_token'

git_data_dirs({
  'default' => { 'path' => '/var/opt/gitlab/git-data' }
})

# 应用节点连接Praefect
# /etc/gitlab/gitlab.rb
git_data_dirs({
  'default' => {
    'gitaly_address' => 'tcp://praefect.internal:2305'
  }
})

对象存储

# 使用对象存储替代本地存储
# /etc/gitlab/gitlab.rb

# 统一对象存储配置
gitlab_rails['object_store']['enabled'] = true
gitlab_rails['object_store']['proxy_download'] = true
gitlab_rails['object_store']['connection'] = {
  'provider' => 'AWS',
  'region' => 'us-east-1',
  'aws_access_key_id' => 'AKIAXXXXXXXX',
  'aws_secret_access_key' => 'xxxxxxxx'
}

# 各功能的存储桶
gitlab_rails['object_store']['objects']['artifacts']['bucket'] = 'gitlab-artifacts'
gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = 'gitlab-diffs'
gitlab_rails['object_store']['objects']['lfs']['bucket'] = 'gitlab-lfs'
gitlab_rails['object_store']['objects']['uploads']['bucket'] = 'gitlab-uploads'
gitlab_rails['object_store']['objects']['packages']['bucket'] = 'gitlab-packages'
gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = 'gitlab-dependency-proxy'
gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = 'gitlab-terraform'
gitlab_rails['object_store']['objects']['pages']['bucket'] = 'gitlab-pages'

# 使用MinIO (S3兼容)
gitlab_rails['object_store']['connection'] = {
  'provider' => 'AWS',
  'endpoint' => 'http://minio.internal:9000',
  'aws_access_key_id' => 'minio_access_key',
  'aws_secret_access_key' => 'minio_secret_key',
  'path_style' => true
}

监控

# GitLab内置Prometheus监控

# 启用监控 /etc/gitlab/gitlab.rb
prometheus['enable'] = true
prometheus['listen_address'] = '0.0.0.0:9090'

grafana['enable'] = true
grafana['admin_password'] = 'grafana_password'

# 监控端点
# Prometheus: http://gitlab.example.com:9090
# Grafana: http://gitlab.example.com/-/grafana

# 关键指标
# - gitlab_workhorse_http_requests_total
# - gitlab_rails_queue_duration_seconds
# - gitaly_commands_total
# - redis_connected_clients
# - pg_stat_activity_count

# 告警规则示例
groups:
  - name: gitlab
    rules:
      - alert: GitLabHighErrorRate
        expr: rate(gitlab_workhorse_http_requests_total{code=~"5.."}[5m]) > 0.1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "GitLab高错误率"
          
      - alert: GitLabDatabaseConnections
        expr: pg_stat_activity_count > 100
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "数据库连接数过高"

总结

本文介绍了GitLab的高可用架构,包括负载均衡、数据库集群、Redis Sentinel和Gitaly集群。根据用户规模选择合适的架构可以确保服务稳定性。

下一篇我们将学习GitLab API使用。

发表回复

后才能评论