VyOS로 MySQL DB망을 분리하며 Route와 NAT를 구분한 과정
VyOS로 DB 전용망을 분리하며 Live ISO 영속성, 버전별 NAT 문법, Route는 정상인데 외부 통신이 실패한 원인을 해결한 과정을 정리했다.
프로젝트 기간: 2026-08-18 ~ 2026-09-02
글 범위: VyOS Routing·NAT 기반 MySQL DB망 분리
MySQL Primary와 Replica를 service network에서 분리하기 위해 VyOS router를 추가했다. DB server는 private network에만 연결하고, Swarm worker와 monitoring server가 필요한 traffic만 router를 통해 접근하도록 만들었다.
구조는 단순해 보였다.
Service network
→ VyOS eth0
→ VyOS eth1
→ DB private network
├─ MySQL Primary
└─ MySQL Replica
하지만 실제 구축에서는 route, NAT, interface 문법, 영속 설치를 각각 구분해야 했다.
VMware network를 두 개로 나눴다
VyOS VM에는 network adapter를 두 개 연결했다.
- WAN 역할 adapter: 기존 service network
- LAN 역할 adapter: VMware Host-only DB network
DB1과 DB2에도 두 번째 adapter를 추가해 DB network에 연결했다. 전환 검증이 끝난 뒤 기존 service network adapter는 Connected를 해제했다. MySQL을 두 network address에 동시에 listen시키는 방법도 있었지만, 그렇게 하면 DB망 분리의 의미가 약해진다.
DB server의 default gateway는 VyOS의 DB-side address로 바꿨다. monitoring server에는 DB subnet으로 가는 static route를 추가했다. application worker도 service network에서 VyOS를 통해 DB endpoint에 접근한다.
첫 번째 문제: 설정이 재부팅 후 사라질 수 있었다
VyOS에서 interface와 route를 설정하는 도중 다음 경고를 봤다.
WARNING: You are currently configuring a live-ISO environment,
changes will not persist until installed
ISO로 부팅한 live environment에서 작업하고 있었기 때문이다. 이 상태의 commit은 현재 runtime에는 반영되지만 disk에 설치된 system 설정이 아니다.
나는 install image로 local disk에 VyOS를 설치하고 현재 config.boot를 복사했다. VM을 종료한 뒤 VMware에서 ISO 연결을 해제하고 disk boot를 우선했다. 재부팅 후 show version, interface, route와 configuration을 다시 확인했다.
이 경험 이후 network appliance는 “현재 ping이 된다”보다 “재부팅 후 같은 설정으로 올라온다”까지 검증해야 완료로 보게 됐다.
두 번째 문제: VyOS 버전별 NAT 문법이 달랐다
Source NAT rule을 만들면서 다음 문법이 거부됐다.
set nat source rule 100 outbound-interface name 'eth0'
Configuration path ... is not valid
사용 중인 VyOS 1.3.5에서는 outbound-interface name eth0가 아니라 outbound-interface eth0 형식을 사용해야 했다. 문서나 예제가 어느 version 기준인지 확인하지 않고 그대로 적용한 것이 원인이었다.
문법을 수정한 뒤에도 commit이 실패했다.
Source NAT configuration error in rule 10:
outbound-interface not specified
Masquerade rule에는 interface를 넣었지만 NO-NAT exclude rule에는 빠져 있었다. 이 version에서는 exclude rule에도 outbound interface가 필요했다.
최종 원칙은 다음과 같다.
Rule 10
source: DB private network
destination: internal service network
outbound: service interface
action: exclude
Rule 100
source: DB private network
outbound: service interface
translation: masquerade
내부 service traffic은 DB 원래 source address를 보존하고, internet 방향 traffic만 VyOS address로 변환한다.
Route가 정상인데 internet ping은 실패했다
DB2에서 ip route get 결과는 VyOS를 gateway로 선택하고 있었다. DB에서 VyOS의 LAN interface까지 ping도 됐다. 하지만 외부 address로 source를 지정한 ping은 응답이 없었다.
처음에는 upstream gateway나 VMware Host-only network를 의심했다. 실제 원인은 앞 단계 NAT rule의 commit 실패였다. DB와 VyOS 양쪽 default route는 존재했지만 private source address를 upstream에서 응답 가능한 address로 바꾸는 source NAT가 적용되지 않았다.
Route와 NAT의 역할을 나누면 원인이 명확해진다.
- Route: packet을 어느 next hop으로 보낼지 결정한다.
- Source NAT: return traffic이 돌아올 수 있도록 source address를 변환한다.
commit이 실패한 상태에서 실행한 save는 실패한 변경을 저장하지 않는다. 나는 rule을 수정해 commit 성공을 확인한 뒤 save하고, 다음 순서로 다시 점검했다.
1. DB interface와 address
2. DB default route
3. DB → VyOS LAN reachability
4. VyOS interface와 default route
5. VyOS ARP
6. source NAT rules와 counters
7. 외부 IP 통신
8. DNS name resolution
내부 traffic에 NO-NAT를 둔 이유
DB traffic까지 모두 masquerade하면 MySQL에는 모든 connection이 VyOS에서 오는 것처럼 보일 수 있다. 그러면 application worker별 account Host 제한과 monitoring source 구분이 어려워진다.
그래서 internal service network 목적지는 NAT하지 않고 route만 적용했다. MySQL은 실제 client source를 보고 허용 여부를 판단한다. 외부 package update처럼 internet으로 나가는 traffic만 masquerade한다.
DB network 전환 뒤 listener를 하나로 줄였다
망분리 직후에는 관리 편의를 위해 기존 service address listener를 남길지 고민했다. 결론은 private address 하나만 listen하는 것이었다.
MySQL listener → DB private address only
Replication source → DB private address
Exporter → DB private address
Backup NFS access → DB private route
Administrator → Tailscale or controlled jump path
운영체제 firewall은 모든 구성 완료 뒤 한 번에 적용하기로 했지만, listener와 MySQL account Host를 먼저 제한했다. 방화벽 하나만 보안 경계로 기대하지 않고 application 설정에서도 범위를 줄인 것이다.
이 작업에서 얻은 교훈
network 장애를 “ping이 안 된다”로 묶으면 해결이 늦어진다. interface, route, NAT/return route, service listener, access policy를 순서대로 나눠야 한다.
VyOS 구축에서는 version에 맞는 syntax와 live ISO 여부도 중요했다. 현재 설정이 동작하는 것과 재부팅 뒤 영속되는 것은 다른 검증이다. 최종적으로 DB server를 service network에서 분리하고도 replication, monitoring, backup과 package update 경로를 유지할 수 있었다.