저장소 미러링 문제 해결
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
미러링이 실패하면 GitLab이 프로젝트 세부 정보 페이지에 경고를 표시합니다. 영향받는 저장소 옆에 GitLab이 Error 배지를 표시합니다. GitHub 저장소로 미러링할 때 다음 메시지가 나타나면: 다음 문제 중 하나가 발생하고 있을 수 있습니다:
미러링이 실패하면 GitLab이 프로젝트 세부 정보 페이지에 경고를 표시합니다. 예: [warning-solid] Pull mirroring failed 1 hour ago. 경고 텍스트를 선택하여 Mirroring repositories 설정으로 이동합니다.
영향받는 저장소 옆에 GitLab이 Error 배지를 표시합니다. 오류 메시지를 보려면 배지 위에 마우스를 올립니다. 오류 메시지에는 인증 실패나 분기된 브랜치와 같은 일반적인 문제에 대한 구체적인 세부 정보가 포함됩니다. 다른 오류는 Git 작업에서 직접 올 수 있습니다.
GitHub로 미러링 시 오류 코드 2와 함께 RST_STREAM 수신#
GitHub 저장소로 미러링할 때 다음 메시지가 나타나면:
13:Received RST_STREAM with error code 2
다음 문제 중 하나가 발생하고 있을 수 있습니다:
- GitHub 설정이 커밋에 사용된 이메일 주소를 노출하는 푸시를 차단하도록 설정되어 있을 수 있습니다. 이 문제를 해결하려면 다음 중 하나를 수행합니다:
- GitHub 이메일 주소를 공개로 설정합니다.
- Block command line pushes that expose my email 설정을 끕니다.
- 저장소가 GitHub 파일 크기 제한인 100 MB를 초과합니다. 이 문제를 해결하려면 GitHub에 구성된 파일 크기 제한을 확인하고 대형 파일을 관리하기 위해 Git Large File Storage (LFS) 사용을 고려합니다.
기한 초과#
GitLab을 업그레이드할 때 사용자 이름이 표현되는 방식의 변경으로 인해 %40 문자가 @로 대체되도록 미러링 사용자 이름과 비밀번호를 업데이트해야 합니다.
연결 차단됨: 서버가 공개 키 인증만 허용함#
GitLab과 원격 저장소 사이의 연결이 차단되어 있습니다. TCP 확인이 성공하더라도 GitLab에서 원격 서버까지의 경로에 있는 네트워킹 컴포넌트에서 차단 여부를 확인해야 합니다.
이 오류는 방화벽이 나가는 패킷에서 Deep SSH Inspection을 수행할 때 발생할 수 있습니다.
사용자 이름을 읽을 수 없음: 터미널 프롬프트 비활성화됨#
외부 저장소용 GitLab CI/CD를 사용하여 새 프로젝트를 생성한 후 이 오류가 발생하면:
-
Bitbucket Cloud에서:
"2:fetch remote: "fatal: could not read Username for 'https://bitbucket.org': terminal prompts disabled\n": exit status 128." -
Bitbucket Server(자체 호스팅)에서:
"2:fetch remote: "fatal: could not read Username for 'https://lab.example.com': terminal prompts disabled\n": exit status 128.
미러된 저장소의 URL에 저장소 소유자가 지정되어 있는지 확인합니다:
-
상단 표시줄에서 Search or go to를 선택하고 프로젝트를 찾습니다.
-
왼쪽 사이드바에서 Settings > Repository를 선택합니다.
-
Mirroring repositories를 펼칩니다.
-
저장소 소유자가 지정되지 않은 경우 URL을 삭제하고 다음 형식으로 다시 추가하여
OWNER,ACCOUNTNAME,PATH_TO_REPO,REPONAME을 값으로 대체합니다:-
Bitbucket Cloud에서:
https://OWNER@bitbucket.org/ACCOUNTNAME/REPONAME.git -
Bitbucket Server(자체 호스팅)에서:
https://OWNER@lab.example.com/PATH_TO_REPO/REPONAME.git
-
미러링을 위해 Cloud 또는 자체 호스팅 Bitbucket 저장소에 연결할 때 문자열에 저장소 소유자가 필요합니다.
푸시 미러: LFS objects are missing#
다음과 같은 오류가 발생할 수 있습니다:
GitLab: GitLab: LFS objects are missing. Ensure LFS is properly set up or try a manual "git lfs push --all".
이 문제는 푸시 미러링에 SSH 저장소 URL을 사용할 때 발생합니다. SSH를 통해 LFS 파일을 전송하는 푸시 미러링은 지원되지 않습니다.
해결 방법은 푸시 미러에 SSH 대신 HTTPS 저장소 URL을 사용하는 것입니다.
이 문제를 해결하기 위한 이슈 249587이 있습니다.
풀 미러에 LFS 파일이 누락됨#
경우에 따라 풀 미러링이 LFS 파일을 전송하지 않을 수 있습니다. 이 문제는 SSH 저장소 URL을 사용할 때 발생합니다.
해결 방법은 대신 HTTPS 저장소 URL을 사용하는 것입니다.
풀 미러링이 파이프라인을 트리거하지 않음#
다음과 같은 여러 이유로 파이프라인이 실행되지 않을 수 있습니다:
-
미러 업데이트를 위한 파이프라인 트리거가 활성화되지 않았을 수 있습니다. 이 설정은 풀 미러링을 구성할 때만 활성화할 수 있습니다. 나중에 프로젝트를 확인할 때 상태가 표시되지 않습니다.
외부 저장소용 CI/CD를 사용하여 미러링을 설정할 때 이 설정은 기본적으로 활성화됩니다. 저장소 미러링이 수동으로 재구성되면 파이프라인 트리거가 기본적으로 꺼져 있으며 이것이 파이프라인이 실행되지 않는 이유일 수 있습니다.
-
rules구성이 파이프라인에 job이 추가되는 것을 방지합니다. -
파이프라인은 풀 미러를 설정한 계정을 사용하여 트리거됩니다. 해당 계정이 더 이상 유효하지 않으면 파이프라인이 실행되지 않습니다.
-
브랜치 보호가 미러링을 설정한 계정이 파이프라인을 실행하는 것을 방지할 수 있습니다.
저장소가 업데이트 중입니다, 하지만 실패나 성공이 눈에 띄지 않음#
드물게 Redis의 미러링 슬롯이 소진될 수 있으며, 이는 메모리 부족(OoM) 이벤트로 인해 Sidekiq 워커가 재수집될 때 발생할 수 있습니다. 이 경우 미러링 job은 빠르게 시작하고 완료되지만 실패나 성공하지 않습니다. 또한 명확한 로그를 남기지 않습니다. 이 문제를 확인하려면:
-
Rails 콘솔을 열고 Redis의 미러링 용량을 확인합니다:
current = Gitlab::Redis::SharedState.with { |redis| redis.scard('MIRROR_PULL_CAPACITY') }.to_i maximum = Gitlab::CurrentSettings.mirror_max_capacity available = maximum - current -
미러링 용량이
0이거나 매우 낮은 경우 다음을 사용하여 모든 멈춘 job을 비울 수 있습니다:Gitlab::Redis::SharedState.with { |redis| redis.smembers('MIRROR_PULL_CAPACITY') }.each do |pid| Gitlab::Redis::SharedState.with { |redis| redis.srem('MIRROR_PULL_CAPACITY', pid) } end -
명령어를 실행한 후 백그라운드 job 페이지에 새 미러링 job이 예약되는 것이 표시되어야 합니다. 특히 수동으로 트리거할 때 그렇습니다.
유효하지 않은 URL#
SSH를 통해 미러링을 설정하는 중에 이 오류가 발생하면 URL이 유효한 형식인지 확인합니다.
미러링은 호스트와 프로젝트 경로가 :로 구분된 git@gitlab.com:gitlab-org/gitlab.git 형식의 SCP와 유사한 클론 URL을 지원하지 않습니다. ssh://git@gitlab.com/gitlab-org/gitlab.git과 같이 ssh:// 프로토콜을 포함하는 표준 URL이 필요합니다.
호스트 키 확인 실패#
이 오류는 대상 호스트 공개 SSH 키가 변경될 때 반환됩니다. 공개 SSH 키는 거의 변경되지 않습니다. 호스트 키 확인이 실패하지만 키가 여전히 유효하다고 생각되면 저장소 미러를 삭제하고 다시 생성해야 합니다. 자세한 내용은 저장소 미러 생성을 참조하세요.
미러 사용자가 삭제되어 저장소 미러링이 비활성화됨#
다음과 유사한 이메일 알림을 받을 수 있습니다:
Repository mirroring on <project_path> was disabled because the mirror user <username> was deleted.
To re-enable mirroring, update your repository mirroring settings.
이 문제는 각 미러가 구성한 사용자에 연결되어 있기 때문에 발생합니다. 해당 사용자의 계정이 삭제되면 GitLab이 자동으로 미러를 비활성화합니다. 미러를 만드는 데 사용된 그룹 액세스 토큰이나 프로젝트 액세스 토큰이 취소될 때도 동일한 동작이 적용됩니다. 관련 봇 사용자도 삭제되기 때문입니다.
미러를 다른 사용자에게 재할당할 수 없습니다. 이 문제를 해결하려면 다른 사용자로 미러를 다시 설정합니다.
자세한 내용은 이슈 488449를 참조하세요.
미러 사용자 및 토큰을 단일 서비스 계정으로 전송#
이를 위해서는 GitLab Rails 콘솔에 대한 접근이 필요합니다.
사용 사례: 여러 사용자가 자신의 GitHub 자격 증명을 사용하여 저장소 미러링을 설정한 경우 사람들이 회사를 떠날 때 미러링이 중단됩니다. 이 스크립트를 사용하여 분산된 미러링 사용자와 토큰을 단일 서비스 계정으로 마이그레이션합니다:
데이터를 변경하는 명령어는 올바르게 실행되지 않거나 적절한 조건에서 실행되지 않으면 손상을 줄 수 있습니다. 항상 테스트 환경에서 먼저 명령어를 실행하고 복원할 준비가 된 백업 인스턴스를 준비하세요.
svc_user = User.find_by(username: 'ourServiceUser')
token = 'githubAccessToken'
Project.where(mirror: true).each do |project|
import_url = project.unsafe_import_url
# The expected url output is https://token@project/path.git
repo_url = if import_url.include?('@')
# Case 1: The url is something like https://23423432@project/path.git
import_url.split('@').last
elsif import_url.include?('//')
# Case 2: The url is something like https://project/path.git
import_url.split('//').last
end
next unless repo_url
final_url = "https://#{token}@#{repo_url}"
project.mirror_user = svc_user
project.import_url = final_url
project.username_only_import_url = final_url
project.save
end
The requested URL returned error: 301#
http:// 또는 https:// 프로토콜을 사용하여 미러링할 때 저장소에 정확한 URL을 지정했는지 확인합니다: https://gitlab.example.com/group/project.git
HTTP 리다이렉트는 따르지 않으며 .git을 생략하면 301 오류가 발생할 수 있습니다:
13:fetch remote: "fatal: unable to access 'https://gitlab.com/group/project': The requested URL returned error: 301\n": exit status 128.
GitLab 인스턴스에서 Geo 보조 노드로 푸시 미러 실패#
HTTP 또는 HTTPS 프로토콜을 사용하는 GitLab 저장소의 푸시 미러링은 대상이 Geo 보조 노드일 때 실패합니다. 이는 푸시 요청이 Geo 기본 노드로 프록시되기 때문이며 다음 오류가 표시됩니다:
13:get remote references: create git ls-remote: exit status 128, stderr: "fatal: unable to access 'https://gitlab.example.com/group/destination.git/': The requested URL returned error: 302".
이는 Geo 통합 URL이 구성되고 대상 호스트 이름이 보조 노드의 IP 주소로 확인될 때 발생합니다.
다음을 통해 오류를 방지할 수 있습니다:
- SSH 프로토콜을 사용하도록 푸시 미러를 구성합니다. 하지만 저장소에는 LFS 객체가 포함되지 않아야 합니다. LFS 객체는 항상 HTTP 또는 HTTPS를 통해 전송되며 여전히 리다이렉트됩니다.
- 소스 인스턴스의 모든 요청을 기본 Geo 노드로 직접 전달하는 역방향 프록시를 사용합니다.
- 소스의 로컬
hosts파일 항목을 추가하여 대상 호스트 이름이 Geo 기본 노드의 IP 주소로 강제 확인되도록 합니다. - 대신 대상에 풀 미러를 구성합니다.
풀 또는 푸시 미러가 업데이트 실패: The project is not mirrored#
GitLab 사일런트 모드가 활성화된 경우 풀 및 푸시 미러가 업데이트 실패합니다. 이 경우 UI에서 미러링을 허용하는 옵션이 비활성화됩니다.
관리자가 GitLab 사일런트 모드가 비활성화되었는지 확인할 수 있습니다.
사일런트 모드로 인해 미러링이 실패하면 다음과 같은 디버그 단계가 있습니다:
- API를 사용하여 미러 트리거에
The project is not mirrored가 표시됩니다. - 풀 또는 푸시 미러가 이미 설정되어 있지만 미러된 저장소에 더 이상 업데이트가 없는 경우 아래와 같이 프로젝트의 풀 및 푸시 미러 세부 정보 및 상태가 최근이 아닌 것을 확인합니다. 이는 미러링이 일시 중지되었으며 GitLab 사일런트 모드를 비활성화하면 자동으로 재시작됨을 나타냅니다.
예를 들어 사일런트 모드가 가져오기를 방해하는 경우 출력은 다음과 유사합니다:
"id": 1,
"update_status": "finished",
"url": "https://test.git"
"last_error": null,
"last_update_at": null,
"last_update_started_at": "2023-12-12T00:01:02.222Z",
"last_successful_update_at": null
초기 미러링 실패: Unable to pull mirror repo: Unable to get pack index#
다음과 유사한 오류가 발생할 수 있습니다:
13:fetch remote: "error: Unable to open local file /var/opt/gitlab/git-data/repositories/+gitaly/tmp/quarantine-[OMITTED].idx.temp.temp\nerror: Unable to get pack index https://git.example.org/ebtables/objects/pack/pack-[OMITTED].idx\nerror: Unable to find fcde2b2edba56bf408601fb721fe9b5c338d10ee under https://git.example.org/ebtables
Cannot obtain needed object fcde2b2edba56bf408601fb721fe9b5c338d10ee
while processing commit 2c26b46b68ffc68ff99b453c1d30413413422d70.
error: fetch failed.\n": exit status 128.
이 문제는 Gitaly가 "dumb" HTTP 프로토콜을 통해 저장소 미러링 또는 가져오기를 지원하지 않기 때문에 발생합니다.
서버가 "smart"인지 "dumb"인지 확인하려면 cURL을 사용하여 git-upload-pack 서비스에 대한 참조 검색을 시작하고 Git "smart" 클라이언트를 에뮬레이션합니다:
$GIT_URL="https://git.example.org/project"
curl --silent --dump-header - "$GIT_URL/info/refs?service=git-upload-pack"\
-o /dev/null | grep -Ei "$content-type:"
- "smart" 서버는
Content-Type응답 헤더에application/x-git-upload-pack-advertisement를 보고합니다. - "dumb" 서버는
Content-Type응답 헤더에text/plain을 보고합니다.
자세한 내용은 참조 검색에 대한 Git 문서를 참조하세요.
이를 해결하려면 다음 중 하나를 수행할 수 있습니다:
- 소스 저장소를 "smart" 서버로 마이그레이션합니다.
- SSH 프로토콜을 사용하여 저장소를 미러링합니다(인증 필요).
오류: File directory conflict#
다음과 유사한 오류가 발생할 수 있습니다:
13:preparing reference update: file directory conflict
이 오류는 소스 저장소와 미러 저장소 사이에 태그 또는 브랜치 이름 충돌이 있을 때 발생합니다. 예:
- 미러 저장소에
x/y라는 태그 또는 브랜치가 있습니다. - 소스 저장소에
x라는 태그 또는 브랜치가 있습니다.
이 문제를 해결하려면 충돌하는 태그 또는 브랜치를 삭제합니다. 충돌하는 태그 또는 브랜치를 식별할 수 없으면 미러 저장소에서 모든 태그를 삭제합니다. 또는 분기된 브랜치 덮어쓰기 옵션을 사용할 수 있습니다.
태그를 삭제하면 미러 저장소에서 수행된 모든 작업에 영향을 미칠 수 있습니다.
미러 저장소에서 모든 태그를 삭제하고 제거하려면:
-
미러된 저장소의 로컬 복사본에서 다음을 실행합니다:
git tag -l | xargs -n 1 git push --delete origin -
왼쪽 사이드바에서 Settings > Repository를 선택합니다.
-
Mirroring repositories를 펼칩니다.
-
Update now ([retry])를 선택합니다.
대형 LFS 파일과 함께 푸시 미러링이 멈춤#
대형 LFS 객체가 포함된 프로젝트를 푸시 미러링할 때 타임아웃 문제가 발생할 수 있습니다. 이 문제는 Git LFS 작업이 기본 활동 타임아웃을 초과할 때 발생합니다. 이 오류는 미러링 로그에 나타납니다:
push to mirror: git push: exit status 1, stderr: "remote: GitLab: LFS objects are missing. Ensure LFS is properly set up or try a manual \"git lfs push --all\""
이 문제를 해결하려면 미러를 구성하기 전에 LFS 활동 타임아웃 값을 늘립니다:
git config lfs.activitytimeout 240
이 명령어는 타임아웃을 240초로 설정합니다. 파일 크기와 네트워크 조건에 따라 이 값을 조정할 수 있습니다.
