- 저장소 무결성
- 저장소 refs의 체크섬
- 업로드된 파일의 무결성
- LDAP 체크
- 현재 비밀을 사용하여 데이터베이스 값이 복호화될 수 있는지 확인
- 암호화된 토큰 복구 불가 시 초기화
- 문제 해결
무결성 검사 Rake 작업
GitLab은 다양한 구성 요소의 무결성을 검사하기 위해 Rake 작업을 제공합니다.
또한, GitLab 구성 Rake 작업 확인을 참조하십시오.
저장소 무결성
Git은 매우 복원력이 뛰어나고 데이터 무결성 문제를 방지하기 위해 노력하지만,
종종 문제가 발생할 수 있습니다. 다음 Rake 작업은 GitLab 관리자가 문제 있는 저장소를 진단할 수 있도록 돕기 위한 것입니다.
이 Rake 작업은 Git 저장소의 무결성을 확인하기 위해 세 가지 다른 방법을 사용합니다.
- Git 저장소 파일 시스템 검사 (
git fsck
).
이 단계는 저장소의 객체 연결성 및 유효성을 확인합니다. - 저장소 디렉터리에서
config.lock
여부를 확인합니다. -
refs/heads
에서 브랜치/참조 잠금 파일이 있는지 확인합니다.
config.lock
또는 참조 잠금이 존재한다고 해서 반드시 문제가 나타나는 것은 아닙니다.
잠금 파일은 Git과 GitLab이 저장소에서 작업을 수행할 때 정상적으로 생성되고 제거됩니다.
이 파일들은 데이터 무결성 문제를 방지하기 위한 것입니다. 그러나 Git 작업이 중단되는 경우 이러한 잠금이 제대로 정리되지 않을 수 있습니다.
다음 증상은 저장소 무결성에 문제가 있음을 나타낼 수 있습니다. 사용자가 이러한 증상을 경험하면
아래 설명된 Rake 작업을 사용하여 어떤 저장소가 문제를 일으키고 있는지 확인할 수 있습니다.
- 코드를 푸시하려고 할 때 발생하는 오류 -
remote: error: cannot lock ref
- GitLab 대시보드를 보거나 특정 프로젝트에 접근할 때 발생하는 500 오류.
프로젝트 코드 저장소 확인
이 작업은 프로젝트 코드 저장소를 순회하며 이전에 설명한 무결성 검사를 실행합니다.
프로젝트가 풀 저장소를 사용하는 경우 해당 저장소도 확인됩니다.
다른 유형의 Git 저장소는 확인되지 않습니다.
-
리눅스 패키지 설치:
sudo gitlab-rake gitlab:git:fsck
-
자체 컴파일 설치:
sudo -u git -H bundle exec rake gitlab:git:fsck RAILS_ENV=production
저장소 refs의 체크섬
하나의 Git 저장소는 각 저장소의 모든 refs를 체크섬으로 비교하여 다른 저장소와 비교할 수 있습니다.
두 저장소에 동일한 refs가 있으며, 두 저장소 모두 무결성 검사를 통과하면 두 저장소가 동일하다는 것을 확신할 수 있습니다.
예를 들어, 이는 저장소의 백업과 소스 저장소를 비교하는 데 사용될 수 있습니다.
모든 GitLab 저장소 확인
이 작업은 GitLab 서버의 모든 저장소를 순회하며 <PROJECT ID>,<CHECKSUM>
형식으로 체크섬을 출력합니다.
- 저장소가 존재하지 않으면 프로젝트 ID는 빈 체크섬입니다.
- 저장소가 존재하지만 비어 있는 경우 출력 체크섬은
0000000000000000000000000000000000000000
입니다. -
존재하지 않는 프로젝트는 건너뜁니다.
-
리눅스 패키지 설치:
sudo gitlab-rake gitlab:git:checksum_projects
-
자체 컴파일 설치:
sudo -u git -H bundle exec rake gitlab:git:checksum_projects RAILS_ENV=production
예를 들어,
- ID#2인 프로젝트가 존재하지 않으면 건너뜁니다.
- ID#4인 프로젝트가 저장소가 없으면 체크섬은 비어 있습니다.
- ID#5인 프로젝트가 비어 있는 저장소를 가지고 있으면 체크섬은
0000000000000000000000000000000000000000
입니다.
출력은 다음과 같이 나타날 수 있습니다:
1,cfa3f06ba235c13df0bb28e079bcea62c5848af2
3,3f3fb58a8106230e3a6c6b48adc2712fb3b6ef87
4,
5,0000000000000000000000000000000000000000
6,6c6b48adc2712fb3b6ef87cfa3f06ba235c13df0
특정 GitLab 리포지토리 확인
선택적으로, 특정 프로젝트 ID는 환경 변수를 설정하여 체크섬을 처리할 수 있습니다.
환경 변수 CHECKSUM_PROJECT_IDS
에 쉼표로 구분된 정수 목록을 설정합니다. 예를 들어:
sudo CHECKSUM_PROJECT_IDS="1,3" gitlab-rake gitlab:git:checksum_projects
업로드된 파일의 무결성
사용자가 GitLab 설치에 업로드할 수 있는 다양한 유형의 파일이 있습니다.
이러한 무결성 검사는 누락된 파일을 감지할 수 있습니다.
또한, 로컬에 저장된 파일의 경우 업로드 시 체크섬이 생성되고 데이터베이스에 저장되며, 현재 파일과 비교하여 검증합니다.
무결성 검사는 다음 유형의 파일에 대해 지원됩니다:
- CI 아티팩트
- LFS 오브젝트
- 프로젝트 수준의 보안 파일 (GitLab 16.1.0에서 도입)
-
사용자 업로드
-
리눅스 패키지 설치:
sudo gitlab-rake gitlab:artifacts:check sudo gitlab-rake gitlab:ci_secure_files:check sudo gitlab-rake gitlab:lfs:check sudo gitlab-rake gitlab:uploads:check
-
자체 컴파일 설치:
sudo -u git -H bundle exec rake gitlab:artifacts:check RAILS_ENV=production sudo -u git -H bundle exec rake gitlab:ci_secure_files:check RAILS_ENV=production sudo -u git -H bundle exec rake gitlab:lfs:check RAILS_ENV=production sudo -u git -H bundle exec rake gitlab:uploads:check RAILS_ENV=production
이러한 작업은 특정 값을 무시하기 위해 사용할 수 있는 몇 가지 환경 변수를 수용합니다:
변수 | 유형 | 설명 |
---|---|---|
BATCH |
정수 | 배치의 크기를 지정합니다. 기본값은 200입니다. |
ID_FROM |
정수 | 시작할 ID를 지정합니다. 해당 값을 포함합니다. |
ID_TO |
정수 | 끝낼 ID 값을 지정합니다. 해당 값을 포함합니다. |
VERBOSE |
불리언 | 실패를 요약하지 않고 개별적으로 나열합니다. |
sudo gitlab-rake gitlab:artifacts:check BATCH=100 ID_FROM=50 ID_TO=250
sudo gitlab-rake gitlab:ci_secure_files:check BATCH=100 ID_FROM=50 ID_TO=250
sudo gitlab-rake gitlab:lfs:check BATCH=100 ID_FROM=50 ID_TO=250
sudo gitlab-rake gitlab:uploads:check BATCH=100 ID_FROM=50 ID_TO=250
예시 출력:
$ sudo gitlab-rake gitlab:uploads:check
업로드 무결성 확인 중
- 1..1350: 실패: 0
- 1351..2743: 실패: 0
- 2745..4349: 실패: 2
- 4357..5762: 실패: 1
- 5764..7140: 실패: 2
- 7142..8651: 실패: 0
- 8653..10134: 실패: 0
- 10135..11773: 실패: 0
- 11777..13315: 실패: 0
완료!
예시 상세 출력:
$ sudo gitlab-rake gitlab:uploads:check VERBOSE=1
업로드 무결성 확인 중
- 1..1350: 실패: 0
- 1351..2743: 실패: 0
- 2745..4349: 실패: 2
- 업로드: 3573: #<Errno::ENOENT: 파일이나 디렉터리가 존재하지 않음 @ rb_sysopen - /opt/gitlab/embedded/service/gitlab-rails/public/uploads/user-foo/project-bar/7a77cc52947bfe188adeff42f890bb77/image.png>
- 업로드: 3580: #<Errno::ENOENT: 파일이나 디렉터리가 존재하지 않음 @ rb_sysopen - /opt/gitlab/embedded/service/gitlab-rails/public/uploads/user-foo/project-bar/2840ba1ba3b2ecfa3478a7b161375f8a/pug.png>
- 4357..5762: 실패: 1
- 업로드: 4636: #<Google::Apis::ServerError: 서버 오류>
- 5764..7140: 실패: 2
- 업로드: 5812: #<NoMethodError: nil에 대해 정의되지 않은 메서드 `hashed_storage?`>
- 업로드: 5837: #<NoMethodError: nil에 대해 정의되지 않은 메서드 `hashed_storage?`>
- 7142..8651: 실패: 0
- 8653..10134: 실패: 0
- 10135..11773: 실패: 0
- 11777..13315: 실패: 0
완료!
LDAP 체크
LDAP 체크 Rake 태스크는 바인드 DN 및 비밀번호 자격 증명(구성된 경우)을 테스트하고 LDAP 사용자 샘플을 나열합니다. 이 태스크는 gitlab:check
태스크의 일부로도 실행되지만 독립적으로 실행할 수 있습니다. 자세한 내용은 LDAP Rake Tasks - LDAP 체크를 참조하세요.
현재 비밀을 사용하여 데이터베이스 값이 복호화될 수 있는지 확인
이 태스크는 데이터베이스의 모든 가능한 암호화 값에 대해 실행되며, 현재 비밀 파일(gitlab-secrets.json
)을 사용하여 복호화할 수 있는지 확인합니다.
자동 해결은 아직 구현되지 않았습니다. 복호화할 수 없는 값이 있는 경우, 값을 재설정하는 방법에 대한 단계를 따를 수 있습니다. 비밀 파일이 분실되었을 때 해야 할 일에 대한 문서를 참조하세요 when the secrets file is lost.
데이터베이스의 크기에 따라 모든 테이블의 모든 행을 확인하므로 시간이 많이 걸릴 수 있습니다.
-
리눅스 패키지 설치:
sudo gitlab-rake gitlab:doctor:secrets
-
직접 컴파일한 설치:
bundle exec rake gitlab:doctor:secrets RAILS_ENV=production
예제 출력
I, [2020-06-11T17:17:54.951815 #27148] INFO -- : 데이터베이스의 암호화 값 확인 중
I, [2020-06-11T17:18:12.677708 #27148] INFO -- : - ApplicationSetting 실패: 0
I, [2020-06-11T17:18:12.823692 #27148] INFO -- : - 사용자 실패: 0
[...] 암호화된 데이터를 포함할 수 있는 기타 모델
I, [2020-06-11T17:18:14.938335 #27148] INFO -- : - 그룹 실패: 1
I, [2020-06-11T17:18:15.559162 #27148] INFO -- : - Operations::FeatureFlagsClient 실패: 0
I, [2020-06-11T17:18:15.575533 #27148] INFO -- : - ScimOauthAccessToken 실패: 0
I, [2020-06-11T17:18:15.575678 #27148] INFO -- : 총: 1 행(들)에 영향을 미쳤습니다
I, [2020-06-11T17:18:15.575711 #27148] INFO -- : 완료!
상세 모드
어떤 행과 열이 복호화되지 못했는지에 대한 더 자세한 정보를 얻으려면 VERBOSE
환경 변수를 전달할 수 있습니다:
-
리눅스 패키지 설치:
sudo gitlab-rake gitlab:doctor:secrets VERBOSE=1
-
직접 컴파일한 설치:
bundle exec rake gitlab:doctor:secrets RAILS_ENV=production VERBOSE=1
예제 상세 출력
I, [2020-06-11T17:17:54.951815 #27148] INFO -- : 데이터베이스의 암호화 값 확인 중
I, [2020-06-11T17:18:12.677708 #27148] INFO -- : - ApplicationSetting 실패: 0
I, [2020-06-11T17:18:12.823692 #27148] INFO -- : - 사용자 실패: 0
[...] 암호화된 데이터를 포함할 수 있는 기타 모델
D, [2020-06-11T17:19:53.224344 #27351] DEBUG -- : > 그룹[10].runners_token에 대해 문제가 발생했습니다: 유효성 검사 실패: 경로가 비어 있을 수 없습니다
I, [2020-06-11T17:19:53.225178 #27351] INFO -- : - 그룹 실패: 1
D, [2020-06-11T17:19:53.225267 #27351] DEBUG -- : - 그룹[10]: runners_token
I, [2020-06-11T17:18:15.559162 #27148] INFO -- : - Operations::FeatureFlagsClient 실패: 0
I, [2020-06-11T17:18:15.575533 #27148] INFO -- : - ScimOauthAccessToken 실패: 0
I, [2020-06-11T17:18:15.575678 #27148] INFO -- : 총: 1 행(들)에 영향을 미쳤습니다
I, [2020-06-11T17:18:15.575711 #27148] INFO -- : 완료!
암호화된 토큰 복구 불가 시 초기화
- GitLab 16.6에서 도입됨.
경고: 이 작업은 위험하며 데이터 손실로 이어질 수 있습니다. 극도로 주의하여 진행하십시오.
이 작업을 수행하기 전에 GitLab 내부에 대한 지식을 갖추어야 합니다.
일부 경우, 암호화된 토큰을 더 이상 복구할 수 없으며 문제가 발생할 수 있습니다.
대부분의 경우, 매우 큰 인스턴스에서 그룹 및 프로젝트에 대한 러너 등록 토큰이 손상될 수 있습니다.
손상된 토큰을 초기화하려면:
-
손상된 암호화된 토큰이 있는 데이터베이스 모델을 식별합니다. 예를 들어,
Group
및Project
가 될 수 있습니다. -
손상된 토큰을 식별합니다. 예를 들어,
runners_token
입니다. -
손상된 토큰을 초기화하려면
gitlab:doctor:reset_encrypted_tokens
를VERBOSE=true MODEL_NAMES=Model1,Model2 TOKEN_NAMES=broken_token1,broken_token2
와 함께 실행합니다. 예를 들어:VERBOSE=true MODEL_NAMES=Project,Group TOKEN_NAMES=runners_token bundle exec rake gitlab:doctor:reset_encrypted_tokens
이 작업이 수행하려고 하는 모든 작업을 볼 수 있습니다:
I, [2023-09-26T16:20:23.230942 #88920] INFO -- : Project, Group에서 읽을 수 없는 경우 runners_token 초기화 I, [2023-09-26T16:20:23.230975 #88920] INFO -- : DRY RUN 모드로 실행 중, 실제로 레코드는 업데이트되지 않음 D, [2023-09-26T16:20:30.151585 #88920] DEBUG -- : > Fix Project[1].runners_token I, [2023-09-26T16:20:30.151617 #88920] INFO -- : 1/9 프로젝트 확인 완료 D, [2023-09-26T16:20:30.151873 #88920] DEBUG -- : > Fix Project[3].runners_token D, [2023-09-26T16:20:30.152975 #88920] DEBUG -- : > Fix Project[10].runners_token I, [2023-09-26T16:20:30.152992 #88920] INFO -- : 11/29 프로젝트 확인 완료 I, [2023-09-26T16:20:30.153230 #88920] INFO -- : 21/29 프로젝트 확인 완료 I, [2023-09-26T16:20:30.153882 #88920] INFO -- : 29 프로젝트 확인 완료 D, [2023-09-26T16:20:30.195929 #88920] DEBUG -- : > Fix Group[22].runners_token I, [2023-09-26T16:20:30.196125 #88920] INFO -- : 1/19 그룹 확인 완료 D, [2023-09-26T16:20:30.196192 #88920] DEBUG -- : > Fix Group[25].runners_token D, [2023-09-26T16:20:30.197557 #88920] DEBUG -- : > Fix Group[82].runners_token I, [2023-09-26T16:20:30.197581 #88920] INFO -- : 11/19 그룹 확인 완료 I, [2023-09-26T16:20:30.198455 #88920] INFO -- : 19 그룹 확인 완료 I, [2023-09-26T16:20:30.198462 #88920] INFO -- : 완료!
-
이 작업이 올바른 토큰을 초기화한다고 확신하는 경우, 드라이 실행 모드를 비활성화하고 작업을 다시 실행합니다:
DRY_RUN=false VERBOSE=true MODEL_NAMES=Project,Group TOKEN_NAMES=runners_token bundle exec rake gitlab:doctor:reset_encrypted_tokens
문제 해결
다음은 위에 문서화된 Rake 작업을 사용하여 발견할 수 있는 문제에 대한 해결책입니다.
유장 객체
gitlab-rake gitlab:git:fsck
작업은 다음과 같은 유장 객체를 찾을 수 있습니다:
dangling blob a12...
dangling commit b34...
dangling tag c56...
dangling tree d78...
이들을 삭제하려면 하우스키핑 실행해 보세요.
문제가 지속되면 Rails Console를 통해 가비지 수집을 트리거해 보세요:
p = Project.find_by_path("project-name")
Repositories::HousekeepingService.new(p, :gc).execute
유장 객체가 2주 기본 유예 기간보다 젊고 자동으로 만료될 때까지 기다리지 않으려면 다음을 실행하세요:
Repositories::HousekeepingService.new(p, :prune).execute
누락된 원격 업로드에 대한 참조 삭제
gitlab-rake gitlab:uploads:check VERBOSE=1
는 외부에서 삭제되어 실제로 존재하지 않는 원격 객체를 감지하지만 해당 참조가 여전히 GitLab 데이터베이스에 존재하는 경우를 확인합니다.
오류 메시지가 포함된 예제 출력:
$ sudo gitlab-rake gitlab:uploads:check VERBOSE=1
Uploads의 무결성 확인
- 100..434: 실패: 2
- 업로드: 100: 원격 객체가 존재하지 않음
- 업로드: 101: 원격 객체가 존재하지 않음
완료!
외부에서 삭제된 원격 업로드에 대한 이 참조를 삭제하려면 GitLab Rails Console을 열고 다음을 실행하세요:
uploads_deleted=0
Upload.find_each do |upload|
next if upload.retrieve_uploader.file.exists?
uploads_deleted=uploads_deleted + 1
p upload ### 삭제 전 확인 허용
# p upload.destroy! ### 실제로 삭제하려면 주석 해제
end
p "#{uploads_deleted} 개의 원격 객체가 삭제되었습니다."
누락된 아티팩트에 대한 참조 삭제
gitlab-rake gitlab:artifacts:check VERBOSE=1
는 아티팩트(또는 job.log
파일)가 다음과 같은 경우를 감지합니다:
- GitLab 외부에서 삭제되었습니다.
- GitLab 데이터베이스에 여전히 참조가 있습니다.
이 시나리오가 감지되면 Rake 작업이 오류 메시지를 표시합니다. 예를 들어:
Job 아티팩트의 무결성 확인
- 1..15: 실패: 2
- Job 아티팩트: 9: #<Errno::ENOENT: 그런 파일이나 디렉터리가 없습니다 @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/artifacts/4b/22/4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a/2022_06_30/8/9/job.log>
- Job 아티팩트: 15: 원격 객체가 존재하지 않음
완료!
이 누락된 로컬 및/또는 원격 아티팩트(job.log
파일)에 대한 참조를 삭제하려면:
- GitLab Rails Console을 엽니다.
-
다음 Ruby 코드를 실행합니다:
artifacts_deleted = 0 ::Ci::JobArtifact.find_each do |artifact| ### 아티팩트 반복 # next if artifact.file.filename != "job.log" ### 주석 해제 시 `job.log` 파일만 처리 next if artifact.file.file.exists? ### 파일 참조가 유효한 경우 건너뜀 artifacts_deleted += 1 puts "#{artifact.id} #{artifact.file.path}가 누락되었습니다." ### 삭제 전 확인 허용 # artifact.destroy! ### 실제로 삭제하려면 주석 해제 end puts "식별된/삭제된 유효하지 않은 참조 수: #{artifacts_deleted}"
손실된 LFS 객체에 대한 참조 삭제
gitlab-rake gitlab:lfs:check VERBOSE=1
가 데이터베이스에 존재하지만 디스크에 없는 LFS 객체를 감지하면, LFS 문서의 절차를 따르세요 데이터베이스 항목을 제거하기 위해.
흔들리는 객체 저장 참조 업데이트
객체 저장소에서 로컬 저장소로 마이그레이션한 경우 파일이 누락되었다면, 흔들리는 데이터베이스 참조가 남아 있게 됩니다.
이는 다음과 같은 오류로 마이그레이션 로그에서 확인할 수 있습니다:
W, [2022-11-28T13:14:09.283833 #10025] WARN -- : Ci::JobArtifact ID 11 전송 실패: nil:NilClass에 대한 정의되지 않은 메서드 `body`
W, [2022-11-28T13:14:09.296911 #10025] WARN -- : Ci::JobArtifact ID 12 전송 실패: nil:NilClass에 대한 정의되지 않은 메서드 `body`
객체 저장소를 비활성화한 후 누락된 아티팩트에 대한 참조를 삭제하려고 시도할 때, 다음과 같은 오류가 발생합니다:
RuntimeError (Object Storage는 JobArtifactUploader에 대해 활성화되어 있지 않습니다)
이러한 참조를 로컬 저장소를 가리키도록 업데이트하려면:
- GitLab Rails 콘솔을 엽니다.
-
다음 Ruby 코드를 실행합니다:
artifacts_updated = 0 ::Ci::JobArtifact.find_each do |artifact| ### 아티팩트 반복 next if artifact.file_store != 2 ### file_store가 이미 로컬 저장소를 가리키면 건너뜁니다 artifacts_updated += 1 # artifact.update(file_store: 1) ### 실제로 업데이트하려면 주석을 해제하세요 end puts "업데이트된 file_store 수: #{artifacts_updated}"
누락된 아티팩트에 대한 참조를 삭제하는 스크립트가 이제 제대로 작동하고 데이터베이스를 정리합니다.
누락된 보안 파일에 대한 참조 삭제
VERBOSE=1 gitlab-rake gitlab:ci_secure_files:check
는 보안 파일이 다음과 같은 경우를 감지합니다:
- GitLab 외부에서 삭제되었습니다.
- GitLab 데이터베이스에 여전히 참조가 있습니다.
이 시나리오가 감지되면 Rake 작업이 오류 메시지를 표시합니다. 예를 들어:
CI Secure Files의 무결성 확인
- 1..15: 실패: 2
- Job SecureFile: 9: #<Errno::ENOENT: 해당 파일이나 디렉터리가 없음 @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/ci_secure_files/4b/22/4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a/2022_06_30/8/9/distribution.cer>
- Job SecureFile: 15: 원격 개체가 존재하지 않음
완료!
로컬 또는 원격 보안 파일에 대한 이러한 참조를 삭제하려면:
- GitLab Rails 콘솔을 엽니다.
-
다음 Ruby 코드를 실행합니다:
secure_files_deleted = 0 ::Ci::SecureFile.find_each do |secure_file| ### 보안 파일 반복 next if secure_file.file.file.exists? ### 파일 참조가 유효하면 건너뜁니다 secure_files_deleted += 1 puts "#{secure_file.id} #{secure_file.file.path}이(가) 누락되었습니다." ### 삭제 전 검증 허용 # secure_file.destroy! ### 실제로 삭제하려면 주석을 해제하세요 end puts "식별된/삭제된 유효하지 않은 참조 수: #{secure_files_deleted}"