프로덕션에서 살아남는 DevOps/SRE 면접 질문 20가지

|Operation Risk|29분 읽기

면접관이 정말 보고 싶어 하는 것

몇 년간 양쪽 자리에 다 앉아봤습니다. 면접을 보러 간 적도 있고, 면접관으로 들어간 적도 있어요. 그러면서 분명해진 게 하나 있는데, 면접관이 진짜 알고 싶어 하는 건 용어 정의가 아니더라고요. "Kubernetes가 뭔가요?"에 술술 답하는 사람보다, "Pod가 Running인데 503이 나면 어디부터 보겠어요?"에서 멈칫하지 않는 사람이 훨씬 신뢰가 갑니다. 앞 질문은 외우면 되지만, 뒷 질문은 실제로 새벽에 깨본 사람만 답할 수 있거든요.

프로덕션에서는 정답보다 사고 순서가 훨씬 중요합니다. 문제를 어떻게 레이어별로 쪼개고, 어디서부터 확인하며, 사용자 영향을 최소화하면서 원인을 좁혀가는가. 이게 핵심이에요. 정답 한 줄을 아는 것보다, 잘못된 가정을 빨리 버릴 줄 아는 사람이 운영에서는 더 오래 살아남습니다.

그래서 실제 면접에서 자주 나오는 20가지 질문을 정리해봤습니다. 답변은 암기용이 아니라, 운영자가 장애 앞에서 실제로 머릿속에 굴리는 순서에 맞춰 구성했어요.

네트워크와 트래픽 문제 해결

1. Pod는 Running인데 503 오류가 발생합니다. 어떻게 디버깅하겠습니까?

503은 보통 애플리케이션이 죽었다는 의미가 아닙니다. 정상 백엔드를 찾지 못했다는 신호죠. 그래서 앱부터 보면 시간을 버립니다. 요청이 흘러가는 경로를 레이어별로 끊어서 봐야 해요.

Pod 레벨 확인

  • kubectl get pod -o wide로 상태 확인
  • kubectl logs <pod>kubectl describe pod <pod>로 상세 정보 파악
  • readiness/liveness probe 실패 여부
  • 애플리케이션 포트와 컨테이너 포트 일치 여부

Service 레벨 확인

  • kubectl get endpoints로 Service가 Pod를 제대로 잡고 있는지
  • Service selector와 Pod label 매칭 확인
  • targetPort가 실제 컨테이너 포트와 일치하는지

Ingress/Gateway 레벨 확인

  • Ingress Controller 로그
  • host, path, TLS 설정
  • Backend Service 연결 상태

가장 흔한 원인은 readiness probe 실패로 Pod가 Service Endpoint에서 조용히 빠지는 경우입니다. Pod는 멀쩡히 Running으로 보이는데 endpoints 목록에는 없는 거죠. 그래서 저는 503을 보면 거의 반사적으로 kubectl get endpoints부터 칩니다. "트래픽이 어느 지점까지 도달했는가"를 기준으로 역추적하는 게 503 디버깅의 핵심이에요.

2. CNI 플러그인은 어떻게 동작합니까?

CNI(Container Network Interface)는 Pod에 네트워크를 붙이는 표준 인터페이스입니다. Kubernetes는 네트워킹을 직접 구현하지 않고, 이 일을 CNI 플러그인에 위임해요. 쿠버네티스 입장에서 네트워크는 "내가 알아서 하는 것"이 아니라 "외부에 맡기는 것"이라는 거죠.

주요 역할은 이렇습니다.

  • Pod IP 할당 및 veth pair 생성
  • Pod network namespace 연결
  • Node 간 Pod 통신을 위한 라우팅 구성
  • NetworkPolicy 적용
  • overlay/underlay 네트워크 구성

Calico는 BGP 기반 라우팅과 NetworkPolicy에 강점이 있고, Cilium은 eBPF 기반으로 보안과 관측성 쪽이 강합니다. 선택은 결국 "우리 환경이 무엇을 더 필요로 하느냐"의 문제예요.

운영 관점에서 진짜 중요한 건, CNI가 흔들리면 Pod 간 통신, DNS, Service 통신, NetworkPolicy까지 줄줄이 영향을 받는다는 점입니다. CNI는 가장 아래 레이어라서, 여기가 깨지면 위에서 보이는 증상은 전혀 다른 곳을 가리키게 돼요. "DNS가 안 돼요"라고 올라온 티켓이 사실은 CNI 문제였던 경우, 한두 번이 아닙니다.

스케줄링과 배포 전략

3. Kubernetes 스케줄링 동작 방식

Kubernetes Scheduler는 Filtering과 Scoring 두 단계로 동작합니다.

Filtering 단계에서는 Pod를 올릴 수 없는 Node를 걸러냅니다.

  • CPU/Memory 부족
  • taint/toleration 불일치
  • nodeSelector, node affinity 조건 불일치
  • PV zone 제약

Scoring 단계에서는 남은 Node 중 가장 적합한 곳을 고릅니다.

  • 리소스 여유도
  • Pod 분산 정책
  • affinity 선호 조건
  • topology spread constraints

Pod가 Pending에서 안 넘어간다면 kubectl describe pod의 Events부터 봐야 해요. 여기서 사람들이 자주 하는 실수가, 머릿속으로 원인을 추측하기 시작하는 겁니다. 추측하지 말고 스케줄러가 왜 못 올렸는지 이벤트 메시지를 그대로 읽으면 됩니다. "0/5 nodes are available" 뒤에 붙는 사유가 답을 거의 다 말해주거든요.

4. Stateful 애플리케이션 무중단 배포

Stateful 애플리케이션은 Pod만 갈아끼운다고 무중단이 되지 않아요. 애플리케이션 버전, 데이터, 스키마, 복제 구조를 같이 봐야 합니다. Stateless에서 통하던 감각으로 접근하면 데이터가 어긋나는 순간 복구가 훨씬 고통스러워져요.

기본 접근법은 이렇습니다.

  • StatefulSet으로 Pod 순서와 안정적인 네트워크 ID 유지
  • RollingUpdate로 한 번에 하나씩 교체
  • readiness probe로 준비되지 않은 Pod에 트래픽 차단
  • replica/standby 구조 활용
  • backward compatible 스키마 설계
  • 배포 전 백업과 롤백 경로 확보

핵심은 "애플리케이션 배포"와 "데이터 변경"을 분리해서 생각하는 겁니다. 특히 DB 스키마 변경은 expand → deploy → contract 순서로 가야 안전해요. 컬럼을 먼저 추가하고(expand), 새 코드를 배포하고(deploy), 구버전이 다 빠진 뒤 옛 컬럼을 정리하는(contract) 흐름이죠. 한 번에 스키마와 코드를 동시에 바꾸려다 롤백 경로가 막히는 사고, 금융권에서 꽤 자주 봤습니다.

디버깅과 문제 해결

5. 로그 없이 간헐적 Pod 재시작

로그가 없다는 건 애플리케이션 로그를 남기기 전에 죽었거나, 죽는 순간 로그를 flush할 시간이 없었다는 뜻일 가능성이 큽니다. 그러니 앱 로그가 비어 있다고 단서가 없는 게 아니에요. 단서가 다른 곳에 있는 거죠.

확인 순서.

  1. kubectl describe pod로 Events 확인
  2. kubectl get pod -o yaml에서 lastState 확인
  3. OOMKilled 여부와 liveness probe 실패 확인
  4. Node의 CPU, Memory, DiskPressure 상태
  5. 컨테이너 exit code 확인
  6. kubectl logs <pod> --previous로 이전 컨테이너 로그

자주 보는 원인.

  • 메모리 limit 초과로 인한 OOMKilled
  • liveness probe timeout 또는 path 오류
  • node resource pressure
  • 애플리케이션 초기화 실패
  • 외부 의존성 지연으로 인한 probe 실패

liveness probe가 너무 빡빡하게 잡혀서, 멀쩡한 앱이 초기화하는 동안 죽임을 당하는 경우도 흔합니다. 로그가 없을 때는 앱만 들여다보지 말고 쿠버네티스 이벤트, 컨테이너 상태, 노드 상태를 같이 봐야 그림이 그려져요.

6. 60초마다 latency 급증 디버깅

주기적인 latency 증가는 예약 작업이나 주기적 리소스 사용을 먼저 의심해야 합니다. 일정한 간격으로 뛴다는 건, 누군가가 시계를 보고 움직이고 있다는 뜻이니까요.

확인 항목.

  • cron job 또는 scheduled task
  • JVM GC 또는 런타임 GC
  • DB checkpoint, vacuum, backup
  • 로그 flush/rotate, metrics scraping
  • batch job, cache refresh
  • autoscaling metric 수집 주기
  • 외부 API rate limit

디버깅 방법.

  • latency spike 시점과 인프라 지표를 시간축으로 맞춰 겹쳐 보기
  • trace에서 느려지는 구간 확인
  • DB slow query, GC log 확인
  • cron/scheduler 실행 시간 확인

"60초마다"라는 패턴 자체가 가장 강한 단서입니다. 이 주기를 기준선으로 깔아두고 애플리케이션, DB, 런타임, 인프라 작업을 하나씩 대조하면 범인이 의외로 빨리 나와요. 모니터링 솔루션을 다루던 시절, 이런 톱니 모양 그래프는 거의 항상 주기적 작업이 범인이었습니다.

CI/CD와 배포 최적화

7. 50개 이미지 빌드 시간 단축 (20분 → 5분)

핵심은 **"모든 이미지를 매번 처음부터 다시 빌드하지 않는 것"**입니다. 50개 중 실제로 바뀐 건 보통 한두 개거든요.

개선 방향.

  • 변경된 서비스만 빌드하도록 path 기반 change detection
  • 빌드 병렬화
  • Docker layer cache 활용
  • BuildKit, Kaniko, Buildx 등 빌드 도구 활용
  • base image 표준화로 캐시 적중률 향상
  • dependency install과 app copy 단계 분리
  • remote cache 또는 registry cache 사용
  • 테스트와 빌드 병렬 실행

가장 큰 효과는 병렬화와 캐싱에서 나옵니다. 다만 여기서 한 가지. 무작정 병렬화하면 runner 비용과 registry 부하가 같이 올라가요. 빌드는 빨라졌는데 청구서가 늘거나, registry가 병목이 돼서 결국 또 느려지는 식이죠. 그래서 손대기 전에 병목이 어디인지 먼저 측정해야 합니다. 측정 없이 병렬화부터 거는 건 추측으로 운영하는 거예요.

8. 안전한 CI/CD 파이프라인 설계

보안은 배포 직전에 한 번 스캔하고 끝나는 게 아닙니다. 파이프라인 전체에 분산되어 있어야 해요. 마지막 게이트 하나에 모든 걸 맡기면, 그 게이트가 뚫리는 순간 방어선이 통째로 사라집니다.

주요 설계 요소.

  • Secret을 코드/이미지/로그에 남기지 않고 전용 저장소 사용
  • CI runner 권한 최소화
  • branch protection과 approval gate
  • 이미지 취약점 스캔과 IaC 스캔
  • SAST/DAST 적용
  • 아티팩트 서명 및 검증
  • SBOM 생성
  • 배포 권한과 빌드 권한 분리
  • 감사 로그 유지

운영 관점에서 정말 중요한 건 **"누가, 어떤 코드와 아티팩트를, 어떤 권한으로, 어느 환경에 배포했는지"**가 나중에 추적 가능해야 한다는 점입니다. 사고는 결국 터지고, 그때 가장 먼저 묻게 되는 질문이 "이거 누가 올렸어?"거든요. 파이프라인이 그 답을 들고 있어야 합니다.

인프라 관리와 고가용성

9. 다중 리전 고가용성 시스템 설계

다중 리전의 핵심은 여러 리전에 배포하는 게 아니라, 장애가 났을 때 트래픽과 데이터 정합성을 어떻게 처리할지 미리 결정하는 것입니다. 리전을 늘리는 건 쉬워요. 어려운 건 한쪽이 죽었을 때의 동작이죠.

설계 요소.

  • Active-Active 또는 Active-Passive 구조 선택
  • 글로벌 로드밸런서 또는 DNS 기반 라우팅
  • 리전 간 데이터 복제와 RTO/RPO 정의
  • 장애 감지와 failover 자동화
  • 리전별 독립 배포 가능성
  • 공통 의존성 제거
  • 운영 Runbook과 DR 훈련

Active-Active는 가용성은 높지만 데이터 정합성 관리가 까다롭습니다. Active-Passive는 구조는 단순한데 전환 시간과 복구 절차가 관건이에요. 어느 쪽도 공짜가 아닙니다.

그래서 면접에서 "다중 리전으로 가겠습니다"라고만 답하면 좀 약해요. **"가용성, 비용, 정합성, 운영 복잡도 사이의 trade-off를 이렇게 저울질해서 이 구조를 택하겠습니다"**라고 답하는 사람이, 실제로 DR 훈련을 돌려본 사람처럼 보입니다.

10. Terraform drift 관리

Terraform drift는 코드와 실제 클라우드 인프라가 어긋난 상태를 말합니다. 콘솔에서 누가 손가락으로 한 번 고치는 순간 시작되죠.

관리 방법.

  • remote backend와 state locking 적용
  • PR 기반 변경 프로세스
  • CI에서 terraform plan 실행
  • 수동 콘솔 변경 제한
  • drift detection 주기적 수행
  • 환경별 state 분리
  • state 파일 접근 권한 제한

중요한 건 Terraform을 **"가끔 한 번 돌리는 도구"가 아니라 "인프라의 기준 정보"**로 운영하는 겁니다. 코드가 실제 상태를 더 이상 설명하지 못하면, 그 시점부터 Terraform은 신뢰를 잃고 아무도 plan 결과를 안 믿게 돼요. 급해서 콘솔로 손댄 게 불가피했다면, 사후에라도 반드시 코드에 반영하거나 state를 정리해야 합니다. 이걸 미루면 drift가 쌓여서 나중엔 plan 한 번 돌리는 것조차 무서워집니다.

보안과 관측성

11. 대규모 Secret 관리

대규모 환경에서 Secret은 안전하게 저장하는 것만으로 끝나지 않아요. 접근·교체·감사까지 같이 관리해야 합니다.

핵심 원칙.

  • Secret을 Git, 이미지, CI 로그에 저장 금지
  • 중앙 Secret Manager 사용
  • 역할 기반 접근 제어
  • 환경별 Secret 분리
  • 정기적 rotation 적용
  • Secret 접근 로그 감사
  • short-lived credential 사용
  • 애플리케이션에는 필요한 Secret만 주입

Secret 관리의 목표는 "숨기는 것"이 아니라 **"누가 언제 어떤 Secret에 접근했는지 통제하고 추적하는 것"**입니다. 한번 노출된 Secret은 이미 노출된 거예요. 그래서 노출 자체를 0으로 만드는 데 매달리기보다, 노출됐을 때 빠르게 rotation하고 추적할 수 있는 구조가 현실적으로 더 강합니다.

12. Observability 설계

Observability는 로그를 많이 쌓는 게 아니라, 장애가 났을 때 원인을 빠르게 좁힐 수 있도록 신호를 설계하는 일입니다. 로그를 무작정 쌓으면 비용만 늘고, 정작 사고 때는 그 더미에서 뭘 찾아야 할지 몰라요.

기본 구성은 Metrics, Logs, Traces 세 축입니다.

  • Metrics: 시스템 상태와 성능 추세
  • Logs: 개별 이벤트와 에러 상세
  • Traces: 서비스 간 요청 흐름

운영 관점의 설계 요소.

  • 표준 로그 포맷과 correlation ID
  • 서비스별 RED 지표 (Rate, Errors, Duration)
  • 인프라별 USE 지표 (Utilization, Saturation, Errors)
  • 대시보드와 알림 기준

특히 correlation ID는 MSA 환경에서 거의 생명줄입니다. 요청 하나가 서비스 열 개를 거쳐 가는데 ID가 안 따라붙으면, 장애 났을 때 어느 구간에서 깨졌는지 추적이 사실상 불가능해져요. 좋은 Observability는 장애가 끝난 뒤 로그를 뒤지는 구조가 아니라, 장애 시작점을 실시간으로 좁혀주는 구조입니다.

장애 대응과 SRE 실무

13. SLO 기반 노이즈 없는 알림 설계

좋은 알림은 "시끄러운 알림"이 아니라 **"조치가 필요한 알림"**입니다. 알림이 너무 많이 울리면, 사람은 결국 알림을 무시하기 시작해요. 그게 진짜 위험한 상태죠.

설계 순서.

  1. 사용자 관점의 SLI 정의 (성공률, 지연시간, 가용성)
  2. SLO 정의 (예: 99.9% 요청 성공률, p95 latency 300ms 이하)
  3. Error Budget 설정
  4. Error Budget이 빠르게 소진될 때 알림 발생
  5. 내부 지표는 보조 알림으로 분리

CPU 90%가 그 자체로 장애는 아닐 수 있어요. 사용자는 CPU가 몇 퍼센트인지 모르고, 알 필요도 없습니다. 하지만 사용자 요청 실패율이 올라가거나 지연시간이 SLO를 위협하면 그건 깨워야 하는 알림이에요. 알림 기준을 인프라 지표가 아니라 사용자 경험에 맞춰야 하는 이유가 여기 있습니다.

14. 프로덕션 장애 대응 첫 5단계

장애 대응의 첫 목표는 완벽한 원인 분석이 아닙니다. 사용자 영향 최소화예요. 원인은 사후에 천천히 파도 되지만, 사용자가 겪는 장애는 지금 이 순간에도 진행 중이거든요.

  1. 영향 범위 확인: 전체인지 일부인지 특정 리전인지
  2. 장애 선언 및 커뮤니케이션: 조치 담당자/의사결정자/커뮤니케이션 담당을 분리
  3. 최근 변경사항 확인: 배포/설정/인프라/외부 의존성
  4. 즉시 완화 조치: rollback/traffic shift/feature flag off/scale out/circuit breaker
  5. 타임라인 기록: 언제 무엇을 확인했고 어떤 조치를 했는지

여기서 3번을 강조하고 싶어요. 장애 대부분은 "방금 뭔가 바뀐" 곳에서 시작합니다. 배포 직후, 설정 변경 직후. 그래서 침착하게 "최근에 뭐가 바뀌었지?"를 먼저 묻는 사람이 복구도 빨라요. 운영 사고에서 진짜 필요한 건 영웅적인 디버깅이 아니라 침착함과 구조화입니다. 원인 분석은 중요하지만, 사용자 영향이 계속되는 동안엔 복구와 완화가 먼저예요.

15. Graceful Degradation 설계

Graceful Degradation은 일부 기능이 실패해도 전체 서비스가 같이 죽지 않도록 설계하는 방식입니다. 한 군데 삐끗했다고 서비스 전체가 내려가면, 그건 설계가 장애를 증폭시키고 있는 거예요.

예시.

  • 추천 API 장애 → 기본 추천 목록 제공
  • 결제 부가기능 장애 → 핵심 결제만 유지
  • 외부 API 장애 → 캐시 데이터 사용
  • 검색 장애 → 인기상품 또는 최근 데이터 제공
  • 비핵심 기능을 feature flag로 차단
  • circuit breaker로 장애 전파 차단
  • timeout/retry 정책 적용

주의할 점은 retry를 무작정 늘리면 오히려 장애를 키운다는 겁니다. 죽어가는 서비스에 재시도 트래픽을 쏟아부으면 회복할 틈을 빼앗는 꼴이거든요. 이걸 retry storm이라고 부르는데, 한 번 겪으면 잊히지 않아요. 그래서 retry에는 timeout, backoff, circuit breaker, bulkhead 패턴이 세트로 따라붙어야 합니다.

비용과 업그레이드 관리

16. AWS 비용 3배 급증 대응

먼저 비용 증가를 서비스, 리전, 계정, 태그 기준으로 분해합니다. "비용이 올랐다"는 한 덩어리로는 아무것도 못 해요. 쪼개야 범인이 보입니다.

확인 순서.

  • Cost Explorer에서 서비스별 증가 항목
  • 리전별 비용 증가와 최근 생성된 리소스
  • Auto Scaling, NAT Gateway, 데이터 전송, 로그 저장 비용
  • 비정상 트래픽 또는 배치 작업 실패
  • 태그 미적용 리소스
  • 예산 알림과 Cost Anomaly Detection 설정

자주 발생하는 원인.

  • Auto Scaling 오작동
  • 대량 로그 적재
  • NAT Gateway/Data Transfer 비용 폭증
  • 잘못된 인스턴스 타입
  • 종료되지 않은 테스트 리소스
  • 배치 작업 재시도 루프

저는 운영에서 비용도 장애의 한 종류로 봅니다. 다만 일반 장애와 다른 점은, 비용은 알림이 없으면 청구서가 날아올 때까지 모른다는 거예요. 그래서 비용 알림, 예산 정책, 태그 정책, 리소스 TTL 정책이 없는 조직은 항상 한 박자 늦게 발견합니다. 재시도 루프 하나가 조용히 NAT Gateway 비용을 끌어올리고 있는데, 한 달 뒤에야 알아채는 식이죠.

17. Kubernetes 무중단 업그레이드

Kubernetes 업그레이드는 컨트롤 플레인, 노드, 애플리케이션 가용성을 한꺼번에 봐야 합니다. 어느 한 층만 보고 올리면 꼭 다른 층에서 터져요.

기본 절차.

  1. 현재-목표 버전 호환성과 API deprecation 확인
  2. 애드온 호환성 확인 (CNI, CSI, Ingress Controller, Monitoring Agent)
  3. 컨트롤 플레인 업그레이드
  4. 워커 노드를 순차적으로 cordon/drain
  5. 노드 업그레이드 후 uncordon
  6. PodDisruptionBudget으로 최소 가용성 보장
  7. readiness probe로 준비된 Pod만 트래픽 수신
  8. 주요 서비스 smoke test

특히 2번, API deprecation을 놓치면 업그레이드 후에 멀쩡하던 매니페스트가 갑자기 안 먹는 사태가 납니다. 그리고 6번 PDB는 양날의 검이에요. 잘못 설정하면 drain이 영영 안 끝나고 막히거나, 반대로 너무 느슨하면 업그레이드 도중 가용성이 깨집니다. OKD 환경에서 노드를 순차적으로 굴려본 사람은, 이 균형을 맞추는 게 생각보다 섬세한 작업이라는 걸 압니다.

실전에서 통하는 사고방식

DevOps/SRE 면접에서 좋은 답변은 명령어를 많이 아는 답변이 아닙니다. 문제를 레이어별로 쪼개고, 사용자 영향도를 먼저 판단하며, 최근 변경사항과 운영 리스크를 함께 보는 답변이에요.

프로덕션에서 살아남는 사고방식을 정리하면 이렇습니다.

  • 추측보다 증거를 먼저 본다
  • 원인 분석보다 영향 완화를 먼저 한다
  • 단일 컴포넌트가 아니라 요청 경로 전체를 본다
  • 배포, 인프라, 네트워크, 권한, 데이터 변경을 함께 본다
  • 장애가 끝난 뒤 재발 방지까지 설계한다

결국 이 면접은 지식 테스트가 아니라 운영 사고방식 테스트입니다. 실제 장애를 몇 번 정통으로 맞아본 사람은, 답변에서 순서와 근거와 리스크 통제 방식이 저절로 드러나더라고요. 외운 사람과 겪은 사람은 두세 마디만 들어도 갈립니다.

문제가 터졌을 때 어디서부터 보고, 무엇을 먼저 처리하며, 어떤 근거로 판단하는가. 코드를 짜던 자리에서도, 아키텍처를 그리던 자리에서도, 운영을 책임지던 자리에서도, 결국 프로덕션이 묻는 질문은 늘 같았어요. 그리고 그 질문에 몸으로 답할 수 있는 사람이, 새벽에 깨워도 믿고 맡길 수 있는 사람입니다.

#DevOps#SRE#면접#Kubernetes#프로덕션