Ubuntu 정적 IP 전환과 Swarm 주소 변경에서 배운 것
nmtui에서 NIC가 보이지 않았던 원인부터 서버별 인터페이스 이름, Swarm quorum을 유지한 정적 IP 전환 절차까지 기록했다.
프로젝트 기간: 2026-08-18 ~ 2026-09-02
글 범위: Ubuntu Netplan과 Docker Swarm 주소 전환 트러블슈팅
MeetBack 서버의 주소를 역할에 맞게 정리하면서 처음 부딪힌 문제는 nmtui에 물리 NIC가 보이지 않는 현상이었다. NetworkManager를 설치했고 명령도 실행됐지만, interface 목록에는 unmanaged만 표시됐다.
처음에는 package 설치가 잘못됐거나 VMware adapter가 인식되지 않은 것으로 의심했다. 하지만 systemd-networkd는 active였고 networkctl status에서는 interface와 DHCP address, gateway가 정상적으로 보였다.
NetworkManager를 설치해도 관리 주체가 바뀌지 않았다
원인은 Ubuntu Server의 실제 network backend가 Netplan의 renderer: networkd였기 때문이다.
network:
version: 2
renderer: networkd
NetworkManager package를 추가했다고 기존 interface 관리권이 자동으로 넘어오는 것은 아니다. nmcli에서 unmanaged로 보인 것은 NIC 고장이 아니라 다른 backend가 관리하고 있다는 뜻이었다.
나는 NetworkManager를 제거하고 Netplan + systemd-networkd로 통일했다. 운영 도구가 둘이면 같은 interface를 서로 다른 방식으로 해석할 수 있고, 나중에 누가 어느 설정을 바꿔야 하는지 불분명해진다.
확인 순서도 다음처럼 고정했다.
systemctl is-active systemd-networkd
networkctl status <interface> --no-pager
ip -br link
ip -br -4 addr
ip route
모든 서버가 같은 NIC 이름을 쓰지 않았다
두 번째 문제는 interface 이름이었다. 일부 VM은 ens33을 사용했지만, 물리 서버와 다른 VM에서는 eno1, eno4 같은 이름이 사용됐다. 공통 Netplan 파일에서 ens33을 가정하면 해당 interface가 없는 서버에서는 설정이 적용되지 않는다.
나는 각 host에서 hostname, interface, MAC address, current IP와 route를 먼저 수집했다. 그 뒤 서버별 실제 이름을 반영한 Netplan을 작성했다.
network:
version: 2
renderer: networkd
ethernets:
<actual-interface>:
dhcp4: false
addresses:
- <service-address>/<prefix>
routes:
- to: default
via: <gateway>
nameservers:
addresses:
- <dns-1>
- <dns-2>
원격 SSH에서 network를 바꾸는 작업은 연결을 스스로 끊을 수 있다. 가능하면 VMware console이나 out-of-band 경로를 열어 두고 netplan generate로 syntax를 확인한 뒤 netplan try를 우선 사용했다. Tailscale도 관리 경로로 유지했지만, route 변경 중에는 그것만 믿지 않고 console 복구 수단을 함께 준비했다.
IP 변경은 OS 설정 하나로 끝나지 않았다
처음에는 정적 IP를 바꾸면 server 주소가 정리되는 것으로 생각하기 쉽다. 하지만 이 환경에서 IP는 여러 시스템의 식별자로 사용됐다.
- Docker Swarm node advertise address
- Prometheus scrape target
- NFS export client address
- MySQL account Host 제한
- MySQL replication source host
- VyOS route와 NAT source network
- SSH known_hosts와 운영 문서
따라서 Netplan만 바꾼 뒤 다음 서버로 넘어가면 cluster나 access policy가 이전 주소를 계속 참조할 수 있다. 나는 host 하나의 주소 변경을 하나의 작은 migration으로 취급했다.
Manager 주소는 한 대씩 바꿨다
Swarm manager 3대는 Raft quorum을 유지해야 한다. 세 manager의 network를 동시에 바꾸면 control plane이 과반수를 잃을 수 있다.
변경 순서는 다음 원칙을 따랐다.
- 현재 leader와 manager 상태를 확인한다.
- 한 manager만 대상으로 network를 변경한다.
- 새 주소로 통신과 membership을 복구한다.
- manager가
Ready와Reachable상태인지 확인한다. - quorum이 정상인 것을 확인한 뒤 다음 manager로 넘어간다.
worker는 service 영향을 줄이기 위해 먼저 drain하고 주소 변경과 재가입을 진행했다. 재가입 시 advertise address와 필요하면 data path address를 새 주소로 명시했다.
docker node ls
docker node inspect self --pretty
docker info
중요한 점은 기존 node object와 새로 가입한 node가 중복으로 남지 않게 정리하는 것이다. 단순히 OS IP만 바꾸고 기다리는 방식보다 cluster state를 확인하며 재가입하는 편이 원인을 추적하기 쉬웠다.
DB망 전환은 더 큰 변경 단위였다
DB server는 service network에서 private DB network로 이동했다. 이때는 address뿐 아니라 MySQL listener, replication source, account Host, exporter, backup NFS export와 monitoring target을 함께 바꿔야 했다.
MySQL default 설정 파일에는 loopback bind가 남아 있었고, 별도 zz- 설정 파일이 뒤에서 private address로 덮어쓰는 형태였다. 파일 한 줄만 보고 판단하지 않고 runtime 값을 확인했다.
sudo ss -lntp '( sport = :3306 )'
sudo mysql -NBe "SHOW VARIABLES LIKE 'bind_address';"
최종적으로 DB server의 기존 service network NIC 연결을 제거하고 MySQL은 private address 하나에만 listen하도록 했다. 연결을 편하게 하려고 두 주소를 모두 listen시키면 network separation의 목적이 약해지기 때문이다.
이 과정에서 만든 점검 목록
주소를 바꾼 직후에는 ping 성공만 확인하지 않았다.
1. Link: interface가 UP인가
2. Address: 예상한 prefix와 source address인가
3. Route: default와 목적지 route가 맞는가
4. Gateway: 다음 hop까지 도달하는가
5. Port: 실제 service listener에 연결되는가
6. Application: cluster, replication, exporter가 새 주소를 읽는가
7. Monitoring: 이전 target이 남지 않았는가
이 순서를 사용하니 “network가 안 된다”는 큰 문제를 link, route, NAT, listener, policy 중 하나로 줄일 수 있었다.
트러블슈팅에서 얻은 교훈
nmtui에 NIC가 안 보였던 문제는 NetworkManager를 더 설치한다고 해결되는 문제가 아니었다. 어떤 backend가 실제로 관리하는지부터 확인해야 했다. interface 이름도 template보다 실측이 우선이었다.
그리고 IP 변경은 단순 OS 작업이 아니었다. 분산 cluster에서는 node identity이고, DB에서는 account policy이며, NFS에서는 export 권한이고, Prometheus에서는 label과 target이다. 이 영향 범위를 함께 변경하지 않으면 configuration drift가 장애로 돌아온다.