diff --git a/_quarto.yml b/_quarto.yml index c5fe1e7..ea01365 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -33,15 +33,13 @@ website: contents: - text: "6-1. Neutron의 agent에 대해 알아보기" file: lectures/ch6/neutron_agents.qmd + - text: "6-4. OVS(Open vSwitch)란 무엇인가?" + file: lectures/ch6/what_is_ovs.qmd - text: "6-12. SNAT/DNAT란?" file: lectures/ch6/snat_dnat.qmd - text: "6-15. OVS와 VXLAN를 이용해 가상 네트워크 만들기" file: lectures/ch6/ovs_vxlan_vpn.qmd - - - - format: html: theme: @@ -49,4 +47,4 @@ format: - custom.scss toc: true lang: ko - include-after-body: _footer.html \ No newline at end of file + include-after-body: _footer.html diff --git a/lectures/ch6/what_is_ovs.qmd b/lectures/ch6/what_is_ovs.qmd new file mode 100644 index 0000000..ff9da05 --- /dev/null +++ b/lectures/ch6/what_is_ovs.qmd @@ -0,0 +1,351 @@ +--- +title: "6-4. OVS(Open vSwitch)란 무엇인가?" +description: "OVS(Open vSwitch)가 왜 필요한지, 브리지와 포트, 플로우, 그리고 Linux bridge·OVS·OVN의 역할 차이를 개념 중심으로 정리합니다." +code: "6-4" +--- + +## [6-4-1] OVS(Open vSwitch)란 + +OVS를 한 문장으로 정리하면: + +> **호스트(서버) 내부에서 패킷을 스위칭하고, 정책을 적용하고, (필요하면) 오버레이로 캡슐화까지 하는 ‘프로그램 가능한 소프트웨어 스위치’ 입니다** +> + +여기서 중요한 포인트는 **“프로그램 가능(Programmable)”**입니다. + +- 물리 스위치처럼 단순히 MAC 학습해서 포워딩만 하는 게 아니라 +- **규칙(정책) 중심**으로 트래픽을 분류하고 처리할 수 있고 +- 그 규칙을 사람이 수동으로 넣을 수도 있고(단일 호스트) +- 오케스트레이터/컨트롤러가 대규모로 자동으로 내려보내게 만들 수도 있습니다(클러스터) + +--- + +## [6-4-2] Open vSwitch가 등장한 이유 + +가상화( VM )와 컨테이너가 보편화되면서 네트워크의 복잡성이 많이 올라갔습니다. + +예전에는 트래픽이 대부분 **물리 스위치**를 중심으로 흐르고, 서버는 그 위에 연결된 노드에 불가했습니다. + +하지만 클라우드 환경에서는: + +- 한 대의 서버 안에 VM/컨테이너가 수십~수백 개 +- 이들끼리 내부 통신(동일 호스트 내부, 또는 다른 호스트로 이동) +- 테넌트(사용자/프로젝트) 별로 네트워크 분리 +- 보안 정책(ACL), 관측(미러링/샘플링), 오버레이(VXLAN/Geneve), 자동화가 필수 + +즉, **“스위치가 서버 안으로 들어왔다”**고 보는 게 자연스럽습니다. + +그 **“서버 안의 스위치”** 역할을 하는 대표가 **OVS(Open vSwitch)** 입니다. + +--- + +## [6-4-3] OVS에서 많이 나오는 개념들 + +OVS 문서를 보다 보면 `bridge`, `port`, `interface`, `internal`, `patch`, `tunnel` 같은 단어가 계속 나옵니다. + +이 용어들을 먼저 정리해두면 뒤의 `flow`와 `datapath` 이야기가 훨씬 덜 헷갈립니다. + +가장 먼저 큰 그림은 이렇게 잡으면 됩니다. + +- **bridge** = 가상 스위치 본체 +- **port** = 스위치에 연결되는 논리적 연결점 +- **interface** = 그 포트를 실제로 구현하는 인터페이스 + +즉, OVS는 보통 **bridge 안에 port가 있고, port 아래에 interface가 붙는 구조**로 이해하면 됩니다. + +### 브리지(Bridge) + +OVS에서 **브리지(br0, br-int, br-ex 등)** 는 “가상의 스위치 1대”라고 보면 가장 이해가 빠릅니다. + +- 하나의 브리지는 하나의 L2 스위칭 도메인처럼 동작합니다. +- MAC 학습, VLAN 처리, 플로우 적용, 포트 연결 같은 일이 이 단위에서 이뤄집니다. +- 실무에서는 `br-int`, `br-ex`, `br-tun`처럼 역할별로 브리지를 나누는 구성이 자주 나옵니다. + +예를 들어: + +- `br-int` = 내부 통합 브리지 +- `br-ex` = 외부 네트워크 연결 브리지 +- `br-tun` = VXLAN/Geneve 같은 오버레이용 브리지 + +브리지는 “스위치 본체”이고, 실제 연결은 그 아래 포트와 인터페이스를 통해 붙습니다. + +### 포트(Port) + +포트는 스위치에 연결되는 **논리적 연결점**입니다. + +여기서 중요한 점은, OVS의 포트는 “NIC 하나”와 1:1로만 대응하지 않는다는 것입니다. + +- 가장 단순한 경우에는 포트 하나에 인터페이스 하나가 붙습니다. +- 하지만 **bond**처럼 포트 하나 아래 여러 인터페이스가 붙는 경우도 있습니다. + +즉, 포트는 “스위치 입장에서 보는 연결 단위”에 더 가깝습니다. + +### 인터페이스(Interface) + +인터페이스는 포트를 실제로 구현하는 **실체**입니다. + +여기에는 여러 종류가 들어올 수 있습니다. + +- 물리 NIC (`eth0`, `ens3` 등) +- VM/컨테이너 vNIC +- `internal` 인터페이스 +- `patch` 인터페이스 +- `vxlan`, `geneve`, `gre` 같은 터널 인터페이스 + +즉, 인터페이스는 “실제로 패킷이 드나드는 구체적인 입구/출구”라고 보면 됩니다. + +### VM/컨테이너 vNIC + +VM이나 컨테이너의 가상 NIC이 OVS 브리지에 붙는 가장 흔한 형태입니다. + +```text +[VM vNIC] [VM vNIC] + | | + v v + +-------------------+ + | br0 (OVS) | + +-------------------+ +``` + +OpenStack에서는 인스턴스의 TAP/vNIC가 OVS 포트로 연결되는 구조를 자주 보게 됩니다. + +### 업링크(Uplink) 포트 + +업링크는 OVS의 엄밀한 객체 이름이라기보다, **호스트 밖으로 나가는 물리 연결**을 뜻하는 운영 용어입니다. + +보통 물리 NIC이 이 역할을 맡습니다. + +```text + +-------------------+ + | br0 (OVS) | + +-------------------+ + | + eth0 ---> 물리 스위치 +``` + +즉 업링크 포트는 “가상 스위치가 외부 물리 네트워크와 만나는 지점”입니다. + +### 내부 포트(`internal`) + +`internal` 포트는 호스트 OS 자체가 OVS 브리지에 직접 붙는 인터페이스라고 생각하면 됩니다. + +- 호스트가 브리지에 IP를 올릴 때 자주 사용합니다. +- 관리용 IP를 브리지 쪽으로 옮기거나, 호스트 네트워크 스택이 OVS와 직접 연결되게 만들 때 등장합니다. + +쉽게 말하면 “호스트 자신도 OVS 스위치에 하나의 포트로 참여시키는 방식”입니다. + +### 패치 포트(`patch`) + +패치 포트는 **같은 호스트 안의 두 OVS 브리지를 직접 이어주는 포트 쌍**입니다. + +예를 들어 `br-int`와 `br-ex`를 연결할 때, 외부 NIC를 거치지 않고 OVS 내부에서 바로 이어줄 수 있습니다. + +이건 “가상 스위치끼리 연결하는 짧은 내부 케이블”이라고 생각하면 이해가 쉽습니다. + +### 터널 포트(`vxlan`, `geneve`, `gre` 등) + +터널 포트는 다른 호스트의 OVS 브리지와 IP 네트워크 위에서 연결할 때 사용합니다. + +```text +[Host A] br0 ===(VXLAN/Geneve over IP)=== br0 [Host B] +``` + +즉, 물리적으로는 떨어져 있는 두 호스트를 논리적으로 같은 네트워크처럼 보이게 만드는 포트입니다. + +OpenStack에서 테넌트 네트워크를 여러 컴퓨트 노드에 걸쳐 확장할 때 이 개념이 자주 나옵니다. + +### 본드 포트(Bond) + +본드 포트는 포트 하나 아래에 여러 물리 인터페이스를 묶는 경우입니다. + +- 대역폭 확장 +- 이중화 +- 장애 대응 + +같은 목적을 위해 사용합니다. + +즉, OVS에서 포트는 단순히 “선 하나”가 아니라, **여러 인터페이스를 하나의 논리 포트로 묶는 단위**가 될 수도 있습니다. + +### 이 섹션에서 기억할 핵심 + +- **bridge**는 스위치 본체 +- **port**는 논리 연결점 +- **interface**는 실제 구현체 +- **internal / patch / tunnel / uplink / bond**는 그 연결점이 어떤 역할을 하느냐를 설명하는 자주 쓰이는 개념 + +이 개념들을 잡고 나면, 다음에 나오는 **flow**는 “이 연결점들 사이로 들어오는 패킷을 어떤 규칙으로 처리할 것인가”의 문제로 자연스럽게 이어집니다. + +--- + +## [6-4-4] “플로우(Flow)”는 무엇이고 왜 핵심인가 + +앞 절에서 본 `bridge`, `port`, `interface`는 말 그대로 **패킷이 지나갈 구조물**에 대한 설명이었습니다. + +그런데 구조물만 있다고 해서 OVS가 자동으로 “이 패킷을 어디로 보낼지”까지 설명해 주지는 않습니다. + +예를 들어 패킷이 들어왔을 때 OVS는 결국 아래 질문에 답해야 합니다. + +- 이 패킷은 같은 브리지 안의 다른 VM 포트로 보내야 하나? +- 외부 업링크로 내보내야 하나? +- VXLAN/Geneve 터널 포트로 캡슐화해서 다른 호스트로 보내야 하나? +- 아니면 정책상 드롭해야 하나? + +즉, `bridge/port/interface`가 **길과 연결점의 구조**를 설명한다면, + +**flow는 그 길 위를 지나가는 패킷을 어떤 규칙으로 처리할 것인가**를 설명하는 층입니다. + +OVS가 단순 브리지를 넘어 “프로그램 가능한 스위치”로 불리는 이유도 바로 여기에 있습니다. + +### 플로우 = “패킷을 분류(match)하고 처리(action)하는 규칙” + +플로우는 아주 본질적으로 **두 덩어리**입니다. + +- **Match(조건)**: 어떤 패킷인가? (in_port, MAC, IP, TCP/UDP 포트, VLAN 등) +- **Action(동작)**: 어떻게 처리할까? (어디로 보낼지, 드롭할지, 태그 붙일지, 터널 씌울지, QoS, 미러링 등) + +텍스트로 표현하면 이런 형태의 규칙입니다. + +```text +[조건] in_port=VM1, ip, dst=10.0.0.2 +[동작] output=VM2 +``` + +조금 더 OVS스럽게 말하면, 플로우는 “**어느 포트에서 들어온 어떤 패킷을, 어떤 액션으로 다음 포트나 터널로 보낼지**”를 정하는 규칙입니다. + +예를 들어: + +- VM vNIC 포트로 들어온 패킷을 같은 브리지의 다른 포트로 보낼 수도 있고 +- `patch` 포트를 통해 다른 브리지로 넘길 수도 있고 +- `vxlan` 포트를 통해 원격 호스트로 보낼 수도 있고 +- 보안 정책에 따라 드롭할 수도 있습니다. + +### 왜 “플로우 중심”이어야 하나 + +클라우드 네트워크에서 필요한 건 단순 L2 포워딩이 아니라, 아래가 동시에 필요합니다. + +- 테넌트 분리(서로 섞이지 않게) +- 정책(허용/차단/로깅/미러링) +- 오버레이 캡슐화/디캡슐화 +- 중앙 제어(오케스트레이터가 일관되게 적용) + +이걸 MAC 학습 기반의 단순 브리지만으로 “표준화된 방식으로” 풀기는 어렵습니다. + +플로우 기반은 **“정책을 패킷 처리 규칙으로 직접 표현”** 할 수 있어 자동화/통제가 쉬워집니다. + +즉, 앞에서 본 `bridge/port/interface`가 “배선도”라면, 플로우는 그 배선도 위에서 **실제 교통정리를 하는 규칙표**에 가깝습니다. + +### OVS에서 플로우는 “컨트롤러의 의도”이자 “성능 전략” + +OVS는 내부적으로 **자주 오는 트래픽을 빠르게 처리**하기 위해 플로우(캐시)를 적극 활용합니다. + +- 처음 보는 패킷: 규칙을 찾아보고(또는 만들어보고) +- 이후 같은 흐름의 패킷: 이미 정해둔 처리 방법을 그대로 반복(빠르게) + +즉 플로우는 **정책 표현**이면서 동시에 **성능을 만드는 단위**이기도 합니다. + +--- + +## [6-4-5] 핵심 특징 및 차별점 + +OVS와 Linux bridge는 둘 다 리눅스 호스트 안에서 L2 연결을 만들 수 있지만, **설계 목표가 다릅니다.** + +Linux bridge는 전통적인 소프트웨어 브리지이고, OVS는 **동적 가상화 환경, 원격 제어, 오버레이, 운영 가시성**까지 염두에 두고 설계된 스위치 플랫폼에 가깝습니다. + +| 특징 | Linux bridge | Open vSwitch (OVS) | +|------|--------------|--------------------| +| 제어 방식 | 로컬 브리지 설정 중심. `ip link`, `bridge` 같은 iproute2 도구로 포트·FDB·VLAN을 관리하고, 기본적으로 L2 헤더를 기준으로 동작합니다. | OVSDB 기반 구성 관리와 플로우 중심 제어를 통해 자동화를 염두에 둔 구조입니다. 오케스트레이터가 상태를 감시하고 규칙을 동적으로 배포할 수 있습니다. | +| 터널/오버레이 | 브리지 자체는 L2 브리징이 본업입니다. VXLAN 같은 오버레이는 별도 커널 터널 디바이스와 `bridge fdb` 조합으로 붙여 쓰는 방식입니다. | Geneve, GRE, VXLAN, ERSPAN 등 다양한 터널링을 공식 기능으로 제공합니다. 다중 서버 가상화 환경을 직접 겨냥한 기능입니다. | +| 성능 최적화 | 커널 브리지 경로를 사용하고, 지원 하드웨어가 있으면 switchdev로 포워딩/필터링/학습 오프로딩이 가능합니다. | 커널 datapath 기반 고성능 포워딩을 제공하고, 필요하면 DPDK userspace datapath와 하드웨어 offload까지 사용할 수 있습니다. | +| 가시성/운영 | `bridge` 명령으로 link/FDB/VLAN/MDB/VNI 상태를 볼 수 있는 전통적인 운영 모델입니다. | NetFlow, sFlow, mirroring 같은 운영 가시성과 계측 기능이 더 풍부합니다. | + +정리하면, Linux bridge가 **“호스트 안의 기본 소프트웨어 브리지”**에 가깝다면, OVS는 **“가상화와 오버레이, 원격 제어, 관측까지 고려한 운영형 가상 스위치”**에 더 가깝습니다. + +그런데 실무에서는 여기에 **OVN**까지 같이 등장합니다. 그래서 “Linux bridge, OVS, OVN을 왜 한 번에 비교하느냐?”라는 질문이 생깁니다. + +핵심은 이겁니다. + +- **Linux bridge와 OVS는 직접 비교 대상**입니다. +- **OVN은 OVS의 대체재라기보다 그 위에 올라가는 제어 계층**입니다. + +즉 셋을 완전히 같은 급으로 놓고 “누가 더 좋나”를 비교하면 부정확하지만, OpenStack 네트워크를 설계할 때는 함께 언급될 수밖에 없습니다. + +### OVN은 어디에 들어오나 + +OVN은 “가상 스위치 자체”가 아니라, **여러 호스트에 걸친 논리 네트워크를 중앙에서 설계하고 각 호스트의 OVS에 반영하는 컨트롤 플레인**입니다. + +- OVS는 실제 패킷을 처리하는 데이터플레인 스위치이고 +- OVN은 논리 스위치, 논리 라우터, ACL 같은 의도를 관리하고 +- 그 결과를 각 호스트의 OVS 플로우로 배포하는 상위 계층입니다. + +즉 관계를 더 정확히 쓰면 다음에 가깝습니다. + +```text +단일 호스트 L2 브리징 + -> Linux bridge 또는 OVS + +여러 호스트에 걸친 논리 네트워크 제어 + -> OVN + └─ 실제 패킷 처리는 보통 OVS가 담당 +``` + +따라서 “세 기술이 비슷해서 비교한다”기보다, **설계할 때 함께 등장하지만 서로 같은 층위는 아니다**라고 이해하는 편이 정확합니다. + +## [6-4-6] 핵심 아키텍처: 어떻게 동작하는가 + +OVS를 이해할 때는 아래 세 구성 요소를 먼저 잡아두면 편합니다. + +### `ovs-vswitchd` + +실제 스위치 동작을 구현하는 **userspace 데몬**입니다. + +- 브리지, 포트, 플로우 같은 스위치 로직을 관리합니다. +- slow path에서 패킷을 해석하고, 어떤 액션을 적용할지 결정합니다. + +### `ovsdb-server` + +스위치 구성을 저장하는 **경량 데이터베이스 서버**입니다. + +- `ovs-vswitchd`는 여기에서 자신의 구성을 읽어옵니다. +- OVSDB는 원격 변경 감시와 자동화에 적합해서, 오케스트레이터가 네트워크 상태를 보고 반응하는 구조를 만들 수 있습니다. + +### `openvswitch.ko`와 커널 datapath + +실제 패킷을 빠르게 처리하는 **커널 공간 datapath**입니다. + +- Open vSwitch 문서에서는 이를 “Linux kernel module” 또는 “datapath”로 설명합니다. +- 브리지에 해당하는 datapath와, 포트에 해당하는 vport, 그리고 userspace가 채우는 flow table을 가집니다. + +### 패킷이 실제로 처리되는 순서 + +OVS의 성능 포인트는 “첫 패킷은 천천히 판단하고, 이후 패킷은 빠르게 재사용한다”는 구조에 있습니다. + +1. 패킷이 커널 datapath에 들어오면 먼저 flow table/cache를 조회합니다. +2. 이미 일치하는 flow가 있으면, 커널에서 바로 액션을 실행합니다. +3. 일치하는 flow가 없으면 패킷을 userspace로 올리고, `ovs-vswitchd`가 자신이 가진 규칙과 상태를 기준으로 처리 방법을 결정합니다. +4. 그 결과를 datapath action으로 내려보내고, 가능하면 커널 쪽 cache에 flow를 설치합니다. +5. 이후 같은 흐름의 패킷은 userspace까지 올라가지 않고 fast path에서 처리됩니다. + +즉, **첫 패킷은 slow path(`ovs-vswitchd`)가 판단하고, 이후 패킷은 kernel datapath가 고속 처리**한다고 이해하면 됩니다. + +이 구조 덕분에 OVS는 정책 유연성과 성능을 동시에 가져가려 합니다. DPDK를 사용할 때도 큰 그림은 비슷하고, 달라지는 핵심은 **slow path가 아니라 datapath 구현**입니다. + +## [6-4-7] 마무리 + +- **브리지**: “한 덩어리의 L2 스위칭 도메인(가상 스위치 1대)” +- **포트**: “그 스위치에 붙는 연결점(물리/가상/터널/내부 등 무엇이든)” +- **플로우**: “패킷 처리 정책을 기계가 실행할 수 있는 규칙(조건→동작)” +- **OVS**: “호스트 안에서 정책/오버레이/관측까지 가능한 소프트웨어 스위치” +- **OVN**: “여러 호스트에 걸친 논리 네트워크를 중앙에서 정의하고 OVS로 배포하는 컨트롤 플레인” +- **Linux bridge와 OVS**: 호스트 내부 스위칭 구현 방식으로 직접 비교되는 대상 +- **OVS와 OVN**: 대체 관계라기보다 데이터플레인과 컨트롤 플레인의 역할 분담 관계 + +## [6-4-8] 참조 + +- [Open vSwitch 공식 문서의 What is OVS 소개 페이지](https://docs.openvswitch.org/en/stable/intro/what-is-ovs) +- [Open vSwitch 공식 문서의 Why OVS 설명 페이지](https://docs.openvswitch.org/en/latest/intro/why-ovs/) +- [Open vSwitch 공식 문서의 General FAQ 원격 관리 프로토콜 설명](https://docs.openvswitch.org/en/latest/faq/general/) +- [Linux kernel 공식 문서의 Open vSwitch datapath developer documentation](https://docs.kernel.org/6.15/networking/openvswitch.html) +- [Open vSwitch 공식 문서의 DPDK datapath 설명](https://docs.openvswitch.org/en/latest/intro/install/dpdk/) +- [Open vSwitch 공식 문서의 TC flower 하드웨어 오프로딩 설명](https://docs.openvswitch.org/en/latest/howto/tc-offload/) +- [Linux bridge(8) 공식 매뉴얼 페이지](https://man7.org/linux/man-pages/man8/bridge.8.html) +- [Linux kernel 공식 문서의 VXLAN 설명](https://www.kernel.org/doc/html/v5.8/networking/vxlan.html) diff --git a/lectures/ch6_lec.qmd b/lectures/ch6_lec.qmd index 9ac3b48..4c450ea 100644 --- a/lectures/ch6_lec.qmd +++ b/lectures/ch6_lec.qmd @@ -9,5 +9,6 @@ Neutron은 오픈스택의 네트워킹 서비스입니다. 이 장에서는 Neu ## 하위 목차 - [6-1 Neutron 에이전트 종류 정리](ch6/neutron_agents.qmd) +- [6-4 OVS(Open vSwitch)란 무엇인가](ch6/what_is_ovs.qmd) - [6-12 SNAT/DNAT 개념](ch6/snat_dnat.qmd) - [6-15 OVS/VXLAN 가상 네트워크 만들기](ch6/ovs_vxlan_vpn.qmd) diff --git a/lectures/index.qmd b/lectures/index.qmd index e0e9993..5604872 100644 --- a/lectures/index.qmd +++ b/lectures/index.qmd @@ -16,6 +16,7 @@ title: "오픈스택 강의 자료" - [4-1장. nova의 서비스 종류]() - [5장. Glance]() - [6장. Neutron](ch6_lec.qmd) - - [SNAT/DNAT 개념](ch6/snat_dnat.qmd) - [Neutron Agent 종류 정리](ch6/neutron_agents.qmd) - - [OVS/VXLAN 가상 네트워크 만들기](ch6/ovs_vxlan_vpn.qmd) \ No newline at end of file + - [6-4. OVS(Open vSwitch)란 무엇인가?](ch6/what_is_ovs.qmd) + - [SNAT/DNAT 개념](ch6/snat_dnat.qmd) + - [OVS/VXLAN 가상 네트워크 만들기](ch6/ovs_vxlan_vpn.qmd) diff --git a/tools/scripts/import_notion_zip.py b/tools/scripts/import_notion_zip.py index 30cd82c..fe7d986 100644 --- a/tools/scripts/import_notion_zip.py +++ b/tools/scripts/import_notion_zip.py @@ -233,7 +233,7 @@ def main(): zip_path = Path(zip_arg).resolve() if not zip_path.exists(): - imports_chapter = IMPORTS_DIR / chapter + imports_chapter = IMPORTS_DIR / chapter if '/' not in zip_arg and '\\' not in zip_arg and not imports_chapter.exists(): imports_chapter.mkdir(parents=True) print(f"tools/imports/{chapter}/ 폴더를 생성했습니다. ZIP 파일을 넣어주세요: {imports_chapter}")