Skip to main content

OVS Phần 18: OVS trong OpenStack Neutron

Phần 18/21 trong loạt Open vSwitch (OVS) — bài đầu tiên của Module 4 áp OVN vào một Cloud Management System (CMS) thật, thay vì lab ovn-nbctl tự tay như Bài 17. Neutron — hệ thống networking của OpenStack — chính là CMS kinh điển nhất gắn với OVN, và cũng là nơi kiến trúc "agent tự tính OpenFlow" (thứ Bài 1-16 vẫn ngầm giả định) và kiến trúc OVN (Bài 17) cùng tồn tại song song dưới một framework tên ML2 (Modular Layer 2). Bài này không giải thích lại OVN từ đầu — mọi khái niệm NB DB/SB DB/ovn-northd/ovn-controller đã học ở Bài 17 được dùng lại nguyên vẹn, chỉ nối thêm phần Neutron đứng ở đâu trong chuỗi đó.

Mục tiêu bài học: sau bài này bạn phân biệt được hai kiến trúc Neutron hoàn toàn khác nhau cùng nằm dưới ML2 — ML2/OVS (mechanism driver openvswitch, có agent Python tự tính flow) và ML2/OVN (mechanism driver ovn, dùng lại nguyên OVN core Bài 17, không có agent riêng); đọc hiểu một output ovs-vsctl show thật lấy từ tài liệu DevStack chính thức, gọi đúng tên từng bridge/port; và biết chính xác vì sao br-tun — bridge tưởng như "luôn có" trong Neutron — biến mất hoàn toàn khi chuyển sang ML2/OVN.

Ba câu hỏi mà bài này trả lời:

  1. Ba bridge br-int/br-tun/br-ex thật ra thuộc về kiến trúc nào — có phải cả ML2/OVS lẫn ML2/OVN đều có đủ ba bridge đó không?
  2. neutron-openvswitch-agent (ML2/OVS) và ovn-controller (ML2/OVN, đã học ở Bài 17) khác nhau ở điểm nào trong cách biến cấu hình Neutron thành flow chạy thật?
  3. OpenStack có "khuyến nghị chính thức" chuyển từ OVS agent sang OVN tại một mốc thời gian cụ thể không, hay đây là một quá trình dịch chuyển dần?

Mục lục


1. Sửa một hiểu nhầm trước khi vào bài: type driver khác mechanism driver

Trước khi hỏi "Neutron dùng OVS như thế nào", cần tách rõ hai khái niệm trong khung ML2 (Modular Layer 2) — plugin mặc định của Neutron — rất hay bị gộp nhầm thành một:

Khái niệmTrả lời câu hỏiVí dụ
Type driverNetwork được hiện thực hóa kỹ thuật ra sao (segmentation gì, VNI/VLAN ID cấp phát thế nào)ml2_type_vxlan, ml2_type_vlan, ml2_type_geneve, ml2_type_flat
Mechanism driverAi/cái gì thật sự cấu hình bridge/switch trên từng node để hiện thực hóa network đóopenvswitch, ovn, linuxbridge, sriovnicswitch

Tài liệu chính thức định nghĩa gọn đúng hai vai trò này: type driver "define how an OpenStack network is technically realized" (ví dụ VXLAN), còn mechanism driver "define the mechanism to access an OpenStack network of a certain type" (ví dụ Open vSwitch mechanism driver). Điểm hay gây nhầm: ml2_type_vxlan không hề "thuộc về" mechanism driver openvswitch — nó chỉ là một type driver, đứng cạnh được cả hai mechanism driver openvswitch lẫn ovn, miễn phiên bản đủ mới. Đúng theo bảng "ML2 driver support matrix" trong tài liệu Neutron, dòng VXLAN cho driver ovn ghi rõ "yes (requires OVN 20.09+)" — tức OVN vẫn nhận VXLAN làm network type tenant hợp lệ, dù Geneve mới là tunnel type mặc định/khuyến nghị do đủ chỗ chứa 55-bit metadata (đã giải thích ở Bài 17 Mục 5).

💡 Hình dung như thế này: type driver giống loại giấy tờ bạn chọn để chứng minh danh tính (CMND, hộ chiếu, bằng lái) — chỉ định nghĩa "dữ liệu trông ra sao". Mechanism driver giống cơ quan xử lý giấy tờ đó (công an phường, đại sứ quán, sở giao thông) — quyết định ai thật sự "thực thi" và cấp phát nó. Cùng một loại giấy tờ (VXLAN) có thể được xử lý bởi hai cơ quan khác nhau (openvswitch hoặc ovn), không có ràng buộc 1-1 giữa hai khái niệm.

Từ đây, câu hỏi đúng của bài này không phải "Neutron ML2 driver nào dùng OVS trực tiếp" mà là: mechanism driver openvswitch và mechanism driver ovn khác nhau ra sao trong cách chúng biến cấu hình Neutron thành flow chạy thật — đúng chủ đề hai mục kế tiếp.


2. Kiến trúc ML2/OVS: agent-based, ba bridge br-int/br-tun/br-ex

Mechanism driver openvswitch dựa trên một tiến trình Python chạy thường trực trên mỗi compute/network node — neutron-openvswitch-agent. Tài liệu chính thức mô tả đúng một câu vai trò của nó: "The Open vSwitch agent configures the Open vSwitch to realize L2 networks for OpenStack resources." Agent này nhận thông báo qua RPC (thường qua RabbitMQ) từ neutron-server, rồi tự tính toán và cài đặt flow OpenFlow trực tiếp lên ba bridge cục bộ trên node đó — không có ovn-northd/ovn-controller nào tham gia, đây là kiến trúc hoàn toàn khác OVN.

Ba bridge đó, đúng vai trò tài liệu nội bộ Neutron mô tả:

  • br-int (integration bridge) — nơi mọi VM VIF được gắn vào: "All VM VIFs are plugged into the integration bridge. VM VIFs on a given virtual network share a common 'local' VLAN." Local VLAN ID này chỉ có ý nghĩa cục bộ trong 1 node, khác hẳn VLAN ID thật ngoài fabric vật lý — dùng để cô lập các mạng ảo khác nhau ngay trên br-int trước khi packet được "dịch" sang tunnel ID hay VLAN ID thật.
  • br-tun (tunnel bridge) — nơi tunnel VXLAN/GRE/Geneve originate/terminate, tách biệt hoàn toàn khỏi br-int: "These tunnels originate and terminate on the tunneling bridge of each hypervisor, leaving br-int unaffected." Việc "dịch" giữa local VLAN (trên br-int) và tunnel ID (trên br-tun) được thực hiện qua patch port: "Port patching is done to connect local VLANs on the integration bridge to inter-hypervisor tunnels on the tunnel bridge."
  • br-ex (external bridge) — nối ra cổng vật lý (eth0) để traffic floating IP đi ra/vào được hạ tầng mạng thật: "br-ex is an OVS bridge that is used to connect physical ports (like eth0), so that floating IP traffic for project networks can be received from the physical network infrastructure (and the internet), and routed to self service project network ports."

Ba bridge này nối với nhau bằng hai cặp patch port cố định, luôn tồn tại ngay cả khi chưa có VM nào cần dùng tới: patch-int/patch-tun nối br-intbr-tun, và int-br-ex/phy-br-ex nối br-intbr-ex.

ML2/OVS — Ba Bridge Trên Một Compute Nodeneutron-openvswitch-agent tự cài flow, không có ovn-controller nào tham gianeutron-openvswitch-agent (Python, nhận RPC từ neutron-server qua RabbitMQ)br-int (integration)local VLAN cô lập tenanttap* (VM VIF)qr-* (router-in)qg-* (router-gw)patch-tun / int-br-extag VLAN local — không phải VLAN vật lýbr-tun (tunnel)tunnel VXLAN/GRE/Geneveoriginate/terminate tại đâyvxlan-<hex remote_ip>br-ex (external)nối physical port ra ngoàieth0 (uplink vật lý)patch-int ↔patch-tunint-br-ex ↔phy-br-exVM ra ngoài qua floating IP: tap* → br-int (local VLAN) → patch-int/patch-tun hoặc int-br-ex/phy-br-ex→ br-tun (Geneve/VXLAN, tới compute khác) hoặc br-ex → eth0 (ra fabric vật lý)Hai cặp patch port tồn tại tĩnh — không phụ thuộc VM nào đang chạy

3. Kiến trúc ML2/OVN: Neutron chỉ là OVN/CMS Plugin

Mechanism driver ovn không có agent Python riêng nào chạy liên tục để tự tính flow như ML2/OVS. Tài liệu chính thức chỉ mô tả nó bằng đúng một câu: OVN mechanism driver "can be used for instance network attachments as well as for attachments of other network resources like routers, metadata ports, and so on." — ngắn gọn vì bản chất không có gì đặc biệt để nói thêm: Neutron ở đây chỉ đóng đúng vai trò OVN/CMS Plugin đã học ở Bài 17 Mục 2 — mọi thao tác tạo network/router qua Neutron API chỉ là ghi vào NB DB, sau đó toàn bộ chuỗi ovn-northd → SB DB → ovn-controller → OpenFlow tự vận hành y hệt như lab Bài 17, không có cơ chế lõi nào mới.

Hệ quả trực tiếp của việc dùng lại OVN: mô hình traffic Đông-Tây (E/W) và Bắc-Nam (N/S) khác hẳn ML2/OVS. Tài liệu kiến trúc tham chiếu Neutron-OVN xác nhận: "all the E/W traffic which traverses a virtual router is completely distributed" — hai VM khác subnet trên hai compute khác nhau route thẳng cho nhau qua Geneve, không cần đi qua một network node trung tâm nào. ML2/OVS truyền thống mặc định tập trung phần này ở router namespace trên network node, dù có tùy chọn DVR (Distributed Virtual Router) để phân tán bớt — nhưng đó là một tính năng cấu hình thêm, không phải hành vi mặc định như ML2/OVN. Ngược lại, "N/S traffic that needs SNAT (without floating IPs) will always pass through the centralized gateway nodes" — traffic ra ngoài cần SNAT (Source NAT — đổi source IP private của VM sang IP public của gateway node để đi được ra internet, áp dụng khi VM không có floating IP riêng) vẫn phải qua gateway node tập trung, dù là ML2/OVS hay ML2/OVN.

Điểm quan trọng nhất của cả bài, dễ hiểu sai nếu đọc lướt: br-int vẫn tồn tại trong ML2/OVN — nhưng do ovn-controller tự tạo, không phải do agent Python nào tạo, đúng như đã trích ở Bài 17 Mục 6: "The default is br-int. If this bridge does not exist when ovn-controller starts, it will be created automatically." Nhưng không có br-tun riêng nào cả. Không có tài liệu OVN nào mô tả một bridge tunnel tách biệt — ovn-controller tự đọc bảng Chassis/Encap trong SB DB rồi gắn tunnel port (Geneve/VXLAN) thẳng vào br-int, đúng cơ chế table 0 "physical-to-logical" đã học ở Bài 17 Mục 5: packet vào thẳng br-int, được gán metadata/reg14 ngay tại table 0, không cần bridge trung gian nào để "dịch" tunnel ID sang local VLAN như ML2/OVS phải làm.

Physical/provider bridge vẫn tồn tại, nhưng cơ chế nối khác hẳn cặp int-br-ex/phy-br-ex tĩnh của ML2/OVS — patch port ở đây được tạo động, chỉ khi thật sự cần. Tài liệu về routed provider network của Neutron-OVN mô tả đúng cơ chế này: "When a port in the multisegment network gets bound to compute-1, ovn-controller will create a patch-port between br-int and br-provider1." Cấu hình qua ovn-bridge-mappings (tương tự khái niệm bridge_mappings đã quen ở ML2/OVS), nhưng khác ở chỗ patch port không tồn tại sẵn — nó chỉ xuất hiện khi có VM cần provider network đó thật sự chạy trên node.

💡 Hình dung như thế này: ML2/OVS giống một tòa nhà văn phòng luôn giữ sẵn cả ba cửa (cửa chính, cửa hầm để xe, cửa thoát hiểm) mở suốt ngày dù không có ai dùng cửa thoát hiểm cả tuần. ML2/OVN giống tòa nhà thông minh hơn — cửa chính (br-int) luôn mở, nhưng "cửa thoát hiểm" (patch port ra provider bridge) chỉ tự động hiện ra đúng lúc có người cần dùng, và bản thân "hành lang tunnel" riêng (br-tun) không tồn tại nữa — mọi lối đi ra ngoài tòa nhà đều xuất phát thẳng từ sảnh chính.

ML2/OVN — E/W Phân Tán vs N/S Tập TrungHai VM khác compute route thẳng cho nhau — nhưng SNAT luôn phải ghé qua đúng 1 gateway nodeCompute-1VM-Atenant subnet 1Compute-2VM-Btenant subnet 2Geneve — E/W, distributedcompute ↔ compute trực tiếp, không qua gateway nodeGateway Nodeqg-* / SNATSNAT — N/SSNAT — N/SInternetE/W không bao giờ chạm Gateway Node, dù VM-A và VM-B chạy trên compute khác nhau.N/S cần SNAT thì luôn phải đi qua đúng 1 Gateway Node, bất kể traffic xuất phát từ compute nào.

4. So sánh trực diện: bridge nào còn, bridge nào mất

BridgeML2/OVS (mechanism driver openvswitch)ML2/OVN (mechanism driver ovn)
br-intCó — do neutron-openvswitch-agent tạoCó — do ovn-controller tự tạo khi khởi động
br-tunCó — tunnel VXLAN/GRE/Geneve terminate riêng tại đâyKhông tồn tại — tunnel port gắn thẳng vào br-int
br-ex / br-providerNCó — patch tĩnh int-br-ex/phy-br-ex, luôn tồn tạiCó — patch động br-intbr-providerN, chỉ tạo khi có VM cần, tên/số lượng tùy ovn-bridge-mappings
Ai tính flow OpenFlowneutron-openvswitch-agent, tự tính riêng trên từng node, đồng bộ qua RPC/RabbitMQovn-northd biên dịch một lần dùng chung (SB DB), ovn-controller chỉ đọc lại
ML2/OVS vs ML2/OVN — Cùng Một Compute NodeML2/OVSbr-intlocal VLAN + tap/qg/qrbr-tunGeneve/VXLAN/GRE terminatebr-expatch tĩnh int-br-ex/phy-br-exneutron-openvswitch-agentML2/OVNbr-inttunnel port gắn thẳng vào đâybr-tun — KHÔNG TỒN TẠIkhông có bridge tunnel riêngbr-providerNpatch động, chỉ tạo khi có VM cầnovn-controller (Bài 17)Đúng 3 bridge tồn tại đồng thời chỉ ở ML2/OVS.ML2/OVN thiếu hẳn br-tun — nhìn thấy br-int + br-providerN mà không có br-tunchính là dấu hiệu trực quan nhanh nhất để nhận ra một node đang chạy ML2/OVN.br-providerN không có tên mặc định cố định — tùy ovn-bridge-mappings cấu hình

5. OVN chưa phải superset 100% của ML2/OVS

Tránh viết theo kiểu "OVN toàn diện hơn OVS agent mọi mặt" — Neutron có hẳn một trang tài liệu chính thức tên "Gaps from ML2/OVS", liệt kê những gì ML2/OVS làm được mà ML2/OVN (tại thời điểm tài liệu) chưa hỗ trợ đầy đủ. Một vài gap đáng chú ý nhất (trang này là tài liệu sống, cập nhật theo từng release, nên số lượng/chi tiết có thể đã đổi khi bạn đọc):

  • ML2/OVS tự thêm rule cho phép DHCP query từ mọi instance; ML2/OVN yêu cầu security group rule tường minh cho việc này.
  • Phân giải DNS: ML2/OVN không dùng được networking của host để resolve, chỉ hỗ trợ cấu hình dns_servers thủ công.
  • NDP proxy cho IPv6 chưa được OVN hỗ trợ.
  • Phân mảnh (fragmentation) traffic Đông-Tây qua router giữa hai mạng riêng chưa được lõi OVN hỗ trợ.
  • neutron-metering-agent chỉ hoạt động với Neutron L3 agent (ML2/OVS), không được ovn-router hỗ trợ.
  • QoS packet-rate-limit và minimum-bandwidth-rule chưa hỗ trợ ở OVN.

Nguồn: Gaps from ML2/OVS, Neutron docs


6. Mốc thời gian chuyển hướng sang OVN: không có một ngày công bố

Câu hỏi tự nhiên tiếp theo: "OpenStack khuyến nghị OVN thay OVS agent từ bao giờ?" — câu trả lời trung thực là không có một tuyên bố/nghị quyết chính thức duy nhất từ Neutron team dạng "kể từ release X, khuyến nghị dùng OVN". Thay vào đó là một chuỗi mốc rời rạc từ nhiều dự án con khác nhau trong hệ sinh thái, cho thấy một xu hướng hội tụ dần chứ không phải một ngày công bố:

MốcSự kiệnNguồn
OpenStack Ussuri (~2020)Driver OVN được đưa vào maintain in-tree trong Neutron (trước đó là dự án tách rời networking-ovn): "The networking-ovn mechanism driver has been merged into the neutron repository and is now an in-tree driver for ML2."Neutron 16.0.0 (Ussuri) release notes
OpenStack Charms — hỗ trợ từ Train, mặc định từ Ussuri"The OpenStack Charms project supports OVN starting with OpenStack Train, and uses it by default starting with OpenStack Ussuri."charm-guide, docs.openstack.org
DevStack đổi default backend (Xena cycle, 05/2021)Commit đổi mechanism driver mặc định sang ML2/OVN cho môi trường dev/testopendev.org devstack commit
OpenStack-Ansible mặc định OVN từ 2023.1 (Antelope)"By default, OpenStack-Ansible provisions Open Virtual Network (OVN) mechanism driver (ML2/OVN) instead of ML2/LXB or ML2/OVS since 2023.1 (Antelope) release."openstack-ansible-os_neutron docs

Cách nói an toàn và đúng nguồn cho bài này: từ khoảng Ussuri/Train (2019-2020), OVN được đưa in-tree và một số công cụ triển khai (OpenStack Charms) bắt đầu mặc định dùng nó; tới khoảng Antelope (2023.1), phần lớn công cụ triển khai chính (OpenStack-Ansible, và tương tự với các bộ công cụ khác) đã đồng loạt chuyển default sang ML2/OVN — nhưng không có một "ngày công bố" chính thức duy nhất từ Neutron team upstream. Riêng số liệu vendor cụ thể (ví dụ bản phân phối thương mại nào mặc định OVN từ version nào) phản ánh quyết định của từng vendor, không nên trình bày như quyết định chung của toàn dự án OpenStack.


7. CLI lab: đọc ovs-vsctl show thật từ DevStack

Tài liệu DevStack chính thức có sẵn một output ovs-vsctl show thật lấy từ một node ML2/OVS đang chạy — dùng ngay output này để tập đọc, thay vì phải tự dựng devstack chỉ để lấy một ví dụ minh họa:

stack@devstack-1:~/devstack$ sudo ovs-vsctl show
422adeea-48d1-4a1f-98b1-8e7239077964
Bridge br-tun
fail_mode: secure
Port br-tun
Interface br-tun
type: internal
Port patch-int
Interface patch-int
type: patch
options: {peer=patch-tun}
Port "vxlan-c0a801d8"
Interface "vxlan-c0a801d8"
type: vxlan
options: {df_default="true", in_key=flow, local_ip="172.18.161.6", out_key=flow, remote_ip="172.18.161.7"}
Bridge br-ex
Port phy-br-ex
Interface phy-br-ex
type: patch
options: {peer=int-br-ex}
Port "eth0"
Interface "eth0"
Port br-ex
Interface br-ex
type: internal
Bridge br-int
fail_mode: secure
Port "tapce66332d-ea"
tag: 1
Interface "tapce66332d-ea"
type: internal
Port "qg-65e5a4b9-15"
tag: 2
Interface "qg-65e5a4b9-15"
type: internal
Port "qr-33e5e471-88"
tag: 1
Interface "qr-33e5e471-88"
type: internal
Port "qr-acbe9951-70"
tag: 1
Interface "qr-acbe9951-70"
type: internal
Port br-int
Interface br-int
type: internal
Port patch-tun
Interface patch-tun
type: patch
options: {peer=patch-int}
Port int-br-ex
Interface int-br-ex
type: patch
options: {peer=phy-br-ex}
ovs_version: "2.0.2"

Nguồn: Using DevStack with neutron Networking, docs.openstack.org

Giải nghĩa từng port lạ, đúng thứ tự xuất hiện trong output:

  • vxlan-c0a801d8 (trên br-tun): một tunnel VXLAN cụ thể — hậu tố c0a801d8 là dạng hex của remote_ip. options cho thấy rõ local_ip/remote_ip của hai đầu tunnel và in_key/out_key đặt flow (tunnel key lấy động theo flow, không cố định) — đây chính là cơ chế originate/terminate tunnel đã nói ở Mục 2.
  • phy-br-ex/int-br-ex (trên br-ex/br-int): cặp patch port cố định nối hai bridge, đúng như Mục 2 đã mô tả.
  • eth0 (trên br-ex): uplink vật lý thật, nơi traffic floating IP thoát ra ngoài tới hạ tầng mạng/internet.
  • tapce66332d-ea (trên br-int, tag: 1): tap interface của một VM cụ thể — tag: 1 là local VLAN ID cục bộ trên node này, không phải VLAN thật ngoài fabric.
  • qg-65e5a4b9-15 (tag: 2): qrouter gateway port — port gateway của Neutron router namespace (qrouter-*) ra external network; namespace này dùng port này để SNAT/floating-IP NAT traffic trước khi đẩy tiếp qua br-ex.
  • qr-33e5e471-88, qr-acbe9951-70 (tag: 1): qrouter port — mỗi port nối router vào một subnet tenant cụ thể (ở đây có 2 port qr-*, nghĩa là router này đang nối ít nhất 2 subnet nội bộ).
  • patch-int/patch-tun: cặp patch port cố định nối br-intbr-tun.

Đối chiếu ngay với bảng Mục 4: output này có đủ cả ba bridge br-int/br-tun/br-ex cùng lúc — xác nhận đây chắc chắn là một node ML2/OVS, không phải ML2/OVN (nếu là ML2/OVN, br-tun sẽ không xuất hiện, thay vào đó tunnel port vxlan-*/geneve* sẽ nằm ngay bên trong khối Bridge br-int).


Bài tập cuối bài

  1. Đọc lại đúng output ovs-vsctl show ở Mục 7. Tự vẽ (trên giấy hoặc text) đường đi của traffic từ VM gắn tại tapce66332d-ea ra tới internet qua floating IP (giả định router này là loại centralized, không phải DVR — traffic ra ngoài luôn qua đúng node có qg-*/br-ex này). Đếm chính xác: traffic đi qua bao nhiêu bridge, bao nhiêu patch port, tên từng chặng?
  2. Giả sử node ở Mục 7 là ML2/OVN thay vì ML2/OVS. So với output gốc, ovs-vsctl show trên node đó sẽ thiếu hẳn khối nào? Port vxlan-c0a801d8 sẽ dịch chuyển tới nằm trong khối Bridge nào? Tên br-ex có còn chắc chắn xuất hiện y hệt không, hay có thể đổi tên tùy cấu hình gì?
  3. (Mở rộng, không bắt buộc có môi trường thật) Nếu có quyền truy cập một triển khai OpenStack thật (DevStack hoặc production), chạy sudo ovs-vsctl show trên một compute node, và tự xác định: node đó đang chạy ML2/OVS hay ML2/OVN, dựa đúng vào tiêu chí "có br-tun hay không" đã học ở Mục 4.

Nguồn tham khảo


Tiếp theo: Module 4, Bài 19 — OVS trong Kubernetes (OVN-Kubernetes, Antrea CNI).