---
title: "OpenStack NIC 설정 최적화: 리눅스 브릿지와 VETH 페어를 활용한 효과적인 네트워크 구성 방법"
description: "OpenStack 환경에서 NIC가 OVS에 할당되면 외부 접근이 차단되는 문제를 해결하기 위해 물리 NIC를 리눅스 브릿지에 연결하고 VETH 페어를 이용해 OVS와 연결한다. 브릿지에 IP와 MTU 9000을 설정하고, 스크립트와 rc.local을 통해 부팅 시 자동 적용하도록 구성한다. 이를 통해 제한된 NIC로도 Management, Private Provider, Tenant 네트워크를 안정적으로 운영할 수 있다."
date: "2024-11-28"
last_modified: "2026-08-06T00:36:00.000Z"
type: "Post"
tags:
  - "networking"
  - "network"
  - "troubleshooting"
categories:
  - "🤖 Computer Science"
series:
  - "오픈스택 운영"
canonical_url: "https://blog.pieroot.xyz/openstack-nic-opt"
markdown_url: "https://blog.pieroot.xyz/openstack-nic-opt.md"
---

# OpenStack NIC 설정 최적화: 리눅스 브릿지와 VETH 페어를 활용한 효과적인 네트워크 구성 방법

OpenStack 환경에서 NIC가 OVS에 할당되면 외부 접근이 차단되는 문제를 해결하기 위해 물리 NIC를 리눅스 브릿지에 연결하고 VETH 페어를 이용해 OVS와 연결한다. 브릿지에 IP와 MTU 9000을 설정하고, 스크립트와 rc.local을 통해 부팅 시 자동 적용하도록 구성한다. 이를 통해 제한된 NIC로도 Management, Private Provider, Tenant 네트워크를 안정적으로 운영할 수 있다.

### 서론: 왜 리눅스 브릿지가 필요한가?

OpenStack을 구축할 때 네트워크 구성은 가장 복잡하면서도 중요한 부분입니다. 이상적인 환경에서는 각 네트워크 유형별로 전용 NIC를 할당하지만, 현실에서는 장비 제약으로 인해 충분한 NIC를 확보하기 어려운 경우가 많습니다.

#### OpenStack 네트워크 구성 요소

OpenStack은 다음과 같은 네트워크 구성이 필요합니다:

이론적으로 4개의 NIC가 필요하지만, 실제 환경에서는 3개 이하의 NIC만 사용 가능한 경우가 많습니다. 이 포스트에서는 **Management IP와 Private Provider IP를 동일한 대역(172.30.0.0/16)으로 구성**하여 한정된 NIC로 OpenStack을 운영하는 방법을 설명합니다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=57682116-114a-40c4-9b09-b4ce77953557&kind=s3&pageId=214067c0-15d0-805e-9568-c256a1d36c75&source=block&blockId=214067c0-15d0-80d4-9496-dc31133ecc6a)

---

### 문제 상황: OVS와 NIC 소유권

OpenStack에서 Provider나 Tenant 네트워크로 사용하는 인터페이스는 모두 **OpenvSwitch(OVS)**에 연결해야 합니다. 여기서 핵심적인 문제가 발생합니다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=f7a39973-fba1-4169-a2c9-be19bc450536&kind=s3&pageId=214067c0-15d0-805e-9568-c256a1d36c75&source=block&blockId=214067c0-15d0-8008-b1bf-ffe87027c0f1)

> **OVS가 NIC를 소유하면 어떤 일이 발생하나요?**
> 
> NIC에 OVS 브릿지를 연결하면 해당 NIC의 제어권이 OVS로 넘어갑니다. 이 상태에서는:
> 
> - 해당 NIC에 IP가 설정되어 있어도 **외부에서 접근이 불가능**합니다
> 
> - 패킷이 수신되어도 **시스템이 응답할 수 없습니다**
> 
> - 원격 SSH 접속 중이었다면 **즉시 연결이 끊깁니다**

즉, 원격으로 서버를 관리하던 중 OVS 설정을 하면 접속이 끊기고, 서버실에 직접 가서 복구해야 하는 상황이 발생할 수 있습니다.

---

### 해결 방법: 리눅스 브릿지 + VETH 페어

이 문제를 해결하기 위해 **리눅스 브릿지**와 **VETH(Virtual Ethernet) 페어**를 활용합니다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=99e62901-3cc8-413f-a123-30ab0a141cb6&kind=s3&pageId=214067c0-15d0-805e-9568-c256a1d36c75&source=block&blockId=214067c0-15d0-80cf-a5d4-c9b3adf4e28f)

#### 구성 단계별 설명

> **VETH 페어란?**
> 
> VETH(Virtual Ethernet)는 가상 이더넷 케이블이라고 생각하면 됩니다. 한쪽 끝(veth0)으로 들어간 패킷은 반드시 다른 쪽 끝(veth1)으로 나옵니다. 마치 **양쪽 끝이 서로 연결된 네트워크 케이블**처럼 동작합니다. 문어발 멀티탭을 떠올리면 이해하기 쉽습니다.

#### 왜 이 구성이 효과적인가?

1. **물리 NIC**는 리눅스 브릿지에 연결됩니다

1. **외부 통신용 IP**는 리눅스 브릿지에 할당됩니다

1. **VETH 페어**가 리눅스 브릿지와 OVS를 연결합니다

1. 결과적으로 **외부 통신과 OVS 연동이 모두 가능**해집니다

---

### 사전 준비: 인터페이스 구성 확인

스크립트를 실행하기 전에 현재 시스템의 네트워크 인터페이스 구성을 확인해야 합니다.

```bash
# 현재 인터페이스 목록 확인
ip link show

# 각 인터페이스의 IP 확인
ip addr show
```

이 포스트에서는 다음과 같은 인터페이스 구성을 가정합니다:

> **인터페이스 이름은 시스템마다 다릅니다**
> 
> `eno1`, `enp2s0` 등의 이름은 시스템에 따라 다를 수 있습니다. `ip link show` 명령으로 실제 인터페이스 이름을 확인하고 스크립트에 반영하세요.

---

### 스크립트: 원격 설정을 위한 자동화

이 스크립트를 만든 이유는 `eno2` 인터페이스로 원격 접속하여 관리 작업을 수행하는데, 리눅스 브릿지를 수동으로 설정하면 중간에 연결이 끊기기 때문입니다. 따라서 **처음부터 끝까지 자동으로 실행되는 스크립트**가 필요합니다.

> **스크립트 실행 전 확인 사항**
> 
> - 네트워크 설계가 충분히 완료되어야 합니다
> 
> - 어떤 인터페이스가 외부 통신을 담당하는지 정확히 파악해야 합니다
> 
> - **잘못 실행하면 서버 접속이 불가능**해질 수 있으니 신중히 진행하세요

```bash
#!/bin/bash
# 위 구문은 system 이 파일을 실행할때 어떤 실행기(명령어셋) 으로 동작할지 지정한다.
# 직접 실행할때에는 문제가 없지만 rc.local 로 시스템이 자동으로 실행할때에는 필수로 필요하다

# 브릿지가 가질 IP
INTER_IP="172.30.0.11/16"
# 브릿지가 연결될 물리 장치
PRIV_PORT="eno2"
TEN_PORT="eno1"
PUB_PORT="enp2s0"

BR_NAME="mybr0"
VETH0="veth0"
VETH1="veth1"
OVS_BR="br-vpn"

# 아래 함수는 아직까지는 별 이유 없습니다
cleanup() {
	echo "clean up "
	ip link set $VETH0 down
	ip link set $VETH1 down
	ip link delete $VETH0
	ip link delete $VEHT1
}

# 1. 리눅스 브릿지 생성 및 이름 부여 : mybr0
echo "Creating Linux bridge: mybr0"
brctl addbr $BR_NAME
# 리눅스 브릿지에 물리 장치 연결
brctl addif $BR_NAME $PRIV_PORT

# 2. 브릿지에 외부랑 통신할 IP 부여
echo "Assigning IP address ${INTER_IP} to mybr0"
ip addr add $INTER_IP dev $BR_NAME

# 브릿지의 상태를 up 으로 바꾸어 통신 시작
echo "Bringing up the bridge interface mybr0"
ip link set $BR_NAME up

# 3. ovs 와 통신을 연결해줄 Veth 를 생성 : veth0 and veth1
echo "Creating veth pair: veth0 and veth1"
ip link add $VETH0 type veth peer name $VETH1

# mybr0 브릿지에 Veth의 피어중 하나를 연결
echo "Attaching veth0 to bridge mybr0"
ip link set $VETH0 master $BR_NAME
ip link set $VETH0 up
# 지금 up 으로 바꾸어도 되지만 아래에서 상태를 바꾸기에 지금 할 필요 없음
#ip link set $VETH1 up

# 선택에 따라 다르지만 공인망과 tenant 망은 인터페이스에 ip 가 있을 이유가 없다.
ip addr flush $PUB_PORT
ip link set $PUB_PORT up
ip addr flush $TEN_PORT
ip link set $TEN_PORT up
# ip 설정을 다른 인터페이스에게 제공했기에 물리 인터페이스의 ip 설정을 해제한다.
ip addr flush $PRIV_PORT
ip link set $PRIV_PORT up
# ip 를 설정해도 외부랑 통신할 routing 테이블을 반영해야함. 라우팅 테이블 추가
ip route add default via 172.30.0.1

# ceph 의 성능 개선을 위해 mtu 값 조정 1500 -> 9000
ip link set dev $BR_NAME mtu 9000
ip link set dev $PRIV_PORT mtu 9000

# 4. (Optional) br-vpn에 반대쪽 피어를 연결, 만약 ovs 브릿지가 있다면 연결만 함
echo "Checking for OVS bridge br-vpn"
if ovs-vsctl br-exists $OVS_BR; then
	echo "Attaching veth1 to OVS bridge br-vpn"
	# 피어의 상태를 업으로 변경
	ip link set $VETH1 up
	# ovs 브릿지에 물리 인터페이스로 피어를 연결
	ovs-vsctl add-port $OVS_BR $VETH1
else
	# ovs 브릿지를 생성
	ovs-vsctl add-br $OVS_BR
	ip link set $VETH1 up
	ovs-vsctl add-port $OVS_BR $VETH1
	echo "OVS bridge br-vpn does not exist. Skipping attachment of veth1."
fi

# netplan 을 사용하지 않기에 dns 수동 등록 - system-resolved 에 등록
sudo sed -i '/^#DNS=/c\DNS=8.8.8.8' /etc/systemd/resolved.conf
sudo sed -i '/^#FallbackDNS=/c\FallbackDNS=8.8.4.4' /etc/systemd/resolved.conf

# system-resolved 설정 적용을 위해 반영
sudo systemctl restart systemd-resolved

echo "Setup complete."
```

위 스크립트를 사용하면 사용자가 로컬에서 작업하지 않더라도 한 번에 인터페이스를 설정하고 네트워크 연결까지 구성할 수 있습니다.

다만, 이 스크립트를 사용하기 위해서는 어떤 인터페이스가 외부와 통신하는지 정확히 알고 네트워크 설계가 충분히 이루어진 상태여야 합니다. 그렇지 않으면 정상적인 설정이 어려우므로, 충분한 계획 없이 섣불리 실행하는 것은 권장하지 않습니다.

---

### rc.local을 통한 부팅 시 자동 적용

위 스크립트를 시스템 부팅 시 자동으로 실행되도록 설정합니다. Linux에서 제공하는 **rc.local**을 사용합니다.

#### 적용 절차

**1단계: 스크립트 파일 생성**

Ubuntu 24.04 기준으로 `/etc/rc.local` 파일이 기본적으로 존재하지 않습니다. 직접 생성해야 합니다.

```bash
# vi 또는 nano 에디터로 파일 생성
sudo vi /etc/rc.local

# 위에서 작성한 스크립트 내용을 붙여넣기
```

**2단계: 실행 권한 부여**

```bash
sudo chmod +x /etc/rc.local
```

**3단계: rc-local 서비스 활성화**

```bash
sudo systemctl daemon-reload && sudo systemctl restart rc-local.service
```

> `rc-local.service`는 `/etc/rc.local` 파일이 없으면 기본적으로 비활성화 상태입니다. 파일을 생성하고 서비스를 재시작하면 자동으로 활성화됩니다.

**4단계: 적용 확인**

`ip a` 명령어로 인터페이스 정보를 확인합니다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=95a0b738-7864-4555-ab88-42021daab78f&kind=s3&pageId=214067c0-15d0-805e-9568-c256a1d36c75&source=block&blockId=2f8067c0-15d0-8035-934d-ca2d74be3dd6)

위 스크린샷처럼 `mybr0` 브릿지에 IP가 할당되고, `veth0`/`veth1` 페어가 생성된 것을 확인할 수 있습니다.

---

### 부팅 시 설정 유지 문제

위 과정을 통해 리눅스 브릿지 설정을 완료했지만, 한 가지 더 고려해야 할 사항이 있습니다.

일반적으로 **netplan**이나 **cloud-init**을 사용하면 부팅 시 자동으로 네트워크 설정이 적용되지만, VETH 페어와 리눅스 브릿지 조합은 해당 도구로 설정하기 어렵습니다. 따라서 위에서 설명한 **rc.local**을 통해 부팅 시 자동으로 스크립트가 실행되도록 구성합니다.

---

### 핵심 정리

이 포스트에서 다룬 OpenStack NIC 설정을 정리하면 다음과 같습니다:

✅ **문제**: OVS가 NIC를 소유하면 외부 통신이 불가능해지는 문제 발생

✅ **해결책**: 리눅스 브릿지에 IP를 할당하고 VETH 페어로 OVS와 연결

✅ **스크립트**: 원격 접속 중에도 연결 끊김 없이 설정 가능한 자동화 스크립트 제공

✅ **지속성**: rc.local을 통해 부팅 시 자동으로 설정 적용

✅ **MTU 최적화**: Ceph 등 대용량 트래픽을 위해 9000으로 설정

---

### 주의사항

> **운영 시 주의할 점**
> 
> - **네트워크 설계 선행**: 스크립트 실행 전 네트워크 구조를 충분히 이해하고 계획해야 합니다
> 
> - **로컬 접근 확보**: 잘못된 설정으로 원격 접속이 불가능해질 수 있으니, 콘솔 접근이 가능한 상태에서 테스트하세요
> 
> - **인터페이스 이름 확인**: `eno1`, `enp2s0` 등은 시스템마다 다르므로 반드시 확인 후 스크립트를 수정하세요
> 
> - **백업**: 변경 전 현재 네트워크 설정을 백업해 두는 것이 좋습니다

---

### 참고 자료

- [Linux Bridge 공식 문서](https://wiki.linuxfoundation.org/networking/bridge)

- [Open vSwitch 공식 문서](https://docs.openvswitch.org/en/latest/)

- [OpenStack Networking Guide](https://docs.openstack.org/neutron/latest/admin/)
