홈으로 돌아가기

Docker와 OpenStack의 MTU 불일치: CI/CD 실패를 수정하는 방법

이 기사는 Docker 컨테이너와 OpenStack 오버레이 네트워크 간 MTU 불일치가 CI/CD 파이프라인 실패로 이어지는 방법을 설명합니다. 진단 방법, 단계별 문제 해결, 재발 방지를 위한 모범 사례를 제시합니다.

빌드 실패? Docker의 MTU 불일치가 원인일 수 있습니다
Advertisement 728x90

# Docker와 OpenStack의 MTU 불일치가 CI/CD를 망치는 이유: 진단과 해결

금요일 밤 빌드 실패는 보통 단순한 일시적 오류가 아닙니다. Docker 컨테이너와 OpenStack 오버레이 네트워크 간 MTU 불일치가 원인인 경우가 많아요. 이 문제는 대용량 데이터 전송(예: 리포지토리 클론)에서만 발생하고, 작은 요청은 문제없이 통과합니다. 실제 워크로드가 돌기 전까지 네트워크가 정상인 줄 착각하게 만드는 교묘한 문제죠.

작은 요청은 통과되는데 큰 요청은 왜 실패할까?

이 문제의 특징은 선택성입니다. curl -Iping처럼 작은 패킷을 보내는 명령은 항상 성공합니다. 문제는 대용량 데이터가 필요한 작업에서 시작되죠: git clone, docker pull, 아티팩트 다운로드 등. 원인은 최대 전송 단위(MTU)—분할 없이 전송할 수 있는 가장 큰 IP 패킷 크기입니다.

일반 이더넷 네트워크는 MTU 1500바이트를 사용합니다. 하지만 OpenStack 같은 클라우드 환경에서는 VXLAN이나 GRE 같은 오버레이 기술이 각 패킷을 약 50바이트의 오버헤드로 감싸서 격리된 네트워크를 만듭니다. 물리 네트워크가 1500을 처리할 수 있어도 VM 패킷은 1450바이트만 남아요.

Google AdInline article slot

Docker는 기본 브리지 네트워크에서 MTU 1500을 사용하며 인프라 특성을 무시합니다. 컨테이너는 이 규격으로 패킷을 만들고, 호스트의 1450 MTU 인터페이스에 도달하면 DF(Don't Fragment) 플래그 때문에 전송이 막힙니다. 이상적으로는 Path MTU Discovery가 작동해야 하지만, 방화벽, 보안 그룹, 또는 불안정한 라우터가 "Fragmentation Needed" ICMP 메시지를 차단하는 경우가 많아요.

30초 만에 문제 진단하기

이 세 명령어로 MTU 불일치를 확인하세요:

  • 호스트 네트워크 인터페이스 MTU 확인:

```

Google AdInline article slot

ip link show ens3 | grep mtu

```

OpenStack에서는 mtu 1450이 나와야 합니다.

Google AdInline article slot
  • 컨테이너 내부 MTU 확인:

```

docker run --rm alpine ip link show eth0 | grep mtu

```

Docker 기본값은 mtu 1500. 호스트보다 크면 문제가 맞아요.

  • 분할 차단 핑 테스트 실행:

```

docker run --rm alpine ping -s 1422 -M do -c 3 gitlab.example.com

docker run --rm alpine ping -s 1423 -M do -c 3 gitlab.example.com

```

첫 번째(1422 = 1450 − 28)는 성공, 두 번째는 Message too long 오류가 나야 합니다.

단계별 해결 방법

Docker에서 MTU 설정하기

핵심 해결책: Docker가 올바른 MTU를 사용하도록 설정하세요. /etc/docker/daemon.json 편집:

{
  "mtu": 1450
}

Docker 데몬 재시작:

sudo systemctl restart docker

기존 네트워크 처리하기

주의: daemon.json 변경은 새 네트워크에만 적용됩니다. 기존 네트워크(특히 Docker Compose)는 이전 MTU를 유지해요. 두 가지 선택지:

  • 모든 것 재생성:

```

docker compose down && docker compose up -d

```

  • Docker Compose에서 MTU 명시적 설정:

```yaml

networks:

app-net:

driver: bridge

driver_opts:

com.docker.network.driver.mtu: 1450

```

최종 확인

GitLab Runner 재시작 후 테스트:

sudo gitlab-runner restart
docker run --rm alpine ping -s 1422 -M do -c 3 gitlab.example.com

테스트가 통과하면 완료!

흔한 실수와 모범 사례

  • "만약을 위해" MTU를 너무 낮추지 마세요. 1300으로 내리면 추가 패킷으로 인해 처리량이 10-15% 떨어집니다. 정확히 진단된 값만 사용하세요.
  • 자동화하세요. 인프라 설정(Terraform, Ansible, cloud-init)에 MTU를 내장—수동 조정 금지.
  • 커스텀 네트워크 주의. daemon.json은 기존 네트워크를 건너뜁니다. docker network inspect로 확인.
  • Path MTU Discovery에 기대 말기. 클라우드 환경에서 ICMP 차단으로 고장 납니다.

핵심 요약

  • MTU 불일치는 대용량 전송에서만 발생해 발견이 어려움.
  • OpenStack 오버레이는 헤더로 MTU 50바이트 소모.
  • Docker 기본 1500은 클라우드에서 충돌.
  • 해결: Docker MTU를 호스트 인터페이스에 맞춤.
  • 배포 파이프라인에서 설정 자동화.

— Editorial Team

Advertisement 728x90

다음 읽기