홈

© 2026 Ki Chang. All rights reserved.

본 블로그의 콘텐츠는 CC BY-NC-SA 4.0 라이선스를 따릅니다.

소개JSON Formatter개인정보처리방침이용약관

© 2026 Ki Chang. All rights reserved.

콘텐츠: CC BY-NC-SA 4.0

소개|JSON Formatter|개인정보처리방침|이용약관

Docker가 내 DB 서브넷을 점유하고 있었다 — OCI 네트워크 충돌 삽질기

정기창·2026년 2월 10일

이전 글에서 이어지는 이야기

1부에서 Tailscale을 통해 OCI Compute Instance에 접속하는 것까지 성공했습니다. 이제 Compute에서 HeatWave MySQL 프라이빗 IP로 SSH 터널만 열면 되는 상황이었습니다. 간단할 줄 알았습니다.

증상: No route to host

Compute Instance에 SSH 접속한 뒤, HeatWave 프라이빗 IP로 연결을 시도했습니다.

nc -zv 10.0.1.210 3306
nc: connect to 10.0.1.210 port 3306 (tcp) failed: No route to host

같은 VCN 안에 있는데 No route to host라니. 처음에는 Security List 문제를 의심했습니다.

Security List는 문제가 아니었다

OCI 콘솔에서 확인해보니, HeatWave가 있는 프라이빗 서브넷의 Security List에 3306 포트 Ingress 규칙이 이미 있었습니다. Source CIDR도 10.0.0.0/16으로 VCN 내 모든 트래픽을 허용하고 있었습니다.

SourceProtocolDest Port설명
10.0.0.0/16TCP22SSH
10.0.0.0/16TCP3306MySQL

네트워크 구성도 확인했습니다. Compute와 HeatWave는 같은 VCN(vcn-coolify)에 있고, 서브넷만 다릅니다.

  • Compute: public subnet (10.0.0.0/24), Private IP: 10.0.0.88
  • HeatWave: private subnet (10.0.1.0/24), Private IP: 10.0.1.210

같은 VCN 내 서브넷 간 통신은 기본적으로 가능합니다. Security List도 열려 있습니다. 그런데 왜 No route to host인가?

원인 발견: ip route

라우팅 테이블을 확인하는 순간 원인이 보였습니다.

ip route | grep 10.0.1
10.0.1.0/24 dev docker0 proto kernel scope link src 10.0.1.1

Docker가 10.0.1.0/24 대역을 docker0 브리지 네트워크로 사용하고 있었습니다. HeatWave 프라이빗 서브넷과 정확히 같은 대역입니다.

무슨 일이 벌어지고 있었나

리눅스에서 패킷을 보낼 때는 라우팅 테이블을 위에서부터 매칭합니다.

10.0.1.0/24 dev docker0    ← "10.0.1.x는 docker0로 보내라" (먼저 매칭)
10.0.0.0/24 dev eth0       ← "10.0.0.x는 eth0로 보내라"

10.0.1.210으로 패킷을 보내면, OCI VCN 라우터로 나가야 하는데 Docker가 같은 대역을 선점해서 docker0 브리지로 보내버립니다. Docker 내부에는 당연히 10.0.1.210이라는 호스트가 없으므로 No route to host가 발생한 것입니다.

# 기대한 경로
Compute → eth0 → OCI VCN 라우터 → private subnet → HeatWave (10.0.1.210)

# 실제 경로
Compute → docker0 → Docker 내부 → 없는 주소 → 실패

근본 원인: daemon.json 설정

Docker 데몬 설정 파일을 열어보니 원인이 명확했습니다.

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "default-address-pools": [
    {"base": "10.0.0.0/8", "size": 24}
  ]
}

default-address-pools의 base가 10.0.0.0/8로 설정되어 있었습니다. Docker가 새 네트워크를 생성할 때 10.x.x.x 전체 대역에서 /24 단위로 서브넷을 할당한다는 뜻입니다. Coolify를 설치할 때 이렇게 설정된 것으로 보입니다.

실제로 Docker 네트워크를 확인해보면:

  • bridge 네트워크: 10.0.1.0/24 (HeatWave 서브넷과 충돌)
  • coolify 네트워크: 10.0.2.0/24

해결: Docker 네트워크 대역 변경

OCI VCN과 충돌하지 않는 대역으로 변경해야 했습니다. 172.20.0.0/14를 선택했습니다.

다만 이 작업은 단순히 설정 파일을 바꾸고 Docker를 재시작하는 것만으로 끝나지 않았습니다.

시행착오 1: 기존 컨테이너가 이전 네트워크를 참조

daemon.json을 수정하고 Docker를 재시작한 뒤, 기존 컨테이너를 시작하려 했더니:

Error response from daemon: network 7bd7cd2db781... not found

기존 coolify 네트워크가 network prune으로 삭제되었는데, 컨테이너들은 여전히 이전 네트워크 ID를 참조하고 있었습니다. 새로 coolify 네트워크를 만들어도 ID가 다르니 연결할 수 없었습니다.

시행착오 2: Coolify 재설치

컨테이너별로 네트워크를 수동 연결하는 것보다 Coolify를 재설치하는 것이 깔끔했습니다.

# 기존 컨테이너 전부 삭제
sudo docker rm -f $(sudo docker ps -a -q)

# 네트워크 정리
sudo docker network prune -f

# Coolify 재설치
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | sudo bash

다행히 docker rm -f는 컨테이너만 삭제하고 볼륨은 삭제하지 않습니다. Coolify의 PostgreSQL 데이터가 볼륨에 남아있어서 재설치 후 기존 프로젝트 설정이 자동으로 복원되었습니다. 백업을 해두긴 했지만 사용할 필요가 없었습니다.

결과 확인

# 네트워크 대역 확인
sudo docker network inspect bridge --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
# 172.20.0.0/24 ✅

sudo docker network inspect coolify --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
# 172.20.1.0/24 ✅

# HeatWave 연결 테스트
nc -zv 10.0.1.210 3306
# Connection to 10.0.1.210 3306 port [tcp/mysql] succeeded! ✅

전체 해결 과정 요약

  1. Coolify 백업 (Settings → Backup → Backup Now)
  2. 모든 컨테이너 중지 및 삭제
  3. Docker 네트워크 정리 (docker network prune -f)
  4. daemon.json 수정 (10.0.0.0/8 → 172.20.0.0/14)
  5. Docker 재시작 (systemctl restart docker)
  6. Coolify 재설치 (볼륨 유지로 설정 자동 복구)
  7. 배포된 서비스 Redeploy

교훈

돌이켜 생각해보면 Docker의 default-address-pools를 10.0.0.0/8처럼 넓은 대역으로 설정하는 것은 클라우드 환경에서 위험합니다. OCI, AWS, GCP 모두 10.x.x.x 대역을 VPC/VCN 내부 네트워크로 사용하기 때문입니다.

Docker 네트워크는 172.16.0.0/12이나 192.168.0.0/16 같은 클라우드 VPC와 겹치지 않는 사설 대역을 사용하는 것이 안전합니다. 특히 Coolify처럼 Docker 위에서 동작하는 PaaS를 클라우드 인스턴스에서 운영한다면, 설치 시점에 네트워크 대역을 의식적으로 설정해둘 필요가 있습니다.

No route to host 에러를 보고 Security List만 확인했다면 한참 헤맸을 겁니다. ip route 한 줄이 문제의 핵심을 보여줬습니다.

DockerOCI네트워크Coolify트러블슈팅MySQL

관련 글

OCI MySQL HeatWave, Bastion 없이 Tailscale로 접속하기

Oracle Cloud MySQL HeatWave는 프라이빗 서브넷에만 배치되어 외부 접속이 번거롭습니다. Bastion Service 대신 Tailscale을 활용해 간편하게 접속하는 방법을 정리했습니다.

관련도 91%

Tailscale로 Coolify 대시보드 보안 강화하기: 오라클 클라우드에서의 설정 경험

Coolify 대시보드가 공인 IP로 열려 있는 보안 문제를 Tailscale 메시 VPN으로 해결한 경험. 오라클 클라우드에서의 설정 과정과 IP 제한의 한계를 넘는 방법을 정리했습니다.

관련도 90%

macOS에서 OCI HeatWave MySQL 접속하기: Bastion SSH 터널 설정 가이드

Oracle Cloud HeatWave MySQL에 로컬에서 접속하기 위한 OCI CLI 설정과 Bastion SSH 터널 구성 과정을 정리했습니다. API 키 등록부터 터널 스크립트 작성, 트러블슈팅까지 전체 흐름을 다룹니다.

관련도 90%