GitLab과 함께 NFS 사용하기
NFS는 객체 저장소의 대안으로 사용될 수 있지만 일반적으로
성능 문제로 인해 권장되지 않습니다.
LFS, 업로드 및 아티팩트와 같은 데이터 객체에는 가능한 경우
NFS보다 객체 저장소 서비스가 더 나은 성능을 제공하므로 권장됩니다.
NFS 사용을 제거할 때는 객체 저장소로 이동하는 것 외에도
추가로 취해야 할 단계가 있습니다.
NFS는 저장소 저장소로 사용할 수 없습니다.
파일 시스템 성능을 테스트하기 위해 사용할 수 있는 단계는
파일 시스템 성능 벤치마크를 참조하세요.
승인된 SSH 키의 빠른 조회
빠른 SSH 키 조회 기능은
블록 저장소를 사용하는 경우에도 GitLab 인스턴스의 성능을 향상시킬 수 있습니다.
빠른 SSH 키 조회는
GitLab 데이터베이스를 사용하여 /var/opt/gitlab/.ssh
의
authorized_keys
를 대체합니다.
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 Kernel 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 ID 매퍼 활성화의 반대 작업을 수행하여
NFSv4idmapping
을 비활성화 합니다.
NFS 서버 위임 비활성화
모든 NFS 사용자에게 NFS 서버 위임 기능을 비활성화할 것을 권장합니다. 이는 Linux 커널 버그를 피하기 위한 것으로, 이 버그로 인해 NFS 클라이언트가 많은 TEST_STATEID
NFS 메시지로 인한 과도한 네트워크 트래픽 때문에 급격히 느려질 수 있습니다.
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
마운트된 각 NFS 파일 시스템에 대해 설정된 정보와 옵션은 nfsstat -m
및 cat /etc/fstab
을 실행하여 확인할 수 있습니다.
사용해야 할 여러 옵션이 있습니다:
설정 | 설명 |
---|---|
vers=4.1 |
NFS v4.1을 v4.0 대신 사용해야 합니다. v4.0에는 NFS 클라이언트 버그가 있어 신선하지 않은 데이터로 인해 심각한 문제가 발생할 수 있습니다. |
nofail |
이 마운트가 사용할 수 있을 때까지 부팅 프로세스를 중단하지 않습니다. |
lookupcache=positive |
NFS 클라이언트에게 positive 캐시 결과를 존중하라고 지시하지만 모든 negative 캐시 결과를 무효화합니다. 부정적인 캐시 결과는 Git과 관련된 문제를 일으킵니다. 특히 git push 가 모든 NFS 클라이언트에서 고르게 등록되지 않을 수 있습니다. 부정 캐시는 클라이언트가 파일이 이전에 존재하지 않았음을 ‘기억’하게 합니다. |
hard |
soft 대신. 자세한 내용입니다. |
cto |
cto 는 기본 옵션으로 사용해야 합니다. nocto 를 사용하지 마세요. 자세한 내용입니다. |
_netdev |
네트워크가 온라인 상태일 때까지 파일 시스템 마운트를 기다립니다. high_availability['mountpoint'] 옵션도 참고하세요. |
soft
마운트 옵션
특별한 이유가 없는 한 마운트 옵션으로 hard
를 사용하는 것이 좋습니다.
GitLab.com이 NFS를 사용할 때 soft
를 사용했던 이유는 NFS 서버가 재부팅되는 경우가 있었고
soft
가 가용성을 개선했기 때문입니다. 하지만 모든 인프라는 다릅니다.
예를 들어, NFS가 중복 컨트롤러가 있는 온프레미스 스토리지 어레이에 의해 제공된다면, NFS 서버 가용성에 대해 걱정할 필요가 없을 것입니다.
NFS 매뉴얼 페이지에서는 다음과 같이 명시하고 있습니다:
“soft” 타임아웃은 특정 경우에 데이터 손상이 발생할 수 있습니다.
차이를 이해하기 위해 Linux 매뉴얼 페이지를 읽고,
soft
를 사용하는 경우 위험을 완화하기 위한 조치를 취했는지 확인하세요.
NFS 서버에서 디스크에 대한 쓰기가 발생하지 않아
커밋이 없어지는 것과 같은 행동을 경험한다면,
hard
옵션을 사용하세요. 매뉴얼 페이지에서 다음과 같이 언급합니다:
클라이언트 응답성이 데이터 무결성보다 더 중요한 경우에만 soft 옵션을 사용하십시오.
다른 공급업체들도 유사한 권장 사항을 제공하며,
읽기-쓰기 디렉토리에 대한 추천 마운트 옵션 및 NetApp의
지식 기반에서 강조하는 내용은,
NFS 클라이언트 드라이버가 데이터를 캐시하는 경우, soft
는 GitLab의 쓰기가 실제로 디스크에 있는지에 대한 확실성이 없음을 의미합니다.
hard
옵션으로 설정된 마운트 포인트는 성능이 떨어질 수 있으며,
NFS 서버가 다운될 경우, hard
는 마운트 포인트와 상호작용 시 프로세스가 멈추게 합니다.
멈춘 프로세스를 처리하기 위해 SIGKILL
(kill -9
)를 사용하세요.
intr
옵션은 2.6 커널에서 작동하지 않게 되었습니다.
nocto
마운트 옵션
nocto
를 사용하지 마세요. 대신 기본값인 cto
를 사용하세요.
nocto
를 사용할 경우, dentry 캐시는 항상 acdirmax
초(속성 캐시 시간) 동안 생성된 시점부터 사용됩니다.
이로 인해 여러 클라이언트 간에 오래된 dentry 캐시 문제가 발생하여, 각 클라이언트는 다른(캐시된) 버전의 디렉토리를 볼 수 있습니다.
Linux 매뉴얼 페이지에서 중요한 부분은 다음과 같습니다:
nocto
옵션이 지정된 경우, 클라이언트는 서버의 파일이 변경되었는지를 판단하기 위해 비표준 휴리스틱을 사용합니다.
nocto
옵션을 사용하면 읽기 전용 마운트에서 성능이 개선될 수 있지만, 서버의 데이터가 가끔만 변경되는 경우에만 사용해야 합니다.
우리는 푸시 후 참조가 발견되지 않는 문제에 대한 게시물에서 이러한 행동을 경험했으며, 새로 추가된 느슨한 참조가 로컬 dentry 캐시가 있는 다른 클라이언트에서 누락된 것으로 간주될 수 있습니다, 이 문제에서 설명하는 바와 같이.
단일 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을 재시작해야 합니다.
바인드 마운트
리눅스 패키지에서 구성을 변경하는 대신, 바인드 마운트를 사용하여 데이터를 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 마운트
기본 리눅스 패키지 구성을 사용할 때, 모든 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를 사용하는 것을 고려하세요. 리눅스 패키지는 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 서버의 export 옵션을 조사해야 합니다.
방화벽 환경에서의 NFS
NFS 서버와 NFS 클라이언트 간의 트래픽이 방화벽에 의해 포트 필터링의 영향을 받는 경우, NFS 통신을 허용하도록 방화벽을 재구성해야 합니다.
The Linux Documentation Project (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 사용을 강력히 권장하지 않습니다.
이러한 분산 파일 시스템은 Git이 많은 작은 파일을 사용하고 있어 입출력 접근 패턴에 잘 맞지 않기 때문에 성능이 저하됩니다.
NFS와 함께 PostgreSQL 사용 자제
GitLab은 PostgreSQL 데이터베이스를 NFS를 통해 운영하는 것을 강력히 권장하지 않습니다.
GitLab 지원 팀은 이 구성과 관련된 성능 문제에 대해 도와드릴 수 없습니다.
추가적으로, 이 구성은 PostgreSQL 문서에서 특별히 경고하고 있습니다:
PostgreSQL은 NFS 파일 시스템에 대해 특별한 처리를 하지 않으며, 이는 NFS가 로컬 연결 드라이브처럼 정확하게 작동한다고 가정합니다. 클라이언트 또는 서버 NFS 구현이 표준 파일 시스템 의미를 제공하지 않는 경우, 이는 신뢰성 문제를 일으킬 수 있습니다. 특별히, NFS 서버에 대한 지연(비동기) 쓰기는 데이터 손상 문제를 유발할 수 있습니다.
지원되는 데이터베이스 아키텍처에 대해서는 우리의 복제 및 장애 조치를 위한 데이터베이스 구성에 대한 문서를 참조하십시오.
문제 해결
NFS에 대한 요청 찾기
NFS 관련 문제의 경우, perf
를 사용하여 시스템 요청을 추적하는 것이 도움이 될 수 있습니다:
sudo perf trace -e 'nfs4:*' -p $(pgrep -fd ',' puma)
Ubuntu 16.04에서는 다음을 사용하십시오:
sudo perf trace --no-syscalls --event 'nfs4:*' -p $(pgrep -fd ',' puma)