Docker 시니어 기술면접
새 면접Q. Docker Compose의 의존성 관리(depends_on)와 실제 애플리케이션 준비 상태(readiness)의 차이를 설명하고, 마이크로서비스 환경에서 서비스 간 시작 순서와 헬스체크를 고려한 안정적인 컨테이너 시작 전략을 설계해주세요. 특히 데이터베이스 마이그레이션, 초기화 컨테이너, 재시도 로직을 포함한 프로덕션급 솔루션을 제시해주세요.
depends_on은 컨테이너 시작 순서만 보장하며 애플리케이션의 실제 준비 상태는 확인하지 않습니다. 프로덕션 환경에서는 헬스체크 스크립트(wait-for-it.sh, dockerize)를 엔트리포인트에 통합하거나, 애플리케이션 레벨에서 연결 재시도 로직을 구현해야 합니다. 데이터베이스 마이그레이션은 별도의 init 컨테이너로 분리하고, 애플리케이션 컨테이너는 exponential backoff 방식의 연결 재시도를 구현하며, Compose의 healthcheck와 condition: service_healthy를 조합하여 의존성을 관리합니다. Kubernetes 환경으로의 마이그레이션을 고려하여 init containers와 readiness probe 패턴을 미리 적용하는 것이 좋습니다.
- • depends_on은 시작 순서만 보장하며 애플리케이션 준비 상태는 보장하지 않음
- • 헬스체크 스크립트와 애플리케이션 레벨 재시도 로직 조합 필요
- • 데이터베이스 마이그레이션은 init 컨테이너로 분리하고 healthcheck 조건 활용
- • Kubernetes의 init containers 패턴을 미리 적용하여 이식성 확보
대규모 마이크로서비스 환경에서 순환 의존성(circular dependency)이 발생했을 때 어떻게 해결하시겠습니까? 서비스 메시나 사이드카 패턴을 활용한 해결 방법을 설명해주세요.
Q. Docker 이미지의 레이어 구조와 Union File System의 동작 원리를 설명하고, Dockerfile 작성 시 레이어 순서 최적화, 명령어 통합(RUN chaining), .dockerignore 활용을 통해 이미지 크기와 빌드 캐시 효율성을 동시에 개선하는 전략을 제시해주세요. 특히 Node.js나 Python 같은 인터프리터 언어에서 패키지 의존성 캐싱 전략을 포함해주세요.
Union File System은 여러 레이어를 하나의 파일시스템으로 병합하며, 각 Dockerfile 명령어는 새로운 레이어를 생성합니다. 빌드 최적화를 위해 변경 빈도가 낮은 명령어를 상위에 배치하고(OS 패키지 설치), 자주 변경되는 소스코드 복사는 하위에 배치합니다. Node.js의 경우 package.json과 package-lock.json만 먼저 COPY하여 npm install을 실행한 후 소스코드를 복사하면 의존성 레이어를 효과적으로 캐싱할 수 있습니다. RUN 명령어는 apt-get update && apt-get install && rm -rf /var/lib/apt/lists/* 형태로 체이닝하여 불필요한 캐시를 같은 레이어에서 제거하고, .dockerignore로 node_modules, .git, 테스트 파일 등을 제외하여 빌드 컨텍스트를 최소화합니다.
- • 변경 빈도에 따라 레이어 순서 최적화 - 정적 의존성을 상위 레이어에 배치
- • 패키지 매니저 파일만 먼저 복사하여 의존성 설치 레이어 캐싱
- • RUN 명령어 체이닝으로 임시 파일을 같은 레이어에서 정리
- • .dockerignore로 빌드 컨텍스트 최소화 및 캐시 무효화 방지
멀티아키텍처 이미지(amd64, arm64)를 빌드할 때 docker buildx의 동작 원리와 크로스 컴파일 vs QEMU 에뮬레이션의 성능 차이를 설명해주세요. 어떤 상황에서 어떤 방식을 선택하시겠습니까?
Q. Docker의 DNS 기반 서비스 디스커버리 메커니즘과 embedded DNS server(127.0.0.11)의 동작 원리를 설명하고, 멀티 호스트 환경에서 overlay 네트워크의 VXLAN 터널링과 Gossip 프로토콜을 통한 네트워크 상태 동기화 과정을 설명해주세요. 특히 네트워크 파티션 상황에서의 동작과 성능 오버헤드를 포함해주세요.
Docker의 embedded DNS server는 각 컨테이너의 /etc/resolv.conf에 127.0.0.11로 설정되며, 컨테이너 이름이나 네트워크 별칭을 IP 주소로 해석합니다. Overlay 네트워크는 VXLAN을 사용하여 여러 호스트의 컨테이너를 L2 네트워크로 연결하며, UDP 4789 포트를 통해 캡슐화된 패킷을 전송합니다. Swarm의 Gossip 프로토콜(SWIM)은 노드 간 네트워크 상태와 서비스 정보를 전파하며, 네트워크 파티션 발생 시 각 파티션은 독립적으로 동작하다가 복구 시 상태를 병합합니다. VXLAN 캡슐화는 약 50바이트의 오버헤드를 추가하며, 고성능이 필요한 경우 host 네트워크나 macvlan을 고려해야 합니다.
- • embedded DNS server(127.0.0.11)가 컨테이너 이름을 IP로 해석하여 서비스 디스커버리 제공
- • overlay 네트워크는 VXLAN(UDP 4789)으로 멀티호스트 L2 네트워크 구성
- • Gossip 프로토콜로 네트워크 상태 동기화, 파티션 복구 시 상태 병합
- • VXLAN 캡슐화 오버헤드와 고성능 요구사항 고려 필요
Service Mesh(Istio, Linkerd)와 Docker overlay 네트워크의 차이점을 설명하고, 각각의 트래픽 관리, 보안, 관찰성 측면에서의 장단점을 비교해주세요. 언제 Service Mesh 도입을 고려해야 할까요?
Q. Docker의 User Namespace 재매핑 메커니즘을 설명하고, 컨테이너 내부의 root 사용자를 호스트의 비특권 사용자로 매핑하는 과정을 설명해주세요. 또한 이 기능이 볼륨 마운트 권한과 파일 소유권에 미치는 영향과, 프로덕션 환경에서 발생할 수 있는 문제점 및 해결 방법을 제시해주세요.
User Namespace 재매핑은 컨테이너 내부의 UID/GID를 호스트의 다른 범위로 매핑하여 컨테이너 root가 호스트에서는 비특권 사용자로 동작하게 합니다. dockerd를 --userns-remap 옵션으로 실행하면 /etc/subuid와 /etc/subgid 파일을 참조하여 매핑 범위를 설정합니다(예: 컨테이너 UID 0이 호스트 UID 100000으로 매핑). 볼륨 마운트 시 호스트 파일의 소유권이 재매핑된 UID와 일치하지 않아 권한 문제가 발생할 수 있으며, 이는 chown으로 소유권을 조정하거나 Dockerfile에서 USER 지시어로 특정 UID를 사용하여 해결합니다. 프로덕션에서는 rootless 모드와 함께 사용하거나, Kubernetes의 PodSecurityPolicy/PodSecurityStandard로 보안 컨텍스트를 강제하는 것이 좋습니다.
- • User Namespace 재매핑으로 컨테이너 root를 호스트 비특권 사용자로 매핑
- • /etc/subuid, /etc/subgid 파일로 UID/GID 매핑 범위 정의
- • 볼륨 마운트 시 파일 소유권 불일치 문제 발생 가능
- • chown 조정, USER 지시어, rootless 모드, PodSecurityPolicy 조합으로 해결
Linux Capabilities를 활용하여 컨테이너에 필요한 최소 권한만 부여하는 전략을 설명해주세요. CAP_NET_ADMIN, CAP_SYS_ADMIN 같은 위험한 capability를 대체할 수 있는 방법은 무엇입니까?
Q. Docker 컨테이너의 실시간 성능 메트릭을 수집하고 분석하는 방법을 설명해주세요. docker stats API의 한계점과 cAdvisor, Prometheus, Grafana를 활용한 프로덕션급 모니터링 아키텍처를 설계하고, 컨테이너 레벨 메트릭(CPU throttling, OOM kills, I/O wait)을 해석하여 성능 병목을 진단하는 방법을 제시해주세요.
docker stats는 실시간 메트릭을 제공하지만 히스토리 데이터 저장이 불가능하고 alerting 기능이 없습니다. 프로덕션 환경에서는 cAdvisor를 DaemonSet으로 각 노드에 배포하여 컨테이너 메트릭을 수집하고, Prometheus가 이를 스크래핑하여 시계열 데이터베이스에 저장하며, Grafana로 시각화와 알람을 구성합니다. CPU throttling(container_cpu_cfs_throttled_seconds_total)은 CPU 제한에 도달했음을 의미하며 --cpus 값 증가를 고려하고, OOM kills(container_memory_failures_total)는 메모리 부족으로 인한 강제 종료를 나타내므로 메모리 누수 점검이나 --memory 증가가 필요합니다. I/O wait이 높으면 스토리지 성능 개선이나 볼륨 드라이버 변경을 검토해야 합니다.
- • docker stats는 실시간만 제공, 프로덕션에는 cAdvisor + Prometheus + Grafana 스택 필요
- • CPU throttling 메트릭으로 CPU 제한 도달 감지 및 리소스 조정
- • OOM kills 메트릭으로 메모리 부족 문제 진단 및 메모리 누수 점검
- • I/O wait 분석으로 스토리지 병목 식별 및 볼륨 전략 개선
컨테이너 내부에서 발생하는 성능 문제를 디버깅할 때 strace, perf, eBPF 같은 도구를 어떻게 활용하시겠습니까? 특히 프로덕션 환경에서 디버깅 도구 사용 시 주의사항을 설명해주세요.
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!