Git 미드레벨 시스템 설계 면접
새 면접Q. 여러 팀이 독립적으로 개발하는 대규모 프로젝트에서 Git Submodules, Git Subtree, 그리고 별도 저장소 + 패키지 매니저 방식 중 어떤 것을 선택하시겠습니까? 각 방식의 장단점과 함께 의존성 버전 관리, 빌드 시간, 개발자 경험 측면에서 비교 분석하고, 선택 기준을 제시해주세요.
Git Submodules는 각 모듈의 버전을 명확히 고정할 수 있지만 업데이트가 복잡하고 개발자가 실수하기 쉽습니다. Git Subtree는 서브모듈보다 사용이 간편하지만 히스토리가 복잡해지고 원본 저장소와의 동기화가 어렵습니다. 별도 저장소 + 패키지 매니저 방식은 명확한 버전 관리와 CI/CD 통합이 용이하지만 초기 인프라 구축 비용이 높습니다. 팀 간 결합도가 낮고 독립적인 릴리스 주기를 가진다면 패키지 매니저 방식을, 긴밀한 협업과 동시 개발이 필요하다면 모노레포를 권장합니다.
- • Submodules는 버전 고정이 명확하지만 git submodule update 등 추가 명령어 필요
- • Subtree는 단일 저장소처럼 사용 가능하지만 양방향 동기화 복잡
- • 패키지 매니저 방식은 의존성 관리가 명확하고 CI/CD 통합 용이
- • 팀 간 결합도, 릴리스 주기, 인프라 역량에 따라 선택
Submodules를 사용하는 프로젝트에서 여러 서브모듈을 동시에 특정 버전으로 업데이트하고 이를 자동화하는 방법을 설명해주세요.
Q. 자체 호스팅하는 Git 서버(GitLab, Gitea 등)의 고가용성(HA) 아키텍처를 설계해야 합니다. 저장소 데이터, 메타데이터, 첨부파일을 어떻게 복제하고 동기화할 것인지, 액티브-스탠바이와 액티브-액티브 구성의 차이점, 그리고 Git의 분산 특성을 활용한 장애 복구 전략을 설명해주세요.
Git 저장소는 파일 시스템 기반이므로 NFS/GlusterFS 같은 공유 스토리지나 DRBD 같은 블록 레벨 복제를 사용할 수 있습니다. 액티브-스탠바이 구성은 구현이 간단하지만 장애 시 수동 전환이 필요하고, 액티브-액티브는 쓰기 충돌 방지를 위해 로드밸런서에서 저장소별 라우팅이 필요합니다. PostgreSQL 같은 메타데이터 DB는 스트리밍 복제로 동기화하고, 첨부파일은 S3 같은 오브젝트 스토리지를 사용하면 HA가 자동 보장됩니다. Git의 분산 특성상 각 개발자의 로컬 클론이 백업 역할을 하므로, 최악의 경우 여러 개발자의 저장소를 병합하여 복구할 수 있습니다.
- • 저장소 데이터는 공유 스토리지 또는 파일 시스템 레벨 복제 사용
- • 메타데이터 DB는 마스터-슬레이브 복제, 오브젝트 스토리지는 자체 HA 제공
- • 액티브-액티브는 쓰기 충돌 방지 위해 저장소별 라우팅 필요
- • Git의 분산 특성으로 개발자 로컬 클론이 추가 백업 역할
Git 서버의 저장소가 손상되었을 때, 여러 개발자의 로컬 저장소로부터 중앙 저장소를 재구성하는 구체적인 절차를 설명해주세요.
Q. 개발, 스테이징, 프로덕션 환경을 운영하는 서비스에서 각 환경별 설정 파일(config.json, .env)을 Git으로 관리하면서도 민감 정보는 노출하지 않는 시스템을 설계해주세요. git-crypt, SOPS, 환경변수 주입 등의 방식을 비교하고, CI/CD 파이프라인과의 통합 방안을 제시해주세요.
git-crypt는 투명한 암호화/복호화를 제공하지만 GPG 키 관리가 복잡하고 팀원 추가 시 재암호화가 필요합니다. SOPS는 AWS KMS, GCP KMS와 통합되어 키 관리가 용이하고 부분 암호화를 지원하지만 별도 도구 설치가 필요합니다. 환경변수 주입 방식은 설정 템플릿만 Git에 저장하고 실제 값은 CI/CD 시스템(Jenkins, GitLab CI)의 시크릿 변수로 관리하여 가장 안전합니다. 권장 방식은 공개 가능한 설정은 Git에, 민감 정보는 Vault나 AWS Secrets Manager에 저장하고, 배포 시점에 결합하는 것입니다.
- • git-crypt는 투명하지만 GPG 키 관리 복잡, SOPS는 클라우드 KMS 통합 우수
- • 환경변수 주입 방식은 템플릿만 Git 저장, 실제 값은 CI/CD 시크릿으로 관리
- • Vault, AWS Secrets Manager 같은 전용 시크릿 관리 시스템 활용 권장
- • 배포 시점에 설정 템플릿과 시크릿을 동적으로 결합
개발자 로컬 환경에서도 동일한 설정 관리 방식을 적용하면서, 개발자가 실수로 민감 정보를 커밋하는 것을 방지하는 방법을 설명해주세요.
Q. 수천 개의 브랜치가 존재하는 Git 저장소에서 git fetch, git pull 성능이 저하되는 문제를 해결해야 합니다. Git의 ref 저장 방식(loose refs vs packed refs), reference negotiation 프로토콜, 그리고 fetch.prune, fetch.writeCommitGraph 같은 설정이 성능에 미치는 영향을 설명하고 최적화 방안을 제시해주세요.
Git은 각 브랜치를 .git/refs/ 디렉토리에 개별 파일로 저장하는데(loose refs), 수천 개가 되면 파일 시스템 성능이 저하됩니다. git pack-refs 명령으로 .git/packed-refs 단일 파일로 압축하면 I/O가 크게 개선됩니다. fetch 시 reference negotiation 단계에서 서버와 클라이언트가 공통 커밋을 찾는데, commit-graph 파일을 생성하면 이 과정이 빨라집니다. fetch.prune=true로 삭제된 원격 브랜치를 자동 정리하고, fetch.writeCommitGraph=true로 fetch 후 자동으로 commit-graph를 업데이트하면 지속적인 성능을 유지할 수 있습니다. 또한 불필요한 브랜치를 주기적으로 삭제하는 정책도 필요합니다.
- • loose refs는 파일 시스템 부하, packed-refs로 압축하여 I/O 개선
- • commit-graph는 reference negotiation 성능 향상
- • fetch.prune으로 오래된 원격 추적 브랜치 자동 정리
- • 브랜치 라이프사이클 정책으로 불필요한 브랜치 삭제
CI/CD 환경에서 매번 새로운 클론을 생성하는 것과 기존 저장소를 재사용하는 것의 성능 트레이드오프를 분석하고, 최적의 전략을 제시해주세요.
Q. Git 태그를 기반으로 한 자동 배포 시스템을 설계합니다. 개발자가 v1.2.3 형태의 시맨틱 버전 태그를 push하면 자동으로 빌드, 테스트, 배포되는 시스템에서 잘못된 태그 생성, 태그 삭제 후 재생성, 동일 버전 재배포 등의 엣지 케이스를 어떻게 처리하시겠습니까? 멱등성, 롤백, 감사 로그를 고려한 시스템 설계를 제시해주세요.
태그 기반 배포 시스템은 annotated tag만 허용하고 lightweight tag는 거부하여 작성자와 시간 정보를 보장해야 합니다. server-side pre-receive hook에서 시맨틱 버전 형식 검증, 이미 존재하는 태그 재사용 금지, 태그가 가리키는 커밋이 이미 배포된 적 있는지 확인합니다. 태그 삭제는 원칙적으로 금지하되, 필요 시 별도 승인 프로세스를 거치도록 합니다. 배포 시스템은 태그와 커밋 SHA를 함께 기록하여 동일 SHA 재배포 시 스킵하거나 경고를 표시합니다. 모든 배포는 별도 DB에 태그, 커밋, 배포자, 시간, 결과를 기록하여 감사 추적을 보장하고, 롤백 시 이전 태그로 새로운 배포를 트리거합니다.
- • annotated tag만 허용하여 메타데이터 보장, pre-receive hook으로 태그 정책 강제
- • 태그와 커밋 SHA를 함께 추적하여 중복 배포 방지
- • 태그 삭제 금지 또는 승인 프로세스 적용
- • 배포 이력을 별도 DB에 저장하여 감사 추적 및 롤백 지원
동일한 커밋에 여러 태그(v1.2.3, v1.2.3-hotfix, v1.2.4-rc1)가 달릴 수 있는 상황에서, 어떤 태그를 배포할지 결정하는 우선순위 로직을 어떻게 설계하시겠습니까?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!