:bulb: Ubuntu 서버에서 /etc/netplan/50-cloud-init.yaml이 cloud-init에 의해 자동 생성되는 환경일 때, 추가 NIC에 IP·게이트웨이·DNS를 영구적으로 설정하는 방법을 단계별로 정리한다. 환경: Ubuntu(netplan + cloud-init) + 여러 개의 NIC가 장착된 서버

[00] 문제 상황

기존에는 /etc/netplan/ 아래 yaml 파일을 작성하고 netplan apply만 하면 됐는데, 어느 순간부터 설정이 잘 안 먹거나 재부팅하면 사라지는 경우가 있다. 파일 상단을 보면 다음과 같은 주석이 있다.

1
2
3
4
5
# This file is generated from information provided by the datasource. Changes
# to it will not persist across an instance reboot. To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}

즉 이 파일은 cloud-init이 부팅 때마다 자동 생성한다. 직접 수정해도 재부팅 시 cloud-init이 덮어써서 날아갈 수 있다. 이 글에서는 cloud-init의 네트워크 관리를 끄고 netplan을 직접 관리하는 방법을 다룬다.

[01] (가장 중요) 설정할 인터페이스 이름부터 정확히 확인

설정 전에 실제 인터페이스 이름을 반드시 확인한다. 이름이 한 글자라도 틀리면 netplan apply가 적용되지 않는다. (예: ens801f0np0 vs ens810f0np0처럼 숫자 순서를 헷갈리기 쉽다.)

1
2
3
4
5
6
7
8
# 인터페이스 목록과 상태 (가장 간단)
ip -br link

# 하드웨어와 매핑해서 확인
sudo lshw -c network -short

# PCI 디바이스로 확인
lspci | grep -i ethernet

ip -br link 출력 예시:

1
2
3
4
lo               UNKNOWN        00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
ens259f0         UP             aa:bb:cc:00:11:01 <BROADCAST,MULTICAST,UP,LOWER_UP>
ens801f0np0      DOWN           aa:bb:cc:00:11:0a <BROADCAST,MULTICAST>
ens801f1np1      DOWN           aa:bb:cc:00:11:0b <BROADCAST,MULTICAST>

여기서 새로 설정할 인터페이스를 이름과 MAC 주소로 특정해 둔다. 이 글에서는 ens801f0np0(현재 DOWN 상태인 추가 NIC)을 설정한다고 가정한다.

:warning: ens259f0처럼 이미 UP 상태이고 SSH가 그 인터페이스로 들어오고 있다면 그 인터페이스 설정은 건드리지 않는다. 잘못 건드리면 접속이 끊긴다.

[02] 현재 netplan 상태 확인

1
2
ls /etc/netplan/
cat /etc/netplan/50-cloud-init.yaml

자동 생성된 50-cloud-init.yaml 예시(개인정보 치환):

1
2
3
4
5
6
7
8
9
10
11
12
13
network:
    ethernets:
        ens259f0:
            addresses:
            - 192.168.0.108/24
            nameservers:
                addresses:
                - 192.168.0.10
                search: []
            routes:
            -   to: default
                via: 192.168.0.1
    version: 2

이 파일 안에는 현재 관리용 인터페이스 ens259f0의 설정이 들어 있다. 이 점을 기억해 둔다(뒤의 [05]에서 중요).

[03] cloud-init 네트워크 관리 끄기

파일 상단 주석이 알려준 그대로, cloud-init이 더 이상 netplan을 건드리지 못하게 막는다.

1
2
3
sudo tee /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg <<'EOF'
network: {config: disabled}
EOF

:bulb: 이 작업은 파일을 삭제하는 게 아니라 비활성화 설정 파일을 하나 추가하는 것이다. 이걸 해두면 재부팅해도 cloud-init이 50-cloud-init.yaml을 다시 생성/덮어쓰지 않는다.

[04] netplan yaml 작성

기존 파일을 직접 고치기보다 별도 파일을 만드는 것을 권장한다. netplan은 /etc/netplan/ 안의 모든 .yaml파일명 숫자 순서로 병합하므로, 새 인터페이스만 따로 적으면 된다.

1
sudo vim /etc/netplan/60-custom.yaml

내용(값은 본인 환경에 맞게 수정):

1
2
3
4
5
6
7
8
9
10
11
12
# 60-custom.yaml: 추가 NIC(ens801f0np0) 고정 IP 설정 | 생성일: 2026-06-11
network:
  version: 2
  ethernets:
    ens801f0np0:                   # ← [01]에서 확인한 정확한 이름
      addresses:
        - 192.168.10.50/24         # 원하는 IP/프리픽스 길이
      nameservers:
        addresses: [8.8.8.8, 1.1.1.1]
      routes:
        - to: default
          via: 192.168.10.1        # 게이트웨이

default route(기본 게이트웨이)는 보통 하나만

:warning: 기본 게이트웨이(to: default)는 인터페이스 한 곳에만 두는 것이 안전하다. 이미 ens259f0에 default route가 있는데 ens801f0np0에도 default를 주면 라우팅이 꼬일 수 있다.

추가 NIC를 특정 대역 통신 전용으로만 쓸 거라면 default 대신 특정 라우트만 준다.

1
2
3
4
5
6
    ens801f0np0:
      addresses:
        - 192.168.10.50/24
      routes:
        - to: 192.168.20.0/24      # 이 대역만 이 NIC로
          via: 192.168.10.1

굳이 두 인터페이스 모두 default가 필요하면 metric으로 우선순위를 구분한다(숫자가 작을수록 우선).

1
2
3
4
      routes:
        - to: default
          via: 192.168.10.1
          metric: 200

[05] (핵심) 기존 50-cloud-init.yaml은 삭제해야 하나? — 3가지 선택지

cloud-init을 껐으니 기존 파일을 지워도 되는지 헷갈린다. 그냥 삭제하면 안 된다. 그 안에는 현재 관리망(ens259f0)의 IP/게이트웨이/DNS가 들어 있어서, 무턱대고 지우면 netplan apply 순간 SSH가 끊겨 서버에 접속하지 못할 수 있다. 상황에 맞춰 아래 셋 중 하나를 고른다.

선택지 1 — 기존 파일은 그대로 두고 새 파일만 추가 (가장 안전 ✅, 원격 서버 권장)

1
2
3
/etc/netplan/
├── 50-cloud-init.yaml      ← 그대로 둠 (ens259f0 관리망 설정 유지)
└── 60-custom.yaml          ← ens801f0np0 만 새로 추가

netplan이 두 파일을 병합하므로 기존 관리망은 전혀 안 건드린다. 접속이 끊길 위험이 없어 원격 서버라면 이 방법을 추천한다. [03]에서 cloud-init을 비활성화했으므로 재부팅해도 50-cloud-init.yaml이 덮어써지지 않는다.

선택지 2 — 하나로 통합하고 기존 파일 삭제 (정리 우선)

설정 파일을 한 곳으로 모으고 싶다면, 기존 ens259f0 설정을 새 파일로 옮겨 적은 뒤에 기존 파일을 지운다. 순서가 중요하다.

1
2
3
4
5
# 1) 먼저 백업
sudo cp /etc/netplan/50-cloud-init.yaml /root/50-cloud-init.yaml.bak

# 2) 새 파일에 ens259f0 + ens801f0np0 둘 다 작성
sudo vim /etc/netplan/60-custom.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 60-custom.yaml: 전체 NIC 고정 IP 통합 설정 | 생성일: 2026-06-11
network:
  version: 2
  ethernets:
    ens259f0:                      # 기존 관리망 — 50-cloud-init.yaml에서 그대로 옮김
      addresses:
        - 192.168.0.108/24
      nameservers:
        addresses: [192.168.0.10]
      routes:
        - to: default
          via: 192.168.0.1
    ens801f0np0:                   # 새로 추가하는 NIC
      addresses:
        - 192.168.10.50/24
      nameservers:
        addresses: [8.8.8.8, 1.1.1.1]
      routes:
        - to: 192.168.20.0/24
          via: 192.168.10.1
1
2
# 3) 두 인터페이스 설정이 새 파일에 모두 들어간 것을 확인한 뒤에만 기존 파일 삭제
sudo rm /etc/netplan/50-cloud-init.yaml

선택지 3 — 삭제 대신 확장자만 바꿔 비활성화 (가장 되돌리기 쉬움)

netplan은 .yaml 확장자가 아닌 파일은 무시한다. 그래서 삭제 대신 이름만 바꿔 비활성화할 수도 있다.

1
sudo mv /etc/netplan/50-cloud-init.yaml /etc/netplan/50-cloud-init.yaml.disabled

문제가 생기면 다시 .yaml로 되돌리기만 하면 원상복구된다. 통합 파일([선택지 2]의 60-custom.yaml)을 함께 둔 상태에서 안전하게 정리할 때 유용하다.

선택지 기존 파일 추천 상황 위험도
1. 새 파일만 추가 그대로 둠 원격 서버, 관리망 안 건드리고 싶을 때 가장 낮음
2. 통합 후 삭제 옮겨 적고 삭제 설정을 한 파일로 정리하고 싶을 때 중간(순서 주의)
3. 확장자 변경 .disabled로 비활성화 삭제는 부담되고 되돌릴 여지를 남기고 싶을 때 낮음

[06] 권한 설정 및 문법 검증

netplan은 yaml 파일 권한이 느슨하면 경고를 낸다. 소유자만 읽도록 권한을 좁힌다.

1
2
sudo chmod 600 /etc/netplan/60-custom.yaml
sudo netplan generate          # 문법 검증 (오류 있으면 여기서 출력)

[07] 안전하게 적용 — netplan try

원격 서버에서는 netplan apply보다 netplan try를 먼저 쓴다. 설정을 적용한 뒤 일정 시간(기본 120초) 안에 Enter를 누르지 않으면 자동으로 이전 설정으로 롤백한다. 잘못 설정해서 SSH가 끊겨도 스스로 복구되므로 안전하다.

1
2
sudo netplan try
# 화면 지시에 따라, 접속이 유지되면 Enter로 확정

정상 동작을 확인했다면 적용한다.

1
sudo netplan apply

[08] 적용 결과 확인

1
2
3
4
5
6
7
8
9
10
11
# IP가 붙었는지
ip -br addr show ens801f0np0

# 라우트/게이트웨이 확인
ip route

# DNS 확인
resolvectl status ens801f0np0

# 게이트웨이까지 연결되는지
ping -c2 192.168.10.1

ip -br addr에서 인터페이스가 UP 상태이고 지정한 IP가 보이면 성공이다.

[09] 트러블슈팅

증상 점검 포인트
설정이 적용 안 됨 인터페이스 이름 오타 확인([01]), netplan generate에서 yaml 문법/들여쓰기 오류 확인
재부팅하면 사라짐 99-disable-network-config.cfg로 cloud-init을 껐는지 확인([03])
인터페이스가 계속 DOWN 케이블/트랜시버 연결, ip link set ens801f0np0 up, 링크 파트너(스위치 포트) 상태 확인
인터넷이 안 됨 default route가 엉뚱한 NIC에 잡혔는지 ip route로 확인, 게이트웨이 IP가 같은 서브넷인지 확인
DNS만 안 됨 nameservers.addresses 값 확인, resolvectl status로 실제 적용 DNS 확인
apply 후 SSH 끊김 콘솔로 접속해 백업 파일 복구, 이후엔 netplan try로 작업
권한 경고 chmod 600으로 yaml 권한 좁히기([06])

[10] 요약

단계 작업 내용
STEP 01 확인 ip -br link로 설정할 인터페이스 정확한 이름 확정
STEP 03 cloud-init 99-disable-network-config.cfg 생성해 자동 생성 끄기
STEP 04 netplan 별도 yaml에 IP/게이트웨이/DNS 작성 (default route는 하나만)
STEP 05 기존 파일 추가 / 통합 후 삭제 / 확장자 변경 중 선택 (원격은 추가 권장)
STEP 06 검증 chmod 600 + netplan generate로 문법 확인
STEP 07 적용 netplan try로 안전 적용 후 netplan apply
STEP 08 확인 ip -br addr / ip route / resolvectl / ping로 검증