메모리 제약 환경에서의 GitLab 실행

Tier: Free, Premium, Ultimate Offering: Self-Managed

모든 기능을 활성화한 상태로 실행할 때 GitLab은 상당량의 메모리가 필요합니다. GitLab을 모든 기능이 필요하지 않은 작은 설치 환경에서 실행하는 등의 사용 사례가 있습니다. 예시로는 다음과 같은 경우가 있습니다.

  • 개인용이나 매우 작은 팀용으로 GitLab 실행
  • 비용 절감을 위해 클라우드 제공 업체의 소규모 인스턴스 사용
  • Raspberry PI와 같이 리소스가 제약된 디바이스 사용

일부 조정을 통해, GitLab은 최소 요구 사항이나 참조 아키텍처에서 설명된 것보다 훨씬 낮은 사양에서도 편안하게 실행될 수 있습니다.

다음 섹션에는 최소 요구 사항을 충족하지 못하는 환경에서 GitLab을 실행할 수 있도록 하는 조언이 포함되어 있습니다. 대부분의 GitLab 구성 요소는 이러한 설정이 적용된 채로 작동해야 하지만, 제품 기능 및 성능의 예상치 못한 저하가 발생할 수 있습니다. 개발자 최대 5명이 개별 Git 프로젝트 크기가 100MB 이하인 경우 GitLab을 실행할 수 있어야 합니다.

제약된 환경을 위한 최소 요구 사항

GitLab을 실행할 수 있는 최소한의 예상 스펙은 다음과 같습니다.

  • Linux 기반 시스템 (이상적으로 Debian 기반 또는 RedHat 기반)
  • ARM7/ARM64의 4개 CPU 코어 또는 AMD64 아키텍처의 1개 CPU 코어
  • 최소 2GB의 RAM + 1GB의 SWAP, 최적은 2.5GB의 RAM + 1GB의 SWAP
  • 20GB의 사용 가능한 저장 공간
  • 다음 중 임의의 입/출력 성능이 우수한 저장 장치 (순서대로 선호):

위 목록 중 CPU의 단일 코어 성능과 저장 장치의 입/출력 성능이 가장 큰 영향을 미칩니다. 특히 저장 장치는 제약된 환경에서 메모리 스왑이 발생할 것으로 예상되므로 사용 중인 디스크에 더 많은 압력을 가합니다. 작은 플랫폼의 제한된 성능의 일반적인 문제는 매우 느린 디스크 저장 공간으로, 시스템 전체적인 병목 현상을 유발합니다.

이러한 최소화된 설정으로 시스템은 정규 작동 중 메모리 스왑을 사용해야 합니다. 모든 구성 요소가 동시에 사용되지 않으므로 수용할만한 성능을 제공해야 합니다.

시스템 성능 검증

Linux 기반 시스템의 성능을 검증할 수 있는 여러 도구가 있습니다. 시스템의 성능을 확인하는 데 도움을 주는 프로젝트 중 하나는 sbc-bench입니다. 이 프로젝트는 시스템 테스트의 모든 주의 사항과 다른 동작들이 시스템의 성능에 미치는 영향을 설명하는데, 이는 임베디드 시스템에서 GitLab을 실행할 때 특히 중요합니다. 제약된 환경에서 GitLab을 실행하기에 시스템의 성능이 충분한지를 검증하는 방법으로 사용할 수 있습니다.

다음 시스템은 GitLab의 소규모 설치를 실행하는 데 적합한 성능을 제공합니다:

스왑 구성

GitLab을 설치하기 전에 스왑을 구성해야 합니다. 스왑은 물리적 RAM이 가득 찬 경우 사용되는 디스크의 전용 공간입니다. 리눅스 시스템에서 RAM이 부족하면 비활성화된 페이지가 RAM에서 스왑 공간으로 이동됩니다.

스왑 사용은 대게 지연 시간을 증가시킬 수 있다고 여겨집니다. 그러나 GitLab의 작동 방식으로 인해 할당된 메모리 중 상당부분은 자주 액세스되지 않습니다. 스왑은 애플리케이션이 정상적으로 실행 및 작동하며 필요에 따라 가끔 사용될 수 있도록 합니다.

일반적인 지침은 사용 가능한 메모리의 약 50%에 해당하는 스왑을 구성하는 것입니다. 메모리 제약 환경에서는 시스템에 적어도 1GB의 스왑을 구성하는 것이 좋습니다. 이에 대한 여러 안내서가 있습니다:

구성한 후 스왑이 올바르게 활성화되었는지 확인해야 합니다:

free -h
              total        used        free      shared  buff/cache   available
Mem:          1.9Gi       115Mi       1.4Gi       0.0Ki       475Mi       1.6Gi
Swap:         1.0Gi          0B       1.0Gi

시스템이 스왑 공간을 얼마나 자주 사용할지를 구성할 수도 있는데, 이는 /proc/sys/vm/swappiness를 조정함으로써 할 수 있습니다. 스왑니스의 값은 0에서 100까지 범위를 가집니다. 기본값은 60입니다. 값이 낮으면 리눅스는 익명 메모리 페이지를 해제하고 스왑에 기록하는 것에 대한 선호도가 감소하지만, 파일을 기반으로 한 페이지에 대해서는 선호도가 증가합니다:

  1. 현재 세션에서 구성하기:

    sudo sysctl vm.swappiness=10
    
  2. 영구적으로 구성하려면 /etc/sysctl.conf를 편집:

    vm.swappiness=10
    

GitLab 설치

메모리가 제한된 환경에서는 적합한 GitLab 배포판을 고려해야 합니다.

GitLab Enterprise Edition (EE)에는 GitLab Community Edition (CE)보다 훨씬 많은 기능이 포함되어 있지만, 이러한 추가 기능은 컴퓨팅 및 메모리 요구 사항을 증가시킵니다.

메모리 소비가 주요 고려 사항일 때는 GitLab CE를 설치하세요. 나중에 GitLab EE로 업그레이드할 수 있습니다.

Puma 최적화

경고: 이것은 실험적인 알파 기능으로 언제든지 변경될 수 있습니다. 이 기능은 프로덕션 환경에서 사용하기에 준비가 되지 않았습니다. 이 기능을 사용하려면 먼저 프로덕션 데이터 없이 테스트하는 것이 좋습니다. 자세한 내용은 알려진 문제를 참조하세요.

기본 설정대로 GitLab은 많은 동시 연결을 처리할 수 있도록 설계된 구성으로 실행됩니다.

고 처리량이 필요하지 않은 소규모 설치의 경우, Puma 클러스터 모드를 비활성화하는 것을 고려해보세요. 이렇게 하면 한 가지 Puma 프로세스만 애플리케이션을 제공하게 됩니다.

/etc/gitlab/gitlab.rb에서:

puma['worker_processes'] = 0

이렇게 Puma를 구성하면 메모리 사용량이 100-400MB 감소하는 것을 관찰했습니다.

Sidekiq 최적화

Sidekiq는 백그라운드 처리 데몬입니다. GitLab의 기본 구성으로 설정되면 50의 높은 동시성 모드로 실행됩니다. 이는 한 번에 얼마나 많은 메모리를 할당할 수 있는지에 영향을 줍니다. 이 값을 5 또는 10 (권장)으로 구성하는 것이 좋습니다.

/etc/gitlab/gitlab.rb에서:

sidekiq['max_concurrency'] = 10

Gitaly 최적화

Gitaly는 Git 기반 저장소에 효율적인 액세스를 허용하는 저장소 서비스입니다. Gitaly가 강제하는 최대 동시성 및 메모리 제한을 구성하는 것이 좋습니다.

/etc/gitlab/gitlab.rb에서:

gitaly['configuration'] = {
    concurrency: [
      {
        'rpc' => "/gitaly.SmartHTTPService/PostReceivePack",
        'max_per_repo' => 3,
      }, {
        'rpc' => "/gitaly.SSHService/SSHUploadPack",
        'max_per_repo' => 3,
      },
    ],
    cgroups: {
        repositories: {
            count: 2,
        },
        mountpoint: '/sys/fs/cgroup',
        hierarchy_root: 'gitaly',
        memory_bytes: 500000,
        cpu_shares: 512,
    },
}

gitaly['env'] = {
  'GITALY_COMMAND_SPAWN_MAX_PARALLEL' => '2'
}

모니터링 비활성화

GitLab은 추가 구성 없이도 완전한 DevOps 솔루션을 제공하기 위해 기본적으로 모든 서비스를 활성화합니다. 모니터링과 같은 기본 서비스 중 일부는 GitLab이 작동하는 데 필수적이지 않으므로 메모리를 절약하기 위해 비활성화할 수 있습니다.

/etc/gitlab/gitlab.rb에서:

prometheus_monitoring['enable'] = false

이렇게 GitLab을 구성하면 200MB의 메모리 사용량이 감소하는 것을 관찰했습니다.

GitLab 메모리 처리 방식 구성

GitLab은 Ruby 및 Go로 작성된 많은 구성 요소로 이루어져 있으며, GitLab Rails가 가장 크고 가장 많은 메모리를 사용합니다.

GitLab Rails는 메모리 할당기로써 jemalloc을 사용합니다. jemalloc은 성능을 향상시키기 위해 메모리를 더 큰 블록으로 미리 할당하고 더 오래 보유하는 기능입니다. 성능 일부 손실을 감수하고 메모리를 더 오랫동안 보유하는 대신 GitLab을 구성하여 더 이상 필요하지 않은 메모리를 즉시 해제하도록 할 수 있습니다.

/etc/gitlab/gitlab.rb에서:

gitlab_rails['env'] = {
  'MALLOC_CONF' => 'dirty_decay_ms:1000,muzzy_decay_ms:1000'
}

gitaly['env'] = {
  'MALLOC_CONF' => 'dirty_decay_ms:1000,muzzy_decay_ms:1000'
}

이를 통해 애플리케이션 실행 중에 훨씬 더 안정적인 메모리 사용량이 관찰되었습니다.

추가 내부 모니터링 비활성화

GitLab은 자체적인 데이터 구조를 사용하여 자체적인 다양한 측면을 측정합니다. 이러한 기능은 모니터링이 비활성화된 경우 더 이상 필요하지 않습니다.

이러한 기능을 비활성화하려면 GitLab의 관리 영역으로 이동하여 Prometheus Metrics 기능을 비활성화해야 합니다:

  1. 왼쪽 사이드바에서 가장 아래쪽에 있는 관리 영역을 선택합니다.
  2. 설정 > Metrics and profiling을 선택합니다.
  3. Metrics - Prometheus를 확장합니다.
  4. Prometheus Metrics 활성화를 비활성화합니다.
  5. 변경 사항 저장을 선택합니다.

모든 변경 사항이 적용된 구성

  1. 지금까지 설명한 모든 것을 적용하면 /etc/gitlab/gitlab.rb 파일에 다음 구성이 포함되어야 합니다.

    puma['worker_processes'] = 0
    
    sidekiq['max_concurrency'] = 10
    
    prometheus_monitoring['enable'] = false
    
    gitlab_rails['env'] = {
      'MALLOC_CONF' => 'dirty_decay_ms:1000,muzzy_decay_ms:1000'
    }
    
    gitaly['configuration'] = {
      concurrency: [
        {
          'rpc' => "/gitaly.SmartHTTPService/PostReceivePack",
          'max_per_repo' => 3,
        }, {
          'rpc' => "/gitaly.SSHService/SSHUploadPack",
          'max_per_repo' => 3,
        },
      ],
      cgroups: {
        repositories: {
          count: 2,
        },
        mountpoint: '/sys/fs/cgroup',
        hierarchy_root: 'gitaly',
        memory_bytes: 500000,
        cpu_shares: 512,
      },
    }
    gitaly['env'] = {
      'MALLOC_CONF' => 'dirty_decay_ms:1000,muzzy_decay_ms:1000',
      'GITALY_COMMAND_SPAWN_MAX_PARALLEL' => '2'
    }
    
  2. 이러한 변경 사항을 모두 적용한 후에 GitLab을 이 새로운 설정을 사용하도록 다시 구성하세요.

    sudo gitlab-ctl reconfigure
    

    GitLab은 이전까지 메모리 절약 설정과 작동하지 않았기 때문에 이 작업에는 시간이 걸릴 수 있습니다.

성능 결과

위의 구성을 적용한 후, 다음과 같은 메모리 사용량을 예상할 수 있습니다:

              total        used        free      shared  buff/cache   available
Mem:          1.9Gi       1.7Gi       151Mi        31Mi       132Mi       102Mi
Swap:         1.0Gi       153Mi       870Mi