- 리포지터리 무결성
- 리포지터리 refs의 체크섬
- 업로드된 파일 무결성
- LDAP 확인
- 현재 비밀을 사용하여 데이터베이스 값이 해독될 수 있는지 확인
- 복구할 수 없는 암호화된 토큰을 재설정
- 문제 해결
무결성 확인 Rake 작업
GitLab은 다양한 컴포넌트의 무결성을 확인하기 위한 Rake 작업을 제공합니다. 또한 GitLab 구성 무결성 Rake 작업을 확인하세요.
리포지터리 무결성
Git은 매우 탄탄하고 데이터 무결성 문제를 방지하려고 노력하나 때로는 문제가 발생합니다. 다음 Rake 작업은 문제가 있는 리포지터리를 진단하여 수정하는 데 도움을 줍니다.
이러한 Rake 작업은 Git 리포지터리의 무결성을 확인하기 위해 세 가지 다른 방법을 사용합니다.
- Git 리포지터리 파일 시스템 확인 (
git fsck
). 이 단계는 리포지터리의 객체의 연결성과 유효성을 확인합니다. - 리포지터리 디렉터리에서
config.lock
을 확인합니다. -
refs/heads
에서 브랜치/참조 잠금 파일을 확인합니다.
config.lock
또는 참조 잠금 파일의 존재만으로는 문제를 나타내지 않습니다. 잠금 파일은 Git 및 GitLab이 리포지터리에서 연산을 수행하는 동안 정기적으로 생성 및 제거됩니다. 이들은 데이터 무결성 문제를 방지하는 데 사용됩니다. 그러나 Git 연산이 중단된 경우 이러한 잠금들은 제대로 정리되지 않을 수 있습니다.
다음 증상이 리포지터리 무결성에 문제가 있다는 것을 나타낼 수 있습니다. 사용자가 이러한 증상을 경험하는 경우 아래 설명된 Rake 작업을 사용하여 어떤 리포지터리가 문제를 일으키는지 정확히 확인할 수 있습니다.
- 코드를 푸시하려고 할 때 오류가 발생함 -
remote: error: cannot lock ref
- GitLab 대시보드를 보거나 특정 프로젝트에 액세스할 때 500 오류가 발생함.
프로젝트 코드 리포지터리 확인
이 작업은 프로젝트 코드 리포지터리를 순환하며 이전에 설명한 무결성 확인을 실행합니다. 프로젝트가 풀 리포지터리를 사용하는 경우 해당 리포지터리도 확인됩니다. 다른 유형의 Git 리포지터리는 확인되지 않습니다.
-
Linux 패키지 설치:
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 서버의 모든 리포지터리를 순환하며 <프로젝트 ID>,<체크섬>
형식으로 체크섬을 출력합니다.
- 리포지터리가 존재하지 않는 경우 프로젝트 ID는 공백 체크섬입니다.
- 리포지터리가 존재하지만 비어있는 경우 출력 체크섬은
0000000000000000000000000000000000000000
입니다. -
존재하지 않는 프로젝트는 건너뜁니다.
-
Linux 패키지 설치:
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 리포지터리 확인
환경 변수 CHECKSUM_PROJECT_IDS
를 설정하여 특정 프로젝트 ID를 체크섬할 수 있습니다. 이 변수에는 쉼표로 구분된 정수 디렉터리을 설정합니다. 예를 들어:
sudo CHECKSUM_PROJECT_IDS="1,3" gitlab-rake gitlab:git:checksum_projects
업로드된 파일 무결성
다양한 유형의 파일을 사용자가 GitLab 설치에 업로드할 수 있습니다. 이러한 무결성 확인은 누락된 파일을 감지할 수 있습니다. 또한 로컬로 저장된 파일의 경우 업로드시 체크섬이 생성되어 데이터베이스에 저장되며 이러한 확인은 현재 파일과 비교합니다.
다음 유형의 파일에 대해 무결성 확인이 지원됩니다.
- CI artifacts (GitLab 10.7.0에서 추가됨)
- LFS objects (GitLab 10.6.0에서 추가됨)
- 프로젝트 수준 보안 파일 (GitLab 16.1.0에서 추가됨)
-
사용자 업로드 (GitLab 10.6.0에서 추가됨)
-
Linux 패키지 설치:
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: Failures: 0
- 1351..2743: Failures: 0
- 2745..4349: Failures: 2
- 4357..5762: Failures: 1
- 5764..7140: Failures: 2
- 7142..8651: Failures: 0
- 8653..10134: Failures: 0
- 10135..11773: Failures: 0
완료!
세부 출력 예시:
$ sudo gitlab-rake gitlab:uploads:check VERBOSE=1
업로드의 무결성 확인 중
- 1..1350: Failures: 0
- 1351..2743: Failures: 0
- 2745..4349: Failures: 2
- 업로드: 3573: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /opt/gitlab/embedded/service/gitlab-rails/public/uploads/user-foo/project-bar/7a77cc52947bfe188adeff42f890bb77/image.png>
- 업로드: 3580: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /opt/gitlab/embedded/service/gitlab-rails/public/uploads/user-foo/project-bar/2840ba1ba3b2ecfa3478a7b161375f8a/pug.png>
- 4357..5762: Failures: 1
- 업로드: 4636: #<Google::Apis::ServerError: Server error>
- 5764..7140: Failures: 2
- 업로드: 5812: #<NoMethodError: undefined method `hashed_storage?' for nil:NilClass>
- 업로드: 5837: #<NoMethodError: undefined method `hashed_storage?' for nil:NilClass>
- 7142..8651: Failures: 0
- 8653..10134: Failures: 0
- 10135..11773: Failures: 0
완료!
LDAP 확인
LDAP 확인 Rake 작업은 구성된 경우 바인드 DN 및 암호 자격 증명을 테스트하고 LDAP 사용자의 샘플을 나열합니다. 이 작업은 gitlab:check
작업의 일환으로 실행되지만 독립적으로 실행할 수도 있습니다. 자세한 내용은 LDAP Rake Tasks - LDAP Check를 참조하세요.
현재 비밀을 사용하여 데이터베이스 값이 해독될 수 있는지 확인
- GitLab 13.1에서 도입되었습니다.
이 작업은 데이터베이스의 모든 가능한 암호화된 값에 대해 현재 비밀 파일(gitlab-secrets.json
)을 사용하여 해독할 수 있는지 확인합니다.
자동 해결 방법은 아직 구현되지 않았습니다. 해독할 수 없는 값이 있는 경우 비밀 파일이 손실된 경우 문서를 참조하여 재설정하는 방법에 대해 알아볼 수 있습니다.
이 작업은 데이터베이스의 모든 테이블의 모든 행을 확인하기 때문에 데이터베이스의 크기에 따라 매우 긴 시간이 걸릴 수 있습니다.
-
Linux 패키지 설치:
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
환경 변수를 전달할 수 있습니다.
-
Linux 패키지 설치:
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 -- : > Group[10].runners_token의 오류: Validation failed: Route can't be blank
I, [2020-06-11T17:19:53.225178 #27351] INFO -- : - 그룹 오류: 1
D, [2020-06-11T17:19:53.225267 #27351] DEBUG -- : - Group[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에서 도입되었습니다.
일부 경우에는 암호화된 토큰을 더 이상 복구할 수 없어 문제를 일으킬 수 있습니다. 대부분의 경우에는 매우 큰 인스턴스에서 그룹 및 프로젝트의 러너 등록 토큰이 손상될 수 있습니다.
손상된 토큰을 재설정하려면:
- 손상된 암호화된 토큰이 있는 데이터베이스 모델을 식별합니다. 예를 들어
그룹
및프로젝트
일 수 있습니다. - 손상된 토큰을 식별합니다. 예를 들어
runners_token
일 수 있습니다. -
손상된 토큰을 재설정하려면
VERBOSE=true
및MODEL_NAMES=Model1,Model2 TOKEN_NAMES=broken_token1,broken_token2
와 함께gitlab:doctor:reset_encrypted_tokens
를 실행합니다. 예를 들어:VERBOSE=true MODEL_NAMES=프로젝트,그룹 TOKEN_NAMES=runners_token bundle exec rake gitlab:doctor:reset_encrypted_tokens
이 작업이 시도하려는 모든 동작을 볼 수 있습니다:
I, [2023-09-26T16:20:23.230942 #88920] INFO -- : Projuct, Group에서 runners_token을 재설정 중 I, [2023-09-26T16:20:23.230975 #88920] INFO -- : 드라이런 모드에서 실행 중입니다. 실제로 레코드가 업데이트되지는 않습니다. D, [2023-09-26T16:20:30.151585 #88920] DEBUG -- : > Projuct[1].runners_token 수정 I, [2023-09-26T16:20:30.151617 #88920] INFO -- : 1/9 프로젝트 확인됨 D, [2023-09-26T16:20:30.151873 #88920] DEBUG -- : > Projuct[3].runners_token 수정 D, [2023-09-26T16:20:30.152975 #88920] DEBUG -- : > Projuct[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/29 프로젝트 확인됨 D, [2023-09-26T16:20:30.195929 #88920] DEBUG -- : > Group[22].runners_token 수정 I, [2023-09-26T16:20:30.196125 #88920] INFO -- : 1/19 그룹 확인됨 D, [2023-09-26T16:20:30.196192 #88920] DEBUG -- : > Group[25].runners_token 수정 D, [2023-09-26T16:20:30.197557 #88920] DEBUG -- : > 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/19 그룹 확인됨 I, [2023-09-26T16:20:30.198462 #88920] INFO -- : 완료!
-
이 작업이 올바른 토큰을 재설정하는지 확신한다면 드라이런 모드를 비활성화하고 작업을 다시 실행합니다:
DRY_RUN=false VERBOSE=true MODEL_NAMES=프로젝트,그룹 TOKEN_NAMES=runners_token bundle exec rake gitlab:doctor:reset_encrypted_tokens
문제 해결
다음은 위에 문서화된 Rake 작업을 사용하면 발견할 수 있는 문제에 대한 해결책입니다.
매달린 객체
gitlab-rake gitlab:git:fsck
작업을 사용하면 다음과 같은 매달린 객체를 찾을 수 있습니다.
매달린 blob a12...
매달린 commit b34...
매달린 tag c56...
매달린 tree d78...
이를 삭제하려면 housekeeping을 실행해보세요.
문제가 지속되면 Rails 콘솔을 통해 가비지 수집을 시도하세요.
p = Project.find_by_path("프로젝트명")
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
- Upload: 100: 원격 객체가 존재하지 않음
- Upload: 101: 원격 객체가 존재하지 않음
완료!
외부에서 삭제된 원격 업로드에 대한 참조를 삭제하려면 GitLab Rails 콘솔을 열고 다음을 실행하세요.
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
는 GitLab 외부에서 삭제되거나 데이터베이스에 여전히 참조가 있는 아티팩트를 감지합니다.
이러한 시나리오가 감지되면 Rake 작업이 오류 메시지를 표시합니다. 예를 들어:
작업 아티팩트 무결성 확인
- 1..15: 실패: 2
- 작업 아티팩트: 9: #<Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/shared/artifacts/4b/22/4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a/2022_06_30/8/9/job.log>
- 작업 아티팩트: 15: 원격 객체가 존재하지 않음
완료!
이러한 누락된 로컬 및/또는 원격 아티팩트(job.log
파일)에 대한 참조를 삭제하려면 다음을 실행하세요:
- GitLab Rails 콘솔을 엽니다.
-
다음 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 -- : Failed to transfer Ci::JobArtifact ID 11 with error: undefined method `body' for nil:NilClass
W, [2022-11-28T13:14:09.296911 #10025] WARN -- : Failed to transfer Ci::JobArtifact ID 12 with error: undefined method `body' for nil:NilClass
객체 리포지터리 사용을 중지한 후 누락된 아티패트에 대한 참조 삭제를 시도하면 다음과 같은 오류가 발생합니다.
RuntimeError (Object Storage is not enabled for JobArtifactUploader)
이러한 참조를 로컬 스토리지를 가리키도록 업데이트하려면 다음을 실행하세요:
-
GitLab Rails 콘솔을 열고 다음 Ruby 코드를 실행하세요.
artifacts_updated = 0 ::Ci::JobArtifact.find_each do |artifact| ### 아티패트 반복 next if artifact.file_store != 2 ### 파일 리포지터리가 이미 로컬 스토리지를 가리키는 경우 건너뜁니다 artifacts_updated += 1 # artifact.update(file_store: 1) ### 실제로 업데이트하려면 주석 해제 end puts "업데이트된 파일 리포지터리 수: #{artifacts_updated}"
누락된 아티패트에 대한 참조 삭제 스크립트가 이제 올바르게 작동하여 데이터베이스를 정리합니다.
누락된 보안 파일에 대한 참조 삭제
VERBOSE=1 gitlab-rake gitlab:ci_secure_files:check
는 GitLab 외부에서 삭제되거나 데이터베이스에 여전히 참조가 있는 보안 파일을 감지합니다.