GitLab에서 NFS 사용
Offering: GitLab Self-Managed
NFS는 오브젝트 스토리지의 대안으로 사용할 수 있지만 성능상의 이유로 일반적으로 권장되지 않습니다. LFS, 업로드, 아티팩트와 같은 데이터 오브젝트의 경우 더 나은 성능을 위해 NFS보다 오브젝트 스토리지 서비스가 권장됩니다.
NFS는 오브젝트 스토리지의 대안으로 사용할 수 있지만 성능상의 이유로 일반적으로 권장되지 않습니다.
LFS, 업로드, 아티팩트와 같은 데이터 오브젝트의 경우 더 나은 성능을 위해 NFS보다 오브젝트 스토리지 서비스가 권장됩니다. NFS 사용을 제거할 때는 오브젝트 스토리지로 이전하는 것 외에도 추가 단계가 필요합니다.
NFS는 저장소 스토리지에 사용할 수 없습니다.
파일 시스템 성능을 테스트하는 데 사용할 수 있는 단계는 파일 시스템 성능 벤치마킹을 참조하세요.
인증된 SSH 키의 빠른 조회#
빠른 SSH 키 조회 기능은 블록 스토리지를 사용하는 경우에도 GitLab 인스턴스의 성능을 향상시킬 수 있습니다.
빠른 SSH 키 조회는 GitLab 데이터베이스를 사용하여 authorized_keys (in /var/opt/gitlab/.ssh)를 대체합니다.
NFS는 대기 시간을 증가시키므로 /var/opt/gitlab이 NFS로 이동하는 경우 빠른 조회가 권장됩니다.
빠른 조회를 기본값으로 사용하는 것에 대해 조사 중입니다.
NFS 서버#
nfs-kernel-server 패키지를 설치하면 GitLab 애플리케이션을 실행하는 클라이언트와 디렉토리를 공유할 수 있습니다:
sudo apt-get update
sudo apt-get install nfs-kernel-server
필수 기능#
파일 잠금: GitLab은 NFS 버전 4에서만 기본적으로 지원되는 권고 파일 잠금이 필요합니다. NFSv3은 Linux 커널 2.6.5 이상을 사용하는 경우에도 잠금을 지원합니다. 버전 4를 사용하고 NFSv3을 특별히 테스트하지 않는 것을 권장합니다.
권장 옵션#
NFS 내보내기를 정의할 때 다음 옵션도 추가하는 것을 권장합니다:
no_root_squash- NFS는 일반적으로root사용자를nobody로 변경합니다. 이는 NFS 공유가 많은 다른 사용자에 의해 액세스될 때 좋은 보안 조치입니다. 그러나 이 경우 GitLab만 NFS 공유를 사용하므로 안전합니다. GitLab은 파일 권한을 자동으로 관리해야 하기 때문에no_root_squash설정을 권장합니다. 이 설정이 없으면 Linux 패키지가 권한을 변경하려고 할 때 오류가 발생할 수 있습니다. GitLab과 기타 번들 구성 요소는root가 아닌 비권한 사용자로 실행됩니다.no_root_squash권장 사항은 Linux 패키지가 필요에 따라 파일의 소유권과 권한을 설정할 수 있도록 하기 위한 것입니다.no_root_squash옵션을 사용할 수 없는 경우root플래그가 동일한 결과를 달성할 수 있습니다.sync- 동기 동작을 강제합니다. 기본값은 비동기이며 특정 상황에서 데이터가 동기화되기 전에 오류가 발생하면 데이터 손실이 발생할 수 있습니다.
LDAP를 사용하는 Linux 패키지 실행의 복잡성과 LDAP 없이 ID 매핑을 유지 관리하는 복잡성 때문에 대부분의 경우 시스템 간 권한 관리를 단순화하기 위해 숫자 UID와 GID를 활성화해야 합니다(일부 경우 기본적으로 꺼져 있음):
- NetApp 지침
- NetApp 이외의 기기의 경우 NFSv4 idmapper 활성화의 반대를 수행하여 NFSv4
idmapping비활성화
NFS 서버 위임 비활성화#
모든 NFS 사용자에게 NFS 서버 위임 기능을 비활성화하도록 권장합니다. 이는 수많은 TEST_STATEID NFS 메시지로 인한 과도한 네트워크 트래픽으로 NFS 클라이언트가 급격히 느려지는 Linux 커널 버그를 피하기 위한 것입니다.
NFS 서버 위임을 비활성화하려면 다음을 수행합니다:
-
NFS 서버에서 다음을 실행합니다:
echo 0 > /proc/sys/fs/leases-enable sysctl -w fs.leases-enable=0 -
NFS 서버 프로세스를 재시작합니다. 예를 들어 CentOS에서는
service nfs restart를 실행합니다.
이 커널 버그는 이 커밋이 포함된 더 최신 커널에서 수정될 수 있습니다. Red Hat Enterprise 7은 2019년 8월 6일에 이 문제를 해결했을 수 있는 커널 업데이트를 출시했습니다. 수정된 Linux 커널 버전을 사용하고 있다면 NFS 서버 위임을 비활성화할 필요가 없을 수도 있습니다. 그렇더라도 GitLab은 여전히 인스턴스 관리자에게 NFS 서버 위임을 비활성화된 상태로 유지하도록 권장합니다.
NFS 클라이언트#
nfs-common은 애플리케이션 노드에서 실행할 필요가 없는 서버 구성 요소를 설치하지 않고 NFS 기능을 제공합니다.
apt-get update
apt-get install nfs-common
마운트 옵션#
/etc/fstab에 추가할 예시 스니펫:
10.1.0.1:/var/opt/gitlab/.ssh /var/opt/gitlab/.ssh nfs4 defaults,vers=4.1,hard,rsize=1048576,wsize=1048576,noatime,nofail,_netdev,lookupcache=positive 0 2
10.1.0.1:/var/opt/gitlab/gitlab-rails/uploads /var/opt/gitlab/gitlab-rails/uploads nfs4 defaults,vers=4.1,hard,rsize=1048576,wsize=1048576,noatime,nofail,_netdev,lookupcache=positive 0 2
10.1.0.1:/var/opt/gitlab/gitlab-rails/shared /var/opt/gitlab/gitlab-rails/shared nfs4 defaults,vers=4.1,hard,rsize=1048576,wsize=1048576,noatime,nofail,_netdev,lookupcache=positive 0 2
10.1.0.1:/var/opt/gitlab/gitlab-ci/builds /var/opt/gitlab/gitlab-ci/builds nfs4 defaults,vers=4.1,hard,rsize=1048576,wsize=1048576,noatime,nofail,_netdev,lookupcache=positive 0 2
nfsstat -m 및 cat /etc/fstab를 실행하여 마운트된 NFS 파일 시스템에 설정된 정보와 옵션을 볼 수 있습니다.
사용을 고려해야 하는 몇 가지 옵션:
| 설정 | 설명 |
|---|---|
vers=4.1 |
스테일 데이터로 인한 심각한 문제를 일으킬 수 있는 Linux NFS 클라이언트 v4.0 버그 때문에 v4.0 대신 NFS v4.1을 사용해야 합니다. |
nofail |
이 마운트가 사용 가능해지기를 기다리며 부팅 프로세스를 중단하지 않습니다. |
lookupcache=positive |
NFS 클라이언트에게 positive 캐시 결과를 유지하지만 negative 캐시 결과는 무효화하도록 지시합니다. 네거티브 캐시 결과는 Git에서 문제를 일으킵니다. 특히 git push가 모든 NFS 클라이언트에 일관되게 등록되지 않을 수 있습니다. 네거티브 캐시로 인해 클라이언트들은 이전에 파일이 존재하지 않았다고 '기억'하게 됩니다. |
hard |
soft 대신 사용합니다. 추가 세부 정보. |
cto |
cto가 기본 옵션으로 사용해야 합니다. nocto는 사용하지 마세요. 추가 세부 정보. |
_netdev |
네트워크가 온라인 상태가 될 때까지 파일 시스템 마운트를 기다립니다. high_availability['mountpoint'] 옵션도 참조하세요. |
soft 마운트 옵션#
soft를 사용해야 할 특별한 이유가 없는 한 마운트 옵션에서 hard를 사용하는 것이 권장됩니다.
GitLab.com이 NFS를 사용했을 때 NFS 서버가 재부팅될 때가 있어 soft가 가용성을 향상시켰기 때문에 soft를 사용했지만 모든 사람의 인프라는 다릅니다. 예를 들어 NFS가 중복 컨트롤러가 있는 온프레미스 스토리지 어레이에서 제공된다면 NFS 서버 가용성에 대해 걱정할 필요가 없습니다.
NFS man 페이지에는:
"soft" 타임아웃은 특정 경우에 자동으로 데이터 손상을 일으킬 수 있습니다
차이점을 이해하려면 Linux man 페이지를 읽고 soft를 사용하는 경우 위험을 완화하기 위한 조치를 취했는지 확인하세요.
NFS 서버의 디스크에 쓰기가 발생하지 않아서 커밋이 누락되는 경우와 같이 발생할 수 있는 동작을 경험하는 경우 (man 페이지에서와 같이) hard 옵션을 사용하세요:
클라이언트 응답성이 데이터 무결성보다 중요한 경우에만 soft 옵션을 사용하세요
다른 공급업체도 읽기/쓰기 디렉토리에 대한 권장 마운트 옵션 및 NetApp의 지식 기반을 포함하여 유사한 권장 사항을 제시하며, NFS 클라이언트 드라이버가 데이터를 캐시하는 경우 soft는 GitLab의 쓰기가 실제로 디스크에 있는지 확실하지 않다고 강조합니다.
hard 옵션으로 설정된 마운트 포인트는 성능이 저하될 수 있으며 NFS 서버가 다운되면 hard는 마운트 포인트와 상호 작용할 때 프로세스가 중단되도록 합니다. 중단된 프로세스를 처리하려면 SIGKILL (kill -9)을 사용하세요. intr 옵션은 2.6 커널에서 작동이 중단되었습니다.
nocto 마운트 옵션#
nocto를 사용하지 마세요. 대신 기본값인 cto를 사용하세요.
nocto를 사용하면 dentry 캐시는 생성된 시점부터 acdirmax 초(속성 캐시 시간)까지 항상 사용됩니다.
이로 인해 여러 클라이언트에서 스테일 dentry 캐시 문제가 발생하며 각 클라이언트는 디렉토리의 다른 (캐시된) 버전을 볼 수 있습니다.
Linux man 페이지에서 중요한 부분:
nocto옵션이 지정되면 클라이언트는 비표준 휴리스틱을 사용하여 서버의 파일이 변경된 시기를 결정합니다.
nocto옵션을 사용하면 읽기 전용 마운트의 성능이 향상될 수 있지만 서버의 데이터가 가끔만 변경될 때만 사용해야 합니다.
푸시 후 refs를 찾을 수 없는 문제에서 이 동작을 발견했으며 로컬 dentry 캐시가 있는 다른 클라이언트에서 새로 추가된 느슨한 refs가 누락된 것으로 볼 수 있습니다.
단일 NFS 마운트#
기존 데이터를 수동으로 이동하지 않고도 백업을 자동 복원할 수 있도록 마운트 내에 모든 GitLab 데이터 디렉토리를 중첩하는 것이 권장됩니다.
mountpoint
└── gitlab-data
├── builds
├── shared
└── uploads
이를 위해 마운트 포인트 내에 중첩된 각 디렉토리 경로와 함께 Linux 패키지를 다음과 같이 구성합니다:
/gitlab-nfs를 마운트한 다음 다음 Linux 패키지 구성을 사용하여 각 데이터 위치를 하위 디렉토리로 이동합니다:
gitlab_rails['uploads_directory'] = '/gitlab-nfs/gitlab-data/uploads'
gitlab_rails['shared_path'] = '/gitlab-nfs/gitlab-data/shared'
gitlab_ci['builds_directory'] = '/gitlab-nfs/gitlab-data/builds'
sudo gitlab-ctl reconfigure를 실행하여 중앙 위치를 사용하기 시작합니다. 기존 데이터가 있는 경우 이 새 위치로 수동으로 복사하거나 rsync한 다음 GitLab을 재시작해야 합니다.
바인드 마운트#
Linux 패키지의 구성을 변경하는 대신 바인드 마운트를 사용하여 NFS 마운트에 데이터를 저장할 수 있습니다.
바인드 마운트는 하나의 NFS 마운트만 지정하고 기본 GitLab 데이터 위치를 NFS 마운트에 바인드하는 방법을 제공합니다. 일반적으로 /etc/fstab에 단일 NFS 마운트 포인트를 정의하는 것으로 시작합니다. NFS 마운트 포인트가 /gitlab-nfs라고 가정하면 /etc/fstab에 다음 바인드 마운트를 추가합니다:
/gitlab-nfs/gitlab-data/.ssh /var/opt/gitlab/.ssh none bind 0 0
/gitlab-nfs/gitlab-data/uploads /var/opt/gitlab/gitlab-rails/uploads none bind 0 0
/gitlab-nfs/gitlab-data/shared /var/opt/gitlab/gitlab-rails/shared none bind 0 0
/gitlab-nfs/gitlab-data/builds /var/opt/gitlab/gitlab-ci/builds none bind 0 0
바인드 마운트를 사용하면 복원을 시도하기 전에 데이터 디렉토리가 비어 있는지 수동으로 확인해야 합니다. 복원 사전 조건에 대해 자세히 읽으세요.
여러 NFS 마운트#
기본 Linux 패키지 구성을 사용할 때 모든 GitLab 클러스터 노드 간에 3개의 데이터 위치를 공유해야 합니다. 다른 위치는 공유하면 안 됩니다. 다음은 공유해야 하는 3가지 위치입니다:
| 위치 | 설명 | 기본 구성 |
|---|---|---|
/var/opt/gitlab/gitlab-rails/uploads |
사용자가 업로드한 첨부 파일 | gitlab_rails['uploads_directory'] = '/var/opt/gitlab/gitlab-rails/uploads' |
/var/opt/gitlab/gitlab-rails/shared |
빌드 아티팩트, GitLab Pages, LFS 오브젝트 및 임시 파일과 같은 오브젝트. LFS를 사용하는 경우 데이터의 많은 부분을 차지할 수도 있습니다 | gitlab_rails['shared_path'] = '/var/opt/gitlab/gitlab-rails/shared' |
/var/opt/gitlab/gitlab-ci/builds |
GitLab CI/CD 빌드 추적 | gitlab_ci['builds_directory'] = '/var/opt/gitlab/gitlab-ci/builds' |
다른 GitLab 디렉토리는 노드 간에 공유하면 안 됩니다. 노드 특정 파일과 공유할 필요가 없는 GitLab 코드를 포함합니다. 중앙 위치로 로그를 전달하려면 원격 syslog 사용을 고려하세요. Linux 패키지는 UDP 로그 전달 구성을 제공합니다.
여러 NFS 마운트를 사용하면 복원을 시도하기 전에 데이터 디렉토리가 비어 있는지 수동으로 확인해야 합니다. 복원 사전 조건에 대해 자세히 읽으세요.
NFS 테스트#
NFS 서버와 클라이언트를 설정하면 다음 명령을 테스트하여 NFS가 올바르게 구성되었는지 확인할 수 있습니다:
sudo mkdir /gitlab-nfs/test-dir
sudo chown git /gitlab-nfs/test-dir
sudo chgrp root /gitlab-nfs/test-dir
sudo chmod 0700 /gitlab-nfs/test-dir
sudo chgrp gitlab-www /gitlab-nfs/test-dir
sudo chmod 0751 /gitlab-nfs/test-dir
sudo chgrp git /gitlab-nfs/test-dir
sudo chmod 2770 /gitlab-nfs/test-dir
sudo chmod 2755 /gitlab-nfs/test-dir
sudo -u git mkdir /gitlab-nfs/test-dir/test2
sudo -u git chmod 2755 /gitlab-nfs/test-dir/test2
sudo ls -lah /gitlab-nfs/test-dir/test2
sudo -u git rm -r /gitlab-nfs/test-dir
Operation not permitted 오류가 발생하면 NFS 서버 내보내기 옵션을 조사해야 합니다.
방화벽 환경에서의 NFS#
NFS 서버와 NFS 클라이언트 간의 트래픽이 방화벽의 포트 필터링을 받는 경우 NFS 통신을 허용하도록 해당 방화벽을 재구성해야 합니다.
Linux 문서 프로젝트(TDLP)의 이 가이드는 방화벽 환경에서 NFS를 사용하는 기본 사항을 다룹니다. 또한 운영 체제 또는 배포판 및 방화벽 소프트웨어에 대한 특정 문서를 검색하고 검토하는 것을 권장합니다.
Ubuntu 예시:
호스트의 방화벽에서 클라이언트의 NFS 트래픽이 허용되는지 확인하려면 명령을 실행합니다: sudo ufw status. 차단된 경우 아래 명령으로 특정 클라이언트의 트래픽을 허용할 수 있습니다.
sudo ufw allow from <client_ip_address> to any port nfs
알려진 문제#
클라우드 기반 파일 시스템 사용 금지#
GitLab은 다음과 같은 클라우드 기반 파일 시스템 사용을 강력히 권장하지 않습니다:
- AWS Elastic File System (EFS).
- Google Cloud Filestore.
- Azure Files.
지원 팀은 클라우드 기반 파일 시스템 액세스와 관련된 성능 문제를 지원할 수 없습니다.
고객 및 사용자들은 이러한 파일 시스템이 GitLab이 필요로 하는 파일 시스템 액세스에 대해 성능이 좋지 않다고 보고했습니다. git와 같이 많은 소형 파일이 직렬화된 방식으로 쓰여지는 워크로드는 클라우드 기반 파일 시스템에 적합하지 않습니다.
이를 사용하기로 선택한 경우 성능에 영향을 미치기 때문에 GitLab 로그 파일(예: /var/log/gitlab의 파일)을 거기에 저장하는 것을 피하세요. 로그 파일은 로컬 볼륨에 저장하는 것이 좋습니다.
GitLab에서 클라우드 기반 파일 시스템을 사용한 경험에 대한 자세한 내용은 이 Commit Brooklyn 2019 비디오를 참조하세요.
CephFS 및 GlusterFS 사용 금지#
GitLab은 CephFS 및 GlusterFS 사용을 강력히 권장하지 않습니다. 이러한 분산 파일 시스템은 GitLab 입출력 액세스 패턴에 적합하지 않습니다. Git은 많은 소형 파일을 사용하고 액세스 시간 및 파일 잠금 시간이 전파되는 데 걸리는 시간으로 인해 Git 활동이 매우 느려집니다.
NFS와 함께 PostgreSQL 사용 금지#
GitLab은 NFS에서 PostgreSQL 데이터베이스를 실행하는 것을 강력히 권장하지 않습니다. GitLab 지원 팀은 이 구성과 관련된 성능 문제를 지원할 수 없습니다.
또한 이 구성은 PostgreSQL 문서에서 특별히 경고됩니다:
PostgreSQL은 NFS 파일 시스템에 대해 특별한 처리를 하지 않으므로 NFS가 로컬로 연결된 드라이브와 완전히 동일하게 동작한다고 가정합니다. 클라이언트 또는 서버 NFS 구현이 표준 파일 시스템 시맨틱을 제공하지 않으면 신뢰성 문제가 발생할 수 있습니다. 특히 NFS 서버에 대한 지연(비동기) 쓰기는 데이터 손상 문제를 일으킬 수 있습니다.
지원되는 데이터베이스 아키텍처는 복제 및 장애 조치를 위한 데이터베이스 구성에 대한 문서를 참조하세요.
문제 해결#
NFS에 대한 요청 찾기#
NFS 관련 문제의 경우 perf를 사용하여 파일 시스템 요청을 추적하는 것이 도움이 될 수 있습니다:
sudo perf trace -e 'nfs4:*' -p $(pgrep -fd ',' puma)
