易陆发现互联网技术论坛

 找回密码
 开始注册
查看: 230|回复: 3
收起左侧

openstack 中neutron使用ovn网络配置

[复制链接]
发表于 2025-12-18 08:50:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?开始注册

x
概述
《OVN实战二之Overlay实现》介绍了OVN中逻辑交换机、逻辑路由器的用法,本章介绍如何让OVN中的虚拟机访问外部网络和面向外部网络提供服务(NAT)。
拓扑结构
在GNS3中新增一个Linux虚拟机,E0/0连接ovn-node3的E2/0:

% m8 N7 q" u6 {- x* ?% _6 B                               
登录/注册后可看大图
: B% ~1 z$ X7 p$ S5 m* `$ V- I, C. v
3 i3 c" E1 W' s. E6 U
" V( N+ k  p1 S3 S
为Linux的第一块网卡配置上IP地址172.16.10.100,为后面的配置实现两个目标:
☘    vm1可以ping通172.16.10.100;
☘    在172.16.10.100上可以访问vm4中的WWW服务。
创建外部网络
在OVN中和外部网络通讯必须使用某个固定的节点,有点类似于Neutron中的网络节点(注意Neutron中的分布式路由只解决东西向流量的分布式,访问外部网络还是需要网络节点)。OVN通过逻辑路由器的chassis字段识别出绑定到某个固定的节点,我们把上一章的R1改造成固定路由器。新拓扑如下:

. g) ]+ J$ r1 g8 m. O                               
登录/注册后可看大图
$ V# p. ~& f5 l! ?. B
- z! n8 g. P- t

3 V+ Z6 D4 M. g- E
在ovn-node1执行:
sudo ovn-nbctl set Logical_router c971ec21-82d2-480d-a8e6-1d5566de966d options:chassis=c3c30f4f-e7e2-46fa-b621-210fd98858c5
其中的chassis是通过sudo ovn-sbctl show获取到的ovn-node3的chassis。创建网关交换机。在ovn-node1上执行:
sudo ovn-nbctl ls-add gateway-sw1
sudo ovn-nbctl lsp-add gateway-sw1 localnet-port
sudo ovn-nbctl lsp-set-addresses localnet-port unknown
sudo ovn-nbctl lsp-set-type localnet-port localnet
sudo ovn-nbctl lsp-set-options localnet-port network_name=physnet-node3
绑定网关交换机和R1,在ovn-node1上执行
sudo ovn-nbctl lrp-add r1 r1-gs1 00:00:00:10:00:00 172.16.10.20/24
sudo ovn-nbctl lsp-add gateway-sw1 gs1-r1
sudo ovn-nbctl lsp-set-type gs1-r1 router
sudo ovn-nbctl lsp-set-addresses gs1-r1 00:00:00:10:00:00
sudo ovn-nbctl lsp-set-options gs1-r1 router-port=r1-gs1
配置ovn-node3的外部网桥,在ovn-node3上执行:
sudo ovs-vsctl add-br br-ex
sudo ovs-vsctl add-port br-ex ens39
sudo ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet-node3:br-ex
验证结果
通过Linux节点ping 172.16.10.20:

* D. i( n, ]' t  Q                               
登录/注册后可看大图
5 p$ t4 e- O; L% _

; p# e! n! |( X/ l* a
" [1 g) I) Y! M# c( o
通过vm1 ping 172.16.10.20:
1 H/ e, @/ s/ `) P! O: x4 X
                               
登录/注册后可看大图

( p+ Q! z! m7 W2 P# w! \) s  ?
8 `8 y1 u* j" l8 w) d& V* f* k2 N
2 Y# F; y! k$ s8 G2 [* R& g. E  \2 g
但是vm1 此时ping不通172.16.10.100(Linux),这是因为我们少了一部配置,需要为Router配置上NAT映射,把192.168.100.0/24的外网请求全部绑定到172.16.10.20上。在ovn-node1上执行:
sudo ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.100.0/24 external_ip=172.16.10.20 -- add logical_router r1 nat @nat

7 E& ~& [3 l- u, I) d! g7 b2 ~                               
登录/注册后可看大图
. s' o- N2 n; R( |5 d. r
( ?& {6 r9 u; E5 m0 Z
7 i- [2 e( X, C7 l+ q$ F0 ^
发布服务
下面让172.16.10.100(Linux)可以访问vm4上的服务,需要增加一条DNAT映射,把所有172.16.10.10的(172.16.10.20已经用于SNAT映射了)的请求全部映射到192.168.200.40,在ovn-node1上执行:
sudo ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=192.168.200.40 external_ip=172.16.10.10 -- add logical_router r1 nat @nat
在172.16.10.100上访问172.16.10.10

: U- b' |  q3 M5 ~8 X( Z4 k6 G                               
登录/注册后可看大图
2 A* `6 E* _) S% s2 b
1 `$ s+ h- H7 N( z

# H2 W4 @. v0 C2 O
总结
OVN是一个新的“控制器”,它原理简单运行时进程也非常精简,可以独立部署运行。对比起ODL、ONOS它的“小巧”很便于我们理解问题,调试起来也更加方便;对比Neutron而言它可以独立于openstack运行(当让你也可以通过networking-ovn插件把OVN和Neutron组合起来)。
OVN是OVS的新项目,目前网络上关于它的资料少的可怜。笔者在学习的时候基本上是官方文档+代码的方式,走过不少弯路。本系列凸出“实战”,没有涉及过多的OVN原理,把关注点放在了OVN的安装、调试、使用上,希望大家都能有所收获。

8 \' h  c$ @. z* g: M
% a' c/ P, \( }# x2 P6 b2、网络服务Neutron
Neutron基于软件定义网络的思想,实现了网络虚拟化下的资源管理。Neutron的设计目标是实现网络即服务(NaaS),在设计上遵循SDN(Software Defined Network,软件定义网络)架构来管理的。- [4 g2 V6 z. w5 f  \8 w) w
Neutron主要包含Neutron server、Plugin和Agent等组件。Neutron server对外提供 OpenStack网络 API,接收请求,并调用Plugin处理请求;Plugin处理 Neutron Server发来的请求,维护OpenStack逻辑网络的状态, 并调用 Agent 处理请求;Agent处理Plugin的请求,负责在network provider上真正实现各种网络功能;此外还有database,用来存放OpenStack的网络状态信息,包括Network、Subnet、Port、Router等。
3、OVS
OVS(Open vSwitch)是虚拟交换机,遵循SDN(Software Defined Network,软件定义网络)架构来管理的。  L& q. _( X# T* H8 k1 x
OVS介绍参考:https://mp.weixin.qq.com/s?__biz ... 189#wechat_redirect
) h5 D. q( Y- o

2 f7 s2 A, {% Q                               
登录/注册后可看大图
$ s" ?. b/ p* r. L
ovs由三个组件组成:dataPath、vswitchd和ovsdb。! F3 E/ I5 g  T1 w+ p0 u
dataPath(opevswitch.ko):openvswitch.ko是ovs的内核模块,当openvswitch.ko模块被加载到内核时,会在网卡上注册一个钩子函数,每当网络包到达网卡时这个钩子函数就会被调用。openvswitch.ko模块在处理网络包时,会先匹配内核中能不能匹配到策略(内核流表)来处理,如果匹配到了策略,则直接在内核态根据该策略做网络包转发,这个过程全程在内核中完成,处理速度非常快,也称之为fast path(快速通道);如果内核中没有匹配到相应策略,则把数据包交给用户态的vswitchd进程处理,此时叫作slow path(慢通道)。dataPath模块可以通过ovs-dpctl命令来配置。
# A, X8 U, V1 L0 w5 p# z- g7 Fvswitchd:vswitchd是ovs的核心模块,它工作在用户空间(user space),负责与OpenFlow控制器、第三方软件通信。vswitchd接收到数据包时,会去匹配用户态流表,如果匹配成功则根据相关规则转发;如果匹配不成功,则会根据OpenFlow协议规范处理,把数据包上报给控制器(如果有)或者丢弃。
$ ]) I# ^9 R. W1 Bovsdb:ovs数据库,存储整个ovs的配置信息,包括接口、交换内容、vlan、虚拟交换机信息等。
# F+ ^* X8 k" ]; U$ w: v4 vovs相关术语解释:
- o4 b1 T  L! t+ F1、Bridge:网桥,也就是交换机(不过是虚拟的,即vSwitch),一台主机中可以创建多个网桥。当数据包从网桥的某个端口进来后,网桥会根据一定的规则把该数据包转发到另外的端口,也可以修改或者丢弃报文。Bridge桥指的是虚拟交换机。
: S9 ^8 b) {3 D& X. r5 [% L2、Port:交换机的端口,有以下几种类型:+ U  I: Z, ?% q; T9 A' Y
Normal: 将物理网卡添加到bridge时它们会成为Port,类型为Normal。此时物理网卡配置ip已没有意义,它已经“退化成一根网线”只负责数据报文的进出。Normal类型的Port常用于vlan模式下多台物理主机相连的那个口,交换机的一端属于Trunk模式。3 b# \* f+ _5 R0 `% M1 H
Internal: 此类型的Port,ovs会自动创建一个虚拟网卡接口(Interface),此端口收到数据都会转发给这块网卡,从网卡发出的数据也会通过Port交给ovs处理。当ovs创建一个新的Bridge时,会自动创建一个与网桥同名的Internal Port,同时也会创建一个与网桥同名的Interface。另外,Internal Port可配置IP地址,然后将其up,即可实现ovs三层网络。
' c$ q3 M9 {, P/ ]# k4 f: }Patch: 与veth pair功能类似,常用于连接两个Bridge。veth pair:两个网络虚拟端口(设备)
' K& ?4 b' W/ Y& v5 B: U! y* G" {Tunnel: 实现overlay网络,支持GRE、vxlan、STT、Geneve和IPSec等隧道协议。Tunnel:隧道,三层
' n9 ^+ u, e! N, I3、Interface:网卡,虚拟的(TUN/TAP)或物理的都可以。TAP:单个网络虚拟端口(设备),基于二层;TUN:单个网络虚拟端口(设备),基于三层。veth pair:两个网络虚拟端口(设备),常用于连接两个Bridge。3 m& J) d( ~* k3 N3 x
4、Controller:控制器,ovs可以接收一个或多个OpenFlow控制器的管理,主要功能为下发流表来控制转发规则。
( K- K0 `3 ]! U7 Y- I, K5、FlowTable:流表,ovs进行数据转发的核心功能,定义了端口之间的转发数据规则。每条流表规则可以分为匹配和动作两部分,“匹配”决定哪些数据将被处理,“动作”则决定了这些数据将被如何处理。
+ |* V& R5 Q( ]8 d  ~+ k) c7 B) A

) q6 `% ]# n3 D                               
登录/注册后可看大图
  i% Y9 f3 ^) G% {7 ^9 X
ens160的ip地址没有了,用的是br-ex的ip地址出去的。9 r: K4 v5 y$ K) T
% u& Q5 C: O% [0 B5 l
                               
登录/注册后可看大图

: J: D2 U7 J, L4 c8 q  v# Lovs安装$ W: s1 v) X5 Z+ \
1.开启一台新的linux
# u! b$ w9 ]9 d3 h! s4 i. U2.配置在线yum源(openstack那个在线yum源)
配置yum源(先把原有的备份后清空)# cd /etc/yum.repos.d/      # rm -rf *# cat cloud.repo [highavailability]name=CentOS Stream 8 - HighAvailabilitybaseurl=https://mirrors.aliyun.com/centos/8-stream/HighAvailability/x86_64/os/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialgpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[nfv]name=CentOS Stream 8 - NFVbaseurl=https://mirrors.aliyun.com/centos/8-stream/NFV/x86_64/os/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialgpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[rt]name=CentOS Stream 8 - RTbaseurl=https://mirrors.aliyun.com/centos/8-stream/RT/x86_64/os/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialgpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[resilientstorage]name=CentOS Stream 8 - ResilientStoragebaseurl=https://mirrors.aliyun.com/centos/8-stream/ResilientStorage/x86_64/os/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialgpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[extras-common]name=CentOS Stream 8 - Extras packagesbaseurl=https://mirrors.aliyun.com/centos/8-stream/extras/x86_64/extras-common/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Extras-SHA512gpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[extras]name=CentOS Stream  - Extrasmirrorlist=http://mirrorlist.centos.org/?release=&arch=&repo=extras&infra=#baseurl=http://mirror.centos.org///extras//os/baseurl=https://mirrors.aliyun.com/centos/8-stream/extras/x86_64/os/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial[centos-ceph-pacific]name=CentOS - Ceph Pacificbaseurl=https://mirrors.aliyun.com/centos/8-stream/storage/x86_64/ceph-pacific/gpgcheck=0enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Storage[centos-rabbitmq-38]name=CentOS-8 - RabbitMQ 38baseurl=https://mirrors.aliyun.com/centos/8-stream/messaging/x86_64/rabbitmq-38/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Messaging[centos-nfv-openvswitch]name=CentOS Stream 8 - NFV OpenvSwitchbaseurl=https://mirrors.aliyun.com/centos/8-stream/nfv/x86_64/openvswitch-2/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-NFVmodule_hotfixes=1[baseos]name=CentOS Stream 8 - BaseOSbaseurl=https://mirrors.aliyun.com/centos/8-stream/BaseOS/x86_64/os/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialgpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[appstream]name=CentOS Stream 8 - AppStreambaseurl=https://mirrors.aliyun.com/centos/8-stream/AppStream/x86_64/os/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialgpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[centos-openstack-victoria]name=CentOS 8 - OpenStack victoriabaseurl=https://mirrors.aliyun.com/centos/8-stream/cloud/x86_64/openstack-victoria/#baseurl=https://repo.huaweicloud.com/centos/8-stream/cloud/x86_64/openstack-yoga/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Cloudmodule_hotfixes=1[powertools]name=CentOS Stream 8 - PowerTools#mirrorlist=http://mirrorlist.centos.org/?release=&arch=&repo=PowerTools&infra=baseurl=https://mirrors.aliyun.com/centos/8-stream/PowerTools/x86_64/os/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial# yum clean all  清理缓存# yum makecache  重新建立缓存# yum repolist all  列出yum仓库(13个)
3.安装基础包及ovs(Tab补全命令,安装bash-completion包后执行bash就行)8 {2 ?: x2 t0 d
安装openvswitch3.1过程报错说找不到gpgkey文件就禁用gpgcheck=0再次安装就行了
7 p' x7 a0 G" n0 [9 T9 hyum install -y vim net-tools bash-completion centos-release-openstack-victoria.noarch tcpdump openvswitch3.1
8 c# O2 B4 n* I# B# ^& E
或再单独安装yum install -y openvswitch3.1*) F& m9 f- Y/ e
查看安装版本:[root@ovs ~]# ovs-vsctl --version% n! t" @- j" z* u7 o$ @! j( f
4.启动ovs服务$ N" N: W4 p7 t, q/ E
[root@ovs ~]# systemctl start openvswitch
" n7 N. ]5 R: M[root@ovs ~]# systemctl enable openvswitch& F. X1 V& K: M; |4 ~2 X1 y
[root@ovs ~]# ps -ef | grep openvswitch
; M$ u3 ^* i6 F; X[root@ovs ~]# ovs-vsctl show 查看ovs虚拟交换机信息! {) y; _* X5 I# [
[root@ovs ~]# ovs-vsctl --help 求帮助 或[root@ovs ~]# man ovs-vsctl
+ B. K0 q/ V5 N* W7 P% |, A5、创建ovs虚拟交换机
8 Q/ r+ G- ?# a% a/ ~, Z当创建一个虚拟交换机会生成一个和虚拟交换机同名的Port 和Interface,type为internal(内部的)
[root@ovs ~]# ovs-vsctl add-br br-int[root@ovs ~]# ovs-vsctl add-br br-memeda  添加[root@ovs ~]# ovs-vsctl del-br br-memeda  删除[root@ovs ~]# ovs-vsctl list-br   查看br-intbr-memeda[root@ovs ~]# ovs-vsctl show   查询ovs虚拟交换机信息,Bridge桥指的是虚拟交换机54c67146-9a9f-40be-8cb7-e8792879aafa    Bridge br-memeda        Port br-memeda            Interface br-memeda                type: internal    Bridge br-int        Port br-int            Interface br-int                type: internal    ovs_version: "3.1.3"
用轻量级namespace网络命名空间模拟虚拟机
4 f. v2 |/ {) E

( `' a/ L/ D; J# t                               
登录/注册后可看大图
[root@ovs ~]# ip netns    查看网络命名空间[root@ovs ~]# ip netns add ns1    添加网络命名空间[root@ovs ~]# ip netns add ns2[root@ovs ~]# ip netnsns2ns1
创建两个veth pair(一个veth pair有两个网络虚拟接口,veth可理解为网卡端口) 并将一端虚拟接口(veth1和veth2)连接到两个网络命名空间里面。veth pair:两个网络虚拟端口(设备)。
* s! \7 R8 m- y) F1 y$ Q2 v! ^% _
5 y7 E1 e! A$ K! V0 J/ K
                               
登录/注册后可看大图
创建两个veth pair,并分别把这两个veth pair的一端放到上述两个网络命名空间# ip link help 或# man ip link 求帮助第一个网络命名空间配置[root@ovs ~]# ip link add veth11 type veth peer name veth1[root@ovs ~]# ip link set veth1 netns ns1[root@ovs ~]# ip netns exec ns1 ip link set veth1 up第二个网络命名空间配置[root@ovs ~]# ip link add veth22 type veth peer name veth2[root@ovs ~]# ip link set veth2 netns ns2[root@ovs ~]# ip netns exec ns2 ip link set veth2 up
将另外一端虚拟接口(veth11和veth22)连接到ovs虚拟交换机上
, t! b' M3 x( s$ {6 g
# Y/ A) F1 ~3 ^0 m8 ^& Y* Z
                               
登录/注册后可看大图
[root@ovs ~]# ip link set veth11 up[root@ovs ~]# ip link set veth22 up[root@ovs ~]# ovs-vsctl add-port br-memeda veth11[root@ovs ~]# ovs-vsctl add-port br-memeda veth22[root@ovs ~]# ovs-vsctl show  发现br-memeda虚拟交换机多了2个Port(Port veth22、Port veth11)3b79f2e1-f433-4015-905e-8945dcada530    Bridge br-memeda        Port br-memeda            Interface br-memeda                type: internal        Port veth22            Interface veth22        Port veth11            Interface veth11    Bridge br-int        Port br-int            Interface br-int                type: internal    ovs_version: "3.1.3"
为两个网络命名空间手动设置ip地址
: i% d& z$ C. i6 o4 ^' h
& r$ r% e. [  S% c0 ^7 ^
                               
登录/注册后可看大图
[root@ovs ~]# ip netns exec ns1 ip addr add 1.1.1.1/24 dev veth1[root@ovs ~]# ip netns exec ns1 ip a1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:007: veth1@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group d                                                                        efault qlen 1000    link/ether fe:f9:3b:cb:9b:c5 brd ff:ff:ff:ff:ff:ff link-netnsid 0    inet 1.1.1.1/24 scope global veth1       valid_lft forever preferred_lft forever    inet6 fe80::fcf9:3bff:fecb:9bc5/64 scope link       valid_lft forever preferred_lft forever[root@ovs ~]# ip netns exec ns2 ip addr add 1.1.1.2/24 dev veth2[root@ovs ~]# ip netns exec ns2 ip a1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:009: veth2@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group                                                                         default qlen 1000    link/ether 0a:e3:ac:a8:f3:bc brd ff:ff:ff:ff:ff:ff link-netnsid 0    inet 1.1.1.2/24 scope global veth2       valid_lft forever preferred_lft forever    inet6 fe80::8e3:acff:fea8:f3bc/64 scope link       valid_lft forever preferred_lft forever两个网络命名空间测试连通性[root@ovs ~]# ip netns exec ns1 ping -c 3 1.1.1.2PING 1.1.1.2 (1.1.1.2) 56(84) bytes of data.64 bytes from 1.1.1.2: icmp_seq=1 ttl=64 time=2.98 ms64 bytes from 1.1.1.2: icmp_seq=2 ttl=64 time=0.167 ms64 bytes from 1.1.1.2: icmp_seq=3 ttl=64 time=0.081 ms--- 1.1.1.2 ping statistics ---3 packets transmitted, 3 received, 0% packet loss, time 2065msrtt min/avg/max/mdev = 0.081/1.075/2.979/1.346 ms[root@ovs ~]# ip netns exec ns2 ping -c 3 1.1.1.1PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.64 bytes from 1.1.1.1: icmp_seq=1 ttl=64 time=0.923 ms64 bytes from 1.1.1.1: icmp_seq=2 ttl=64 time=0.084 ms64 bytes from 1.1.1.1: icmp_seq=3 ttl=64 time=0.091 ms--- 1.1.1.1 ping statistics ---3 packets transmitted, 3 received, 0% packet loss, time 2007msrtt min/avg/max/mdev = 0.084/0.366/0.923/0.393 ms
vlan虚拟的本地局域网,vlan隔离为了减少网络阻塞和数据包安全
* A* M# ~! E8 H0 W4 Covs虚拟交换机能和物理交换机一样定义vlan,一个vlan10(tag10),一个vlan20(tag20),把插在ovs交换机上的两个虚拟网络设备对端口分别打上不同的tag(默认是0),也就是配置到不同的vlan里,再验证网络连通性。
* h& z( t/ i/ D/ e, j4 e

1 v% X$ P+ }0 ]2 h& C8 r                               
登录/注册后可看大图
[root@ovs ~]# ovs-vsctl set port veth11 tag=10[root@ovs ~]# ovs-vsctl set port veth22 tag=20[root@ovs ~]# ovs-vsctl show  发现br-memeda虚拟交换机的Port veth22和Port veth11下面多了tag标签3b79f2e1-f433-4015-905e-8945dcada530    Bridge br-memeda       Port br-memeda            Interface br-memeda                type: internal       Port veth22            tag: 20            Interface veth22       Port veth11            tag: 10            Interface veth11    Bridge br-int       Port br-int            Interface br-int                type: internal    ovs_version: "3.1.3"
添加不同vlan(tag标签)后ping不通,需借助路由或物理三层交换机
[root@ovs ~]# ip netns exec ns1 ping -c 3 1.1.1.2PING 1.1.1.2 (1.1.1.2) 56(84) bytes of data.--- 1.1.1.2 ping statistics ---3 packets transmitted, 0 received, 100% packet loss, time 2064ms
- P7 d8 N, F: n/ P$ |
                               
登录/注册后可看大图
[root@ovs ~]# ovs-vsctl set port veth22 tag=10  把veth22也改成tag=10就相当于同一个vlan二层互通了[root@ovs ~]# ovs-vsctl show3b79f2e1-f433-4015-905e-8945dcada530    Bridge br-memeda       Port br-memeda            Interface br-memeda                type: internal       Port veth22            tag: 10            Interface veth22       Port veth11            tag: 10            Interface veth11    Bridge br-int       Port br-int            Interface br-int                type: internal    ovs_version: "3.1.3"[root@ovs ~]# ip netns exec ns1 ping -c 3 1.1.1.2   同一个vlan(tag标签)能ping通进行二层通信PING 1.1.1.2 (1.1.1.2) 56(84) bytes of data.64 bytes from 1.1.1.2: icmp_seq=1 ttl=64 time=1.43 ms64 bytes from 1.1.1.2: icmp_seq=2 ttl=64 time=0.093 ms64 bytes from 1.1.1.2: icmp_seq=3 ttl=64 time=0.086 ms--- 1.1.1.2 ping statistics ---3 packets transmitted, 3 received, 0% packet loss, time 2051msrtt min/avg/max/mdev = 0.086/0.535/1.426/0.630 ms
FlowTable:流表,ovs进行数据转发的核心功能,定义了端口之间的转发数据规则。每条流表规则可以分为匹配和动作两部分,“匹配”决定哪些数据将被处理,“动作”则决定了这些数据将被如何处理。
4 M- N8 r- Y% E& ~流量走向,添加流表,针对流量进口添加规则。
( O0 h5 ^9 E3 P* t, i6 q& S: I& D

% [& S: F. i; ?6 @! X8 L  F, `                               
登录/注册后可看大图
6 U! H2 n) B/ G, G/ P" H, I* X

( g7 Q' s" `3 z% R' y/ B                               
登录/注册后可看大图
查看ovs默认的流表[root@ovs ~]# ovs-ofctl dump-flows br-memeda   查看虚拟交换机的流规则 cookie=0x0, duration=2161.884s, table=0, n_packets=49, n_bytes=3682, priority=0 action                                                                        s=NORMAL此时ovs就类似于传统交换机,我们给ovs交换机添加一条优先级为2(数字越大优先级越高,高于默认表项的0优先级)的流表项,把veth11进来的请求都drop掉,发现ns1不能ping通ns2。[root@ovs ~]# ovs-ofctl add-flow br-memeda "priority=2,in_port=veth11,actions=drop"  添加流规则[root@ovs ~]# ovs-ofctl dump-flows br-memeda cookie=0x0, duration=2.578s, table=0, n_packets=0, n_bytes=0, priority=2,in_port=veth11 actions=drop cookie=0x0, duration=2217.329s, table=0, n_packets=49, n_bytes=3682, priority=0 actions=NORMAL[root@ovs ~]# ip netns exec ns1 ping -c 3 1.1.1.2PING 1.1.1.2 (1.1.1.2) 56(84) bytes of data.--- 1.1.1.2 ping statistics ---3 packets transmitted, 0 received, 100% packet loss, time 2076ms删除刚添加的表项,ns1与ns2又能正常通信[root@ovs ~]# ovs-ofctl del-flows br-memeda "in_port=veth11"  删除刚添加的流规则就互通了[root@ovs ~]# ip netns exec ns1 ping -c 3 1.1.1.2PING 1.1.1.2 (1.1.1.2) 56(84) bytes of data.64 bytes from 1.1.1.2: icmp_seq=1 ttl=64 time=0.766 ms64 bytes from 1.1.1.2: icmp_seq=2 ttl=64 time=0.096 ms64 bytes from 1.1.1.2: icmp_seq=3 ttl=64 time=0.088 ms--- 1.1.1.2 ping statistics ---3 packets transmitted, 3 received, 0% packet loss, time 2043msrtt min/avg/max/mdev = 0.088/0.316/0.766/0.318 ms[root@ovs ~]# ovs-ofctl dump-flows br-memeda cookie=0x0, duration=2315.744s, table=0, n_packets=59, n_bytes=4438, priority=0 action                                                                        s=NORMAL4、OVN
OVN建立在OVS之上的,遵循SDN(Software Defined Network,软件定义网络)架构来管理的,用软件将控制面和转发面分离,OVN做控制面,OVS做转发面。
- V  V- E: \% W2 a: O+ eovn是建立在ovs之上的,ovn必须有底层的ovs,ovs可理解为二层交换机,ovn可理解为三层交换机。
* Q! t9 T  U+ T& j0 zOVS介绍参考:https://mp.weixin.qq.com/s?__biz ... 189#wechat_redirect& u1 L- \: U+ g9 g% U- u" |
单纯的ovs在云计算领域还存在着一些问题,例如:
+ G; w# r- y" n1、ovs只能做二层转发,没有三层的能力,无法在ovs上进行路由配置等操作;
. \# T7 ]: Y* I- g2、ovs没有高可用配置;( L+ j: `1 Y2 ]% ?2 {
3、在虚拟化领域vm从一台物理机迁移到另一台物理机,以及容器领域container从一个节点迁移到另一个节点都是非常常见的场景,而单纯的ovs的配置只适用于当前节点。当发生上述迁移过程时,新的节点因对应的ovs没有相关配置,会导致迁移过来的vm或者container无法正常运作。0 ^8 u( i5 h5 U; p+ q) c% I, S
针对这些问题,出现了ovn(Open Virtual Network),ovn提供的功能包括:3 h( k  v$ j7 |) f- [4 _
1、分布式虚拟路由器(distributed virtual routers)9 f' l; e% u1 u: ?- O4 m1 z
2、分布式虚拟交换机(distributed logical switches)  ^; E# S4 S% Y% E- O( I' c: I# _
3、访问控制列表(ACL)* Y' B  D9 j1 Z0 E6 B
4、DHCP: u( [3 s) ~8 e" l3 ~8 u, a( N
5、DNS server5 ~( ~8 i/ w  X+ d- A
在openstack里面,创建一个网络,就相当于创建了一个逻辑虚拟交换机,这个逻辑交换机(网络)信息会被保存到北向数据库里面。openstack创建一个网络,会以逻辑交换机(switch)的形式保存到北向数据库。$ Y( d5 I8 p6 o/ E* K) B
8 v5 s' X# |& C0 t4 U
                               
登录/注册后可看大图

' r- _, x( o! X. R+ A

- [0 F  `1 ?( F7 v" n* d5 ~' W" U                               
登录/注册后可看大图

- t/ q; Q$ ?9 _ovn官网对ovn的逻辑架构如下所示:
                                    CMS                                     |                                     |                         +-----------|-----------+                         |           |           |                         |     OVN/CMS Plugin    |                         |           |           |                         |           |           |                         |   OVN Northbound DB   |                         |           |           |                         |           |           |                         |       ovn-northd      |                         |           |           |                         +-----------|-----------+                                     |                                     |                           +-------------------+                           | OVN Southbound DB |                           +-------------------+                                     |                                     |                  +------------------+------------------+                  |                  |                  |    HV 1          |                  |    HV n          |  +---------------|---------------+  .  +---------------|---------------+  |               |               |  .  |               |               |  |        ovn-controller         |  .  |        ovn-controller         |  |         |          |          |  .  |         |          |          |  |         |          |          |     |         |          |          |  |  ovs-vswitchd   ovsdb-server  |     |  ovs-vswitchd   ovsdb-server  |  |                               |     |                               |  +-------------------------------+     +-------------------------------+
ovn根据功能可以把节点分为两类:
# l& l) ^  E' V; k% @central: 可以看做中心节点,central节点组件包括OVN/CMS plugin、OVN Northbound DB、ovn-northd、OVN Southbound DB。
6 B9 S9 o* H* s8 Mhypervisor(hv): 可以看做工作节点,hypervisor节点组件包括ovn-controller、ovs-vswitchd、ovsdb-server。
" s; y0 c- I) tcentral节点相关组件和hypervisor组件运行在同一个物理节点上。
/ t2 p9 @9 n! b% N0 \1 i相关组件的功能如下:! S( o9 y1 N- A0 _- b3 z; {
1、CMS: 云管软件(Cloud Management Software),例如openstack(ovn最初就是设计给openstack用的)。; S9 |& C! D4 `6 ]$ U7 m
2、OVN/CMS plugin: 云管软件插件,例如openstack的neutron plugin。它的作用是将逻辑网络配置转换成OVN理解的数据,并写到北向数据库(OVN Northbound DB)中。3 E. i$ S: G2 P7 X. |9 k" E
3、OVN Northbound DB: ovn北向数据库,保存CMS plugin下发的配置,它有两个客户端CMS plugin和ovn-northd。通过ovn-nbctl命令直接操作它。北向数据库保存逻辑网络信息(交换机和路由器等)
/ ^$ I: n; R; P4、ovn-northd: 北向进程将OVN Northbound DB中的数据进行转换并保存到OVN Southbound DB。所有信息经过北向数据库通过ovn-northd北向进程和南向数据库互通。% Z/ W0 W" U- X& [# w' p7 N
5、OVN Southbound DB: ovn南向数据库,它也有两个客户端: 上面的ovn-northd和下面的运行在每个hypervisor上的ovn-controller。通过ovn-sbctl命令直接操作它。南向数据库保存各个节点的物理网络信息。
6 o) M0 B! J' R1 C6、ovn-controller: 相当于OVN在每个hypervisor上的agent(代理)。北向它连接到OVN Southbound Database学习最新的配置转换成openflow流表,南向它连接到ovs-vswitchd下发转换后的流表,同时也连接到ovsdb-server获取它需要的配置信息。
" @4 j$ \/ G8 e6 A- [7、ovs-vswitchd和ovs-dbserver: ovs用户态的两个进程。
: j2 A: l! P" l; {' G1 n; o/ W- n每个节点都有个ovn-controller控制器,这个ovn-controller控制器是管理ovs(ovs-vswitchd、ovsdb-server)的,ovn-controller对接到南向数据库,经过ovn-northd北向进程和北向数据库互通,之后和openstack互通。
6 f" [3 Y+ v% h2 T) f5 Y% R2 i南向数据库保存物理网络状态信息,北向数据库保存逻辑网络状态信息。; \1 ~# i4 b/ h3 q1 Y/ m2 w5 Z

$ U! D9 T9 I' F, W3 a$ ?                               
登录/注册后可看大图
) O4 r2 a5 G5 q, U  Y' ^6 p
克隆出两台虚拟机,安装ovs、ovn
CentOS Stream 8 版本systemctl stop firewalld.service systemctl disable firewalld.servicesetenforce 0sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/configmkdir /etc/yum.repos.d/bakmv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/cat <<EOF > /etc/yum.repos.d/cloudcs.repo[ceph]name=cephbaseurl=https://mirrors.aliyun.com/ceph/rpm-18.1.1/el8/x86_64/gpgkey=https://mirrors.aliyun.com/ceph/keys/release.ascgpgcheck=1enabled=1[ceph-noarch]name=ceph-noarchbaseurl=https://mirrors.aliyun.com/ceph/rpm-18.1.1/el8/noarch/gpgcheck=1gpgkey=https://mirrors.aliyun.com/ceph/keys/release.ascenabled=1[ceph-SRPMS]name=SRPMSbaseurl=https://mirrors.aliyun.com/ceph/rpm-18.1.1/el8/SRPMS/gpgcheck=1gpgkey=https://mirrors.aliyun.com/ceph/keys/release.ascenabled=1[highavailability]name=CentOS Stream 8 - HighAvailabilitybaseurl=https://mirrors.aliyun.com/centos/8-stream/HighAvailability/x86_64/os/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialgpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[nfv]name=CentOS Stream 8 - NFVbaseurl=https://mirrors.aliyun.com/centos/8-stream/NFV/x86_64/os/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialgpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[rt]name=CentOS Stream 8 - RTbaseurl=https://mirrors.aliyun.com/centos/8-stream/RT/x86_64/os/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialgpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[resilientstorage]name=CentOS Stream 8 - ResilientStoragebaseurl=https://mirrors.aliyun.com/centos/8-stream/ResilientStorage/x86_64/os/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialgpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[extras-common]name=CentOS Stream 8 - Extras packagesbaseurl=https://mirrors.aliyun.com/centos/8-stream/extras/x86_64/extras-common/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Extras-SHA512gpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[extras]name=CentOS Stream $releasever - Extrasmirrorlist=http://mirrorlist.centos.org/?release=$stream&arch=$basearch&repo=extras&infra=$infra#baseurl=http://mirror.centos.org/$contentdir/$stream/extras/$basearch/os/baseurl=https://mirrors.aliyun.com/centos/8-stream/extras/x86_64/os/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial[centos-ceph-pacific]name=CentOS - Ceph Pacificbaseurl=https://mirrors.aliyun.com/centos/8-stream/storage/x86_64/ceph-pacific/gpgcheck=0enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Storage[centos-rabbitmq-38]name=CentOS-8 - RabbitMQ 38baseurl=https://mirrors.aliyun.com/centos/8-stream/messaging/x86_64/rabbitmq-38/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Messaging[centos-nfv-openvswitch]name=CentOS Stream 8 - NFV OpenvSwitchbaseurl=https://mirrors.aliyun.com/centos/8-stream/nfv/x86_64/openvswitch-2/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-NFVmodule_hotfixes=1[baseos]name=CentOS Stream 8 - BaseOSbaseurl=https://mirrors.aliyun.com/centos/8-stream/BaseOS/x86_64/os/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialgpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[appstream]name=CentOS Stream 8 - AppStreambaseurl=https://mirrors.aliyun.com/centos/8-stream/AppStream/x86_64/os/gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialgpgcheck=1repo_gpgcheck=0metadata_expire=6hcountme=1enabled=1[centos-openstack-victoria]name=CentOS 8 - OpenStack victoriabaseurl=https://mirrors.aliyun.com/centos/8-stream/cloud/x86_64/openstack-victoria/#baseurl=https://repo.huaweicloud.com/centos/8-stream/cloud/x86_64/openstack-yoga/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Cloudmodule_hotfixes=1[powertools]name=CentOS Stream 8 - PowerTools#mirrorlist=http://mirrorlist.centos.org/?release=$stream&arch=$basearch&repo=PowerTools&infra=$infrabaseurl=https://mirrors.aliyun.com/centos/8-stream/PowerTools/x86_64/os/gpgcheck=1enabled=1gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialEOFyum install -y vim net-tools bash-completion git tcpdump autoconf automake libtool make python3 centos-release-openstack-victoria.noarchyum install -y openvswitch3.1*yum install -y ovn22.12*查看安装版本来检查ovn是否安装成功,# ovn-appctl --versionecho 'export PATH=$PATH:/usr/share/ovn/scripts:/usr/share/openvswitch/scripts' >> /etc/profilesource /etc/profile  重新读取配置文件让配置文件立即生效
7 V* @4 w& \8 }, T4 c
                               
登录/注册后可看大图
, H$ M& t' B1 _. [' c2 M; T; w. Z; Q
central相关组件启动:把node1作为central节点,安装central必需的三个组件:OVN Northbound DB、ovn-northd、OVN Southbound DB。2 k$ j( A1 ^  H0 x, ~$ d  \4 Y; F! Q! j  S+ |
在控制节点启动central,只用在一个控制节点上启动即可(node1或node2上开启都行,这里是在node1开启),central只需要一套即可。
ovn-ctl start_northd命令会自动启动北桥数据库、ovn-northd、南桥数据库三个服务[root@node1 ~]# ovn-ctl start_northd/etc/ovn/ovnnb_db.db does not exist ... (warning).Creating empty database /etc/ovn/ovnnb_db.db               [  OK  ]Starting ovsdb-nb                                          [  OK  ]/etc/ovn/ovnsb_db.db does not exist ... (warning).Creating empty database /etc/ovn/ovnsb_db.db               [  OK  ]Starting ovsdb-sb                                          [  OK  ]Starting ovn-northd                                        [  OK  ][root@node1 ~]# ps -ef | grep ovnroot       34102   34101  0 21:02 ?        00:00:00 ovsdb-server -vconsole:off -vfile:info --log-file=/var/log/ovn/ovsdb-server-nb.log --remote=punix:/var/run ovn/ovnnb_db.sock --pidfile=/var/run/ovn/ovnnb_db.pid --unixctl=/var/run/ovn/ovnnb_db.ctl --detach --monitor --remote=db:OVN_Northbound,NB_Global,connections --private-key=db:OVN_Northbound,SSL,private_key --certificate=db:OVN_Northbound,SSL,certificate --ca-cert=db:OVN_Northbound,SSL,ca_cert --ssl-protocols=db:OVN_Northbound,SSL,ssl_protocols --ssl-ciphers=db:OVN_Northbound,SSL,ssl_ciphers /etc/ovn/ovnnb_db.dbroot       34118   34117  0 21:02 ?        00:00:00 ovsdb-server -vconsole:off -vfile:info --log-file=/var/log/ovn/ovsdb-server-sb.log --remote=punix:/var/run ovn/ovnsb_db.sock --pidfile=/var/run/ovn/ovnsb_db.pid --unixctl=/var/run/ovn/ovnsb_db.ctl --detach --monitor --remote=db:OVN_Southbound,SB_Global,connections --private-key=db:OVN_Southbound,SSL,private_key --certificate=db:OVN_Southbound,SSL,certificate --ca-cert=db:OVN_Southbound,SSL,ca_cert --ssl-protocols=db:OVN_Southbound,SSL,ssl_protocols --ssl-ciphers=db:OVN_Southbound,SSL,ssl_ciphers /etc/ovn/ovnsb_db.dbroot       34128       1  0 21:02 ?        00:00:00 ovn-northd: monitoring pid 34129 (healthy)root       34129   34128  0 21:02 ?        00:00:00 ovn-northd -vconsole:emer -vsyslog:err -vfile:info --ovnnb-db=unix:/var/run/ovn/ovnnb_db.sock --ovnsb-db=unix:/var/run/ovn/ovnsb_db.sock --no-chdir --log-file=/var/log/ovn/ovn-northd.log --pidfile=/var/run/ovn/ovn-northd.pid --detach --monitorroot       34302   34259  0 21:07 pts/0    00:00:00 grep --color=auto ovn

2 a) V( T4 l, I3 S8 {  a8 [/ T+ O                               
登录/注册后可看大图
- \% u8 O7 \2 l
hypervisor相关组件启动:hypervisor节点包含三个组件:ovn-controller、ovs-vswitchd和ovsdb-server。5 C) O, J6 L% q8 Y0 I$ M+ p! y" L
启动hypervisor(hv)相关组件:node1和node2两台节点上都要启动,首先启动两个节点上的 ovs-vswitchd 和 ovsdb-server
[root@node1 ~]# ovs-ctl start --system-id=random/etc/openvswitch/conf.db does not exist ... (warning).Creating empty database /etc/openvswitch/conf.db           [  OK  ]Starting ovsdb-server                                      [  OK  ]Configuring Open vSwitch system IDs                        [  OK  ]Inserting openvswitch module                               [  OK  ]Starting ovs-vswitchd                                      [  OK  ]Enabling remote OVSDB managers                             [  OK  ][root@node2 ~]# ovs-ctl start --system-id=random/etc/openvswitch/conf.db does not exist ... (warning).Creating empty database /etc/openvswitch/conf.db           [  OK  ]Starting ovsdb-server                                      [  OK  ]Configuring Open vSwitch system IDs                        [  OK  ]Inserting openvswitch module                               [  OK  ]Starting ovs-vswitchd                                      [  OK  ]Enabling remote OVSDB managers                             [  OK  ]

; _  }( W+ C7 ^* j                               
登录/注册后可看大图

6 ~5 `4 s* Z" X. A, o两个节点分别启动ovn-controller
[root@node1 ~]# ovn-ctl start_controllerStarting ovn-controller                                    [  OK  ][root@node1 ~]# ovs-vsctl show       ovn-controler启动后会自动创建br-int网桥ed157e0c-cac3-46b9-830c-f2d710b475d5    Bridge br-int        fail_mode: secure        datapath_type: system        Port br-int            Interface br-int                type: internal    ovs_version: "3.1.3"[root@node2 ~]# ovn-ctl start_controllerStarting ovn-controller                                    [  OK  ][root@node2 ~]# ovs-vsctl show      ovn-controler启动后会自动创建br-int网桥f6669675-b42d-47de-be95-b26bf6d1e069    Bridge br-int        fail_mode: secure        datapath_type: system        Port br-int            Interface br-int                type: internal    ovs_version: "3.1.3"

9 ?+ e3 O/ ^; y; O  F                               
登录/注册后可看大图
& O: W5 N" u5 Y' j
可以看出此时hypervisor并没有和central关联起来(也就是ovn-controller没有和南向数据库连接)。可以在node1上验证:[root@node1 ~]# ovn-nbctl show
! G; ]. S3 t' ^; x+ thypervisor连接central,开放南北数据库端口:
ovn-northd之所以能连上南向数据和北向数据库,是因为它们部署在同一台机器上,通过unix sock连接central节点开放北向数据库端口6441,该端口主要给CMS plugins连接使用central节点开放南向数据库端口6442,该端口给ovn-controller连接[root@node1 ~]# ovn-nbctl set-connection ptcp:6641:10.1.1.41[root@node1 ~]# ovn-sbctl set-connection ptcp:6642:10.1.1.41[root@node1 ~]# netstat -tulnp |grep 664tcp        0      0 10.1.1.41:6641          0.0.0.0:*               LISTEN      34102/ovsdb-servertcp        0      0 10.1.1.41:6642          0.0.0.0:*               LISTEN      34118/ovsdb-servernode1上ovn-controller连接南向数据库ovn-remote:指定南向数据库连接地址ovn-encap-ip:指定ovs/controller本地ipovn-encap-type:指定隧道协议,这里用的是genevesystem-id:节点标识[root@node1 ~]# ovs-vsctl set Open_vSwitch . external-ids:ovn-remote="tcp:10.1.1.41:6642" external-ids:ovn-encap-ip="10.1.1.41" external-ids:ovn-encap-type=geneve external-ids:system-id=node1node2上ovn-controller连接南向数据库[root@node1 ~]# ovs-vsctl set Open_vSwitch . external-ids:ovn-remote="tcp:10.1.1.41:6642" external-ids:ovn-encap-ip="10.1.1.42" external-ids:ovn-encap-type=geneve external-ids:system-id=node2在node1查看南向数据库信息[root@node1 ~]# ovn-sbctl showChassis node2    hostname: node2    Encap geneve        ip: "10.1.1.42"        options: {csum="true"}Chassis node1    hostname: node1    Encap geneve        ip: "10.1.1.41"        options: {csum="true"}
; B% U0 F" {3 x( W
                               
登录/注册后可看大图

( d) k7 z' O/ i1 [2 @# D8 g以上的逻辑架构是站在底层组件和服务的角度来看的。
' C1 Y7 d* S( m  J' _, l4 V6 f接下来换一种角度,站在逻辑网络的角度来看。7 r- F0 M7 g7 \
& }1 k, {' q. ~! ?2 `
                               
登录/注册后可看大图
  j# Q- u$ v) N# H6 w  a
geneve隧道:ovn-controller连接南向数据库时,指定了external-ids:ovn-encap-type=geneve参数,此时看看两个节点上的ovs信息如下,会发现两个节点上都有一个ovn创建的ovs交换机br-int,而且br-int交换机上添加的节点port/interface类型都为geneve
[root@node1 ~]# ovs-vsctl show    node1上查看ovs信息ed157e0c-cac3-46b9-830c-f2d710b475d5    Bridge br-int        fail_mode: secure        datapath_type: system       Port br-int            Interface br-int                type: internal       Port ovn-node2-0            Interface ovn-node2-0                type: geneve                options: {csum="true", key=flow, remote_ip="10.1.1.42"}    ovs_version: "3.1.3"[root@node2 ~]# ovs-vsctl show    node2上查看ovs信息f6669675-b42d-47de-be95-b26bf6d1e069    Bridge br-int        fail_mode: secure        datapath_type: system       Port ovn-node1-0            Interface ovn-node1-0                type: geneve                options: {csum="true", key=flow, remote_ip="10.1.1.41"}       Port br-int            Interface br-int                type: internal    ovs_version: "3.1.3"[root@node1 ~]# ip link | grep gene  查看geneve隧道link5: genev_sys_6081: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 65000 qdisc noqueue master ovs-system state UNKNOWN mode DEFAULT group default qlen 1000查看geneve隧道link详情,从dstport 6081可以看出geneve隧道udp端口是6081[root@node1 ~]# ip -d link show genev_sys_6081  5: genev_sys_6081: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 65000 qdisc noqueue master ovs-system state UNKNOWN mode DEFAULT group default qlen 1000    link/ether 6a:e3:ff:a5:cc:d6 brd ff:ff:ff:ff:ff:ff promiscuity 1 minmtu 68 maxmtu 65465    geneve external id 0 ttl auto dstport 6081 udp6zerocsumrx    openvswitch_slave addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535查看geneve隧道udp端口,最后一列为“-”表示这个端口是内核态程序监听[root@node1 ~]# netstat -nulp|grep 6081udp        0      0 0.0.0.0:6081            0.0.0.0:*                           -udp6       0      0 :::6081                 :::*                                -[root@node2 ~]# ip link | grep gene5: genev_sys_6081: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 65000 qdisc noqueue master ovs-system state UNKNOWN mode DEFAULT group default qlen 1000[root@node2 ~]# ip -d link show genev_sys_60815: genev_sys_6081: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 65000 qdisc noqueue master ovs-system state UNKNOWN mode DEFAULT group default qlen 1000    link/ether 4e:db:f1:e4:43:94 brd ff:ff:ff:ff:ff:ff promiscuity 1 minmtu 68 maxmtu 65465    geneve external id 0 ttl auto dstport 6081 udp6zerocsumrx    openvswitch_slave addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535[root@node2 ~]# netstat -nulp|grep 6081udp        0      0 0.0.0.0:6081            0.0.0.0:*                           -udp6       0      0 :::6081                 :::*                                -
( d' A- \3 e0 \5 ]
                               
登录/注册后可看大图
在做以下实验验证时需要注意MAC地址的合法性,不要误配置。MAC地址分为三类:广播地址(全F)FF:FF:FF:FF:FF:FF主播地址(第一个字节为奇数)X1:XX:XX:XX:XX:XXX3:XX:XX:XX:XX:XXX5:XX:XX:XX:XX:XXX7:XX:XX:XX:XX:XXX9:XX:XX:XX:XX:XXXB:XX:XX:XX:XX:XXXD:XX:XX:XX:XX:XXXF:XX:XX:XX:XX:XX可用MAC地址(第一个字节为偶数)X0:XX:XX:XX:XX:XXX2:XX:XX:XX:XX:XXX4:XX:XX:XX:XX:XXX6:XX:XX:XX:XX:XXX8:XX:XX:XX:XX:XXXA:XX:XX:XX:XX:XXXC:XX:XX:XX:XX:XXXE:XX:XX:XX:XX:XX
在每个节点上创建一个网络命名空间ns1(因为在两个节点上所以同名ns1不会冲突),网络命名空间可理解为虚拟机,并且在ovs交换机上创建一组port和interfacce,然后把interface放到网络命名空间下。veth pair:两个网络虚拟端口(设备),veth可理解为网卡端口,一个端口在虚拟机上,一个端口在br-int虚拟交换机上。
node1上执行[root@node1 ~]# ip netns add ns1[root@node1 ~]# ip link add veth11 type veth peer name veth12[root@node1 ~]# ip link set veth12 netns ns1[root@node1 ~]# ip link set veth11 up[root@node1 ~]# ip netns exec ns1 ip link set veth12 address 00:00:00:00:00:01[root@node1 ~]# ip netns exec ns1 ip link set veth12 up[root@node1 ~]# ovs-vsctl add-port br-int veth11[root@node1 ~]# ip netns exec ns1 ip addr add 192.168.1.10/24 dev veth12node2上执行,注意veth12的ip和和node1上veth12 ip在同一个子网[root@node2 ~]# ip netns add ns1[root@node2 ~]# ip link add veth11 type veth peer name veth12[root@node2 ~]# ip link set veth12 netns ns1[root@node2 ~]# ip link set veth11 up[root@node2 ~]# ip netns exec ns1 ip link set veth12 address 00:00:00:00:00:02[root@node2 ~]# ip netns exec ns1 ip link set veth12 up[root@node2 ~]# ovs-vsctl add-port br-int veth11[root@node2 ~]# ip netns exec ns1 ip addr add 192.168.1.20/24 dev veth12查看node1上br-int交换机信息[root@node1 ~]# ovs-vsctl showed157e0c-cac3-46b9-830c-f2d710b475d5    Bridge br-int        fail_mode: secure        datapath_type: system       Port br-int            Interface br-int                type: internal       Port veth11            Interface veth11       Port ovn-node2-0            Interface ovn-node2-0                type: geneve                options: {csum="true", key=flow, remote_ip="10.1.1.42"}    ovs_version: "3.1.3"查看node2上br-int交换机信息[root@node2 ~]# ovs-vsctl showf6669675-b42d-47de-be95-b26bf6d1e069    Bridge br-int        fail_mode: secure        datapath_type: system       Port veth11            Interface veth11       Port ovn-node1-0            Interface ovn-node1-0                type: geneve                options: {csum="true", key=flow, remote_ip="10.1.1.41"}       Port br-int            Interface br-int                type: internal    ovs_version: "3.1.3"现在从node1上的ns1 ping node2上的ns1是不通的,因为它们是不同主机上的网络,二/三层广播域暂时还不可达。[root@node1 ~]# ip netns exec ns1 ping -c 3 192.168.1.20PING 192.168.1.20 (192.168.1.20) 56(84) bytes of data.--- 192.168.1.20 ping statistics ---3 packets transmitted, 0 received, 100% packet loss, time 2047ms
: P. D# m# c8 E& t- n* I4 T
                               
登录/注册后可看大图

7 G$ D+ F: f# _7 X3 q$ h( z查看openstack的控制节点发现,ovn的北向数据库中有逻辑交换机信息。: `! V% y( A0 ]2 p: `
在openstack里面,创建一个网络,就相当于创建了一个逻辑虚拟交换机,这个逻辑交换机(网络)信息会被保存到北向数据库里面。一个网络就是一个逻辑交换机。
% _5 G" k) B; ^: k
9 B9 S$ c; {  K8 _( A
                               
登录/注册后可看大图

6 ~& l, t1 H) S. q在node1中查看发现,ovn的北向数据库中没有逻辑交换机信息
+ h1 r4 k3 d& b2 [* D: r, t

) w5 D7 v7 o9 a% Z) L                               
登录/注册后可看大图
! b8 |2 o( |0 l& q9 l7 Q
在openstack不同节点的虚拟机ip互通,这两个虚拟机ip连的是同一个网络,是同一个逻辑交换机上的同一个子网不同ip所以互通。
! l1 q& t( e/ t! w4 t这两个节点的虚拟机ns1的ip是手工配置的独立的、不互通,这两个虚拟机ip没有连到逻辑交换机上,加个逻辑交换机就能互通。
" `7 [( M" R) @

! e4 T% b/ Y$ g                               
登录/注册后可看大图
4 t. K: x8 P7 [5 e
逻辑交换机(Logical Switch):为了使node1和node2上两个连接到ovs交换机的ns能正常通信,需借助ovn的逻辑交换机,注意逻辑交换机是北向数据库概念。
在node1上创建逻辑交换机[root@node1 ~]# ovn-nbctl ls-add ls1[root@node1 ~]#  ovn-nbctl showswitch 86349e35-cdb4-42f7-a702-4b4a9d5653ef (ls1)在逻辑交换机上添加端口添加并设置用于连接node1的端口,注意mac地址要和veth pair网络命名空间内的那端匹配起来[root@node1 ~]# ovn-nbctl lsp-add ls1 ls1-node1-ns1[root@node1 ~]# ovn-nbctl lsp-set-addresses ls1-node1-ns1 00:00:00:00:00:01[root@node1 ~]# ovn-nbctl lsp-set-port-security ls1-node1-ns1 00:00:00:00:00:01添加并设置用于连接node2的端口,注意mac地址要匹配起来[root@node1 ~]# ovn-nbctl lsp-add ls1 ls1-node2-ns1[root@node1 ~]# ovn-nbctl lsp-set-addresses ls1-node2-ns1 00:00:00:00:00:02[root@node1 ~]# ovn-nbctl lsp-set-port-security ls1-node2-ns1 00:00:00:00:00:02查看逻辑交换机信息[root@node1 ~]# ovn-nbctl showswitch 86349e35-cdb4-42f7-a702-4b4a9d5653ef (ls1)    port ls1-node1-ns1        addresses: ["00:00:00:00:00:01"]    port ls1-node2-ns1        addresses: ["00:00:00:00:00:02"]node1上执行,veth11端口连接逻辑交换机端口[root@node1 ~]# ovs-vsctl set interface veth11 external-ids:iface-id=ls1-node1-ns1node2上执行,veth11端口连接逻辑交换机端口[root@node2 ~]# ovs-vsctl set interface veth11 external-ids:iface-id=ls1-node2-ns1再次查看南向数据库信息,发现端口已连接[root@node1 ~]# ovn-sbctl showChassis node2    hostname: node2    Encap geneve        ip: "10.1.1.42"        options: {csum="true"}    Port_Binding ls1-node2-ns1Chassis node1    hostname: node1    Encap geneve        ip: "10.1.1.41"        options: {csum="true"}    Port_Binding ls1-node1-ns1node1上验证网络连通性[root@node1 ~]# ip netns exec ns1 ping -c 3 192.168.1.20PING 192.168.1.20 (192.168.1.20) 56(84) bytes of data.64 bytes from 192.168.1.20: icmp_seq=1 ttl=64 time=4.68 ms64 bytes from 192.168.1.20: icmp_seq=2 ttl=64 time=0.908 ms64 bytes from 192.168.1.20: icmp_seq=3 ttl=64 time=0.756 ms--- 192.168.1.20 ping statistics ---3 packets transmitted, 3 received, 0% packet loss, time 2004msrtt min/avg/max/mdev = 0.756/2.115/4.682/1.816 msnode2上验证网络连通性[root@node2 ~]# ip netns exec ns1 ping -c 3 192.168.1.10PING 192.168.1.10 (192.168.1.10) 56(84) bytes of data.64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=3.34 ms64 bytes from 192.168.1.10: icmp_seq=2 ttl=64 time=0.863 ms64 bytes from 192.168.1.10: icmp_seq=3 ttl=64 time=0.372 ms--- 192.168.1.10 ping statistics ---3 packets transmitted, 3 received, 0% packet loss, time 2003msrtt min/avg/max/mdev = 0.372/1.525/3.342/1.300 ms
现在node1和node2的ns1互通了,相当于创建了两个实例,这两个实例ip用的子网是连在同一个逻辑交换机上的,是同一个逻辑交换机上的同一个子网不同ip所以互通。  B$ T) a4 N! Z8 _) m& a
" n6 ?# V. b0 S! T& `% i5 w
                               
登录/注册后可看大图
5 @  [( f% b3 N0 c
' m! q- |- V1 N- ^7 d
                               
登录/注册后可看大图

) I# G% F$ R3 S% r6 z: I; Zgeneve隧道验证:从node1上的ns1 ping node2上的ns1的例子,抓包看看各个相关组件报文,验证geneve隧道封解包。通过抓包分析,可以看出geneve隧道在ovn/ovs跨主机通信的重要作用,同时也能看到ovn逻辑交换机可以把不同宿主机上的二层网络打通,或者说ovn逻辑交换机可以把ovs二层广播域扩展到跨主机。
// node1上ns1 ping node2上ns1# ip netns exec ns1 ping -c 1 192.168.1.20PING 192.168.1.20 (192.168.1.20) 56(84) bytes of data.64 bytes from 192.168.1.20: icmp_seq=1 ttl=64 time=1.00 ms--- 192.168.1.20 ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 1.009/1.009/1.009/0.000 ms// node1上ns1中的veth12抓包# ip netns exec ns1 tcpdump -i veth12 -ntcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on veth12, link-type EN10MB (Ethernet), capture size 262144 bytes22:23:11.364011 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 24275, seq 1, length 6422:23:11.365000 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 24275, seq 1, length 6422:23:16.364932 ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 2822:23:16.365826 ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 28// node1上veth12的另一端veth11抓包# tcpdump -i veth11 -ntcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on veth11, link-type EN10MB (Ethernet), capture size 262144 bytes22:25:11.225987 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 25166, seq 1, length 6422:25:11.226914 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 25166, seq 1, length 6422:25:16.236933 ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 2822:25:16.237563 ARP, Request who-has 192.168.1.10 tell 192.168.1.20, length 2822:25:16.237627 ARP, Reply 192.168.1.10 is-at 00:00:00:00:00:01, length 2822:25:16.237649 ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 28// node1上genev_sys_6081网卡抓包# tcpdump -i genev_sys_6081 -ntcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on genev_sys_6081, link-type EN10MB (Ethernet), capture size 262144 bytes22:28:15.872064 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 26492, seq 1, length 6422:28:15.872717 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 26492, seq 1, length 6422:28:20.877100 ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 2822:28:20.877640 ARP, Request who-has 192.168.1.10 tell 192.168.1.20, length 2822:28:20.877654 ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 2822:28:20.877737 ARP, Reply 192.168.1.10 is-at 00:00:00:00:00:01, length 28// node1上eth0抓包,可以看出数据包经过genev_sys_6081后做了geneve封装# tcpdump -i eth0 port 6081 -ntcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes22:30:23.446147 IP 10.0.12.7.51123 > 10.0.12.11.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 27458, seq 1, length 6422:30:23.446659 IP 10.0.12.11.50319 > 10.0.12.7.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 27458, seq 1, length 6422:30:28.461137 IP 10.0.12.7.49958 > 10.0.12.11.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 2822:30:28.461554 IP 10.0.12.11.61016 > 10.0.12.7.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: ARP, Request who-has 192.168.1.10 tell 192.168.1.20, length 2822:30:28.461571 IP 10.0.12.11.61016 > 10.0.12.7.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 2822:30:28.461669 IP 10.0.12.7.49958 > 10.0.12.11.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: ARP, Reply 192.168.1.10 is-at 00:00:00:00:00:01, length 28===================跨主机===================// node2上eth0抓包# tcpdump -i eth0 port 6081 -ntcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes22:23:11.364189 IP 10.0.12.7.51123 > 10.0.12.11.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 24275, seq 1, length 6422:23:11.364662 IP 10.0.12.11.50319 > 10.0.12.7.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 24275, seq 1, length 6422:23:16.365086 IP 10.0.12.7.49958 > 10.0.12.11.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 2822:23:16.365487 IP 10.0.12.11.61016 > 10.0.12.7.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 28// node2上genev_sys_6081网卡抓包,可以看到数据包从genev_sys_6081出来后做了geneve解封# tcpdump -i genev_sys_6081 -ntcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on genev_sys_6081, link-type EN10MB (Ethernet), capture size 262144 bytes22:25:11.226186 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 25166, seq 1, length 6422:25:11.226553 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 25166, seq 1, length 6422:25:16.237070 ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 2822:25:16.237162 ARP, Request who-has 192.168.1.10 tell 192.168.1.20, length 2822:25:16.237203 ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 2822:25:16.237523 ARP, Reply 192.168.1.10 is-at 00:00:00:00:00:01, length 28// node2上veth11抓包# tcpdump -i veth11 -ntcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on veth11, link-type EN10MB (Ethernet), capture size 262144 bytes22:28:15.872198 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 26492, seq 1, length 6422:28:15.872235 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 26492, seq 1, length 6422:28:20.876913 ARP, Request who-has 192.168.1.10 tell 192.168.1.20, length 2822:28:20.877274 ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 2822:28:20.877287 ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 2822:28:20.877613 ARP, Reply 192.168.1.10 is-at 00:00:00:00:00:01, length 28// node2上ns1中的veth12抓包# ip netns exec ns1 tcpdump -i veth12 -ntcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on veth12, link-type EN10MB (Ethernet), capture size 262144 bytes22:30:23.446212 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 27458, seq 1, length 6422:30:23.446242 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 27458, seq 1, length 6422:30:28.460912 ARP, Request who-has 192.168.1.10 tell 192.168.1.20, length 2822:30:28.461260 ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 2822:30:28.461272 ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 2822:30:28.461530 ARP, Reply 192.168.1.10 is-at 00:00:00:00:00:01, length 28
逻辑路由器(Logical Router):
) K6 }+ @# E6 j1 N  a前面验证了ovn逻辑交换机跨主机同子网的通信,那不同子网间又该如何通信呢?这就要用到ovn的逻辑路由器了。. L) W$ w, v' h/ t1 {
先在node2上再创建个网络命名空间ns2,ip设置为另外一个子网192.168.2.30/24,并且再增加一个逻辑交换机。2 w7 L8 p! g0 G7 q( S+ R

. T' r# V# w( U+ \                               
登录/注册后可看大图
node2上执行[root@node2 ~]# ip netns  查看网络命名空间ns1 (id: 0)[root@node2 ~]# ip netns add ns2[root@node2 ~]# ip link add veth21 type veth peer name veth22[root@node2 ~]# ip link set veth22 netns ns2[root@node2 ~]# ip link set veth21 up[root@node2 ~]# ip netns exec ns2 ip link set veth22 address 00:00:00:00:00:03[root@node2 ~]# ip netns exec ns2 ip link set veth22 up[root@node2 ~]# ovs-vsctl add-port br-int veth21[root@node2 ~]# ip netns exec ns2 ip addr add 192.168.2.30/24 dev veth22[root@node2 ~]# ip netnsns2 (id: 1)ns1 (id: 0)node1上用ovn命令新增一个逻辑交换机,并配置好端口[root@node1 ~]# ovn-nbctl ls-add ls2[root@node1 ~]# ovn-nbctl lsp-add ls2 ls2-node2-ns2[root@node1 ~]# ovn-nbctl lsp-set-addresses ls2-node2-ns2 00:00:00:00:00:03[root@node1 ~]# ovn-nbctl lsp-set-port-security ls2-node2-ns2 00:00:00:00:00:03node2上ovs交换机端口和ovn逻辑交换机端口匹配起来[root@node2 ~]# ovs-vsctl set interface veth21 external-ids:iface-id=ls2-node2-ns2查看北向数据库和南向数据库信息[root@node1 ~]# ovn-nbctl showswitch 484606e0-944d-4c6b-9807-502f05bebb18 (ls2)    port ls2-node2-ns2        addresses: ["00:00:00:00:00:03"]switch 86349e35-cdb4-42f7-a702-4b4a9d5653ef (ls1)    port ls1-node1-ns1        addresses: ["00:00:00:00:00:01"]    port ls1-node2-ns1        addresses: ["00:00:00:00:00:02"][root@node1 ~]# ovn-sbctl showChassis node2    hostname: node2    Encap geneve        ip: "10.1.1.42"        options: {csum="true"}    Port_Binding ls2-node2-ns2    Port_Binding ls1-node2-ns1Chassis node1    hostname: node1    Encap geneve        ip: "10.1.1.41"        options: {csum="true"}    Port_Binding ls1-node1-ns1
创建ovn逻辑路由器连接两个逻辑交换机
添加逻辑路由器,路由信息保存在北向数据库[root@node1 ~]# ovn-nbctl lr-add lr1逻辑路由器添加连接交换机ls1的端口[root@node1 ~]# ovn-nbctl lrp-add lr1 lr1-ls1 00:00:00:00:11:00 192.168.1.1/24逻辑路由器添加连接交换机ls2的端口[root@node1 ~]# ovn-nbctl lrp-add lr1 lr1-ls2 00:00:00:00:12:00 192.168.2.1/24逻辑路由器连接逻辑交换机ls1[root@node1 ~]# ovn-nbctl lsp-add ls1 ls1-lr1[root@node1 ~]# ovn-nbctl lsp-set-type ls1-lr1 router[root@node1 ~]# ovn-nbctl lsp-set-addresses ls1-lr1 00:00:00:00:11:00[root@node1 ~]# ovn-nbctl lsp-set-options ls1-lr1 router-port=lr1-ls1逻辑路由器连接逻辑交换机ls2[root@node1 ~]# ovn-nbctl lsp-add ls2 ls2-lr1[root@node1 ~]# ovn-nbctl lsp-set-type ls2-lr1 router[root@node1 ~]# ovn-nbctl lsp-set-addresses ls2-lr1 00:00:00:00:12:00[root@node1 ~]# ovn-nbctl lsp-set-options ls2-lr1 router-port=lr1-ls2查看北向数据库和南向数据库信息[root@node1 ~]# ovn-nbctl showswitch 484606e0-944d-4c6b-9807-502f05bebb18 (ls2)    port ls2-node2-ns2        addresses: ["00:00:00:00:00:03"]    port ls2-lr1        type: router        addresses: ["00:00:00:00:12:00"]        router-port: lr1-ls2switch 86349e35-cdb4-42f7-a702-4b4a9d5653ef (ls1)    port ls1-node1-ns1        addresses: ["00:00:00:00:00:01"]    port ls1-node2-ns1        addresses: ["00:00:00:00:00:02"]    port ls1-lr1        type: router        addresses: ["00:00:00:00:11:00"]        router-port: lr1-ls1router e9c151a0-5db7-4af6-91bd-89049c4bbf9f (lr1)    port lr1-ls2        mac: "00:00:00:00:12:00"        networks: ["192.168.2.1/24"]    port lr1-ls1        mac: "00:00:00:00:11:00"        networks: ["192.168.1.1/24"][root@node1 ~]# ovn-sbctl showChassis node2    hostname: node2    Encap geneve        ip: "10.1.1.42"        options: {csum="true"}    Port_Binding ls2-node2-ns2    Port_Binding ls1-node2-ns1Chassis node1    hostname: node1    Encap geneve        ip: "10.1.1.41"        options: {csum="true"}    Port_Binding ls1-node1-ns1
' k- m2 L4 V6 Z- I
                               
登录/注册后可看大图
! X6 e1 {/ d4 j" v( f. L" c& C  q
从node1的ns1(192.168.1.10/24) ping node2的ns2(192.168.2.30),验证跨节点不同子网的连通性。
[root@node1 ~]# ip netns exec ns1 ping -c 1 192.168.2.30connect: Network is unreachable        connect: 网络不可达查看ns1上的路由配置,显然此时没有到192.168.2.0/24网段的路由[root@node1 ~]# ip netns exec ns1 ip route show192.168.1.0/24 dev veth12 proto kernel scope link src 192.168.1.10[root@node1 ~]# ip netns exec ns1 route -nKernel IP routing tableDestination     Gateway         Genmask         Flags Metric Ref    Use Iface192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 veth12
因为路由器是三层概念,要先给ovs的相关port配置上ip
[root@node1 ~]# ovn-nbctl lsp-set-addresses ls1-node1-ns1 00:00:00:00:00:01[root@node1 ~]# ovn-nbctl lsp-set-addresses ls1-node2-ns1 00:00:00:00:00:02[root@node1 ~]# ovn-nbctl lsp-set-addresses ls2-node2-ns2 00:00:00:00:00:03
再给三个网络命名空间添加默认路由,网关为ovn逻辑路由器对应的port ip
node1上ns1 [root@node1 ~]# ip netns exec ns1 ip route add default via 192.168.1.1 dev veth12 node2上ns1 [root@node2 ~]# ip netns exec ns1 ip route add default via 192.168.1.1 dev veth12 node2上ns2 [root@node2 ~]# ip netns exec ns2 ip route add default via 192.168.2.1 dev veth22
再次查看下南北向数据库信息
[root@node1 ~]# ovn-nbctl showswitch 484606e0-944d-4c6b-9807-502f05bebb18 (ls2)    port ls2-node2-ns2        addresses: ["00:00:00:00:00:03"]    port ls2-lr1        type: router        addresses: ["00:00:00:00:12:00"]        router-port: lr1-ls2switch 86349e35-cdb4-42f7-a702-4b4a9d5653ef (ls1)    port ls1-node1-ns1        addresses: ["00:00:00:00:00:01"]    port ls1-node2-ns1        addresses: ["00:00:00:00:00:02"]    port ls1-lr1        type: router        addresses: ["00:00:00:00:11:00"]        router-port: lr1-ls1router e9c151a0-5db7-4af6-91bd-89049c4bbf9f (lr1)    port lr1-ls2        mac: "00:00:00:00:12:00"        networks: ["192.168.2.1/24"]    port lr1-ls1        mac: "00:00:00:00:11:00"        networks: ["192.168.1.1/24"][root@node1 ~]# ovn-sbctl showChassis node2    hostname: node2    Encap geneve        ip: "10.1.1.42"        options: {csum="true"}    Port_Binding ls2-node2-ns2    Port_Binding ls1-node2-ns1Chassis node1    hostname: node1    Encap geneve        ip: "10.1.1.41"        options: {csum="true"}    Port_Binding ls1-node1-ns1
/ l' V7 F/ i: Q+ z3 j# a# A2 l# u
                               
登录/注册后可看大图

8 {: U  U& V" l9 t; Y& S验证网络连通性
node1上ns1连通网关[root@node1 ~]# ip netns exec ns1 ping -c 1 192.168.1.1PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.64 bytes from 192.168.1.1: icmp_seq=1 ttl=254 time=20.10 ms--- 192.168.1.1 ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 20.950/20.950/20.950/0.000 msnode2上ns2连通网关[root@node2 ~]# ip netns exec ns2 ping -c 1 192.168.2.1PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.64 bytes from 192.168.2.1: icmp_seq=1 ttl=254 time=38.5 ms--- 192.168.2.1 ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 38.477/38.477/38.477/0.000 msnode1上ns1 ping node2上ns2[root@node1 ~]# ip netns exec ns1 ping -c 1 192.168.2.30PING 192.168.2.30 (192.168.2.30) 56(84) bytes of data.64 bytes from 192.168.2.30: icmp_seq=1 ttl=63 time=1.23 ms--- 192.168.2.30 ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 1.225/1.225/1.225/0.000 ms
注意:ovn逻辑交换机/逻辑路由器是北向数据库概念,这两个逻辑概念经过ovn-northd“翻译”到了南向数据库中,再通过hypervisor上的ovn-controller同步到ovs/ovsdb-server,最终形成ovs的port和流表等数据。
6 E: L( y1 j/ j  g( B( r$ {# Govn逻辑交换机通过geneve隧道,把二层广播域扩展到了不同主机上的ovs;而ovn逻辑路由器则是把三层广播域扩展到了不同主机上的ovs,从而实现跨主机的网络通信。' R& M" D  H4 o/ o4 m, M
ovn逻辑交换机和逻辑路由器都会在所有的hypervisor中生成对应的流表配置,这也是ovn网络高可用以及解决实例迁移等问题的原理。
1 m% k9 Q7 q, b5 O2 x% J) X

# x. q/ h: K/ V8 O. Q( v+ Z, v. M6 Q1 L9 _( u$ L" v. ?4 q( x
 楼主| 发表于 2025-12-18 08:51:30 | 显示全部楼层
2、网络服务Neutron
( X& m# \% Y. ?( z6 wNeutron基于软件定义网络的思想,实现了网络虚拟化下的资源管理。Neutron的设计目标是实现网络即服务(NaaS),在设计上遵循SDN(Software Defined Network,软件定义网络)架构来管理的。7 K5 G7 v2 W. m+ C* x( i' J
Neutron主要包含Neutron server、Plugin和Agent等组件。Neutron server对外提供 OpenStack网络 API,接收请求,并调用Plugin处理请求;Plugin处理 Neutron Server发来的请求,维护OpenStack逻辑网络的状态, 并调用 Agent 处理请求;Agent处理Plugin的请求,负责在network provider上真正实现各种网络功能;此外还有database,用来存放OpenStack的网络状态信息,包括Network、Subnet、Port、Router等。; U" S# j* L, w; }4 I$ l

  m2 |% Q6 s: @* O& q2 P# h/ ^/ _3、OVS
$ r7 t- M9 q9 l  v: \OVS(Open vSwitch)是虚拟交换机,遵循SDN(Software Defined Network,软件定义网络)架构来管理的。* {- L' O! u1 c/ |' ]6 ?
OVS介绍参考:https://mp.weixin.qq.com/s?__biz ... 189#wechat_redirect  ?  G) E# j8 @' N4 v8 c3 [6 A
在这里插入图片描述
& F: q) W, m. S3 X! _& \ovs由三个组件组成:dataPath、vswitchd和ovsdb。
2 K4 A: F- |0 b8 DdataPath(opevswitch.ko):openvswitch.ko是ovs的内核模块,当openvswitch.ko模块被加载到内核时,会在网卡上注册一个钩子函数,每当网络包到达网卡时这个钩子函数就会被调用。openvswitch.ko模块在处理网络包时,会先匹配内核中能不能匹配到策略(内核流表)来处理,如果匹配到了策略,则直接在内核态根据该策略做网络包转发,这个过程全程在内核中完成,处理速度非常快,也称之为fast path(快速通道);如果内核中没有匹配到相应策略,则把数据包交给用户态的vswitchd进程处理,此时叫作slow path(慢通道)。dataPath模块可以通过ovs-dpctl命令来配置。
9 j) q+ g$ f8 w/ a  a8 p* O! ovswitchd:vswitchd是ovs的核心模块,它工作在用户空间(user space),负责与OpenFlow控制器、第三方软件通信。vswitchd接收到数据包时,会去匹配用户态流表,如果匹配成功则根据相关规则转发;如果匹配不成功,则会根据OpenFlow协议规范处理,把数据包上报给控制器(如果有)或者丢弃。1 W) l5 o8 L5 ~( b1 a( ^3 f
ovsdb:ovs数据库,存储整个ovs的配置信息,包括接口、交换内容、vlan、虚拟交换机信息等。# A1 L0 A! \- |+ r9 M6 V( h! v
ovs相关术语解释:
  I1 P6 k( \- v  u  I1、Bridge:网桥,也就是交换机(不过是虚拟的,即vSwitch),一台主机中可以创建多个网桥。当数据包从网桥的某个端口进来后,网桥会根据一定的规则把该数据包转发到另外的端口,也可以修改或者丢弃报文。Bridge桥指的是虚拟交换机。
, r( t' m6 x& M* M  q2、Port:交换机的端口,有以下几种类型:
$ R4 g5 f& y9 M" \$ Z: ]8 bNormal: 将物理网卡添加到bridge时它们会成为Port,类型为Normal。此时物理网卡配置ip已没有意义,它已经“退化成一根网线”只负责数据报文的进出。Normal类型的Port常用于vlan模式下多台物理主机相连的那个口,交换机的一端属于Trunk模式。" G, f3 @$ p: p2 u
Internal: 此类型的Port,ovs会自动创建一个虚拟网卡接口(Interface),此端口收到数据都会转发给这块网卡,从网卡发出的数据也会通过Port交给ovs处理。当ovs创建一个新的Bridge时,会自动创建一个与网桥同名的Internal Port,同时也会创建一个与网桥同名的Interface。另外,Internal Port可配置IP地址,然后将其up,即可实现ovs三层网络。
+ l. B8 {3 C6 Y% z" H. YPatch: 与veth pair功能类似,常用于连接两个Bridge。veth pair:两个网络虚拟端口(设备)2 @* o; f4 P9 }
Tunnel: 实现overlay网络,支持GRE、vxlan、STT、Geneve和IPSec等隧道协议。Tunnel:隧道,三层" l  V. n& f/ A4 j. K
3、Interface:网卡,虚拟的(TUN/TAP)或物理的都可以。TAP:单个网络虚拟端口(设备),基于二层;TUN:单个网络虚拟端口(设备),基于三层。veth pair:两个网络虚拟端口(设备),常用于连接两个Bridge。
1 f( @, o0 T( P4 X7 `2 c; O' E$ j4、Controller:控制器,ovs可以接收一个或多个OpenFlow控制器的管理,主要功能为下发流表来控制转发规则。; h$ Y0 ~- g& T2 @4 l4 I6 S
5、FlowTable:流表,ovs进行数据转发的核心功能,定义了端口之间的转发数据规则。每条流表规则可以分为匹配和动作两部分,“匹配”决定哪些数据将被处理,“动作”则决定了这些数据将被如何处理。( d$ b# Z' M& e/ G* {4 F: u7 H
在这里插入图片描述
: m/ x5 t3 ~0 T; p! eens160的ip地址没有了,用的是br-ex的ip地址出去的。* w2 K6 u5 {; m" i6 W7 Y, L+ T4 J
在这里插入图片描述, v" {: `/ p1 v, I* ]
ovs安装
! T+ P1 J  S/ }3 ^; E) s1 O7 k1.开启一台新的linux$ B4 Z2 C( U; P  H/ `
2.配置在线yum源(openstack那个在线yum源)- F, [9 X' k  z( Y
$ b* L' y' R) Y& X, z
配置yum源(先把原有的备份后清空)
# q  i( Y' ~) \8 V# cd /etc/yum.repos.d/      # rm -rf *
1 p. z1 ]2 z. ?2 {6 D0 f1 l5 U# cat cloud.repo
5 [, f* \- [" [6 o) U
  G* l( b( ^) o[highavailability]
% g1 `: i1 L1 D6 vname=CentOS Stream 8 - HighAvailability
7 J+ T. R6 D" j- k, ?baseurl=https://mirrors.aliyun.com/centos/8-stream/HighAvailability/x86_64/os/
: m: F% Z* x2 Zgpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
1 d9 W" U+ C, t/ h/ j* a0 l2 n( ygpgcheck=1; s$ U% S& F# R! V$ L8 D8 f
repo_gpgcheck=0- a: }# v, R+ ~4 [& c1 L
metadata_expire=6h
: S/ Q  c: A2 d, g6 Kcountme=1
. B% B9 N: }1 Menabled=1
4 f* ^8 c/ X- c& C
0 @( Y! R3 N! ^6 }  `' I[nfv]
! ~# ]( s, _$ }; q. c4 ?; }name=CentOS Stream 8 - NFV
% q# d- h" N- u+ x( q) e: z0 v# Ebaseurl=https://mirrors.aliyun.com/centos/8-stream/NFV/x86_64/os/4 l1 ^0 ~0 A" Z
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial3 D$ Z! l: |' k, R) `' e' n
gpgcheck=15 `8 i$ V0 `$ W0 k
repo_gpgcheck=0
8 Q! d" p# [! W" C" s  _metadata_expire=6h
# P8 B3 l% {* _' N+ ~8 J: ^8 P- tcountme=10 [/ P; ^! ]6 f
enabled=12 z' l6 Q% T  ^4 y5 v% h  c! z

# W2 U- M" U# c8 b: y1 P! x$ m4 k# w[rt]; n2 P* n2 i2 q: G5 C$ C
name=CentOS Stream 8 - RT
3 G$ U- y% ~+ S: Rbaseurl=https://mirrors.aliyun.com/centos/8-stream/RT/x86_64/os/
$ q) z2 q$ ]% I4 sgpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
& b: ~/ Q  A7 q6 S) _$ fgpgcheck=16 O" b( S  ~# F6 N% Q8 q- x! j' m. }& K
repo_gpgcheck=0
  j% z$ I) s' H2 }9 U! G4 A7 Smetadata_expire=6h  w3 }- ?9 D1 l8 K  E% _
countme=1
8 T: g$ Q% U0 S) U# K* m0 o  c- Nenabled=1
9 [0 B  O2 X9 I' k6 c3 }( Z! O1 S4 `3 h$ ^* T5 h
[resilientstorage]
6 O# U, K; _# p" z- [7 E& |6 P" Q( Q7 dname=CentOS Stream 8 - ResilientStorage7 x; |: e- [# s4 m/ v% P" u1 P
baseurl=https://mirrors.aliyun.com/centos/8-stream/ResilientStorage/x86_64/os/% \1 A% n( A# D! T: b; }* W- l$ t
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
8 w+ p) N' V# H& ~/ R6 G3 H$ L; mgpgcheck=16 A1 I6 U* h8 v% f9 d0 R# q
repo_gpgcheck=0
. e; S( A9 ?7 b" x  v* y0 Ometadata_expire=6h
+ _8 c0 N# L! Z) y7 u5 x7 jcountme=1( }& k. Z4 o- d1 ~! r, c! P& V3 O
enabled=1
8 {/ K3 B: _/ ^. w/ s  q( G2 Y( R5 U+ u/ ^" [5 D  Q" X- i# S) l
[extras-common]
0 X( [) q/ P/ Cname=CentOS Stream 8 - Extras packages
! ?$ L9 \# T" u6 h7 P$ B5 cbaseurl=https://mirrors.aliyun.com/centos/8-stream/extras/x86_64/extras-common/
; |, P: t3 o& Q1 w: v+ r% sgpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Extras-SHA512! A! @3 G' k' g7 h
gpgcheck=1
5 I# j/ h" z1 wrepo_gpgcheck=03 H4 j7 [# {, W) j6 J* [. p- q# s
metadata_expire=6h" h& w+ _5 h2 b, R8 N6 @( A  Y0 s
countme=1
% A8 k1 w) g  Henabled=1
& K  k; A% b5 o- I9 u
1 m" z% T  S8 _[extras]
& r7 y: [  [0 c; xname=CentOS Stream  - Extras6 j6 I# E4 S) a* N* l5 r
mirrorlist=http://mirrorlist.centos.org/?release=&arch=&repo=extras&infra=& k! N. {- V% K' U2 B. H
#baseurl=http://mirror.centos.org///extras//os/
( \0 J: d) Z# I1 Y4 ^" qbaseurl=https://mirrors.aliyun.com/centos/8-stream/extras/x86_64/os/) b8 j; t; o; q6 o. P; b* V
gpgcheck=1
6 I' ^# O$ z% u4 Nenabled=1
  [; c7 y4 v# g! w) egpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
4 c+ u3 b, V* r9 j5 L7 P' A
% v1 o$ Y  A7 L. U+ q2 d[centos-ceph-pacific]* j; f- [* h/ P0 @4 n$ O
name=CentOS - Ceph Pacific
2 p- j( h8 k, ?! a9 O) A% x& d0 }1 X  ubaseurl=https://mirrors.aliyun.com/centos/8-stream/storage/x86_64/ceph-pacific/
" w# I7 t0 g7 }1 l( K( `gpgcheck=0: |& c4 j) l3 L- A8 P
enabled=1& J8 Q5 `/ p0 h+ E, V& p- g; P& ]
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Storage
" J: T; G% n/ [) }* h7 t$ _" [) R' V* O  b- C0 S- }
[centos-rabbitmq-38]
; x7 s6 V7 H1 d5 Z! R3 }! Vname=CentOS-8 - RabbitMQ 38
( J# m8 C7 x0 O: P8 e$ abaseurl=https://mirrors.aliyun.com/centos/8-stream/messaging/x86_64/rabbitmq-38/$ B% e9 W( A) B, D* H$ w! V
gpgcheck=1/ n0 m, M+ ?: D* P  @: U" O- u
enabled=1
$ {# n4 \# k* }3 l5 T. `gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Messaging
# @4 B: w/ V1 ?  j% e# s2 T' F( w6 q3 K! W- t7 v
[centos-nfv-openvswitch]! v. W* s2 T( y4 \: X- J
name=CentOS Stream 8 - NFV OpenvSwitch* W1 P! n0 e  E: }  Q; ~
baseurl=https://mirrors.aliyun.com/centos/8-stream/nfv/x86_64/openvswitch-2/& C- I9 s- F2 n' B
gpgcheck=1
0 b( {. M- A" U0 R& _/ P& ienabled=1
5 A) f) j. U1 g$ bgpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-NFV0 \8 h- p$ Z- D( t( n% L
module_hotfixes=1
) Q! }' n- s: q, F, V8 y! v$ W- ]( U/ r1 ~
[baseos]9 g1 r0 @/ }0 @/ i$ V3 d
name=CentOS Stream 8 - BaseOS
0 M: y% l0 @" h* a3 o6 L5 Obaseurl=https://mirrors.aliyun.com/centos/8-stream/BaseOS/x86_64/os/- [9 R4 }/ t7 F. @+ A1 [) R
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
! Z" Y1 O0 Y; t1 p8 C% Y5 dgpgcheck=1. ^& x" b0 [3 R. `9 e
repo_gpgcheck=0
0 P! t0 U9 X0 H4 Dmetadata_expire=6h$ v9 }1 E* y+ ^9 N7 u
countme=1' b/ z4 q) e0 `5 ^, x& t( z& Z
enabled=1) A. J5 l" B- G3 O! j8 U

# a5 l. Y: j; t8 W* y; A4 ~4 D[appstream]
% F# }5 w$ R# ^  R/ A4 Jname=CentOS Stream 8 - AppStream/ R" _# |% v6 ^
baseurl=https://mirrors.aliyun.com/centos/8-stream/AppStream/x86_64/os/
2 C- V; U3 h( z6 @gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
. @6 s! E3 W/ y0 J% L; @gpgcheck=1- T: I# a5 q8 C8 v$ X
repo_gpgcheck=01 v) u. x, `) _6 [
metadata_expire=6h* r* _! t  S2 [6 k* `
countme=1+ z; q. r! b; R
enabled=1
1 {8 L0 M9 g: ]/ D) Z# z& G1 }* v' ?% A: j8 ]9 V6 P! U
[centos-openstack-victoria]1 {3 r. c8 u3 Q7 }3 e
name=CentOS 8 - OpenStack victoria4 W: |# ~7 ?$ f( f; k
baseurl=https://mirrors.aliyun.com/centos/8-stream/cloud/x86_64/openstack-victoria/: l7 f( R7 `3 G  V7 N
#baseurl=https://repo.huaweicloud.com/centos/8-stream/cloud/x86_64/openstack-yoga/
* h& ~  r1 c! ?$ Ggpgcheck=1
3 S4 V/ P) ]6 H0 H+ qenabled=1
6 l. ?$ H# ^2 p) _4 Wgpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Cloud
5 ]. @2 {3 t. Y' M# o8 s. p# ?$ Xmodule_hotfixes=13 p$ y# z5 {) f& g* w; T' \1 f  q

/ F6 ]3 k% J& F2 @3 e$ `7 O[powertools]0 Z0 G- e. U; Z. [$ `, D
name=CentOS Stream 8 - PowerTools9 t; O* ~  y  [$ N6 r  E: P3 ~6 V
#mirrorlist=http://mirrorlist.centos.org/?release=&arch=&repo=PowerTools&infra=& s$ I1 R4 p# }9 _7 ]
baseurl=https://mirrors.aliyun.com/centos/8-stream/PowerTools/x86_64/os/
& j: B' Z# M1 G, {8 }: ~, fgpgcheck=1
! K. P" f$ _. c- X2 zenabled=1
  d- n. D+ [/ I) z; x4 h" ^3 Wgpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
* j: n, r+ k* F
' [  `/ w0 Z  x# yum clean all  清理缓存
: T0 J8 w/ H" j+ @% C# yum makecache  重新建立缓存
* R5 D, ~: Z, d( e& A9 P# I, N$ x# yum repolist all  列出yum仓库(13个)
3 j; d6 b7 `% a7 x: u) S& b, n3.安装基础包及ovs(Tab补全命令,安装bash-completion包后执行bash就行)4 B/ k' i0 n! \: @
安装openvswitch3.1过程报错说找不到gpgkey文件就禁用gpgcheck=0再次安装就行了
% ~; G. `- X' A5 m) ?yum install -y vim net-tools bash-completion centos-release-openstack-victoria.noarch tcpdump openvswitch3.17 N1 h4 d' X0 l. a+ F( L
或再单独安装yum install -y openvswitch3.1*1 x  J# L$ k) j
查看安装版本:[root@ovs ~]# ovs-vsctl --version
$ D% _& V- ]* E. w4.启动ovs服务; k7 t" S) h, M1 M* j0 s6 n3 @8 Q
[root@ovs ~]# systemctl start openvswitch
. q% I# I8 |; o' N7 d; C[root@ovs ~]# systemctl enable openvswitch, P! z/ }  ~$ E" Q( w2 F) o1 A+ x* M* E
[root@ovs ~]# ps -ef | grep openvswitch
  w; l+ N$ m- H0 C1 k$ ^' L[root@ovs ~]# ovs-vsctl show 查看ovs虚拟交换机信息
7 N" R3 C3 S/ R: Q# J[root@ovs ~]# ovs-vsctl --help 求帮助 或[root@ovs ~]# man ovs-vsctl
0 U3 z4 K! ~" t3 p: l: }2 {5、创建ovs虚拟交换机
4 a, }+ R" c  D. x1 g  w2 D+ F% J当创建一个虚拟交换机会生成一个和虚拟交换机同名的Port 和Interface,type为internal(内部的)
0 X8 ]/ }+ x% T; E; w7 H
' R; W' f; _' r; a; G[root@ovs ~]# ovs-vsctl add-br br-int
) ^, o; t: F) _: [! \  Z3 k[root@ovs ~]# ovs-vsctl add-br br-memeda  添加
7 r' N# T* {+ g. ?4 o) L# o[root@ovs ~]# ovs-vsctl del-br br-memeda  删除2 ?3 w3 }0 q1 [3 G
[root@ovs ~]# ovs-vsctl list-br   查看
) ~- L; }$ p. O8 ?br-int. R- x; G& n) @5 o
br-memeda' a) Y6 x9 K1 t! Y( G! Q- D
[root@ovs ~]# ovs-vsctl show   查询ovs虚拟交换机信息,Bridge桥指的是虚拟交换机& J- t1 w5 k* ]% s3 T
54c67146-9a9f-40be-8cb7-e8792879aafa
) E$ G9 u: h% K4 C) u: G    Bridge br-memeda+ A. p6 x7 ?) ~# @! I5 E
        Port br-memeda# e5 f2 ?% M2 u( V1 s9 y4 \
            Interface br-memeda
  t7 `& e/ b! Y) W; l5 \, m/ g                type: internal
  v) F" T/ |  V1 l. _    Bridge br-int# M$ b" H5 i1 N: [
        Port br-int
+ A3 P1 n! U: e" y            Interface br-int9 X: m: @) d1 E
                type: internal- X$ R" ~9 v, C6 b
    ovs_version: "3.1.3"
4 z/ I, {6 ?9 K( j2 o6 M9 Q- M用轻量级namespace网络命名空间模拟虚拟机
; b9 v2 i! s3 A, l5 l) p在这里插入图片描述& @; m3 t, C- m+ p- P
7 P# x* N  N+ `1 y/ U
[root@ovs ~]# ip netns    查看网络命名空间# n$ W4 }& ^  v
[root@ovs ~]# ip netns add ns1    添加网络命名空间
; W5 _3 }- K4 V[root@ovs ~]# ip netns add ns2
* R5 l2 m7 X) L5 P; l% m[root@ovs ~]# ip netns
) U0 `1 X# P* u" B) yns2. p, [4 d+ n3 \# ?
ns1, a4 b, n: s/ o# s1 h
创建两个veth pair(一个veth pair有两个网络虚拟接口,veth可理解为网卡端口) 并将一端虚拟接口(veth1和veth2)连接到两个网络命名空间里面。veth pair:两个网络虚拟端口(设备)。
4 D& Z( d1 p: V- l8 w: Z: `7 U在这里插入图片描述
6 o; u% N7 ]' b. _9 h, M$ B' Y5 q5 N" a4 I
创建两个veth pair,并分别把这两个veth pair的一端放到上述两个网络命名空间+ |8 j! {; _3 H
# ip link help 或# man ip link 求帮助
4 P+ G3 P) G$ F$ k第一个网络命名空间配置7 i' P7 G0 N- ]6 w2 l9 S' Y
[root@ovs ~]# ip link add veth11 type veth peer name veth1
  y# J; h- X2 ?5 Q' `[root@ovs ~]# ip link set veth1 netns ns1
5 G" y) ^4 X7 i% U[root@ovs ~]# ip netns exec ns1 ip link set veth1 up; U/ z1 o  z5 s( H0 H" }- N
第二个网络命名空间配置
+ }1 z- P# X" n, ^% @[root@ovs ~]# ip link add veth22 type veth peer name veth2  |9 P4 j4 D  R. y0 N" A# p1 T
[root@ovs ~]# ip link set veth2 netns ns2
" u  L' w  `. P- K[root@ovs ~]# ip netns exec ns2 ip link set veth2 up' }8 B' l7 e* C+ @- Q- ^
将另外一端虚拟接口(veth11和veth22)连接到ovs虚拟交换机上
9 d" F1 p0 o2 _. T在这里插入图片描述+ o# ^( O- h1 s8 J; w
& D+ E! b! o" \
[root@ovs ~]# ip link set veth11 up
$ C/ ^* n* U2 W, D6 t; i5 @! p[root@ovs ~]# ip link set veth22 up
2 O& V+ V* k( F9 I5 u[root@ovs ~]# ovs-vsctl add-port br-memeda veth11
! y2 m/ V) `8 i% C3 b% O- k* U[root@ovs ~]# ovs-vsctl add-port br-memeda veth228 f5 \, L0 f4 s9 M
[root@ovs ~]# ovs-vsctl show  发现br-memeda虚拟交换机多了2个Port(Port veth22、Port veth11)$ t; D! }' D6 r7 ^* Y, p
3b79f2e1-f433-4015-905e-8945dcada530- p  Y2 I" F7 V
    Bridge br-memeda
2 W/ s6 }4 E" }* Z  E        Port br-memeda
- G! h- e! v- W            Interface br-memeda
$ \  i1 C2 f9 p% w, W                type: internal
5 y: J/ d9 B9 ~+ W& ?% J        Port veth229 k* g8 b! W, A9 t+ N& _
            Interface veth22& x& Y' |, [8 T3 L' r- L
        Port veth11
  k# n# ]& S. A+ F! O            Interface veth11
( g1 i; D5 S; e6 E* H+ ^, Y! g    Bridge br-int
+ Y+ ~, O# z; Q  k5 l! Q        Port br-int. c0 j5 ^6 J7 ]& D! O- }
            Interface br-int7 S8 L3 U6 Q6 D1 q( w' z
                type: internal
. r3 V9 L$ L% Y4 v# m    ovs_version: "3.1.3"
+ H' q/ W3 X! T为两个网络命名空间手动设置ip地址) l3 u$ i8 ]4 \( r$ l8 S
在这里插入图片描述; D1 Q& b8 i2 I( {) R  x# i6 g

, ]1 g2 @; v. q! s3 N$ x[root@ovs ~]# ip netns exec ns1 ip addr add 1.1.1.1/24 dev veth1
9 a% n! V, \+ ^[root@ovs ~]# ip netns exec ns1 ip a- B  u; [% V  z1 A
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 10002 G7 h, P" X6 D6 C
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
5 `9 b6 J  N) E- B7 _3 S% w- ?7: veth1@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group d                                                                        efault qlen 10002 l6 z9 v3 `" n$ P
    link/ether fe:f9:3b:cb:9b:c5 brd ff:ff:ff:ff:ff:ff link-netnsid 0/ n, l* m. ^) K7 q
    inet 1.1.1.1/24 scope global veth1* y" [+ c! {9 C
       valid_lft forever preferred_lft forever, _7 V  h& ~; z" Y( y
    inet6 fe80::fcf9:3bff:fecb:9bc5/64 scope link
& D2 \2 `3 p8 y7 z2 C& S       valid_lft forever preferred_lft forever' W' B! {7 @3 E
[root@ovs ~]# ip netns exec ns2 ip addr add 1.1.1.2/24 dev veth26 M  D& ?! ?" l: Q" z" c
[root@ovs ~]# ip netns exec ns2 ip a
1 P! E( T  p2 |6 l1 j1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000/ D3 E  v* E) W3 }" z2 s- b" w' n
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00' o5 ]4 @3 F+ w; |: p
9: veth2@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group                                                                         default qlen 1000
5 z4 o  x0 `. x# E: `" U' e3 z+ u3 C    link/ether 0a:e3:ac:a8:f3:bc brd ff:ff:ff:ff:ff:ff link-netnsid 0! \9 F* ], Q& A* p0 F4 h! R
    inet 1.1.1.2/24 scope global veth29 |3 v; Y) y3 \
       valid_lft forever preferred_lft forever+ X! D5 W  \( C9 D% B
    inet6 fe80::8e3:acff:fea8:f3bc/64 scope link
, X" d- h4 D9 r" W: c* V" Y       valid_lft forever preferred_lft forever3 _: `8 S# H: L, F
两个网络命名空间测试连通性
0 P, @* @( V: G5 W9 h" ^' M4 s[root@ovs ~]# ip netns exec ns1 ping -c 3 1.1.1.2
) D) y8 [( _' U; B% SPING 1.1.1.2 (1.1.1.2) 56(84) bytes of data.# E/ }. O3 h  h* ]4 \9 d9 B
64 bytes from 1.1.1.2: icmp_seq=1 ttl=64 time=2.98 ms1 \  O7 ^% L; Z1 M; T) Q3 \) R7 Z
64 bytes from 1.1.1.2: icmp_seq=2 ttl=64 time=0.167 ms/ y7 @9 T; E( o. k' r; @
64 bytes from 1.1.1.2: icmp_seq=3 ttl=64 time=0.081 ms
( F& Y' F3 F; ~# v+ _' v5 I9 W+ L" W9 l0 o
--- 1.1.1.2 ping statistics ---
- ^/ o7 S+ U% }# s3 packets transmitted, 3 received, 0% packet loss, time 2065ms
+ q$ E. T6 p  K! ertt min/avg/max/mdev = 0.081/1.075/2.979/1.346 ms8 o, b9 h  T; f. i  p$ ?
[root@ovs ~]# ip netns exec ns2 ping -c 3 1.1.1.1' K5 I# u+ ?8 l: d# P# }# d4 y3 S
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
4 v3 U/ C+ Z) ^8 o( [" E64 bytes from 1.1.1.1: icmp_seq=1 ttl=64 time=0.923 ms- ~) G9 U. _3 u% E0 r) J  F" x# a
64 bytes from 1.1.1.1: icmp_seq=2 ttl=64 time=0.084 ms
# J; B$ @! j: v) S6 b$ n3 n64 bytes from 1.1.1.1: icmp_seq=3 ttl=64 time=0.091 ms& H1 ?  s4 F; ?! s$ _

7 O- s- ^8 {& `) |; C1 p--- 1.1.1.1 ping statistics ---
+ g" z4 C, F6 w% @3 packets transmitted, 3 received, 0% packet loss, time 2007ms
2 o1 i; s* U7 j; y  R4 h( v! ~rtt min/avg/max/mdev = 0.084/0.366/0.923/0.393 ms
3 b! j% c7 Q' E/ P; ]% I+ Yvlan虚拟的本地局域网,vlan隔离为了减少网络阻塞和数据包安全
" ]5 F: a$ A7 v" Y% [4 Fovs虚拟交换机能和物理交换机一样定义vlan,一个vlan10(tag10),一个vlan20(tag20),把插在ovs交换机上的两个虚拟网络设备对端口分别打上不同的tag(默认是0),也就是配置到不同的vlan里,再验证网络连通性。
3 w9 M4 P7 g( K; O$ Q  M* ?在这里插入图片描述
9 y* r. ~, k( T: H5 J5 Q9 @' D0 N3 B- N/ l% y
[root@ovs ~]# ovs-vsctl set port veth11 tag=10
( \4 A# C4 ?8 }+ o1 @[root@ovs ~]# ovs-vsctl set port veth22 tag=20& J4 A! ]% z$ w
[root@ovs ~]# ovs-vsctl show  发现br-memeda虚拟交换机的Port veth22和Port veth11下面多了tag标签
% y( A& ~" B3 E4 p) M3b79f2e1-f433-4015-905e-8945dcada530
/ N7 V$ a0 q; U: ^% H    Bridge br-memeda
: f/ I+ m2 q0 H' J        Port br-memeda
. S/ I. N6 O( i- l1 [            Interface br-memeda6 A+ T* a- Y9 V- G
                type: internal+ q% h0 R' x4 H
        Port veth22' `3 p2 ?4 W3 ?, l: _
            tag: 20
; a& v3 V# L. z! g0 n7 V            Interface veth22
$ H6 ~% |/ i3 }9 h$ N        Port veth11+ Q/ r0 R) N" u
            tag: 10* O) ~; S1 P2 C# g
            Interface veth11
0 r9 V$ U9 C7 ~/ C! v  B0 U    Bridge br-int; @7 P/ w3 y; ?6 ]  Q: ]1 I) j
        Port br-int
  g3 S( D% z! R6 ?' s            Interface br-int
& I* H  J% y, A$ L8 g2 K& i3 y  z) i$ y                type: internal
1 m  B5 M' O5 k  i: y  H    ovs_version: "3.1.3"1 h1 m" x% l2 w* U3 g! |0 `* ~
添加不同vlan(tag标签)后ping不通,需借助路由或物理三层交换机
/ @+ G7 a( V! d
! h$ C* ?) m0 W) [, n" c# U3 C[root@ovs ~]# ip netns exec ns1 ping -c 3 1.1.1.2/ B  `! U5 J- b
PING 1.1.1.2 (1.1.1.2) 56(84) bytes of data./ W6 f8 z$ _! a5 @( {1 V' }
8 j( T" ~0 m) b# p9 E: L3 W4 o
--- 1.1.1.2 ping statistics ---, W3 s+ r+ z/ g% o, G5 e% f
3 packets transmitted, 0 received, 100% packet loss, time 2064ms3 H4 M; i; b) P9 Q+ j2 l% w
在这里插入图片描述) g& v# }0 {! S' S5 s$ r' }- p* v/ V

3 T0 D0 y8 m6 f/ J* \8 o[root@ovs ~]# ovs-vsctl set port veth22 tag=10  把veth22也改成tag=10就相当于同一个vlan二层互通了- r4 W4 {- N% X) w' ?
[root@ovs ~]# ovs-vsctl show
3 Q) ]7 `! O4 _: j3b79f2e1-f433-4015-905e-8945dcada530" D+ ~8 s0 H2 N1 F
    Bridge br-memeda
+ `8 P% [: B. Z) b        Port br-memeda% P1 m8 a( ~0 ^7 v9 p
            Interface br-memeda
& o$ s# w) ?% a4 M( x                type: internal) f4 w) F% F1 \4 O: Q1 _6 b4 J
        Port veth22
1 _& t  W; ]2 [. r, `            tag: 10; @2 q% \6 f7 {2 H: B; \% P
            Interface veth22
& q' y( J2 {6 r! a3 |! ?        Port veth11+ b, |1 q# r5 \) E
            tag: 10
( {8 b+ K# c) f$ K            Interface veth11% e3 W. X" k8 ^& A9 P- C- [
    Bridge br-int
2 ^, d& ~6 S# z& |  s  E        Port br-int
5 F% c  m% O' o            Interface br-int2 F: i6 g+ i* ~8 j( B& V
                type: internal6 D& k5 N' M: @2 y7 m2 Z% c
    ovs_version: "3.1.3"
) H& ~' L, a3 ]* _4 t3 ~. I* m[root@ovs ~]# ip netns exec ns1 ping -c 3 1.1.1.2   同一个vlan(tag标签)能ping通进行二层通信
- \7 E* e8 E  a* i4 IPING 1.1.1.2 (1.1.1.2) 56(84) bytes of data.
6 U' i# n( m9 ]( `! h" V  Y+ e6 C8 K- O64 bytes from 1.1.1.2: icmp_seq=1 ttl=64 time=1.43 ms1 t9 I  z3 Z& L# y, O8 P
64 bytes from 1.1.1.2: icmp_seq=2 ttl=64 time=0.093 ms/ f, U8 w! W7 Y) O& o( N5 c. H
64 bytes from 1.1.1.2: icmp_seq=3 ttl=64 time=0.086 ms
& x: Z$ }8 p& r3 n. Y
. v2 F: h* |) ]4 L/ X' U--- 1.1.1.2 ping statistics ---
" H, y2 f" Q, h. [* V, a3 packets transmitted, 3 received, 0% packet loss, time 2051ms
* U; `8 @+ A- E; k" b- O( F) xrtt min/avg/max/mdev = 0.086/0.535/1.426/0.630 ms
8 ~0 `* {% M, fFlowTable:流表,ovs进行数据转发的核心功能,定义了端口之间的转发数据规则。每条流表规则可以分为匹配和动作两部分,“匹配”决定哪些数据将被处理,“动作”则决定了这些数据将被如何处理。
1 Z% y6 T% G5 v5 m% S( c+ g流量走向,添加流表,针对流量进口添加规则。" f& o" P( K/ F5 B
在这里插入图片描述
4 h8 j+ ?9 F/ R% @6 k, i在这里插入图片描述
# y; q  F) _: t; J; m0 P3 B
) D8 Y( t3 @6 r) D( R; R查看ovs默认的流表* N4 M8 h4 c6 f1 E( W4 ^: x6 e
[root@ovs ~]# ovs-ofctl dump-flows br-memeda   查看虚拟交换机的流规则
% Y, `9 p7 L  X$ a' a* c: D cookie=0x0, duration=2161.884s, table=0, n_packets=49, n_bytes=3682, priority=0 action                                                                        s=NORMAL/ v' y8 _/ E& `8 v7 e' b
此时ovs就类似于传统交换机,我们给ovs交换机添加一条优先级为2(数字越大优先级越高,高于默认表项的0优先级)的流表项,把veth11进来的请求都drop掉,发现ns1不能ping通ns2。
1 ~  u; x3 z2 t+ D7 Q[root@ovs ~]# ovs-ofctl add-flow br-memeda "priority=2,in_port=veth11,actions=drop"  添加流规则8 \3 S6 _# _: `/ A" q
[root@ovs ~]# ovs-ofctl dump-flows br-memeda% F6 A1 |! {# Z" g# x* @
cookie=0x0, duration=2.578s, table=0, n_packets=0, n_bytes=0, priority=2,in_port=veth11 actions=drop
5 l( p. \9 ?4 P. o- B6 e cookie=0x0, duration=2217.329s, table=0, n_packets=49, n_bytes=3682, priority=0 actions=NORMAL
7 f( Q0 e, q# M5 f& z2 s* T. `- _[root@ovs ~]# ip netns exec ns1 ping -c 3 1.1.1.2# o& s% J% g* w' n) E
PING 1.1.1.2 (1.1.1.2) 56(84) bytes of data.
7 u. m- K& X4 Z4 q8 w
4 p  T8 b0 |& y) q" p% Q--- 1.1.1.2 ping statistics ---3 y4 [; y) N7 @0 t
3 packets transmitted, 0 received, 100% packet loss, time 2076ms( W5 l" A5 G9 o% P% u
删除刚添加的表项,ns1与ns2又能正常通信, `' Q0 h) e& \0 m" m0 B; a& y
[root@ovs ~]# ovs-ofctl del-flows br-memeda "in_port=veth11"  删除刚添加的流规则就互通了
4 r+ x9 F# `6 g4 W$ i[root@ovs ~]# ip netns exec ns1 ping -c 3 1.1.1.2/ Q0 H  X: i4 V
PING 1.1.1.2 (1.1.1.2) 56(84) bytes of data.
: L( A& F5 `, w8 U64 bytes from 1.1.1.2: icmp_seq=1 ttl=64 time=0.766 ms
7 l# @7 \6 ?6 E4 B$ J64 bytes from 1.1.1.2: icmp_seq=2 ttl=64 time=0.096 ms- u" P7 W% W; X% S
64 bytes from 1.1.1.2: icmp_seq=3 ttl=64 time=0.088 ms) {3 @& n2 w5 r! [! k/ S
: x* J. V) V% D  O$ v
--- 1.1.1.2 ping statistics ---4 k1 R4 `" n( n0 _* O+ M
3 packets transmitted, 3 received, 0% packet loss, time 2043ms( c1 ~& g1 X6 N7 m5 F9 u
rtt min/avg/max/mdev = 0.088/0.316/0.766/0.318 ms! ]6 m+ X' K' @0 U  A
[root@ovs ~]# ovs-ofctl dump-flows br-memeda2 O0 f$ ?2 {3 I! ]
cookie=0x0, duration=2315.744s, table=0, n_packets=59, n_bytes=4438, priority=0 action                                                                        s=NORMAL
1 d7 C6 x! X6 t( e4、OVN% U9 p4 ~* ?; d; F! N: m
OVN建立在OVS之上的,遵循SDN(Software Defined Network,软件定义网络)架构来管理的,用软件将控制面和转发面分离,OVN做控制面,OVS做转发面。
' U/ g  D9 M2 Y; Eovn是建立在ovs之上的,ovn必须有底层的ovs,ovs可理解为二层交换机,ovn可理解为三层交换机。. s" n) N6 {9 ]: G  A
OVS介绍参考:https://mp.weixin.qq.com/s?__biz ... 189#wechat_redirect
- P# ?  H; R/ K5 E$ h( a4 K7 s单纯的ovs在云计算领域还存在着一些问题,例如:7 r0 d8 S6 l" T; T& b9 W- Q
1、ovs只能做二层转发,没有三层的能力,无法在ovs上进行路由配置等操作;  I" @+ F1 v  B
2、ovs没有高可用配置;' O8 F& c2 W! E
3、在虚拟化领域vm从一台物理机迁移到另一台物理机,以及容器领域container从一个节点迁移到另一个节点都是非常常见的场景,而单纯的ovs的配置只适用于当前节点。当发生上述迁移过程时,新的节点因对应的ovs没有相关配置,会导致迁移过来的vm或者container无法正常运作。
! Z+ a: E9 _, a$ J" G1 G* b- o, U针对这些问题,出现了ovn(Open Virtual Network),ovn提供的功能包括:/ P- \5 i; B4 Z" w
1、分布式虚拟路由器(distributed virtual routers)
& ]6 |: O+ B0 j' d* O0 c  c2、分布式虚拟交换机(distributed logical switches)
5 w. d7 q% X: X7 K3、访问控制列表(ACL)
) ]: o6 `5 @& P. c! t3 t4、DHCP3 V' I2 T8 r, L& d+ Q
5、DNS server3 D- @7 ^4 s/ J% `; h- c2 e4 u
在openstack里面,创建一个网络,就相当于创建了一个逻辑虚拟交换机,这个逻辑交换机(网络)信息会被保存到北向数据库里面。openstack创建一个网络,会以逻辑交换机(switch)的形式保存到北向数据库。$ `* W: H, Y$ r2 \: D  K
在这里插入图片描述
0 A3 C" U; J) F3 v! C) J' j5 C# q在这里插入图片描述
) y/ g7 o9 \+ t& ?: _ovn官网对ovn的逻辑架构如下所示:% H# a( \  p, M) v8 O; R
, M( R/ B, C1 C* _
                                    CMS
3 [. U& h0 U! P9 V5 _                                     |* n  S% F- k9 I8 [
                                     |0 S; Q' w9 g# P$ _: t- I# X3 @5 z
                         +-----------|-----------+9 M& ~9 ~* H$ i) r. J3 X
                         |           |           |+ T: z3 w) y4 M" z& B; K- \& [7 A
                         |     OVN/CMS Plugin    |' @2 B  b2 S# t3 D- @3 c
                         |           |           |/ {, X0 M* V) Y! S
                         |           |           |
/ V4 Z9 |. {  V* o                         |   OVN Northbound DB   |
* J! H  w, D: H9 Z! i7 z                         |           |           |
" l9 l, H7 R4 F+ ]0 U                         |           |           |$ n6 z/ [0 J+ ?* b% J
                         |       ovn-northd      |: B2 X  G. i% j, V8 V. U
                         |           |           |9 g* ^; S( k- {) j% I
                         +-----------|-----------+
" k& V: s0 ~* U6 a9 d/ B                                     |
+ m/ c, P( Q7 P+ k                                     |9 k# G( [8 D. x! [
                           +-------------------+
$ Y& w5 X5 t0 o                           | OVN Southbound DB |
# K6 {. W3 v$ o6 ]' b7 ^" M                           +-------------------+6 f7 Y# _6 X0 F5 L
                                     |9 Y( J$ I& u6 t, B6 a+ u
                                     |* R9 H& j5 N6 j. {
                  +------------------+------------------+! a* ^3 l  K' V. K/ d* Y
                  |                  |                  |
' G0 r' T8 }1 C* j; X    HV 1          |                  |    HV n          |. o& e  m" t& A3 N& C, B
  +---------------|---------------+  .  +---------------|---------------+
6 |8 N2 C" S8 W0 S  |               |               |  .  |               |               |
, w6 D9 {+ l0 r. x8 E  |        ovn-controller         |  .  |        ovn-controller         |, B3 i, L. B1 Q  S4 M
  |         |          |          |  .  |         |          |          |
% V' U( I2 p9 ^  |         |          |          |     |         |          |          |
: {, w6 t* Q: d$ {  |  ovs-vswitchd   ovsdb-server  |     |  ovs-vswitchd   ovsdb-server  |
$ S8 p8 h, L7 H% J6 e  |                               |     |                               |  b" q6 y9 W% m+ o& B7 O
  +-------------------------------+     +-------------------------------+
; v. q6 @; G3 Y: Jovn根据功能可以把节点分为两类:
- F6 v8 f' s) j+ N  ocentral: 可以看做中心节点,central节点组件包括OVN/CMS plugin、OVN Northbound DB、ovn-northd、OVN Southbound DB。" U2 C2 \' g! O
hypervisor(hv): 可以看做工作节点,hypervisor节点组件包括ovn-controller、ovs-vswitchd、ovsdb-server。9 c7 H7 g2 K: m9 U# u
central节点相关组件和hypervisor组件运行在同一个物理节点上。
$ _8 ]2 B& Y7 @( u" j相关组件的功能如下:3 q; T! x# Q! y  q: `
1、CMS: 云管软件(Cloud Management Software),例如openstack(ovn最初就是设计给openstack用的)。" c  M8 J0 `( A! h9 D, w# I
2、OVN/CMS plugin: 云管软件插件,例如openstack的neutron plugin。它的作用是将逻辑网络配置转换成OVN理解的数据,并写到北向数据库(OVN Northbound DB)中。
' b' a, A+ m9 v: H2 C+ [; G( a3、OVN Northbound DB: ovn北向数据库,保存CMS plugin下发的配置,它有两个客户端CMS plugin和ovn-northd。通过ovn-nbctl命令直接操作它。北向数据库保存逻辑网络信息(交换机和路由器等)+ {! B& W  K0 X
4、ovn-northd: 北向进程将OVN Northbound DB中的数据进行转换并保存到OVN Southbound DB。所有信息经过北向数据库通过ovn-northd北向进程和南向数据库互通。
$ Z0 `8 `. f+ @+ v# c3 \5、OVN Southbound DB: ovn南向数据库,它也有两个客户端: 上面的ovn-northd和下面的运行在每个hypervisor上的ovn-controller。通过ovn-sbctl命令直接操作它。南向数据库保存各个节点的物理网络信息。
6 G! p' }: u' e6 O6、ovn-controller: 相当于OVN在每个hypervisor上的agent(代理)。北向它连接到OVN Southbound Database学习最新的配置转换成openflow流表,南向它连接到ovs-vswitchd下发转换后的流表,同时也连接到ovsdb-server获取它需要的配置信息。
$ \4 V. e' s6 U7 l9 v7、ovs-vswitchd和ovs-dbserver: ovs用户态的两个进程。7 T, O+ s* L3 q' y5 U) u; I
每个节点都有个ovn-controller控制器,这个ovn-controller控制器是管理ovs(ovs-vswitchd、ovsdb-server)的,ovn-controller对接到南向数据库,经过ovn-northd北向进程和北向数据库互通,之后和openstack互通。" ?7 W" e- p. \$ E+ e! ?( @- }
南向数据库保存物理网络状态信息,北向数据库保存逻辑网络状态信息。
& E" \7 O+ b8 V) x在这里插入图片描述/ M( d% _' J8 a0 h
克隆出两台虚拟机,安装ovs、ovn
5 J3 a4 I2 A9 j+ t+ X
' D: X# r6 W7 T8 s* N0 vCentOS Stream 8 版本$ I0 c  I* y6 `  @# _

& D4 S" v2 F3 Q. [. R9 Asystemctl stop firewalld.service : `8 c1 ^  ]/ g; R6 O
systemctl disable firewalld.service
6 \+ g4 J2 g# ^8 ?  i& J0 fsetenforce 0& F/ W1 ^% T, e9 {4 m* J4 m4 }
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
# c% a5 N" [3 R7 p8 |* [mkdir /etc/yum.repos.d/bak
; R/ {- o- {2 {- V* o1 [+ P5 Dmv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/0 z, ~9 D1 i$ d4 O  Q2 U4 D5 X
0 {9 W6 Z) t" |0 X5 U8 v
cat <<EOF > /etc/yum.repos.d/cloudcs.repo$ Q7 i- Z! R4 w; d; W
[ceph]! }0 w, G+ z" {- U3 T
name=ceph
  w! c/ E# h$ u2 L8 z4 Z" Abaseurl=https://mirrors.aliyun.com/ceph/rpm-18.1.1/el8/x86_64/( r- i' M% n8 O; y' H
gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc
0 a) H( F+ c  xgpgcheck=1
% W+ M$ B% ?, }enabled=16 N3 Z9 w  B1 J$ I! ]/ m/ V
- ^, f' D1 Q* X+ B
[ceph-noarch]- Q: E# W5 s( X' X: q* v
name=ceph-noarch
8 |0 A6 x- o, {! D% r9 a- w& N/ Kbaseurl=https://mirrors.aliyun.com/ceph/rpm-18.1.1/el8/noarch/. c& T8 r9 x5 S! c1 ^2 F
gpgcheck=1
1 \3 ]/ u5 J; L$ y* |gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc! K) f1 S& j; t, |
enabled=1  f: T5 o! ?* K9 p% e; ^2 }

; g4 O) L, s' z: _2 J& i[ceph-SRPMS]6 X$ W3 K  w& D5 B9 Q/ h
name=SRPMS/ q9 J3 T  c1 e0 @' k
baseurl=https://mirrors.aliyun.com/ceph/rpm-18.1.1/el8/SRPMS/. S* r4 Z, O1 n
gpgcheck=1/ j0 P# N& b) f" K$ }
gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc
3 l9 g4 j. s5 K. m0 S& B* genabled=1
+ b# w. Z7 I& |8 u. ]" u0 \5 ~4 A. t8 n2 A! H4 [  ?1 a9 `  \
[highavailability]
% k5 A  w5 `. F! Wname=CentOS Stream 8 - HighAvailability
$ O, v0 I/ J( @) Zbaseurl=https://mirrors.aliyun.com/centos/8-stream/HighAvailability/x86_64/os/0 g! r, T2 G- W# P7 n
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial- |! r, B) R5 U
gpgcheck=18 {) j# n$ v3 c* ~2 [  O
repo_gpgcheck=0$ x, l* `& {4 _" k/ N/ L) J
metadata_expire=6h, ~$ \/ A0 s) r
countme=1
7 L& \2 ^' ?- ~7 P( a" senabled=1& v7 F9 ^! a: c
5 E- Y* W0 Q, B3 F
[nfv]
+ }1 c$ c( ?. W( |, ]  Vname=CentOS Stream 8 - NFV; y0 p, u: m, m) O0 P+ E+ r
baseurl=https://mirrors.aliyun.com/centos/8-stream/NFV/x86_64/os/
7 a, D3 T4 F6 p/ y) z  \3 ogpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
9 d$ U, r/ w3 v& C' r# v) {gpgcheck=16 _+ C' ~# G5 e3 q6 P  ?- T' n9 Y
repo_gpgcheck=09 R1 D' n9 q+ ?/ t4 E
metadata_expire=6h3 J; L4 A3 }% W1 ?
countme=17 e" h/ |  e  t+ \# {
enabled=1
& G5 \. h; \: s/ ?4 S' S, p, E8 H- ^* P' V! K
[rt]
9 b) U) Z7 ?9 u$ l3 o0 O2 y- u! N& sname=CentOS Stream 8 - RT
" @& k* q! F* W1 _  n4 f# mbaseurl=https://mirrors.aliyun.com/centos/8-stream/RT/x86_64/os/
4 s0 H( H/ m$ @7 L' Pgpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
, a+ C9 m; U. Wgpgcheck=1
% S+ h6 G; U: [$ a0 v) q, @8 P# G. ]repo_gpgcheck=04 @# m& C, ]6 S- h! B0 q. c- W6 j: L
metadata_expire=6h
% x2 C9 ]) H# Dcountme=1+ c0 l2 e) `. z- a% b4 A
enabled=1
# @: V2 \* P# M5 h5 J, G4 A  s: K" ?0 b
[resilientstorage]* i' M3 E2 U6 X
name=CentOS Stream 8 - ResilientStorage7 \) Q- w( u, z8 {' D. S
baseurl=https://mirrors.aliyun.com/centos/8-stream/ResilientStorage/x86_64/os/
/ H% p) r' I! [: G, V) Egpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
+ Q* A0 P4 R) p( g2 J9 ~gpgcheck=1' O/ J* ?! G( l) R
repo_gpgcheck=0* r2 `/ {2 |  }9 b
metadata_expire=6h
4 [2 Q8 B  e; D& Qcountme=15 [* t* q, f( \% S/ V" G* {
enabled=1; d7 v/ [  N6 ^* m  }
" X7 D) W/ _" T/ e' p8 W
[extras-common]
% z1 n0 j9 Y. Lname=CentOS Stream 8 - Extras packages5 M# N( ]+ W7 |: e, _* M& o
baseurl=https://mirrors.aliyun.com/centos/8-stream/extras/x86_64/extras-common/
2 w9 o& h# o  Q+ K2 rgpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Extras-SHA512
' V" _7 x& T9 b. `5 Lgpgcheck=1
, ~. f6 A5 b% D) W5 f# ^. w& U, orepo_gpgcheck=0
- J- T7 p) t+ X1 M/ }metadata_expire=6h
5 h, A* q0 o3 G, \" acountme=1
5 f+ B1 Q% E% c# @$ J1 ^enabled=1
  Z# _7 k! @# i, K/ x
5 W! m6 W& s3 x( Z/ l- O; O+ `) h[extras]( ]8 H" z7 o! N6 L( r2 \6 t# n- I
name=CentOS Stream $releasever - Extras
: B; Q$ s* Y/ z6 V+ Q6 mmirrorlist=http://mirrorlist.centos.org/?release=$stream&arch=$basearch&repo=extras&infra=$infra" e' U/ @2 [" Q7 ]
#baseurl=http://mirror.centos.org/$contentdir/$stream/extras/$basearch/os/! m1 p8 j2 L+ f2 M/ x5 h' p
baseurl=https://mirrors.aliyun.com/centos/8-stream/extras/x86_64/os/
3 ~4 L4 g' x2 y, z! Q( B& K+ \gpgcheck=1
% f" a3 Z# m+ d3 henabled=1' ]/ p0 r2 o  m3 b
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
# @$ I5 A! z8 Z' v* h9 d9 v- ]+ S0 l1 M) Q2 w# ?. o$ n: i
[centos-ceph-pacific]3 [- o7 ?6 \* k, W! M% ?
name=CentOS - Ceph Pacific7 @# k6 ^3 _; m/ o$ W+ m' T
baseurl=https://mirrors.aliyun.com/centos/8-stream/storage/x86_64/ceph-pacific/
: T* S1 W( v" z- T0 ^  @$ h* Ogpgcheck=0( S" t# p; U# R
enabled=1$ X8 N1 F! d( |7 j- t
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Storage
. u4 [3 h8 x1 p6 z
8 C0 Z. v4 F) U[centos-rabbitmq-38]
. s+ R: Z" k1 v" L) |name=CentOS-8 - RabbitMQ 38% D2 g) t/ C" J
baseurl=https://mirrors.aliyun.com/centos/8-stream/messaging/x86_64/rabbitmq-38/% ~8 z1 T2 [1 O0 K, x
gpgcheck=1" o* W: g! `" ?* v, |2 k1 B2 v; Q
enabled=1
+ d# J! r: r; B1 B; |6 Ygpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Messaging; R9 X: P7 m7 V/ I: Q4 _

9 C# R3 }3 R- [2 P3 `6 O[centos-nfv-openvswitch]
; l8 V, G5 u1 O% Z6 gname=CentOS Stream 8 - NFV OpenvSwitch$ v) r! A7 ?7 u) _* f, X
baseurl=https://mirrors.aliyun.com/centos/8-stream/nfv/x86_64/openvswitch-2/
7 `: ^4 X/ Y# u9 H" c; j3 H" ]gpgcheck=1& f$ u9 p4 E* y, N
enabled=1
3 Z& Q5 h5 z' i. Z0 p$ a$ agpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-NFV
6 O- \5 _6 y0 `module_hotfixes=13 N0 W2 g* y# j" y( X, O; ^: r; X

1 L% X$ l* P( R[baseos]
# ?0 A5 g( u% }! L, C. Wname=CentOS Stream 8 - BaseOS% Y7 E# {6 p% p* b3 Z
baseurl=https://mirrors.aliyun.com/centos/8-stream/BaseOS/x86_64/os/" B) Z* [$ K; Y0 q2 i' U2 A* H% L
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial) A! ]! r  _3 E
gpgcheck=1
( b, |* k% Q9 E1 }3 R2 R1 S  ]8 arepo_gpgcheck=0
8 _% z( P% ^$ p3 J7 F" y. zmetadata_expire=6h
3 g$ \: m+ C' K; s1 Hcountme=16 s$ s9 O; d& ]0 H: w
enabled=1% j0 b" J* v4 s9 W9 h
9 E  D, F/ Y: G8 T4 q! i! P
[appstream]: S" p  t2 o! G* w" `" ?* T2 |3 }
name=CentOS Stream 8 - AppStream3 d( L8 H3 }6 Y; v2 ^6 n" f( S& o( ^
baseurl=https://mirrors.aliyun.com/centos/8-stream/AppStream/x86_64/os/
8 \2 [0 E" w# ], _$ O* ?  Egpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
) }1 {) E: o0 K9 Q$ g$ tgpgcheck=1( a3 x2 A% |* |5 P
repo_gpgcheck=0
. ?4 l+ i& U, m, y" I0 O8 hmetadata_expire=6h
+ H) J1 ^/ ?$ q1 ^countme=10 w  D! d# f" |. R
enabled=1( C/ m9 g. a5 e
! R8 T& p, h5 b' B6 M, }$ M
[centos-openstack-victoria]2 O% L8 S& Z( x# \& X/ i3 N$ {! @
name=CentOS 8 - OpenStack victoria
& i/ o$ _, m1 p8 a3 L9 cbaseurl=https://mirrors.aliyun.com/centos/8-stream/cloud/x86_64/openstack-victoria/# W5 j" U; U  ^! i0 M0 ~
#baseurl=https://repo.huaweicloud.com/centos/8-stream/cloud/x86_64/openstack-yoga/) W# w7 m) H& S* [6 B# H+ k2 l5 ]( _
gpgcheck=1
) k( }9 B( H! l7 `3 venabled=18 c8 z/ B8 ?8 h
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Cloud
! J& p1 T+ @: v( T& J9 Lmodule_hotfixes=13 f4 n6 S' K- w# `2 t1 Q7 g
2 D1 x" y+ F/ ]7 o' I& `1 Z+ y
[powertools]
0 n  W  ^$ C5 O0 S. a* Mname=CentOS Stream 8 - PowerTools
4 u, g5 {) Q) ?0 H#mirrorlist=http://mirrorlist.centos.org/?release=$stream&arch=$basearch&repo=PowerTools&infra=$infra
, h( w  H' ]! i! A2 Bbaseurl=https://mirrors.aliyun.com/centos/8-stream/PowerTools/x86_64/os/9 j# p5 `6 g: m+ Y
gpgcheck=1
& E" z8 p# j! P2 d: g6 o1 n6 x% renabled=18 r; r' L2 P4 v" X9 `8 L1 X' Q0 ~, |
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial6 K5 n, A* A5 F# q; U
EOF
7 @) l" [, l6 P  s! x+ `! u7 B4 E' f3 |8 S# \
yum install -y vim net-tools bash-completion git tcpdump autoconf automake libtool make python3 centos-release-openstack-victoria.noarch2 w! z& o- ?+ o3 K. P
yum install -y openvswitch3.1*- @8 ]4 Y3 d$ M' f# j/ z5 r
yum install -y ovn22.12*" }" x- ~2 \4 N+ I1 @- C8 x" {# A
查看安装版本来检查ovn是否安装成功,# ovn-appctl --version4 Y3 ?( C+ ^9 d, H8 v: {
echo 'export PATH=$PATH:/usr/share/ovn/scripts:/usr/share/openvswitch/scripts' >> /etc/profile
+ h- G+ r, O2 W! S4 O! r8 Isource /etc/profile  重新读取配置文件让配置文件立即生效
0 |+ F4 a) t+ {+ b5 x/ \; @5 y在这里插入图片描述8 y( ?1 k( a! e0 I- k
central相关组件启动:把node1作为central节点,安装central必需的三个组件:OVN Northbound DB、ovn-northd、OVN Southbound DB。
6 B& p, C( c8 ~% W; z0 x在控制节点启动central,只用在一个控制节点上启动即可(node1或node2上开启都行,这里是在node1开启),central只需要一套即可。
, V+ H$ w  |% ]
# Y' N% n; `0 r5 `; p% N8 vovn-ctl start_northd命令会自动启动北桥数据库、ovn-northd、南桥数据库三个服务. a; @: s0 L! u! u2 A- s! ]: ]
[root@node1 ~]# ovn-ctl start_northd5 g1 w0 ]: U0 y. v# e
/etc/ovn/ovnnb_db.db does not exist ... (warning).
* L' v) W: f) _; F- @9 u9 TCreating empty database /etc/ovn/ovnnb_db.db               [  OK  ]
0 Y1 i7 G* Q: b9 G' K9 jStarting ovsdb-nb                                          [  OK  ]
+ f8 c" Q4 O0 M- J5 \& n/etc/ovn/ovnsb_db.db does not exist ... (warning).0 G1 X  i; ?# E3 c: E4 j+ ?1 O
Creating empty database /etc/ovn/ovnsb_db.db               [  OK  ]
9 B0 G8 z! h& I3 R. _  m( `& lStarting ovsdb-sb                                          [  OK  ]
2 o; @: S8 D4 z# X" XStarting ovn-northd                                        [  OK  ]
, n4 z4 g/ V7 b1 l1 X( i% F/ q# Q( B0 D" J3 q
[root@node1 ~]# ps -ef | grep ovn
! {% N1 o, c( K/ D$ sroot       34102   34101  0 21:02 ?        00:00:00 ovsdb-server -vconsole:off -vfile:info --log-file=/var/log/ovn/ovsdb-server-nb.log --remote=punix:/var/run ovn/ovnnb_db.sock --pidfile=/var/run/ovn/ovnnb_db.pid --unixctl=/var/run/ovn/ovnnb_db.ctl --detach --monitor --remote=db:OVN_Northbound,NB_Global,connections --private-key=db:OVN_Northbound,SSL,private_key --certificate=db:OVN_Northbound,SSL,certificate --ca-cert=db:OVN_Northbound,SSL,ca_cert --ssl-protocols=db:OVN_Northbound,SSL,ssl_protocols --ssl-ciphers=db:OVN_Northbound,SSL,ssl_ciphers /etc/ovn/ovnnb_db.db, v2 k8 W% R6 {9 a1 a
root       34118   34117  0 21:02 ?        00:00:00 ovsdb-server -vconsole:off -vfile:info --log-file=/var/log/ovn/ovsdb-server-sb.log --remote=punix:/var/run ovn/ovnsb_db.sock --pidfile=/var/run/ovn/ovnsb_db.pid --unixctl=/var/run/ovn/ovnsb_db.ctl --detach --monitor --remote=db:OVN_Southbound,SB_Global,connections --private-key=db:OVN_Southbound,SSL,private_key --certificate=db:OVN_Southbound,SSL,certificate --ca-cert=db:OVN_Southbound,SSL,ca_cert --ssl-protocols=db:OVN_Southbound,SSL,ssl_protocols --ssl-ciphers=db:OVN_Southbound,SSL,ssl_ciphers /etc/ovn/ovnsb_db.db# s; n8 u+ x9 I$ c4 P4 {
root       34128       1  0 21:02 ?        00:00:00 ovn-northd: monitoring pid 34129 (healthy)
2 k3 r$ J) G) b) J5 I0 h9 s  i$ |+ Zroot       34129   34128  0 21:02 ?        00:00:00 ovn-northd -vconsole:emer -vsyslog:err -vfile:info --ovnnb-db=unix:/var/run/ovn/ovnnb_db.sock --ovnsb-db=unix:/var/run/ovn/ovnsb_db.sock --no-chdir --log-file=/var/log/ovn/ovn-northd.log --pidfile=/var/run/ovn/ovn-northd.pid --detach --monitor
* r+ j, W( U4 G1 `" W# a3 Aroot       34302   34259  0 21:07 pts/0    00:00:00 grep --color=auto ovn
5 A. o5 o$ O0 N# L) O在这里插入图片描述
+ }" x# c2 [/ H/ O- fhypervisor相关组件启动:hypervisor节点包含三个组件:ovn-controller、ovs-vswitchd和ovsdb-server。2 P. D/ Y4 x+ X9 @+ @0 L6 O3 i
启动hypervisor(hv)相关组件:node1和node2两台节点上都要启动,首先启动两个节点上的 ovs-vswitchd 和 ovsdb-server- K. @5 L% ~4 X8 h: J

; J5 L8 q: m# T- Y7 N2 e[root@node1 ~]# ovs-ctl start --system-id=random0 ^% q. z# T* ]4 [7 v
/etc/openvswitch/conf.db does not exist ... (warning).8 o, N( q& ]; o3 ^6 C( t8 c
Creating empty database /etc/openvswitch/conf.db           [  OK  ]
& C' F6 }3 }9 |2 \) E( L5 ~Starting ovsdb-server                                      [  OK  ]: M9 ?: a6 v. X. k' P
Configuring Open vSwitch system IDs                        [  OK  ]
' n* K9 J* P, t+ c0 ZInserting openvswitch module                               [  OK  ]) k/ |: M4 A8 c  J4 Z/ q! q
Starting ovs-vswitchd                                      [  OK  ]
/ ^0 S# Z% v+ d" d6 H/ ~Enabling remote OVSDB managers                             [  OK  ]4 {  O" c. l3 I. X: i; M3 a# H

# _# V7 a1 D" N  o& f[root@node2 ~]# ovs-ctl start --system-id=random
! G1 [' p2 t/ W( f/etc/openvswitch/conf.db does not exist ... (warning).
9 Z* ]" J' ^9 _- iCreating empty database /etc/openvswitch/conf.db           [  OK  ]3 V1 M/ |5 X6 {' C$ N1 \
Starting ovsdb-server                                      [  OK  ]
9 f' t# _5 s- |8 mConfiguring Open vSwitch system IDs                        [  OK  ]4 k: X. r. q- y) _
Inserting openvswitch module                               [  OK  ]
" s. B) K% M' CStarting ovs-vswitchd                                      [  OK  ]
1 \9 {( P( ~" zEnabling remote OVSDB managers                             [  OK  ]
& D* ^' Z, y; r. t在这里插入图片描述6 K) G: m1 D  _- ]
两个节点分别启动ovn-controller
' \, A( L, U% B6 q; [! L+ ^8 }/ U  d, c6 c; V* N3 d
[root@node1 ~]# ovn-ctl start_controller( ^/ Q7 ^; c% d2 ?' q1 V7 Z
Starting ovn-controller                                    [  OK  ]
$ _) S5 l: ?- h: E$ I[root@node1 ~]# ovs-vsctl show       ovn-controler启动后会自动创建br-int网桥2 F. k5 O6 g+ C. Y7 d
ed157e0c-cac3-46b9-830c-f2d710b475d5" [' A2 ~& e& U+ n
    Bridge br-int/ y7 V/ D: t! t. B; J
        fail_mode: secure+ U3 Q1 J/ @1 ]! ~' L
        datapath_type: system
2 I' }/ Y& q+ b. q/ d: r; j; K7 K6 v        Port br-int- u5 G0 w; b: ~( ]+ s& B
            Interface br-int9 ]6 k5 c% }  @* I( r+ ^
                type: internal0 K" z' v9 j+ ?- l1 b! `$ ]7 d
    ovs_version: "3.1.3"
: S$ D* U3 A; Q$ u
& U6 W; i6 P' C- }5 ~: j[root@node2 ~]# ovn-ctl start_controller
# p. k% o0 {2 J; ?8 D; o% oStarting ovn-controller                                    [  OK  ]5 P2 B" C& F% ?' [* ?* E
[root@node2 ~]# ovs-vsctl show      ovn-controler启动后会自动创建br-int网桥
: x4 R/ g- _; u% x( K1 Wf6669675-b42d-47de-be95-b26bf6d1e069
2 n# F/ w: x7 Z* j: ?    Bridge br-int
8 W/ i- q$ w+ K0 ^& T0 z        fail_mode: secure
. P. s2 Q2 _2 x5 F3 J3 K& B        datapath_type: system
% J& R3 E: f) ^" ?3 L) V2 z6 H        Port br-int
5 S( O' y% `' v2 k( Z: d# `0 _            Interface br-int7 u/ Y+ C4 n2 Z+ w' A' b. R
                type: internal
- t& L) N+ w* z8 i! r3 l    ovs_version: "3.1.3"
( z$ F- F. F7 A* g/ o) l/ C在这里插入图片描述
+ H5 ]0 }0 \* C/ @. F" Y可以看出此时hypervisor并没有和central关联起来(也就是ovn-controller没有和南向数据库连接)。可以在node1上验证:[root@node1 ~]# ovn-nbctl show
$ m$ j3 G7 ]7 o3 T; shypervisor连接central,开放南北数据库端口:9 {% b( X! ]/ U4 d' s

3 {6 H- ]: f1 A* v% ]6 ]2 oovn-northd之所以能连上南向数据和北向数据库,是因为它们部署在同一台机器上,通过unix sock连接
, M8 |! M0 D( a8 V3 q5 H0 }$ n& Pcentral节点开放北向数据库端口6441,该端口主要给CMS plugins连接使用! E2 [/ G! ~9 v7 T5 Z
central节点开放南向数据库端口6442,该端口给ovn-controller连接1 y5 O, Q/ _+ C6 m
[root@node1 ~]# ovn-nbctl set-connection ptcp:6641:10.1.1.41
2 f* x6 ~% p; ]- ][root@node1 ~]# ovn-sbctl set-connection ptcp:6642:10.1.1.41+ m$ Q1 Z& m" g2 x& n4 T; L
[root@node1 ~]# netstat -tulnp |grep 6641 n- k3 L. a& K' D; |" i) q
tcp        0      0 10.1.1.41:6641          0.0.0.0:*               LISTEN      34102/ovsdb-server
( B" L* W  Z2 A( \) xtcp        0      0 10.1.1.41:6642          0.0.0.0:*               LISTEN      34118/ovsdb-server4 l5 F& m& Y' r0 N5 M
node1上ovn-controller连接南向数据库& N6 e: B  F" ?/ ^' a9 C9 o+ r, P$ a
ovn-remote:指定南向数据库连接地址
7 H: L% w( U/ [ovn-encap-ip:指定ovs/controller本地ip
4 |% b1 x& [8 S( ?7 ?  ^ovn-encap-type:指定隧道协议,这里用的是geneve
* X7 n; \6 B  C- L" U' ^& b5 f" bsystem-id:节点标识8 J% h7 k/ ^# {
[root@node1 ~]# ovs-vsctl set Open_vSwitch . external-ids:ovn-remote="tcp:10.1.1.41:6642" external-ids:ovn-encap-ip="10.1.1.41" external-ids:ovn-encap-type=geneve external-ids:system-id=node1% H2 c- h" T, ]4 _& l7 [

. o5 K+ E* J: s# W& jnode2上ovn-controller连接南向数据库
  c6 g4 r) E# Z( H1 @6 M0 n: D* s[root@node1 ~]# ovs-vsctl set Open_vSwitch . external-ids:ovn-remote="tcp:10.1.1.41:6642" external-ids:ovn-encap-ip="10.1.1.42" external-ids:ovn-encap-type=geneve external-ids:system-id=node2
$ @2 U" C* d: J7 j  s- F1 @* B! B0 `4 T" G! ?
在node1查看南向数据库信息
( [. k0 `. E9 G) f5 h8 f0 Q[root@node1 ~]# ovn-sbctl show" h, d7 J" F; T" c+ }4 ?5 j
Chassis node2
2 V! v" _, p( |0 \: G/ i' G) x$ n    hostname: node2
8 n% P7 k/ ~9 C0 G& G$ H    Encap geneve
, k  T  J% z& }7 \! k  R        ip: "10.1.1.42"
+ i' `2 F' u, N, A* b0 B        options: {csum="true"}+ K# G/ c$ r0 p7 Q
Chassis node1' L( Y: G% h5 Y& f' B3 `' X% h
    hostname: node1
- W3 L5 t3 K+ t& W5 ^6 _    Encap geneve
& }6 _9 e3 K9 V4 I3 X9 P        ip: "10.1.1.41"* k" Z, h* ^( v
        options: {csum="true"}
, X: t) f) }7 F7 o0 O在这里插入图片描述! {0 z' I! A5 |+ `  n$ ]4 D$ o  }
以上的逻辑架构是站在底层组件和服务的角度来看的。1 n, W2 U5 U, ?, m
接下来换一种角度,站在逻辑网络的角度来看。9 ^2 T6 H' \8 |' y. `3 a
在这里插入图片描述
3 ]& u! y- C% P. o' ?* c; Bgeneve隧道:ovn-controller连接南向数据库时,指定了external-ids:ovn-encap-type=geneve参数,此时看看两个节点上的ovs信息如下,会发现两个节点上都有一个ovn创建的ovs交换机br-int,而且br-int交换机上添加的节点port/interface类型都为geneve
# f# W% N2 F8 l" h5 a: Q# [
  |  _$ v1 K+ i. ?  @8 v[root@node1 ~]# ovs-vsctl show    node1上查看ovs信息
7 n; g! r! l( q& q& X4 ied157e0c-cac3-46b9-830c-f2d710b475d5
% K9 K8 O8 J* y0 T0 d    Bridge br-int
1 r  Y* s- d! Q; J3 n! |7 u: C        fail_mode: secure
0 W5 \# j' _4 \2 M& X% V9 \        datapath_type: system1 b. O! d' |+ v$ q& W& M) S3 E
        Port br-int
$ x9 z+ d/ C- D# Q( r+ g            Interface br-int; _0 g) x- q! k& I( ]
                type: internal
: C. J. t& w3 O" Z3 H  I7 R* e        Port ovn-node2-0/ _$ w: z% x' g% g
            Interface ovn-node2-0
" F: G  }, c5 G* k& j                type: geneve7 i5 Q+ k' |! r1 H+ r( F$ n/ q5 g
                options: {csum="true", key=flow, remote_ip="10.1.1.42"}
% f! L, k- L9 |, Z    ovs_version: "3.1.3"
1 `+ M1 `  f& K4 D( c  M7 O
$ V1 `4 a; t0 F; [+ y[root@node2 ~]# ovs-vsctl show    node2上查看ovs信息
& t4 Y# X- c8 j8 Wf6669675-b42d-47de-be95-b26bf6d1e069
) f6 R- J3 @' J  a    Bridge br-int# o6 d  E) A+ s  K! j9 w3 w. T9 B
        fail_mode: secure- [( H: _" q- a& w
        datapath_type: system
; S! X% [# I# ]6 R        Port ovn-node1-0
. x" W" X5 y; f1 h$ h            Interface ovn-node1-0: H& b, X+ R' B
                type: geneve7 a: p& C1 N4 N5 w1 O: e- s
                options: {csum="true", key=flow, remote_ip="10.1.1.41"}& q4 G% K8 _5 N' c
        Port br-int! e3 Z* Q  w# k# l2 k- g
            Interface br-int
( O6 o& ^! d  ?" C$ F                type: internal& n' V$ a; A+ K6 `! i/ [' O! R
    ovs_version: "3.1.3"
% `6 W. y# w& b, Y+ x[root@node1 ~]# ip link | grep gene  查看geneve隧道link0 R$ j1 N; x+ e% L
5: genev_sys_6081: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 65000 qdisc noqueue master ovs-system state UNKNOWN mode DEFAULT group default qlen 1000% x$ Q  _7 y, ~
查看geneve隧道link详情,从dstport 6081可以看出geneve隧道udp端口是6081
2 j6 x4 e+ E: n' V[root@node1 ~]# ip -d link show genev_sys_6081  & N5 q( M. e: I" r* W
5: genev_sys_6081: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 65000 qdisc noqueue master ovs-system state UNKNOWN mode DEFAULT group default qlen 1000- E" {% t" y! ?4 J6 e9 l
    link/ether 6a:e3:ff:a5:cc:d6 brd ff:ff:ff:ff:ff:ff promiscuity 1 minmtu 68 maxmtu 65465
4 G+ R- a; J9 w% P' S    geneve external id 0 ttl auto dstport 6081 udp6zerocsumrx
" A2 D+ Z/ ~7 ]3 y! A/ z    openvswitch_slave addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535  L. c% F1 n1 q9 M% V
查看geneve隧道udp端口,最后一列为“-”表示这个端口是内核态程序监听, l/ E5 u+ a, M- @
[root@node1 ~]# netstat -nulp|grep 6081
' t: |% A6 ^/ A, I3 S# s  {9 L" ?9 Vudp        0      0 0.0.0.0:6081            0.0.0.0:*                           -
& i5 ~* B; a6 N6 y# }udp6       0      0 :::6081                 :::*                                -
+ x2 q3 g6 _% n: B: A! m$ E% t1 ?* q% z; x9 e+ U4 W) N" W/ v0 W8 ~2 i. i
[root@node2 ~]# ip link | grep gene
0 n- a" w9 z% d7 w' e$ e5: genev_sys_6081: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 65000 qdisc noqueue master ovs-system state UNKNOWN mode DEFAULT group default qlen 1000$ m) _2 z- P; M
[root@node2 ~]# ip -d link show genev_sys_6081. u6 e! D% i, h" n$ j3 L
5: genev_sys_6081: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 65000 qdisc noqueue master ovs-system state UNKNOWN mode DEFAULT group default qlen 1000
7 k& j  N  N% l1 y    link/ether 4e:db:f1:e4:43:94 brd ff:ff:ff:ff:ff:ff promiscuity 1 minmtu 68 maxmtu 65465+ u  v. G' Y0 O/ B) R( t; S* h
    geneve external id 0 ttl auto dstport 6081 udp6zerocsumrx
4 X$ k& f& z% k- p6 L0 G    openvswitch_slave addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
. Y% K+ p  d( n* O- B# v[root@node2 ~]# netstat -nulp|grep 6081% d2 h, T, F) Z! k- V& Q% B
udp        0      0 0.0.0.0:6081            0.0.0.0:*                           -' F) k5 b, u2 A& b: ^# g
udp6       0      0 :::6081                 :::*                                -6 `8 W6 f! {' @% y
在这里插入图片描述9 B% v/ m6 D+ u% H) z! U. }
- |( `1 b6 f4 N+ _8 S
在做以下实验验证时需要注意MAC地址的合法性,不要误配置。MAC地址分为三类:
7 n! e, \; M4 l6 H3 B0 S广播地址(全F)+ x1 O* Y, Q. l
FF:FF:FF:FF:FF:FF
5 S+ b/ F" N: h# I主播地址(第一个字节为奇数)5 t6 [; z: M* d; E$ e* l2 g2 a2 @1 H
X1:XX:XX:XX:XX:XX. ^! U' m$ q5 t- U. N& y6 ~& S
X3:XX:XX:XX:XX:XX
/ E3 x" j, R" t0 RX5:XX:XX:XX:XX:XX0 U9 O3 f. p) `! w+ y
X7:XX:XX:XX:XX:XX
# @* T  m' x3 m5 H4 [1 pX9:XX:XX:XX:XX:XX
" w  [% `9 a- f6 Q: ^2 z2 v: wXB:XX:XX:XX:XX:XX$ O- ~) Y0 x0 p6 q0 R
XD:XX:XX:XX:XX:XX5 u3 }5 y5 h: f% M2 Z
XF:XX:XX:XX:XX:XX% k6 Q6 p/ K) L0 b
可用MAC地址(第一个字节为偶数)* V/ @+ y4 B% o/ {6 X4 O6 C
X0:XX:XX:XX:XX:XX. ^/ j. ^2 m, L! _
X2:XX:XX:XX:XX:XX
* _/ ?0 e' D" N. oX4:XX:XX:XX:XX:XX
7 M" J" i$ Q6 x3 I- JX6:XX:XX:XX:XX:XX
% S/ R1 S% U/ wX8:XX:XX:XX:XX:XX3 w: \1 U. h! u7 {) n6 Z
XA:XX:XX:XX:XX:XX7 h: P3 N; f. D8 t5 m- S" N* a
XC:XX:XX:XX:XX:XX
( m4 R- N# V8 {, ?. O$ N  L# [4 J% bXE:XX:XX:XX:XX:XX3 @0 Z# @- z: z% _) R& Y7 M) o. a
在每个节点上创建一个网络命名空间ns1(因为在两个节点上所以同名ns1不会冲突),网络命名空间可理解为虚拟机,并且在ovs交换机上创建一组port和interfacce,然后把interface放到网络命名空间下。veth pair:两个网络虚拟端口(设备),veth可理解为网卡端口,一个端口在虚拟机上,一个端口在br-int虚拟交换机上。$ q. b" g: Y0 b/ c/ W6 R

- g/ A+ ]$ x7 b9 ~/ Hnode1上执行$ s2 X3 b2 i. Z: b2 g
[root@node1 ~]# ip netns add ns1, r/ N3 D1 o! Y8 [3 g! S
[root@node1 ~]# ip link add veth11 type veth peer name veth12( n; d0 u, ^1 q- b" l! O
[root@node1 ~]# ip link set veth12 netns ns13 J5 z- B# B! }0 w6 M* D- N
[root@node1 ~]# ip link set veth11 up
4 j9 q$ C) V" R/ ^( y[root@node1 ~]# ip netns exec ns1 ip link set veth12 address 00:00:00:00:00:018 X4 Q( W9 {# L) n+ M$ v% h! Q
[root@node1 ~]# ip netns exec ns1 ip link set veth12 up
/ q* `. Y' O) C" H7 ?[root@node1 ~]# ovs-vsctl add-port br-int veth11
6 q# j9 r9 ]! {# L6 v[root@node1 ~]# ip netns exec ns1 ip addr add 192.168.1.10/24 dev veth12, J' d# h( [0 w, n3 Q
+ K( }* {) U" o6 v) _1 z
node2上执行,注意veth12的ip和和node1上veth12 ip在同一个子网
) w4 W' h( V, x5 v/ m( w9 H[root@node2 ~]# ip netns add ns1
4 ^. E% Q# e6 U9 h$ I[root@node2 ~]# ip link add veth11 type veth peer name veth12
9 G: L- u! v( w5 s3 X9 A) a* Y& a[root@node2 ~]# ip link set veth12 netns ns1
" f" |1 C6 p, F) `* n[root@node2 ~]# ip link set veth11 up
' L  c7 f8 K  V0 Z[root@node2 ~]# ip netns exec ns1 ip link set veth12 address 00:00:00:00:00:02
3 t8 W1 _+ X+ ~& ?( D7 V" J0 \[root@node2 ~]# ip netns exec ns1 ip link set veth12 up$ W8 ~: b+ l2 W* x' D! B+ A" C
[root@node2 ~]# ovs-vsctl add-port br-int veth11# G  c4 r' ~5 _4 {; a! u5 g, c/ I0 `
[root@node2 ~]# ip netns exec ns1 ip addr add 192.168.1.20/24 dev veth12
. n6 z* D2 c+ E' [5 m
6 C" ?* B- Q$ L9 k/ r; v查看node1上br-int交换机信息, p; e% z2 O: }5 k6 k9 V+ @+ A
[root@node1 ~]# ovs-vsctl show! ~& P, y! b1 m! Q% \$ ~
ed157e0c-cac3-46b9-830c-f2d710b475d5
& M- N0 j9 U. h" X5 o) H    Bridge br-int5 r1 \/ E5 e5 r, h" m" d/ x7 J7 g
        fail_mode: secure
: k2 g2 a3 e8 s% ?1 ]2 |# Z        datapath_type: system
0 w1 ]- Q9 z  P" k& ]        Port br-int) j" P* w, P# T% [" q; @! ~
            Interface br-int3 R# \) Q7 q' q
                type: internal
# R: T; }5 L9 r. Q3 G. K        Port veth11$ k8 E5 I3 {$ _# j4 W+ D5 T' b
            Interface veth11
$ e( A& E# g6 ?( B* S. `( O: c4 K        Port ovn-node2-0
6 S- Q9 i' K% p- q            Interface ovn-node2-0
% W/ {# F7 p/ q8 u& p                type: geneve
2 k  l0 ?7 G  v3 |( b: v                options: {csum="true", key=flow, remote_ip="10.1.1.42"}
+ [. D1 f" I" N, e4 g+ J! w, G    ovs_version: "3.1.3"8 g9 }0 i; r6 N4 s9 ^  T
查看node2上br-int交换机信息
  _& }6 H* N0 C8 w7 ~1 _[root@node2 ~]# ovs-vsctl show
% c8 g  J/ D% P4 Sf6669675-b42d-47de-be95-b26bf6d1e0696 W1 }" v4 S% Z! v9 O2 L% k" d
    Bridge br-int5 W) ~2 Y! y, V3 Q% j
        fail_mode: secure
1 w- d+ H/ T3 }8 V9 _" M3 e5 X        datapath_type: system# }4 f9 F  v+ T7 j
        Port veth114 j; H" c6 U( c4 Y
            Interface veth11
: `% I3 D2 V. I' v* t( X% ], J        Port ovn-node1-0
+ V( ^3 w& s3 f& k            Interface ovn-node1-0# d. A) x- x" E4 b/ Y/ _/ j
                type: geneve
; I" Z3 ?6 e* Y5 Y1 A                options: {csum="true", key=flow, remote_ip="10.1.1.41"}
( Z' ?7 A+ r) g" j        Port br-int3 ]" `2 H1 j" s4 v
            Interface br-int
5 d6 x3 p: ^1 L3 r: J                type: internal% ~  t0 h* h  C; B1 t% f5 ]
    ovs_version: "3.1.3"
5 U: z5 O( ?, j/ u$ d6 k3 D7 \
: ?9 A! `2 n/ {. Y* N/ p: B( I9 m现在从node1上的ns1 ping node2上的ns1是不通的,因为它们是不同主机上的网络,二/三层广播域暂时还不可达。: P. H# m' C" x7 ^% E
[root@node1 ~]# ip netns exec ns1 ping -c 3 192.168.1.20
! u' }% x3 o- @# F& PPING 192.168.1.20 (192.168.1.20) 56(84) bytes of data.
. l& L: u( ?5 e. `' ^' Q. t  T
6 T. \6 V7 C/ b--- 192.168.1.20 ping statistics ---5 i7 ^0 V0 l% A$ O; F1 z0 |5 h
3 packets transmitted, 0 received, 100% packet loss, time 2047ms9 W: @6 c3 c- u, f* h7 I* @* d: J
在这里插入图片描述' M2 w1 [. j/ b1 E* G
查看openstack的控制节点发现,ovn的北向数据库中有逻辑交换机信息。4 C+ f0 U0 M2 `  v$ b0 T
在openstack里面,创建一个网络,就相当于创建了一个逻辑虚拟交换机,这个逻辑交换机(网络)信息会被保存到北向数据库里面。一个网络就是一个逻辑交换机。5 c7 C) ]$ b- e; d& K8 R
在这里插入图片描述
$ ?0 u* K! b( x+ R1 E' b$ [在node1中查看发现,ovn的北向数据库中没有逻辑交换机信息
- q7 n' X' a# |1 ~7 N: ~( \. i# s0 W在这里插入图片描述
/ A7 V# }0 L$ e7 D在openstack不同节点的虚拟机ip互通,这两个虚拟机ip连的是同一个网络,是同一个逻辑交换机上的同一个子网不同ip所以互通。
8 y: V9 N# e- j+ w0 R2 g这两个节点的虚拟机ns1的ip是手工配置的独立的、不互通,这两个虚拟机ip没有连到逻辑交换机上,加个逻辑交换机就能互通。
" X9 `3 y7 I6 j3 ~) K在这里插入图片描述
* Y: s, N& ^9 l! L, l逻辑交换机(Logical Switch):为了使node1和node2上两个连接到ovs交换机的ns能正常通信,需借助ovn的逻辑交换机,注意逻辑交换机是北向数据库概念。3 L- I1 o- [* B. i/ `7 F' v
' z. Q0 D+ _, W0 t- l0 K: T0 j3 U) w0 [
在node1上创建逻辑交换机
- e, A- V; }  B$ B9 Z$ T3 ~+ `[root@node1 ~]# ovn-nbctl ls-add ls1
* E$ f2 |( U# a2 L1 U[root@node1 ~]#  ovn-nbctl show
, Y3 U  d! c$ L7 x, R% o. c" e# @switch 86349e35-cdb4-42f7-a702-4b4a9d5653ef (ls1)
  E. V7 `  L9 E1 h* G6 `在逻辑交换机上添加端口5 i( B8 J  @1 I8 r: S. x- ?
添加并设置用于连接node1的端口,注意mac地址要和veth pair网络命名空间内的那端匹配起来
( q7 ]8 X; {3 X5 D, L; h' ~[root@node1 ~]# ovn-nbctl lsp-add ls1 ls1-node1-ns1
8 G. z6 }9 i, i( R2 s  u[root@node1 ~]# ovn-nbctl lsp-set-addresses ls1-node1-ns1 00:00:00:00:00:01
6 R5 s  K0 A. D+ N1 L[root@node1 ~]# ovn-nbctl lsp-set-port-security ls1-node1-ns1 00:00:00:00:00:01
) ~! r1 U. p' R& B# z添加并设置用于连接node2的端口,注意mac地址要匹配起来
4 A# F: z/ R3 |1 \[root@node1 ~]# ovn-nbctl lsp-add ls1 ls1-node2-ns1
4 |& r% t5 N# Q1 [  ?: x[root@node1 ~]# ovn-nbctl lsp-set-addresses ls1-node2-ns1 00:00:00:00:00:02# V* W% g1 C4 V6 O: O
[root@node1 ~]# ovn-nbctl lsp-set-port-security ls1-node2-ns1 00:00:00:00:00:02
8 X% ?/ `) D! A查看逻辑交换机信息
9 K1 r; _- m  x$ v! A& ?4 S# S[root@node1 ~]# ovn-nbctl show
& Y/ x% `1 C( B! b. E) Rswitch 86349e35-cdb4-42f7-a702-4b4a9d5653ef (ls1)
8 N) N; C) ^' ^5 f    port ls1-node1-ns1
0 [: b* S1 g4 `3 y        addresses: ["00:00:00:00:00:01"], Q: c6 b5 ?5 [
    port ls1-node2-ns1- v' G! K5 v- r. |
        addresses: ["00:00:00:00:00:02"]
0 X# H& s6 y+ i5 e
/ O: q- ?3 P9 y4 Snode1上执行,veth11端口连接逻辑交换机端口
# \/ U& z/ ~) [* [$ w[root@node1 ~]# ovs-vsctl set interface veth11 external-ids:iface-id=ls1-node1-ns1# P$ X  q5 m! p( u
node2上执行,veth11端口连接逻辑交换机端口
% \5 c& }' l/ \* ?[root@node2 ~]# ovs-vsctl set interface veth11 external-ids:iface-id=ls1-node2-ns1
& p6 d0 G) @' k" V" Q. @' M" P再次查看南向数据库信息,发现端口已连接
+ R) ]7 k/ V3 @) E[root@node1 ~]# ovn-sbctl show8 S% ]) [* I9 Q" N6 P4 z
Chassis node2
6 f6 O/ h) r$ \! H: V    hostname: node2
, O7 W, l: ]3 f9 z% Q$ g    Encap geneve
9 A& n& B- I1 U, F$ h        ip: "10.1.1.42"* _+ |! O3 V2 ?" c4 M$ u
        options: {csum="true"}/ A- V# ?# g) n/ L& ~7 ?* H6 T* a2 M: @
    Port_Binding ls1-node2-ns1  k4 r; S# p8 m  Y
Chassis node1
- Z  |" G* h+ {5 S9 S  Z    hostname: node1
1 J; M$ B4 ~+ m, f0 z% \% E    Encap geneve! J+ F- d. R' k! Q
        ip: "10.1.1.41"
& _9 S+ s- T! V% Q- Z& O4 ~+ h        options: {csum="true"}
* d& e/ n# D5 I    Port_Binding ls1-node1-ns1
2 |* k5 L5 j/ qnode1上验证网络连通性$ S7 V# T+ R) _9 x  e9 J# I
[root@node1 ~]# ip netns exec ns1 ping -c 3 192.168.1.20
/ Q# d/ C/ O1 Y. WPING 192.168.1.20 (192.168.1.20) 56(84) bytes of data.& E* o, J5 V3 b0 |! l; ^
64 bytes from 192.168.1.20: icmp_seq=1 ttl=64 time=4.68 ms
; g4 k0 ], S1 X64 bytes from 192.168.1.20: icmp_seq=2 ttl=64 time=0.908 ms
! [. b; @5 {6 s0 t' P* I  ?64 bytes from 192.168.1.20: icmp_seq=3 ttl=64 time=0.756 ms5 B; N+ H% I7 w4 ^3 t

8 k3 A- F0 Y$ c( M--- 192.168.1.20 ping statistics ---
  ]/ }7 m* _. v; F1 {5 E: }3 packets transmitted, 3 received, 0% packet loss, time 2004ms7 c8 e. z0 a9 i: \1 u4 K
rtt min/avg/max/mdev = 0.756/2.115/4.682/1.816 ms. c4 m  ~3 c; t; v* O" k$ O# v
node2上验证网络连通性; L0 z; ^, f3 N! D6 W
[root@node2 ~]# ip netns exec ns1 ping -c 3 192.168.1.10$ {% _, f/ \  W; B/ }; M4 r9 P
PING 192.168.1.10 (192.168.1.10) 56(84) bytes of data.
; t  n2 `. p1 w$ L+ K64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=3.34 ms
) p! C# H! W/ O) d' J64 bytes from 192.168.1.10: icmp_seq=2 ttl=64 time=0.863 ms- N% Y, l4 F" t$ u* k. D
64 bytes from 192.168.1.10: icmp_seq=3 ttl=64 time=0.372 ms
6 V1 o) H5 m2 i2 X7 ^- B( U' O- e! a' P+ u
--- 192.168.1.10 ping statistics ---3 S' ^. |9 l$ f6 [; ^. T1 N+ B
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
. T; ]! m  @/ H6 J$ G$ U" n1 wrtt min/avg/max/mdev = 0.372/1.525/3.342/1.300 ms# z2 @- A: h+ K1 b0 ^
现在node1和node2的ns1互通了,相当于创建了两个实例,这两个实例ip用的子网是连在同一个逻辑交换机上的,是同一个逻辑交换机上的同一个子网不同ip所以互通。2 |$ g' z: n9 t& y- D
在这里插入图片描述
4 i" G+ h# u% O. r3 \; }在这里插入图片描述$ O+ W  _4 [  T5 {' |5 P
geneve隧道验证:从node1上的ns1 ping node2上的ns1的例子,抓包看看各个相关组件报文,验证geneve隧道封解包。通过抓包分析,可以看出geneve隧道在ovn/ovs跨主机通信的重要作用,同时也能看到ovn逻辑交换机可以把不同宿主机上的二层网络打通,或者说ovn逻辑交换机可以把ovs二层广播域扩展到跨主机。  W, {5 T, {: B: r$ p4 d6 o
1 Y" W! ]0 C( S+ W0 p" D& u# x
// node1上ns1 ping node2上ns1
+ L7 @: J# x! C# ip netns exec ns1 ping -c 1 192.168.1.20/ ?( L( {0 x/ O
PING 192.168.1.20 (192.168.1.20) 56(84) bytes of data.2 |3 C2 u# c3 n8 V& j3 P  \
64 bytes from 192.168.1.20: icmp_seq=1 ttl=64 time=1.00 ms1 g+ \0 q3 X7 }+ e1 D% l
--- 192.168.1.20 ping statistics ---+ C7 r. [3 w5 K* H  S0 h4 r  f% p
1 packets transmitted, 1 received, 0% packet loss, time 0ms& d5 d6 a8 d8 X. Q
rtt min/avg/max/mdev = 1.009/1.009/1.009/0.000 ms
8 Q! P& B( {3 Y& @8 `9 R/ D4 T) s! B
// node1上ns1中的veth12抓包6 v8 Y/ }1 \, j% }7 L( `4 ?
# ip netns exec ns1 tcpdump -i veth12 -n% I3 ~! h, g  r3 K/ K9 L
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode. M1 ^5 f' i4 _& k
listening on veth12, link-type EN10MB (Ethernet), capture size 262144 bytes
3 D# G0 F! C$ d2 O! d1 S5 q# B$ V22:23:11.364011 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 24275, seq 1, length 64: v  ?4 u( @4 p
22:23:11.365000 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 24275, seq 1, length 642 N7 J4 o* N# o2 W& F
22:23:16.364932 ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 28% s; L' \5 |$ h5 F+ @$ l; L
22:23:16.365826 ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 28
8 ]! T2 X, c- v$ M) m1 c" q% R3 B" e) E7 O
// node1上veth12的另一端veth11抓包8 U* y) L' v. N
# tcpdump -i veth11 -n5 X% F% {' t1 A, z
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
2 R8 ^' A" Y+ Q5 K( M  j- R/ l, qlistening on veth11, link-type EN10MB (Ethernet), capture size 262144 bytes6 l' y8 c: j7 E8 c5 K
22:25:11.225987 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 25166, seq 1, length 64
5 q( Z6 ?4 D8 I# o# B7 k22:25:11.226914 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 25166, seq 1, length 648 W3 y4 R6 A2 R7 S+ Z" K
22:25:16.236933 ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 28
, p: T+ H( U1 C7 V  Q22:25:16.237563 ARP, Request who-has 192.168.1.10 tell 192.168.1.20, length 28  P/ ~* W* D) _& [
22:25:16.237627 ARP, Reply 192.168.1.10 is-at 00:00:00:00:00:01, length 28
2 I. Z: B, r9 N$ D% M$ q22:25:16.237649 ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 28
( ?/ g. v: M' L' f9 i4 e8 W5 Y4 N
; ?  X0 G1 \5 Y9 O) e// node1上genev_sys_6081网卡抓包# C, _  f  f% u' ?5 `& @
# tcpdump -i genev_sys_6081 -n- M7 p6 g8 q5 U; k" s" q5 _" |
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode0 E! B: ^2 H# Z7 p- o7 g7 p2 \
listening on genev_sys_6081, link-type EN10MB (Ethernet), capture size 262144 bytes5 E( V' F4 a* [' w+ |
22:28:15.872064 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 26492, seq 1, length 64
7 p% `& Q) g4 }4 x& U! A22:28:15.872717 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 26492, seq 1, length 64
/ s7 K" ?! b9 R+ l# A" H22:28:20.877100 ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 28
9 }  c3 Z$ Y( M) u! b2 r' G3 M22:28:20.877640 ARP, Request who-has 192.168.1.10 tell 192.168.1.20, length 286 o. x: j& f1 w* A; \
22:28:20.877654 ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 28
  ^& ]5 e3 t, o$ w6 Y! ~8 T22:28:20.877737 ARP, Reply 192.168.1.10 is-at 00:00:00:00:00:01, length 28/ T" |; [  S* }* i% ^. n3 x0 u+ m

/ V0 r# t2 I4 K8 T// node1上eth0抓包,可以看出数据包经过genev_sys_6081后做了geneve封装
0 L* p. B$ S* T, P4 x# tcpdump -i eth0 port 6081 -n- Q6 j9 H/ B6 }6 Y
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode4 p0 ^5 w; @! h. h+ P
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
, `& G6 J( ~' N7 [' u" c, x  w/ v, Z22:30:23.446147 IP 10.0.12.7.51123 > 10.0.12.11.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 27458, seq 1, length 648 k0 h) {  u  n* A5 L$ g
22:30:23.446659 IP 10.0.12.11.50319 > 10.0.12.7.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 27458, seq 1, length 64
8 \! ~4 d/ i- r( I22:30:28.461137 IP 10.0.12.7.49958 > 10.0.12.11.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 28
8 G3 B. I- x/ A# b22:30:28.461554 IP 10.0.12.11.61016 > 10.0.12.7.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: ARP, Request who-has 192.168.1.10 tell 192.168.1.20, length 283 {2 b8 l6 G5 G
22:30:28.461571 IP 10.0.12.11.61016 > 10.0.12.7.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 28" N# `4 d5 s0 ?
22:30:28.461669 IP 10.0.12.7.49958 > 10.0.12.11.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: ARP, Reply 192.168.1.10 is-at 00:00:00:00:00:01, length 28, Y. j1 R4 u. h6 n, f) Y
6 @: p# ]. [  j3 J* A( [9 u
===================跨主机===================% g# G; x; I% I: n+ P* i

' ?! k$ l3 g! T) i1 Q// node2上eth0抓包
! P$ t6 {: F- f, Z1 ~& d/ D# tcpdump -i eth0 port 6081 -n
! i% B8 [. I" G4 g# X/ stcpdump: verbose output suppressed, use -v or -vv for full protocol decode
2 f- {# \" n1 Q4 Q! S$ Y; ?, Clistening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes; ~* U; g$ f1 u; H7 l- G
22:23:11.364189 IP 10.0.12.7.51123 > 10.0.12.11.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 24275, seq 1, length 64
# F7 |) D3 c) S* b% O9 V( s$ c22:23:11.364662 IP 10.0.12.11.50319 > 10.0.12.7.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 24275, seq 1, length 64: h9 M) M) F( |( j! [$ f# f- C
22:23:16.365086 IP 10.0.12.7.49958 > 10.0.12.11.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 281 w- `, ~) L2 Z9 W  t5 R
22:23:16.365487 IP 10.0.12.11.61016 > 10.0.12.7.6081: Geneve, Flags [C], vni 0x1, options [8 bytes]: ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 28: ]! l8 g+ j' p' G: s! C

- ~) ^, @8 I1 Z: Q5 |, s" Q// node2上genev_sys_6081网卡抓包,可以看到数据包从genev_sys_6081出来后做了geneve解封
. a' Q. l. V3 P9 n8 C; D# tcpdump -i genev_sys_6081 -n7 I' S) @( k  O! W
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode8 }/ F. V6 c* G; u  D
listening on genev_sys_6081, link-type EN10MB (Ethernet), capture size 262144 bytes
4 R' j) T6 Y1 R  x+ o22:25:11.226186 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 25166, seq 1, length 64; Y0 H! `2 t9 l! e8 D
22:25:11.226553 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 25166, seq 1, length 64) @( g# i' F3 L3 p( x) p
22:25:16.237070 ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 28
" |8 q$ Z* ~$ v- H22:25:16.237162 ARP, Request who-has 192.168.1.10 tell 192.168.1.20, length 28& x$ O2 t; u: f6 M9 R  K# B8 C$ a
22:25:16.237203 ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 28# L' x  E2 [+ p1 H" Z* }5 `
22:25:16.237523 ARP, Reply 192.168.1.10 is-at 00:00:00:00:00:01, length 28
: k# U+ ~- ?- ?: k1 u$ A: A& D1 i! Q, r
// node2上veth11抓包" Q. I3 [4 j; V! F( x7 Y
# tcpdump -i veth11 -n
6 m4 N0 \; U9 L2 x6 k8 S* {1 `) Dtcpdump: verbose output suppressed, use -v or -vv for full protocol decode/ T# w) _* K/ U5 X" B
listening on veth11, link-type EN10MB (Ethernet), capture size 262144 bytes
" E9 W! x. S! p, p: g22:28:15.872198 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 26492, seq 1, length 64
" G. E+ H4 H6 F22:28:15.872235 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 26492, seq 1, length 64
/ K7 j7 J1 o+ F& H* b0 W22:28:20.876913 ARP, Request who-has 192.168.1.10 tell 192.168.1.20, length 28
$ S- c; n4 p& F' L6 {5 h22:28:20.877274 ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 28  ^9 ^8 @" L9 r/ l1 w( P$ [
22:28:20.877287 ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 28
4 X0 x; X* T, I+ r6 N3 ^/ j3 T22:28:20.877613 ARP, Reply 192.168.1.10 is-at 00:00:00:00:00:01, length 28% G, r1 d! G! K/ W

2 D, \" s5 x* Z' j// node2上ns1中的veth12抓包
9 G* F4 p; @2 h0 ]; p6 S  R1 Y6 `# ip netns exec ns1 tcpdump -i veth12 -n
2 m, U4 s3 x1 b' v' Dtcpdump: verbose output suppressed, use -v or -vv for full protocol decode$ s. [) Z1 k% k9 ^/ v# o' D7 W
listening on veth12, link-type EN10MB (Ethernet), capture size 262144 bytes; ^$ x, a; N8 l  ~& U
22:30:23.446212 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 27458, seq 1, length 64
$ a" n$ f" @, Q0 w22:30:23.446242 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 27458, seq 1, length 64  M& \! Y- Q2 w  v- k2 F, Y
22:30:28.460912 ARP, Request who-has 192.168.1.10 tell 192.168.1.20, length 28
$ G, F6 F! {+ U+ Z22:30:28.461260 ARP, Request who-has 192.168.1.20 tell 192.168.1.10, length 28
7 m0 U" j  Z$ q; h1 M6 j2 Q22:30:28.461272 ARP, Reply 192.168.1.20 is-at 00:00:00:00:00:02, length 28
1 {4 f. l7 Z' I22:30:28.461530 ARP, Reply 192.168.1.10 is-at 00:00:00:00:00:01, length 288 D; a0 C- ]$ x, b
逻辑路由器(Logical Router):# o2 b. V" P, j9 W0 Y& u: f' t1 B* Q
前面验证了ovn逻辑交换机跨主机同子网的通信,那不同子网间又该如何通信呢?这就要用到ovn的逻辑路由器了。
' Z  t9 q+ m/ X5 p* {9 N7 H4 w先在node2上再创建个网络命名空间ns2,ip设置为另外一个子网192.168.2.30/24,并且再增加一个逻辑交换机。" R1 X6 K% N. o% `3 n
在这里插入图片描述
. |( E2 k) Z' b# s
% f2 e3 v/ P) Fnode2上执行! `  R4 t2 T/ p0 y' L! L  p) G' w% E; Z
[root@node2 ~]# ip netns  查看网络命名空间4 N, n( H  K- U% A/ Z$ }7 e
ns1 (id: 0)5 w7 S' ^) `9 I4 O
[root@node2 ~]# ip netns add ns25 {! _' T' t' l! V
[root@node2 ~]# ip link add veth21 type veth peer name veth22
: k" [" v7 n( k; t) v[root@node2 ~]# ip link set veth22 netns ns2$ O, t" b) [$ |4 u. Y
[root@node2 ~]# ip link set veth21 up. y9 C; d4 j2 g/ {6 K% O7 p
[root@node2 ~]# ip netns exec ns2 ip link set veth22 address 00:00:00:00:00:03
# S( x; L" q& L7 |! H( }[root@node2 ~]# ip netns exec ns2 ip link set veth22 up& E# @, a+ w3 {; m+ x
[root@node2 ~]# ovs-vsctl add-port br-int veth21
. {. o. P4 C/ B: r6 ~[root@node2 ~]# ip netns exec ns2 ip addr add 192.168.2.30/24 dev veth22
6 j! r- V5 n2 H! x/ \4 y1 O( U  V[root@node2 ~]# ip netns
. S* B0 W: D7 |# ~3 G2 t" tns2 (id: 1); f0 `- q: T6 j7 _2 o, y
ns1 (id: 0)% s" c% x6 t; ]1 D
& {1 O/ A! E: _; g* X( B
node1上用ovn命令新增一个逻辑交换机,并配置好端口
- C$ A& f4 e; m1 F* N! v[root@node1 ~]# ovn-nbctl ls-add ls2
& u+ i1 G9 C8 N5 Q9 R[root@node1 ~]# ovn-nbctl lsp-add ls2 ls2-node2-ns29 J- n3 j# \9 P0 t; l
[root@node1 ~]# ovn-nbctl lsp-set-addresses ls2-node2-ns2 00:00:00:00:00:03
) d* ?' Y" }' ][root@node1 ~]# ovn-nbctl lsp-set-port-security ls2-node2-ns2 00:00:00:00:00:03
1 z) Y7 n  x; x2 {0 F* g1 `8 F7 Q9 ^) t  Y2 }
node2上ovs交换机端口和ovn逻辑交换机端口匹配起来
, K& t! z( O' F! |9 d+ j" e[root@node2 ~]# ovs-vsctl set interface veth21 external-ids:iface-id=ls2-node2-ns2
' T' t7 @% i& O+ {5 q5 @' i; j; M* Q
' H) y( F1 X9 v" o- {查看北向数据库和南向数据库信息
3 i' U) a$ n  u  H3 g1 l[root@node1 ~]# ovn-nbctl show
: y+ {% p$ y( C# ~* F0 rswitch 484606e0-944d-4c6b-9807-502f05bebb18 (ls2)
9 m! k7 K" y' J; b' [    port ls2-node2-ns2: p7 ^. W$ E- R: }& E% p0 u
        addresses: ["00:00:00:00:00:03"]5 n- Z- U+ s/ h% M
switch 86349e35-cdb4-42f7-a702-4b4a9d5653ef (ls1)
* V6 E* D! L: j8 f' x1 S# B/ H    port ls1-node1-ns1
: v: @; R# T$ `        addresses: ["00:00:00:00:00:01"]4 S/ Z8 D4 M" `" b2 P; G7 z+ ]
    port ls1-node2-ns1
9 t& E6 ^$ y3 Z2 k+ X7 N, I; Y        addresses: ["00:00:00:00:00:02"]
4 `( t& Z) @/ w, X[root@node1 ~]# ovn-sbctl show
+ Z+ O. p& |6 u9 jChassis node2
* D1 a# L7 V$ C3 @    hostname: node2' Y, f5 p, U$ J. [, e. q
    Encap geneve' T7 d! [2 ^) @, Z
        ip: "10.1.1.42"; a3 `2 L- W- b5 x6 ?$ o& g
        options: {csum="true"}
8 b6 q6 S, \* P, l* M    Port_Binding ls2-node2-ns2* k, y7 l& G* H9 l+ R
    Port_Binding ls1-node2-ns1
; A; x9 I* R' y8 l# hChassis node19 E! ^( e0 L3 R% ~, ~2 V
    hostname: node19 p& t8 i/ q* V( i8 ?" P: F
    Encap geneve  M/ V! x4 e6 P& j5 u9 }/ \5 }
        ip: "10.1.1.41"
8 a/ v# W$ A, l        options: {csum="true"}
( ]( V/ J& L( i2 j" z+ n! t    Port_Binding ls1-node1-ns1
" E) b: F# j  R& l* ~( [$ v/ J创建ovn逻辑路由器连接两个逻辑交换机
7 t- [1 u/ W5 U0 j/ o
6 E# q+ T- G. F( \! f添加逻辑路由器,路由信息保存在北向数据库
2 p' Q& _' {! a0 \" @* \* w[root@node1 ~]# ovn-nbctl lr-add lr1
( ~* u4 o! }) q4 X6 J逻辑路由器添加连接交换机ls1的端口
/ z4 z* P7 O2 q0 b3 A[root@node1 ~]# ovn-nbctl lrp-add lr1 lr1-ls1 00:00:00:00:11:00 192.168.1.1/248 F8 K1 `- Z# d' b/ m7 |* r
逻辑路由器添加连接交换机ls2的端口: u2 ^8 P; h( t2 O; C( c
[root@node1 ~]# ovn-nbctl lrp-add lr1 lr1-ls2 00:00:00:00:12:00 192.168.2.1/24
7 i8 H: p  O8 F. |
3 A$ ]2 L# }1 ^- K逻辑路由器连接逻辑交换机ls18 e, J' d: @4 |1 t  t- a, ?5 \
[root@node1 ~]# ovn-nbctl lsp-add ls1 ls1-lr1
  T0 w4 W7 j/ D7 @. `  C[root@node1 ~]# ovn-nbctl lsp-set-type ls1-lr1 router* i7 {3 C5 q- K; q% V2 f
[root@node1 ~]# ovn-nbctl lsp-set-addresses ls1-lr1 00:00:00:00:11:003 U  h& h& [+ A  [0 g7 M
[root@node1 ~]# ovn-nbctl lsp-set-options ls1-lr1 router-port=lr1-ls1
3 H  T3 p' F0 [) G0 p  _% Q+ [2 ^1 z7 S
逻辑路由器连接逻辑交换机ls2
# p" D/ Y% k) E' m$ i[root@node1 ~]# ovn-nbctl lsp-add ls2 ls2-lr1
7 J# f- \; H) `9 L[root@node1 ~]# ovn-nbctl lsp-set-type ls2-lr1 router' `- ?( t. g. g0 `2 X- w3 z
[root@node1 ~]# ovn-nbctl lsp-set-addresses ls2-lr1 00:00:00:00:12:00
- g- c; Q0 N6 n: r9 P9 a[root@node1 ~]# ovn-nbctl lsp-set-options ls2-lr1 router-port=lr1-ls2
: H/ p$ T  T. g4 l0 O# v
: l/ ]0 k+ K0 |查看北向数据库和南向数据库信息
) {' N2 p/ T3 s[root@node1 ~]# ovn-nbctl show$ j- g+ w  s! P( b3 P
switch 484606e0-944d-4c6b-9807-502f05bebb18 (ls2)
- i' j1 d% V' ^$ Y    port ls2-node2-ns22 u1 q* f4 s9 _" `# B8 h
        addresses: ["00:00:00:00:00:03"]
/ p% p& ?8 E$ y    port ls2-lr1
7 ]3 b% X  O. l; @8 i        type: router! }" \, U" p( H0 P& y& ~# n
        addresses: ["00:00:00:00:12:00"]; j4 t1 g4 P- _# ~
        router-port: lr1-ls20 y5 C! X( R) J8 s7 I
switch 86349e35-cdb4-42f7-a702-4b4a9d5653ef (ls1)' E& Z6 g( B2 k0 h2 `
    port ls1-node1-ns12 R& C& J, t; P2 C! x$ ^
        addresses: ["00:00:00:00:00:01"]& b0 {- _+ u; o. v+ ]  C6 @- d; {
    port ls1-node2-ns1. R. S6 D3 v7 d$ Z5 W1 q. s
        addresses: ["00:00:00:00:00:02"]) X% [) v& t7 Q7 l/ }
    port ls1-lr1
, v& c' ~4 n& J& P7 X        type: router
) C  @3 r7 |; g" B3 R        addresses: ["00:00:00:00:11:00"]0 q* ~" m% Y' X% Y1 o4 v
        router-port: lr1-ls1
# K7 f- o, d) Erouter e9c151a0-5db7-4af6-91bd-89049c4bbf9f (lr1)& x3 ~8 n7 d8 }) ?
    port lr1-ls2
  `* n" {2 [6 n5 x) Z& O3 a        mac: "00:00:00:00:12:00"# p/ N" L; {/ Z
        networks: ["192.168.2.1/24"]# x3 E/ f$ n% Z: h8 l
    port lr1-ls1
' c/ W- I5 E* ^# Y4 u/ H# [        mac: "00:00:00:00:11:00"
8 w6 R$ g" C" Q5 r        networks: ["192.168.1.1/24"]/ x0 [6 b4 ?4 Z- b( {6 J
[root@node1 ~]# ovn-sbctl show8 i2 b, r2 Y' t/ k
Chassis node2
7 T% a( D3 \: j+ a    hostname: node2( B) h6 h8 Y' F4 \3 _: w
    Encap geneve
1 Q1 Q0 [' n, B. Z$ i6 V        ip: "10.1.1.42"( @5 ]9 Q/ j7 w! Q( m$ l1 T, g
        options: {csum="true"}
! e. J" C6 \9 W5 p) {    Port_Binding ls2-node2-ns2. u: d, w  h! T  u- ~+ }% d3 m" t
    Port_Binding ls1-node2-ns19 N+ D! C& w2 N/ @( \" c  Y+ u
Chassis node1
1 j  p# i( A" V: b7 P4 z) `4 b" A    hostname: node10 O8 X* t) p- j( C/ M; n* X, Z% Z
    Encap geneve; ^: |* d& B5 W& H3 o+ g$ T
        ip: "10.1.1.41"7 L3 ~: p0 H- d& R5 L
        options: {csum="true"}( X, X! Q9 w) U' z! A3 Y
    Port_Binding ls1-node1-ns1
! ^& r% G1 y  v( M8 a  h在这里插入图片描述) t8 Q2 o5 ~$ X% S6 [4 A7 I
从node1的ns1(192.168.1.10/24) ping node2的ns2(192.168.2.30),验证跨节点不同子网的连通性。
8 G) N0 e- t& T* W- u9 f0 @0 ^
% Y; J  [1 m& G  m- t; w[root@node1 ~]# ip netns exec ns1 ping -c 1 192.168.2.30/ C; }5 P* f# L6 {; Q' L
connect: Network is unreachable        connect: 网络不可达
9 A* r% f+ R% B! \, K; D, f查看ns1上的路由配置,显然此时没有到192.168.2.0/24网段的路由; \: Q6 V; ]% w' w1 i
[root@node1 ~]# ip netns exec ns1 ip route show8 {( b8 k* G( R- Y
192.168.1.0/24 dev veth12 proto kernel scope link src 192.168.1.10+ f: R' x* }6 t/ Y; Y$ i
[root@node1 ~]# ip netns exec ns1 route -n, W) p/ I9 r, D; R6 g
Kernel IP routing table# B. k8 P# i7 }3 r) y' {$ Y
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
9 l. h3 y0 E6 r+ e4 \0 K192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 veth127 l9 h( A7 ?. s0 \* J; r* a
因为路由器是三层概念,要先给ovs的相关port配置上ip
- g3 V5 S$ d- Z7 [6 J0 l
5 B/ K9 X, q" K. C[root@node1 ~]# ovn-nbctl lsp-set-addresses ls1-node1-ns1 00:00:00:00:00:01" |) O5 h- I, o0 {6 y
[root@node1 ~]# ovn-nbctl lsp-set-addresses ls1-node2-ns1 00:00:00:00:00:02
: Y3 t7 ?5 Y: _* M2 M4 U[root@node1 ~]# ovn-nbctl lsp-set-addresses ls2-node2-ns2 00:00:00:00:00:03
9 y# I1 Y( W* d) s- {再给三个网络命名空间添加默认路由,网关为ovn逻辑路由器对应的port ip. E" p* p( ~2 q6 p1 h" a6 B
: x( U" K3 k" F( E: w
node1上ns1
/ R5 @# g/ Z) n# {- T [root@node1 ~]# ip netns exec ns1 ip route add default via 192.168.1.1 dev veth121 p, w; W( V; \/ c2 q
node2上ns1
; C5 N& R: ~+ W4 @ [root@node2 ~]# ip netns exec ns1 ip route add default via 192.168.1.1 dev veth12/ U3 [% r1 X0 p- e5 t" B: E
node2上ns2
, M5 v4 \% ^; b& D6 [3 X [root@node2 ~]# ip netns exec ns2 ip route add default via 192.168.2.1 dev veth228 j' @& @# d" {
再次查看下南北向数据库信息/ E3 P5 T( z1 N* Q
* A* W7 A. b/ Y: r. ]1 g9 W' K1 L4 C
[root@node1 ~]# ovn-nbctl show& {. H9 \$ {. A2 a. g
switch 484606e0-944d-4c6b-9807-502f05bebb18 (ls2)4 V; ~9 R+ c1 j# r4 d
    port ls2-node2-ns2
/ o* N" i# Q' u- Y  b        addresses: ["00:00:00:00:00:03"]9 Y# ?2 G' x. W; j9 q3 w
    port ls2-lr1
! }7 ^# H1 Z: w+ z( S" b        type: router
& |; j* o' w. [: f: W/ F2 D        addresses: ["00:00:00:00:12:00"]
6 x+ E, `; u( ]# E        router-port: lr1-ls2% P" ^& I0 [8 F
switch 86349e35-cdb4-42f7-a702-4b4a9d5653ef (ls1)  b' s2 J) Y3 X5 U, R
    port ls1-node1-ns1, F- Y3 \+ O. L- v
        addresses: ["00:00:00:00:00:01"]
# `3 E( d) \5 M: \, `    port ls1-node2-ns1& G, W+ o7 t) `/ {
        addresses: ["00:00:00:00:00:02"], \$ J8 B* Y& l6 d
    port ls1-lr1+ b( V8 C7 A  C2 ^9 E& E
        type: router
4 `# O3 c7 C' s* x# `, y5 y, Z( K* Y5 Y        addresses: ["00:00:00:00:11:00"]
0 h) Q8 r5 J9 Q: v        router-port: lr1-ls1
. X- Q+ {1 E! _8 Mrouter e9c151a0-5db7-4af6-91bd-89049c4bbf9f (lr1)
0 x6 h$ A& I3 g- Q! C- P$ @3 u    port lr1-ls2$ c& L+ a5 Q  S2 {6 q. o
        mac: "00:00:00:00:12:00"
9 U; P0 S% J  v4 E        networks: ["192.168.2.1/24"]
8 u7 p4 H/ o( a5 N7 Z5 l% C! W    port lr1-ls1
  |6 r: Q0 m, O- h7 _# S* z, Z/ r        mac: "00:00:00:00:11:00"
- H% L/ T3 u4 C; B        networks: ["192.168.1.1/24"]
; a) W! A5 q8 R/ S; C) ][root@node1 ~]# ovn-sbctl show0 K5 X# W) s- E  x1 I- X- e
Chassis node25 q- @3 B2 w. W: t
    hostname: node2( Y+ U% S, C% r0 A( C- }
    Encap geneve
: m1 h' v  H/ A6 T        ip: "10.1.1.42"
% X4 u  s) [1 H5 ?        options: {csum="true"}
/ Y9 \' q; ^$ j' j# I- l  }; T: b    Port_Binding ls2-node2-ns2
: b" x9 x! l, ]* g* A    Port_Binding ls1-node2-ns1( T7 p, _0 [8 o
Chassis node1
6 L7 n. {' o$ q4 N    hostname: node1
' ^! \4 R5 N- i/ P0 {' A    Encap geneve, O+ g% E; D: v" u3 L8 a$ f4 s
        ip: "10.1.1.41"+ p" X3 I1 E& `  J1 i& E
        options: {csum="true"}# b6 l7 J9 k% j2 z- N2 r! ~
    Port_Binding ls1-node1-ns15 n  c# Y7 n( s. N  j+ ~- ?
在这里插入图片描述8 B. J9 n6 \- e( j% H6 Z
验证网络连通性
" E+ X+ C4 |; c& n6 m& d4 Z
# O- U% l% T; \; ^/ y: pnode1上ns1连通网关
7 \+ B* j7 Z4 s+ b[root@node1 ~]# ip netns exec ns1 ping -c 1 192.168.1.1
3 F1 i1 r( k% M; B) O: ?PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.2 l6 q5 l: t, x3 U. G6 p7 h
64 bytes from 192.168.1.1: icmp_seq=1 ttl=254 time=20.10 ms# N, Z' X  z  j, G- Z0 |3 y
* y* s2 O0 d9 Y0 I
--- 192.168.1.1 ping statistics ---
$ T5 X% ]/ C  q) @: S/ W* I2 K/ w1 packets transmitted, 1 received, 0% packet loss, time 0ms
" m/ I) G9 P, y2 `2 D  irtt min/avg/max/mdev = 20.950/20.950/20.950/0.000 ms" d3 V; O+ {6 r4 W9 F# Z

" f+ u$ Q* P# c: p8 Unode2上ns2连通网关
" v% L. q6 d1 h[root@node2 ~]# ip netns exec ns2 ping -c 1 192.168.2.1, Q: B% _/ m4 i' g3 Y
PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.
% {  |! n( c# f: p64 bytes from 192.168.2.1: icmp_seq=1 ttl=254 time=38.5 ms
1 z- f) _1 X0 D+ z! w! [; k7 {$ Y2 |/ T3 L( ?! c% W" T
--- 192.168.2.1 ping statistics ---
0 M9 [1 A6 g" y( Q7 p1 packets transmitted, 1 received, 0% packet loss, time 0ms
2 p5 Z* @: _6 @& j9 ortt min/avg/max/mdev = 38.477/38.477/38.477/0.000 ms
# G/ m; q% [3 ?9 `( X& Z" N: T7 X+ ?! I
node1上ns1 ping node2上ns2+ m; Y6 ~9 {3 \+ k1 f3 G; n4 n5 O
[root@node1 ~]# ip netns exec ns1 ping -c 1 192.168.2.30
" `0 {0 I- I7 Z; I: bPING 192.168.2.30 (192.168.2.30) 56(84) bytes of data." R1 Y! u$ M. @# d; w- O5 [
64 bytes from 192.168.2.30: icmp_seq=1 ttl=63 time=1.23 ms. ?7 l2 n5 O" E
" e" g' c& K/ b8 \4 ^9 y- J
--- 192.168.2.30 ping statistics ---! c# H- w) }  c7 Y/ Y5 d1 B
1 packets transmitted, 1 received, 0% packet loss, time 0ms' w- y2 f0 D7 U6 L
rtt min/avg/max/mdev = 1.225/1.225/1.225/0.000 ms
) O4 U; S& b! W. Y6 o& T复制; i2 U, ~3 {3 C8 I
注意:ovn逻辑交换机/逻辑路由器是北向数据库概念,这两个逻辑概念经过ovn-northd“翻译”到了南向数据库中,再通过hypervisor上的ovn-controller同步到ovs/ovsdb-server,最终形成ovs的port和流表等数据。
* k  z4 G# }; A/ i+ [5 I& a" Q, novn逻辑交换机通过geneve隧道,把二层广播域扩展到了不同主机上的ovs;而ovn逻辑路由器则是把三层广播域扩展到了不同主机上的ovs,从而实现跨主机的网络通信。
9 n. o7 W' L  j2 x2 a. x8 u- Uovn逻辑交换机和逻辑路由器都会在所有的hypervisor中生成对应的流表配置,这也是ovn网络高可用以及解决实例迁移等问题的原理。
 楼主| 发表于 2025-12-18 08:52:36 | 显示全部楼层
1. OVN及其SDN技术基础
, ?, Y) A# l! \, G% c4 ]/ [1.1 OVN简介
' W8 p& t$ V3 [+ P- ]9 aOVN(Open Virtual Network)是Open vSwitch的一个组件,它提供了一套基于OpenFlow的高级虚拟网络抽象,这些抽象涵盖了从基本交换到L3服务。作为一个SDN(Software-Defined Networking)解决方案,OVN旨在简化网络配置和管理,为虚拟机(VMs)和容器提供灵活的网络抽象和安全策略。与传统的网络堆栈不同,OVN允许管理员通过逻辑上定义的网络设备来构建和管理网络,而无需关心具体的物理硬件。
2 K7 Z0 d7 J' l% _$ Z* t# h5 r: {* Q. e6 s4 m6 v4 M9 u
1.2 SDN技术基础6 E9 F5 ]' ?0 D: D
SDN是一种新型网络架构,它将网络的控制层(负责决策)和数据转发层(执行决策)分离。控制层采用中央控制器来集中管理和优化网络流。SDN通过提供可编程的网络来强化了网络灵活性和动态调整能力,减少了传统网络固化的、逐个设备配置的复杂性。
& t& ?& j6 `) j+ o' _. b: w0 t- \4 y' T$ S2 @, @
在SDN架构中,OpenFlow协议是核心,它定义了控制器与交换机之间的通信标准。OpenFlow允许控制器动态地查询、修改流表项,从而实现对网络流量的精细控制。这一点对于支持动态的虚拟网络环境尤为关键,因为它可以迅速响应虚拟机的创建和销毁操作。& R3 d2 `; L5 E( {5 l& T- Y

) c. e1 K; P  @2. BGP协议及其在自动化网络中的作用* t# E7 `' x% Q' S
2.1 BGP协议概述8 L3 X* u) C) P% `; D0 {
2.1.1 BGP协议的发展和特点
  T2 @. Z1 ]) g1 I边界网关协议(Border Gateway Protocol,BGP)是用于在自治系统之间进行路由信息的交换和路由决策的路径矢量协议。BGP经过了数十年的演进,从早期的BGP-1、BGP-2发展到现行的BGP-4版本。BGP-4是目前广泛使用的版本,它引入了对无类域间路由(Classless Inter-Domain Routing, CIDR)的支持,并引入了诸如路由聚合、社群(community)等特性,大大提高了路由协议的效率和可管理性。7 p4 Y" I3 F' A; |2 e/ c
  |/ Q& A* Z9 {) a$ A( F( Z
BGP的核心特点体现在以下几个方面:
; R) }3 E; r- }; L( b/ J3 B  X9 c6 s5 g0 N$ `
可扩展性 :BGP能够处理大型网络中的路由表,支持互联网的全球扩展。
/ q; O6 Z/ B6 }. [0 G0 Z策略路由 :BGP允许网络管理员根据复杂策略来选择路由,而不仅仅是根据距离或跳数。, L; ?5 e0 L& `
可靠性 :BGP具有健壮的建立和维护连接的能力。
3 \+ }. A  U/ s  R( ]+ m' U标准化 :BGP的标准和功能被广泛接受和实现,这为不同厂商的设备之间的互操作性提供了基础。
7 Z2 w8 g2 r6 \, j. |随着云计算和数据中心的发展,BGP在自动化网络中的作用越来越重要。其协议特性和健壮性使其成为数据中心之间、数据中心与互联网之间以及大型企业网络内部不可或缺的路由协议。( I8 H4 w/ }* r" ]
& f/ C$ h3 V+ o! S" [+ F
2.1.2 BGP协议的工作原理
2 W/ u( Q6 z, J; mBGP通过在自治系统(Autonomous Systems,AS)边界路由器之间交换网络可达性信息来工作。每个AS由一个或多个边界路由器组成,这些路由器负责与其他AS的路由器进行通信。
" z" U- _# L  |+ I  t. B
; U2 a5 X# `3 ^- Z4 |& IBGP工作流程大致如下:* h6 U% [$ Y: ?$ t! o
$ D- G+ ?' ?" b" p
邻居发现 :BGP路由器通过发送开放消息来发现邻居,并建立TCP连接。4 x8 ^8 o1 y- ]- L& w: i
邻居建立 :一旦TCP连接被建立,BGP路由器交换打开消息并验证彼此的配置。
& s5 l8 O1 M) x# m路由信息交换 :路由器交换路由信息,包含网络可达性声明和路径属性。% F* l8 _& ?0 {+ x, i. B+ A; g
路由选择 :根据BGP属性和策略,路由器选择最佳路径,然后将这些路由声明发送给其他邻居。
5 z% ]$ Y; }2 x+ T$ S9 N路由更新 :路由器通过增量更新来维护路由表,仅当路由改变时才发送更新信息,而不是定期发送整个路由表。
+ O$ U7 i/ s1 jBGP的决策过程非常复杂,涉及多种属性,比如AS路径长度、起源类型、MED值等,这些都是决定最佳路由的因素。BGP的这些复杂特性使其非常适合用于大型和复杂的网络环境。' J  r8 `+ e$ P- f+ I/ E
: Z5 X4 s& e- I: `- N' ?
2.2 BGP在自动化网络中的应用& }. Y; n" }. C" R5 z
2.2.1 BGP在数据中心的应用场景* X& r+ P* x: }' [0 P, d
在数据中心环境中,BGP通常用于以下几个方面:* C0 W0 ]! T/ g3 y9 d

# L9 l( n! g4 {% i数据中心互连 :数据中心之间通过BGP来实现数据的高效传输和路由决策。/ `! ]$ v+ B6 _# w1 U% G
多数据中心负载均衡 :BGP可以与健康检查工具结合,用于在多个数据中心之间进行流量分发。
  z' c. D. h5 N' O7 {0 w动态路由协议 :在数据中心内部,BGP可以作为动态路由协议来提高网络的灵活性和可靠性。- z/ Z& C- j6 q7 Z
2.2.2 BGP在云网络中的优势和挑战/ q& h) b  F8 Z3 x# i) A
云网络中的BGP应用具有以下优势:+ S( S: O/ y% @: \

% q/ Q4 ]( n2 G2 O, J8 ]) A灵活的网络设计 :云网络的可扩展性要求其具备灵活的网络设计,BGP能够满足这一需求。+ z( Y" {' q, L, v5 Y$ s: i
高效的多路径路由 :BGP支持ECMP(Equal-Cost Multi-Path Routing),使得流量可以在多条路径之间进行负载均衡。! s7 S' L% M( P. S+ }
复杂的网络策略实现 :BGP提供了丰富的策略路由能力,可以实现复杂的网络策略。; {+ _0 e+ o4 Y9 [: e7 H
然而,BGP也存在挑战:
2 v8 m# H( N' h: `9 E9 D/ I' D! j9 s
配置复杂性 :BGP的配置和管理相对复杂,需要专业知识。
5 U' b# f- [- |* ^( z路由稳定性和收敛时间 :在大规模网络中,BGP的稳定性和收敛时间可能会成为问题。( j; T/ W3 q3 l9 U) C
安全问题 :BGP面临着恶意攻击和配置错误的风险,需要特别的安全措施。; v9 J3 u  l2 X3 f
通过适当的设计和策略,可以在自动化网络中充分利用BGP的优势,并有效应对挑战。
& }2 e4 \9 u: ~' H  x: Z4 n. |' b2 h" |- `" ?
3. Neutron ML2插件的网络技术驱动集成
' K- o7 W# P$ |: GNeutron ML2插件是OpenStack Neutron组件的多层插件驱动,它为网络的虚拟化提供了一个模块化的解决方案。ML2不仅支持传统网络模型,还支持SDN控制器,如OVN。本章将深入探讨ML2插件的原理和实践应用,以及如何集成网络技术驱动,从而实现更高效、更灵活的网络管理。3 L% ?0 b9 C" }4 H8 i
% p' ?8 M4 h. O1 h$ E
3.1 Neutron ML2插件原理
& |+ _  i! D3 z3.1.1 ML2插件架构和工作机制% a% L% g0 S0 {0 @
ML2插件在Neutron中的作用是通过一个抽象的层次来集成不同的网络提供者和驱动。它将网络类型和网络技术解耦,允许多个网络技术在同一Neutron实例中共存。ML2定义了多种网络类型,包括VLAN、Flat、Gre、VxLAN等,以及对应的网络提供者类型,如local、flat、 VLAN、Geneve、VXLAN等。
$ e5 w0 [; C( O1 B' c  W# @6 y4 {9 i6 h) h/ ^8 g
ML2的工作机制是基于Type-Drivers和Mechanism-Drivers的组合。Type-Drivers定义了Neutron如何处理不同类型的网络以及如何与Mechanism-Drivers交互。Mechanism-Drivers则与具体的网络控制器或物理设备接口,例如,OVN、OpenDaylight或传统的二层交换机。
4 L: T+ d- M8 t* y4 C- I! M. |% @; T
# h! c* @: U+ d9 L3.1.2 ML2插件与OVN的集成机制, C; o2 u+ k: l# A' L# s& X
ML2与OVN的集成机制为网络虚拟化提供了一个强大的抽象层。OVN作为一个SDN控制器,提供了高级的网络功能,例如逻辑路由器、逻辑交换机以及安全策略等。通过ML2插件,Neutron可以将逻辑网络模型映射到OVN中的相应组件。
, R7 e5 W  l0 U9 u4 F9 u# @" M  U9 m
集成机制涉及以下几个关键步骤:
- P2 `) l2 F3 H* P0 G, A
1 L! g1 p: ]- V9 n2 ]) y9 N配置ML2插件以使用OVN作为Mechanism-Drivers。  r/ w3 N3 ~) u" ~
创建OVN网络资源,如逻辑交换机和路由器,并将它们关联到Neutron端。. M6 z( T; b7 ]3 Q( `4 P; w) L- \
Neutron通过ML2插件进行网络操作,由OVN负责实现具体的网络行为。
) \: C: E/ L7 V2 ~, ?4 m2 j这种集成方式简化了网络配置过程,提升了网络的灵活性和可扩展性。Neutron的高级逻辑网络抽象被OVN转换为实际的网络资源和流表项。
5 {: a  z/ |) g9 F! l8 A& x
4 i# f% G# d" y2 l/ ]3.2 Neutron ML2插件的实践应用5 H$ |* C! \5 L
3.2.1 ML2插件在网络自动化中的配置4 R8 D/ s7 f) p/ ^, o
网络自动化是现代数据中心管理的一个关键要素。ML2插件通过提供一个统一的接口,使得网络管理员可以轻松地实现网络的自动化配置。' l/ J5 r3 E  ~$ g) k

5 a# ~) N2 C5 E在自动化配置中,网络管理员首先需要在Neutron中定义所需的网络资源,例如子网、路由器和安全组。然后,他们可以通过REST API或CLI工具将这些资源应用到ML2插件中,由ML2插件负责与OVN控制器通信来实现具体的网络设置。
  |4 f6 L3 }  T8 m. I4 [' _2 P' D; ^
# 通过CLI配置网络资源的示例
. A/ U- r, b  B7 E* t8 ineutron net-create my-vlan --provider:network_type=vlan --provider:physical_network=my-vlan --provider:segmentation_id=1004 o/ v/ b7 Z# s% B* T. Q
neutron subnet-create my-vlan 192.168.100.0/24 --name my-subnet/ g% L* d' ^: I
一键获取完整项目代码
3 |! u7 N, T6 C  n5 a+ }' S: K  Xbash/ z0 r$ d8 @$ m; D
3.2.2 ML2插件与物理网络设备的集成
7 E( h: {/ g3 ~6 LML2插件也支持与多种物理网络设备集成,使得物理网络与虚拟网络之间可以无缝对接。ML2插件通过Mechanism-Drivers与物理设备进行交互,支持设备发现、配置同步等功能。
0 H* U+ t) ]- `0 h/ |6 d" l
3 \2 B8 T8 c) W0 f: U9 z! q一个典型的集成案例是在ML2插件中配置一个VLAN型的网络,并将其映射到物理交换机上的特定VLAN。这样,虚拟机和物理服务器可以在同一个VLAN上通信,实现网络的平滑扩展。6 R# R; `1 R& }5 I
) N( o7 Z# n+ }  D/ t: ~* o
# 配置VLAN映射的示例# q* ]2 f: D- K5 b; s' d1 A
neutron net-create my-physnet --provider:network_type=vlan --provider:physical_network=my-physnet --provider:segmentation_id=100
) _2 }# v) v/ X" q一键获取完整项目代码
( i2 [/ }8 N+ }3 _bash7 m, J+ E6 H# ?
在表格中,我们可以概括ML2插件与物理网络设备集成的几个关键点:: F) B$ a4 h1 A4 ^
. V: W8 \$ m! U1 m/ D+ g1 c
集成步骤        描述, h* i  j7 X) w- E/ `. ^$ E3 B
网络定义        在Neutron中定义物理网络类型和设备
5 [) P) E; @' B2 g  J9 G; x, ?VLAN配置        指定VLAN ID并将其与物理网络关联  D9 B  `3 [* q. z( [% O% U
设备连接        通过Mechanism-Drivers配置交换机或路由器
" p3 O( b8 h- w+ F+ |  w# w网络同步        ML2插件与物理设备同步网络状态和配置
1 p, r$ ]8 g% b; U/ WML2插件的灵活集成机制,使得物理网络和虚拟网络能够更有效地协同工作,为云环境下的网络自动化和虚拟网络提供了坚实的基础。  \$ ^1 b$ E( O- N8 L, ^
* ^' I/ y" K. k; K# ~$ y
4. OVN南北向数据库的网络配置和硬件交互  q2 q* p" Q3 B( p
4.1 OVN南北向数据库概念解析4 C8 w% C4 V& U5 E8 k8 q4 n
4.1.1 南北向数据库的作用和设计
* w: ^( q: f* I" F/ \+ `% k& m! \& [  _( _在SDN架构中,南北向数据库扮演着核心的角色,它负责存储网络的全局状态信息,并对外提供接口以实现网络策略的动态调整和维护。南北向数据库的设计要满足以下几点:, q% I# a  D. K) z, z

! H5 N  p% {. R; {; Z; k: l高可用性 :数据库需要设计为可扩展和高可用性,以支持大量虚拟机和容器的网络状态管理,确保网络配置的连续性和一致性。
/ |: j* `$ t( E7 ^! s( A9 X数据一致性 :网络状态信息必须保证实时更新,并在多个控制器之间保持一致性。这对于复杂的网络拓扑和动态变化的虚拟网络环境至关重要。
7 h# x7 k. @) f" r; a  ?! m% Y安全性 :南北向数据库需要有适当的安全措施,以避免未授权访问对网络状态信息的篡改。7 a+ k. t$ h' i
标准化接口 :为了便于各种网络功能和服务的集成,南北向数据库应该提供标准化的接口和协议,支持多种网络应用的接入。
( `( B/ {6 {0 n% S" T3 B4.1.2 南北向数据库的数据结构和协议
# M- n' ?: \/ s- z$ M: v0 V7 P  n南北向数据库的数据结构通常采用层次化的模型,以支持网络抽象和虚拟化。数据结构包括但不限于以下内容:
9 w6 ?2 g/ W8 L7 |
, z! g, b4 g2 g4 C+ r逻辑交换机(Logical Switches) :用于虚拟网络的逻辑表示,类似于传统网络中的交换机。  h  {- j* h2 L5 [2 i/ ]0 K7 V) R
逻辑路由器(Logical Routers) :为不同逻辑网络提供路由服务。
7 w% H4 J5 j% d' E3 S逻辑端口(Logical Ports) :代表虚拟机或容器的网络接口。
- H- U. s- Y1 \/ F- ?( v5 u0 v逻辑流表(Logical Flows) :定义了如何处理经过逻辑交换机的数据包。& P3 i6 X# H* k7 T
南北向数据库通过特定的协议与其它组件进行交互。例如,OVN使用自定义的协议如OVN-KB(Kentucky Blue)和OVN-DB(Database)协议与上层应用以及底层硬件设备通信。这些协议能够详细描述网络的状态和配置信息,并保证数据的正确传播。# V2 E: \' ]  R' g
5 R  D- a( b5 P- J+ W2 {
4.2 网络配置和硬件交互实现" c4 [- Z5 ]1 M- e- u
4.2.1 配置OVN数据库与物理网络的连接
8 L3 A; e1 W8 H6 F7 {) P4 n要实现OVN南北向数据库与物理网络的连接配置,需要完成以下步骤:
6 n4 {- Z" U: s2 h4 F
1 O" A! X  ^3 c, s1 K' X安装和配置OVN控制器 :首先需要在控制节点上安装OVN软件包,并根据网络需求配置OVN南北向数据库。1 A' p1 c- D) x) P0 n

' E9 D9 B% l' |  c+ E4 e配置OVN南北向数据库 :通过OVN的命令行工具配置南北向数据库,创建逻辑网络组件,如逻辑交换机和逻辑路由器,并定义相应的逻辑端口和流表。, N2 ?9 A  C% Z. t2 k! p: L

; i0 d% ?# ^: t: S连接物理网络设备 :确保物理网络设备(如交换机)支持与OVN控制器的通信,并且已经根据逻辑网络的配置调整了相应的转发策略。
6 f/ v. I% A  a& d
5 E4 }/ j- q# t8 b, A4 F3 ~( N' b以下是一个简单的OVN控制器初始化配置示例:
  ^4 C3 b5 t2 |
* ^4 u6 H- z( z$ B$ ^) S+ }# Q# 初始化OVN南北向数据库
+ z% ~% i, G1 v9 A  S& X# |) j; Kovn-nbctl --init8 g4 j. \+ {) A& j1 Y+ C5 P
# 设置逻辑交换机- ?& k9 f0 N# l( j/ Y7 O1 A
ovn-nbctl --if-exists del-lswitch <switch_name>
( e4 g# o: n- e# p( Oovn-nbctl -- --id=@switch create logical_switch name=<switch_name>
; M& v. g; L0 o# 设置逻辑端口, J6 j  z' n$ {' h, q
ovn-nbctl --if-exists del-lport <port_name>: H& r. U$ X$ B
ovn-nbctl -- --id=@port create logical_port name=<port_name> type=router \9 p' \# _; S; E' w: _+ y
    options:router-port=<router_port_name> addresses=<mac_address>
7 R* S6 c: {  _9 @  ^一键获取完整项目代码" g# b1 ?/ Z: n5 }6 `7 |- a
bash
" w, z5 {9 z& x4.2.2 硬件交互在SDN中的实践案例
9 W4 L! e4 |  t; Z2 g' ~5 J: L0 w一个典型的硬件交互实践案例是将OVN与传统网络设备进行集成,以实现无缝的物理和虚拟网络集成。以下是具体步骤:% E* ~+ g# r  t( b
7 v& t% j+ ^% R8 d4 y
硬件设备配置 :首先,需要在硬件交换机上配置VXLAN隧道,并指定其与OVN控制器的通信IP地址。1 {' `3 h+ |3 |: a, ]% R- P  ]1 d5 a9 J4 T
隧道接口配置 :在OVN控制器上创建一个隧道接口,并将其与物理网络交换机的VXLAN隧道关联。9 y! ^$ u' F5 Y5 h) n, |% Z
创建逻辑路由器和端口 :通过OVN-NB配置一个逻辑路由器,并为其创建一个或多个逻辑端口与物理网络交换机的逻辑交换机桥接。
) g% j" t1 R( k- N' e- g6 h为了便于理解,以下是一个简化的隧道接口配置示例:
) q, t( N, z7 o/ W
$ R( v4 S3 H  Y& b+ \# 创建VXLAN隧道接口
$ x4 v- S  G" {+ w( E) O# Q: Lovn-nbctl -- --id=@vxlan create logical_router name=<router_name>8 W2 ^7 }5 o+ Y6 H
ovn-nbctl -- --id=@vxlan-port create logical_router_port name=<vxlan_port_name> type=vxlan \
7 u1 n7 M( j; m    addresses=<vxlan_vni> peer-address=<peer_address> options:peer-src-ip=<peer_src_ip>
! J  R/ n" U' @3 D3 g
/ S5 _! K! S- D6 s# f9 {0 b# 与物理网络交换机的逻辑交换机桥接
* a  g( V) ~, h5 ?. @! m- o. Yovn-nbctl -- --id=@phys-port create logical_router_port name=<phys_port_name> type=patch \
  l1 z+ Y  ], D# Y/ _" f; a! k' b    options:peer=<router_port_name>9 s# S! p5 c$ H6 {
ovn-nbctl -- --id=@ls create logical_switch name=<ls_name>
* _7 \) W2 x" J' X9 E& {6 H- {) tovn-nbctl -- --id=@ls-port create logical_switch_port name=<ls_port_name> type=internal \
9 k- @7 R! _$ g    addresses=<mac_address> attached-figure=<phys_port_name> options:peer=<ls_port_name>; }' G0 c7 L0 t" y
一键获取完整项目代码9 Q( x8 K% n0 Z, i- n0 O
bash
$ |$ W7 `; C2 }
# R4 H4 m" `' L" R) E* }通过上述配置,可以使得虚拟机或容器的网络流量通过逻辑交换机,逻辑路由器最终到达物理网络交换机,实现南北向数据流通。. L4 @, u: R3 t8 v3 V+ {

! d% f$ Q4 l" r& {* ^7 R4 x% y; f0 }在这一章中,我们深入了解了OVN南北向数据库的概念、设计原则、数据结构以及如何进行网络配置和硬件交互。这些内容为理解SDN架构的网络自动化和虚拟网络管理提供了坚实的基础。接下来的章节将继续探讨更为高级的网络技术实践和案例。
2 F$ a& @7 P: W) s$ R% X- e$ x6 K3 i1 J3 \
5. BGP EVPN在数据中心的路由和多租户应用
% B% s- ^- k4 U) {* R% c/ m  }& z- k5.1 BGP EVPN技术详解9 Q. d. t: q2 I) u7 x/ S
5.1.1 EVPN的原理和优势& M5 ]5 J1 @: g% a5 ^1 R
EVPN(Ethernet Virtual Private Network)是一种在多协议标记交换(MPLS)网络中实现虚拟局域网(VLAN)间路由的技术。它结合了MPLS和网络虚拟化的优势,为数据中心网络带来了更加灵活和扩展性更高的解决方案。BGP EVPN使用边界网关协议(BGP)作为控制平面的协议,不仅能够实现数据中心内部的路由,还能实现数据中心之间的路由。8 {1 O  A' p: X7 r7 T

' W3 t+ w8 v  t) r3 @  DEVPN的一个主要优势在于其多租户环境下的支持能力。在一个共享的基础设施中,EVPN可以提供租户之间的隔离,同时提供租户内部的广播、未知单播和多播流量的传输。其核心优势包括:# }6 K7 v+ u0 k  f5 p" k1 ?* r

7 d4 V" k5 f* l0 ~: M* N6 ]7 ^5 d" U3 I3 m灵活性 - EVPN可以配置为多种类型的网络,如VLAN-aware桥接、VLAN-bundle模式或VxLAN模式,这使得它能够适应不同的网络设计和需求。
) v% @6 e' f# D8 W高效路由 - 通过使用BGP进行控制平面的更新,EVPN可以动态学习网络拓扑变化,优化路由决策,减少不必要的数据平面流量。( z& U) v/ g0 m" C0 f6 }! E
扩展性 - 在大规模数据中心环境下,EVPN通过层次化设计,降低了网络规模增长对控制平面的冲击。8 @8 ~& k' M9 [6 ]1 T0 E$ }
高级服务 - EVPN支持高级网络服务,如高级多播、快速故障切换、负载均衡和冗余路径选择等。2 a' n0 Z6 }- \, i
5.1.2 EVPN在数据中心网络中的应用: d0 T% A" h' [- H9 V  D4 w
在数据中心环境中,EVPN被用来构建多租户网络,为不同的客户提供虚拟网络服务。这些虚拟网络通过虚拟路由器和虚拟交换机实现隔离,并允许租户内部的通信。EVPN支持下列关键功能,使其在数据中心中成为优选:  k( R0 }; M% i3 |
& l* {' k& `9 g/ N5 ]5 P
VXLAN网关 - EVPN可以作为虚拟扩展局域网(VXLAN)的网关,实现不同VXLAN间的数据转发。
# {$ g7 Q1 D) ^. v8 Z自动发现 - EVPN可以自动发现网络中的设备,包括路由器、交换机和虚拟机,减少手动配置。% P7 p; e3 m4 S7 b; G
多路径转发 - 支持多条路径,提高了网络的可靠性和带宽利用率。
" [' e$ s/ V* E0 _8 J/ _负载均衡 - EVPN可以实现数据中心内流量的负载均衡,提高资源利用率。
$ I" c, ~! A* U8 i5.2 多租户环境下的路由配置
5 T4 R4 g) `: F( ~5.2.1 租户网络隔离和路由策略' H) A" b" \! h' C! C
在多租户环境中,网络隔离是保障各个租户数据安全的关键。EVPN提供了一种机制来确保租户间的隔离,并可以配置不同的路由策略来满足不同租户的需求。
3 |, g6 ~1 |! A1 h8 `- i/ z( V$ U+ ~8 {% e
租户网络隔离通常通过VRF(Virtual Routing and Forwarding)实例实现,每个租户都与一个VRF相关联,这样租户之间的路由就不会互相影响。而在EVPN环境中,VRF的配置与传统的网络有所不同,因为EVPN需要支持VXLAN封装,这对路由策略和交换机的配置带来了额外的要求。
6 O/ x5 U7 N, _& Z* ?+ ^( }5 p8 @- o) M
路由策略包括:
; i6 E# j; @. a" \4 R" ^% ]( c2 M( |2 _/ w+ \8 m
路由传播控制 - 管理不同租户间路由的传播,可以对哪些路由被允许在租户间传播设置规则。
4 i$ ~: A' }9 |8 P) D; a7 Y0 \流量转发策略 - 确定租户数据在数据中心网络中的最佳路径。( ^* I" c+ `9 J* x' {
多租户策略一致性 - 在网络架构设计时考虑多个租户的策略一致性,保证网络配置不会出现冲突。' I- A4 m# F  D9 \# \9 [5 W
5.2.2 EVPN在多租户环境中的应用案例
9 y( Y( I& X' |4 D让我们考虑一个多租户数据中心的典型案例,其中需要为多个租户提供独立的网络服务。假设数据中心为三个不同的租户A、B和C提供服务。每个租户需要有自己的网络空间,并且租户之间需要完全隔离。
) Z/ l6 R" d1 T2 a# |
1 K9 G  I# N7 h3 Z1 V& g在这种情况下,每个租户的VLAN可以映射到EVPN的不同实例中。例如,租户A的所有VLAN流量被映射到VRF_A,租户B和C同理。数据中心的核心交换机使用BGP EVPN进行配置,每个VRF通过BGP的路由反射器(Route Reflector)实例进行通信。
. g/ w% J: e! ?- E" O5 g, b  P. y, h3 Q5 w  p' Y2 S
为了实现租户间的路由策略,数据中心管理员可能会使用以下配置步骤:
7 e. P; Y8 m# Z
" T2 n' q. `& y8 I; b配置VRF和EVPN实例 - 在核心交换机上为每个租户创建VRF实例,并为每个VRF实例配置EVPN。
/ y' R5 z7 t+ p1 t  z1 b4 b4 f% R配置VLAN和VXLAN - 将租户的VLAN关联到对应的VXLAN隧道,并将VXLAN配置映射到EVPN实例。, D1 K* r1 E: L$ F9 L( d
配置BGP协议 - 配置BGP协议,包括路由反射器和邻居关系,以及BGP的多协议扩展来支持EVPN。$ D. ~. |* u; U" k# Y  M# o8 J
定义路由策略 - 为每个租户配置路由传播策略,确保路由信息只在需要的VRF之间传播。- d" q, i  f* ~2 K3 `
通过这些步骤,数据中心可以在EVPN环境中为多个租户创建独立的网络,同时确保网络的可靠性和扩展性。
' O8 o1 Z7 h/ C. S
. ?( X8 x+ p! q/ N5 V6. Python在OpenStack生态中的编程应用/ K( M: L# h. P2 F/ r# v- w
6.1 Python与OpenStack的集成
+ k5 p* c4 H  N  `6.1.1 OpenStack生态中的Python应用
3 `0 `: E  G# d) O% K6 ROpenStack作为领先的开源云平台解决方案,广泛应用于构建大规模的IaaS云服务。其生态系统中,Python语言扮演着至关重要的角色。Python在OpenStack中的应用主要体现在以下几个方面:# e6 q' R8 e, ^+ a) v. D

$ v7 g( s/ m9 ^核心服务编写 :OpenStack的绝大多数核心服务,包括计算服务Nova、对象存储服务Swift、网络服务Neutron、身份服务Keystone等,都用Python编写。这是因为Python简洁易学,有丰富的库支持,非常适合快速开发复杂的系统。
8 _9 P: h4 v4 T6 {+ I! c! _% p- _8 g插件和扩展 :用户可以通过Python编写插件或扩展,来增加OpenStack的功能或对现有功能进行定制化。' v+ g6 g- j3 c* O
命令行工具和API客户端 :OpenStack的命令行工具是用Python编写的,也提供了Python客户端库,使得开发者可以轻松地通过Python代码与OpenStack API进行交互。
: B; c  ]% t2 n4 T! F6.1.2 Python在OpenStack网络服务中的作用
# O- G. m( h2 d在OpenStack的网络服务组件Neutron中,Python主要承担如下角色:  s# g4 `/ X; [# ?& e, d
/ M( t* k6 z( p: b* j9 U4 w  r
自动化网络配置 :利用Python脚本,可以自动化网络拓扑的创建、管理和配置,大大提升网络部署的效率。
. T7 P8 i! M1 h! ^" n5 s/ B4 x网络策略实现 :通过编写Python程序,可以实现复杂的网络策略控制和自动化决策流程。# |$ y# v- V/ o7 [" `1 U# G
监控和故障处理 :Python的高效率和可读性使得编写监控工具和故障诊断脚本成为可能,帮助及时发现网络问题并自动恢复。" c2 R- {- B& C5 ?* v
Python在OpenStack网络服务中的应用不仅限于网络管理,还包括身份验证、授权、资源调度等核心功能,对于整个平台的运维和管理起到了关键作用。# I. q' f' x! [* ^$ Y' K7 d: V  e
' T6 `7 m) Y1 `
6.2 Python在网络自动化脚本编写
& K1 i5 K/ p9 A' _6.2.1 利用Python进行网络资源的自动化管理
/ b5 U+ d+ a, {; U- _7 S3 \在OpenStack中,网络资源的管理可以非常复杂,特别是在资源众多、配置频繁变更的云环境中。利用Python编写自动化管理脚本,可以实现网络资源的快速配置和恢复,同时降低操作错误的可能性。以下是一个简化的Python脚本示例,用于创建OpenStack网络和子网:
1 S4 \" ]6 q- C4 N! e3 M% {$ f0 H- W( a, K$ p: K
from keystoneauth1 import loading
& j3 G9 ?, i1 j3 ^5 d2 Q! @4 g- @from keystoneauth1 import session- L0 k4 }4 D9 N) M2 d. S5 N2 X) Z! S
from keystoneclient.v3 import client as ksclient" {9 N/ x- o. H# h8 P
from neutronclient.v2_0 import client as nclient" h2 x) D! e' ^* G. ]

+ T4 Y) n( a! `! z# ?8 k9 ?$ m0 k) n+ p# Keystone认证
7 i  D7 r- @& U9 @' qloader = loading.get_plugin_loader('password')
, F5 P' i2 |2 A$ p& L! iauth = loader.load_from_options(auth_url='http://keystone:5000/v3', username='admin', password='password', project_name='admin', user_domain_name='Default', project_domain_name='Default')* R* o3 q) y6 m: c
: O' v& J; r, l; [7 T* ^& E, T
sess = session.Session(auth=auth)$ O/ R6 |5 ?6 F! }3 v% }
keystone = ksclient.Client(session=sess)
  B4 W' U, ^7 ^9 lnova = ksclient.Client('2', session=sess)
3 v9 m7 r- [) X1 N3 i1 kneutron = nclient.Client('2', session=sess)
) a% `3 d6 m" J3 P0 {8 s
5 [# P8 ]# n# e/ ?# 创建网络6 r% f- x, A7 i: l  u+ R
network = neutron.create_network(name='auto_network', admin_state_up=True)3 U3 x$ U' n% s6 E( V# A+ z
! {* r* I9 B" H: U2 h0 b, e) t+ q
# 创建子网
5 c& y/ b8 }  B$ {subnet = neutron.create_subnet(network_id=network['network']['id'], cidr='192.168.1.0/24', ip_version=4, name='auto_subnet')
6 w% L1 g, a3 q) i; ~
/ I1 C; _5 h) W6 [: Iprint('Network ID:', network['network']['id'])/ h- c$ ^1 o1 T( h% K$ M& A/ a. j  J+ K. O
print('Subnet ID:', subnet['subnet']['id'])
  j$ n+ P3 R' K5 {) e! h1 t/ |( B, p8 t一键获取完整项目代码
& m( t" @* F1 i0 Ipython
5 a3 {! ~/ X4 g4 Q/ |6 I9 m8 A& }& e0 @- U: H. \  q0 X2 q
这个脚本首先通过Keystone进行认证,然后使用Neutron的客户端库创建网络和子网。脚本逻辑简单明了,便于维护和扩展。
9 T- \8 ?5 A: X  a0 I
) p' t6 L& \" f) q) Q6.2.2 Python脚本在网络故障排除中的应用
) ^/ N* T- r1 G$ O网络故障排除是网络运维中的一个重要环节。Python脚本可以用来实现网络监控、日志收集、异常检测等功能。下面展示了一个使用Python脚本监控网络状态并发送报警的简单示例:+ v% t* v  p( q. ^
0 w1 A$ C5 V% Q: Q* g. L6 A
import neutronclient.v2_0.client as neutron_client
: J0 W- c# N: r7 F& l
7 g# M& A1 t- }: W% @. [# 初始化Neutron客户端
2 b& L2 ?' }0 {, a; vneutron = neutron_client.Client('2', session=sess)
4 o! d4 L  k3 `+ ^
' i3 J% P) Q4 i0 N1 m# 获取网络的详细信息( i9 i3 }- M4 E! K& F  d
network = neutron.show_network('auto_network')8 r* q8 @7 [' _/ i$ o

2 B. F" i' _% a# 检查网络状态& B; X5 ]+ @, q! r6 C/ o9 D
if network['network']['status'] == 'ACTIVE':
& Z4 ^: P, H3 Q6 s. R7 Y# O  q" d    print('The network is active.')8 J6 R8 x$ Q" o: F: }
else:
& e& o$ l9 L( ~  r* H+ N) ~* @    print('The network is down. Sending alerts!')
) D% R; Z" ]* S) _7 G    # 这里可以添加发送报警邮件或短信的逻辑
! D: x! s( C. B/ r一键获取完整项目代码
- Q! v( {3 V' S$ E+ Apython
& G$ T5 N/ C9 {' ^( o* M( `
  S  c1 I/ i' u) G这个脚本通过检查网络状态,当网络不处于活跃状态时会发送报警。实际应用中,可以将这个脚本集成到定时任务中,定期检查并记录网络状态,实现自动化故障排除。$ _' j6 e' p. y* p
1 c; H! s; x; l
Python在网络自动化脚本编写中的应用非常广泛,以上示例仅触及了皮毛。实际使用时,可以根据需要编写更复杂的逻辑,处理网络的动态配置、高可用性部署、带宽管理、安全策略调整等任务。通过Python脚本,可以使网络操作更加灵活、高效,并易于与OpenStack平台进行集成。# z2 X+ U. s& M3 [0 @
4 ~5 _0 _3 P- ]$ @; v3 {
7. 虚拟网络自动化的实施与租户网络隔离: H* Q% h+ n9 L5 _( u$ q
虚拟网络自动化是现代数据中心网络管理的核心,它通过软件定义网络(SDN)和网络功能虚拟化(NFV)技术,实现了网络资源的快速部署和管理。本章将详细介绍虚拟网络自动化实施的策略、工具以及如何实现租户网络隔离和安全策略。- _5 c  y" Q: `# }5 j

1 y- L  J: F6 t$ v  ?/ ~; h7.1 虚拟网络自动化实施$ f( A' n) K6 Y: X) T0 u: K
7.1.1 自动化网络的策略和工具1 Y: v+ @. {+ `6 S6 l
虚拟网络自动化的实施需要基于一系列明确的策略和适当的工具。策略方面,需要明确哪些网络服务可以被自动化,哪些场景适合进行自动化部署。例如,在云计算环境中,自动化可以用于快速配置虚拟网络、子网、负载均衡器和防火墙规则等。
+ t5 @5 b: {1 ~0 W* {3 ], @/ w' _8 S3 p. d- l+ H0 D( g% i
工具的选择同样至关重要,合适的工具能够提高效率并减少人为错误。常见的自动化网络工具包括:
# J8 `) G  l: S, V% V* y2 f# B
& i+ B% i9 s7 x2 H7 W+ p" W1 |Ansible:一种自动化运维工具,它通过编写playbook来自动化网络配置和部署。- D1 _$ w- T0 d% N
OpenStack Ansible:基于Ansible的OpenStack部署和管理工具,可以自动化虚拟机的网络配置。7 q- t# x4 @# T- k$ J* Y
Terraform:用于构建、更改和版本控制基础架构的安全和可靠方式的工具。
2 _" w) u, I7 r& ]( @7.1.2 虚拟网络自动化的部署和管理* T2 O( f: i" j
在部署和管理虚拟网络时,应遵循以下步骤:4 }3 B* K, K7 b4 Y  X4 {( a; ]
) @% }: z5 ]# B6 L. k/ C9 Y
需求分析 :确定自动化网络需求,包括网络服务类型、性能指标和安全性要求。6 V$ B3 R4 k: U' G' S/ i# B
设计网络自动化架构 :设计可扩展、可靠的网络架构,选择合适的自动化工具和策略。. g; C! y1 `1 o. _, ^7 F7 \
自动化工具配置 :根据设计的架构,配置自动化工具的参数。
1 k* B3 l6 T1 Z8 R网络模板化 :创建网络配置模板,包括所有必要的参数和设置。
1 ?! t! W8 g7 s# I' ?部署和测试 :部署网络自动化工具和配置,测试网络服务是否按预期工作。' w- e# E$ O; w5 z1 T! h( |
监控和优化 :部署监控工具以跟踪网络性能,并根据反馈进行优化调整。  D/ L- P8 s: ?; m* L' k
7.2 租户网络隔离和安全策略* _. d3 I! X( }" y* [2 G$ k" K
在多租户环境中,确保租户间网络隔离是重要的安全措施。实现隔离的方法多种多样,每种方法都有其特定的用途和优势。8 P# Q" Q5 d. [

# [9 O6 z, M4 J- F7.2.1 实现租户网络隔离的技术方法- B% e0 L% ~/ v% K
租户网络隔离可以通过以下几种技术方法实现:4 j$ P: h: N% P# d
' p" d! j& Z# U0 V: v
VLAN (Virtual Local Area Network) :虚拟局域网,可以将一个物理网络划分为多个逻辑网络。/ ~% j) m  P( n. d/ s- G+ O
VXLAN (Virtual Extensible LAN) :一种网络虚拟化技术,它允许在IP网络上封装以太网帧,实现大规模的租户隔离。
9 e: I  G; l6 S" [Subnetting :子网划分,通过分配不同的IP地址范围给各个租户来实现隔离。
* q7 x: i' v2 h- m4 n! V9 ?/ \Firewalls and ACLs (Access Control Lists) :防火墙和访问控制列表,用于定义允许和拒绝的流量规则。& G$ D5 _- f% {: v
7.2.2 租户网络安全策略的设计和实施
& _% y+ @* P; n在设计和实施租户网络安全策略时,应当考虑以下几个方面:
# W- }4 i1 a4 P! F  b; ~3 y, L) a8 k5 M) ?
最小权限原则 :每个租户只能访问其必要的资源和网络服务。
  |) ^% G  S, Q入侵检测和防御 :部署入侵检测系统(IDS)和入侵防御系统(IPS)以监控和防御潜在的安全威胁。
8 ~' Q' L+ U9 N' {7 M6 P: q% T3 P流量监控和日志分析 :实时监控网络流量,并对日志数据进行分析,以便及时发现异常行为。* X& o2 c' Z, Y0 t0 P
安全更新和补丁管理 :定期更新系统和应用程序的安全补丁,以防止已知漏洞的利用。
( U0 H; [- f6 b% X6 \灾难恢复和备份 :制定灾难恢复计划和备份策略,以确保在安全事件发生时能快速恢复服务。
# {# q& f4 y8 {' q. _" Q' K通过结合虚拟网络自动化实施与租户网络隔离的技术方法和安全策略,可以构建一个可扩展、安全和高效的多租户网络环境。
7 t; A: x7 Z! a, {9 m6 ?2 X
 楼主| 发表于 2025-12-18 09:04:06 | 显示全部楼层
安装OpenStack(allinone)环境2 t2 y, ]% W0 T9 x6 [
% P7 S! x5 d' \. T' R' ?4 c! V8 Z
### 参考"Packstack使用"章节安装,但是不要配置外网网络9 n! h4 N1 N1 r  G6 R" ]
一键获取完整项目代码
% E/ e$ q& t1 {2 V安装OVN组件
- U8 m7 d2 X1 l2 w% \/ I9 v4 _: x3 H- _! g0 Z
### 控制节点
3 `. \, d5 _  G# h# yum install -y openvswitch-ovn-central python-networking-ovn
9 J& ~2 I! B! C  _### 所有节点
% d, C- p0 [5 k2 j: q- Y. t/ [5 ?" ]# yum install -y openvswitch openvswitch-ovn-common openvswitch-ovn-host
' i4 q, t, j( p/ R### 控制节点
- L" A8 g0 C4 F* L5 c# systemctl start ovn-northd* e7 X: V0 f  E% |
# systemctl enable ovn-northd
9 |5 w# [, W5 m$ }### 验证OVN服务6640、6641、6642端口监听情况
$ ]% b. m5 n. f% V1 D# netstat -lntp |grep ovsdb-server( U9 F$ p/ d+ |. x7 ^* Q
一键获取完整项目代码* D3 v/ ^6 q3 T
开启OVN
- W/ p0 t0 j1 z8 K4 {  |/ g7 {
* I, o) U* ?: L* r9 S7 n! u### 所有节点7 ~! u. q  e& ?4 s
# vim /etc/neutron/neutron.conf
3 }! W% q3 J  y3 w1 u1 N[qos]0 c) U: k# a* \* s* e) f
notification_drivers = ovn-qos8 a; P. y# G# F, o% ?
# vim /etc/neutron/plugins/ml2/ml2_conf.ini8 b- @% v/ E5 s6 @
[ml2]# i0 |' g2 {6 }3 p- N9 [
mechanism_drivers = ovn+ |6 Z. @+ R5 i6 G
extension_drivers = port_security; k8 N# O: f! c: D# Y
) h  d& C# N$ i& p: B* D' Y
[ovn]
8 _6 R4 e! s- D$ x7 u  Z" }# lovn_nb_connection = tcp:92.0.0.10:6641$ x$ W+ n! R7 t- P; p
ovn_sb_connection = tcp:92.0.0.10:6642
3 `) w5 O! [6 uovn_l3_mode = False
5 m* f0 U+ r7 ~5 o7 novn_l3_scheduler = chance
5 p. r' G: e2 i6 Eovn_native_dhcp = True
, m  U* K- V* [1 a: Fneutron_sync_mode = repair3 x" O& h% S+ S5 K. e- s! g* B" o
# systemctl restart openvswitch/ w1 P5 A. w5 v
一键获取完整项目代码
2 P" P+ r0 Y( f3 H6 t" U% ^- g9 Y8 v8 f* b7 W! i
配置OVN
: c# C, O/ U" d4 w, o
" H+ y% v8 _9 r1 H1 C### 所有节点
3 Y8 n3 O; @, m$ `. h# ovs-vsctl set open . external-ids:ovn-remote=tcp:92.0.0.10:6642) V7 n  m" M9 Q3 J. x
# ovs-vsctl set open . external-ids:ovn-encap-type=flat,vxlan
5 x7 L( ?" z4 h### 使用节点IP
- n* W( U2 j$ P# ovs-vsctl set open . external-ids:ovn-encap-ip=92.0.0.109 N. H) r5 \+ \) s  p7 W# C
### 控制节点
4 }1 S1 K  N/ ~# ovs-vsctl set open . external-ids:ovn-bridge-mappings=extnet:br-ex
; m6 d6 o+ {  k3 j1 ?7 X一键获取完整项目代码" u$ F0 L# |2 t$ I& {0 M$ a
删除neutron默认配置
) r$ ]( {" t: |. A8 c' h
# |) b: b$ H5 X2 J### 所有节点* `4 T$ u" Z4 y* r& h0 a! B( y
# systemctl disable neutron-openvswitch-agent
. n6 I6 K: y5 i9 v9 I9 M. u& F# systemctl stop neutron-openvswitch-agent+ U: _& S/ v; a3 S$ ]( ^$ ?
# systemctl disable neutron-dhcp-agent
" c+ F1 I/ x, {+ {) p1 \% n# systemctl stop neutron-dhcp-agent
& T% J$ w/ V) w- @6 N# systemctl disable neutron-metadata-agent2 A0 I5 H( ?8 c! I# A
# systemctl stop neutron-metadata-agent
% o/ D8 }3 o7 v+ h. W& _; F - g6 ]. h7 e9 X) s- y. N
# ovs-vsctl del-br br-tun
$ a! g% h0 Q! V! g3 _" O# ovs-vsctl del-port br-int patch-tun, U1 Q6 A' P- e% e( P5 ^3 V) ?1 G4 Z
# ovs-vsctl del-controller br-int
3 q: A& D0 T1 F# ovs-vsctl set bridge br-int protocols=[]
0 Q# w- x  z& S2 g
: U9 `* v! X" L, Y# N6 P) i: K### 非控制节点
" {- s: ?2 L! Y: i& ^# q0 S# ovs-vsctl del-manager* S9 C+ C. f/ C' Q1 ^# s

, h  o3 \5 W* W& F# c### 所有节点
  I. z) U8 w% Z9 k  F# systemctl start ovn-controller+ K" R- ]. ^) j0 s
# systemctl enable ovn-controller
( ], Y1 D# ~' f1 i" k. M5 H) m: \# ip -all netns delete& b, [1 g& W$ }
一键获取完整项目代码
& A$ E$ G; P+ m# y; s
$ K& n; v, m! b5 r/ [/ }重启neutron服务3 S0 {$ n1 z/ T: y8 {& e$ f

& A* L. x, P2 t" D0 R  m### 控制节点$ e6 e2 h* z1 ^+ t) N- E7 Q( q
# systemctl restart neutron-server
4 [6 o7 `+ d# r/ m" _/ X) V- \ * S: I& F+ ]1 k; r& L' t
### 所有节点) _& n/ L" Q( r/ h5 m
# systemctl restart \
1 T9 U, Y% j5 R4 T+ @) s% r- ?openstack-nova-api \& [5 V: W9 U: Z# |3 o" e
openstack-nova-cert \
$ U+ P8 {& w/ l( c6 iopenstack-nova-compute \/ {! @  k* f  t" p6 w! o( O
openstack-nova-conductor \
& D& M6 A; L" Kopenstack-nova-consoleauth \
/ [: N# H/ o$ B0 A% eopenstack-nova-novncproxy \
4 I) K% G: p9 Jopenstack-nova-scheduler
4 E& P( o+ L+ ?2 S/ ] 1 G, x7 V6 n8 E" o! h9 W
# systemctl restart \
7 b+ e  t, i0 @# I1 I6 ~. Nopenstack-glance-api \0 m/ S9 u6 C$ T  F
openstack-glance-registry! d4 Y& }) R' V+ t  W& L

( c2 A+ y, C. n$ _/ R### 如果安装了cinder服务也需要重启
' a% A3 p8 M$ q; F1 y4 H# systemctl restart \" ]5 l1 _& g* }% z, x
openstack-cinder-api \
7 A, J6 ?& l6 y; H, ]; t/ D  \openstack-cinder-backup \: K# G2 F4 I3 b* K- J
openstack-cinder-scheduler \
( [5 ~( ~; o7 \3 q: Vopenstack-cinder-volume \# z% ]! g! H6 l! R- k
openstack-losetup
1 g8 {- i6 u0 e一键获取完整项目代码
6 s( r7 {( {& M! M9 l- I- t- J
2 f* d9 |5 e$ T# I& Z( r3 v8 x验证安装3 [' a( {! D* R5 `' s

# J4 |7 c# n4 r. C( `- [7 T# openstack network create --project admin --external --provider-network-type flat --provider-physical-network extnet external_network  v1 ~; V, r  [6 ]
# openstack subnet create --no-dhcp --subnet-range 192.168.200.0/24 --allocation-pool start=192.168.200.13,end=192.168.200.20 --gateway 192.168.200.1 --dns-nameserver 114.114.114.114 --network external_network public_subnet
1 O6 E0 t! r2 o# g0 S+ @# openstack flavor list
  ^" j' [% Q" j2 T# openstack network list0 h( \7 a4 [0 X; ?3 I' f. i
# openstack server list0 l0 q: \1 s# S. j
# openstack server create --flavor m1.tiny --image cirros --nic net-id=eb13d91a-4ff4-4226-b926-eac9cc864299
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

站长推荐上一条 /4 下一条

北京云银创陇科技有限公司以云计算运维,代码开发

QQ|返回首页|Archiver|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )点击这里给我发消息

GMT+8, 2026-4-8 21:20 , Processed in 0.104710 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

快速回复 返回顶部 返回列表