# openstack
# nova
主机发放完之后可以把镜像删掉,因为系统盘是通过镜像复制的
openstack 中实例快照是作为镜像使用的,可以直接作为云主机镜像,不能直接还原
硬盘快照是用于创建相同的云硬盘,可以挂载给主机,不能直接还原快照。也可以放做启动盘使用
# glance
所有服务的 API endpoint 地址均存放在 keystone 数据库中
写操作会通过 glance-registry,读操作可以直接去数据库中查
glance 使用 swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 default_store = swift stores = file,http,swift swift_store_auth_version = 2 swift_store_auth_address = <None> swift_store_user = edu:user1 swift_store_key = redhat swift_store_container = glance swift_store_create_container_on_put = True swift_store_large_object_size = 5120 swift list swift list hahah swift download swift upload swift post
# neutron
# 组件
neutron-server:分为 core api 和 extent api,实现不同的功能, 比如 extent 实现 elb,fw,vpn,core 实现基本网络功能
plugin:类似 driver,可以理解为插件
agent:功能实现,比如 l2 l3
L3 agent 部署在哪个节点,那个节点就是网络节点。可以和 controller 复用
1 2 3 4 5 6 7 8 9 10 [root@controller ~] +--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+ | ID | Agent Type | Host | Availability Zone | Alive | State | Binary | +--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+ | 1e20baf7-e125-4172-bee9-4e97a1d4bc21 | Metadata agent | controller | None | :-) | UP | neutron-metadata-agent | | 21ba2da5-cefa-42e4-82cf-ee5483750b7b | DHCP agent | controller | nova | :-) | UP | neutron-dhcp-agent | | 341c3190-6ec3-48e4-860b-4df5e7c56d72 | Open vSwitch agent | compute01 | None | :-) | UP | neutron-openvswitch-agent | | dbd6f772-1f93-463a-83c3-c5c65ed16dc4 | Open vSwitch agent | controller | None | :-) | UP | neutron-openvswitch-agent | | f0a9a873-1173-4d0f-8753-8b58341442ed | L3 agent | controller | nova | :-) | UP | neutron-l3-agent | +--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
ml2: 支持多种 plugin
1 2 3 4 5 [ml2] type_drivers = flat,vlan,vxlan tenant_network_types = vxlan mechanism_drivers = openvswitch,l2population extension_drivers = port_security
qbr
linux bridge,用于实现安全组,每个 vm 都有自己的 qbr
br-ex
连接外部 (external) 网络的网桥。在配置文件中指定的名字,可以修改
br-int
集成 (integration) 网桥,所有 instance 的虚拟网卡和其他虚拟网络设备都将连接到该网桥。没有上行链路的虚拟交换机
br-tun
隧道 (tunnel) 网桥,基于隧道技术的 VxLAN 和 GRE 网络将使用该网桥进行通信。
br-eth1
有上行链路虚拟交换机,不同节点之间通信,包括云主机之间通信
vlan 场景:
集中式路由场景,不同 vpc 互访需要到 network 节点。分布式路由,会把 l3 agent 部署在 compute 上
1 2 ovs-vsctl add-br br111 ovs-vsctl add-port br111 ens36
# openstack 网络类型
flat,vlan,vxlan,local,gre
local :本地网络,经过 br-int 实现内部通信,不能出去
flat :不带 vlan tag 的网络
配置参考 vlan 网络,在 ml2.ini 中,配置支持 flat 网络类型,租户网络类型
在 [flat] 中定义标识
flat_networks = provider1111
vim /etc/neutron/plugins/ml2/openvswitch_agent.ini [ovs] bridge_mappings = provider1111:br-eth1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 vim /etc/neutron/plugins/ml2/ml2_conf.ini [ml2] type_drivers = flat,vlan,vxlan tenant_network_types = flat mechanism_drivers = openvswitch,l2population extension_drivers = port_security [ml2_type_flat] flat_networks = provider111 vim /etc/neutron/plugins/ml2/openvswitch_agent.ini [ovs] bridge_mappings = provider111:br-eth1 openstack-service restart neutron
br-int 只有一个,br-eth1 可以有多个
vnet0 只有在 kvm 中可以看到
flat 网络在 br-int 中有内部 tag,同一租户,内部 tag 一样
vlan :
tenant_network_types 决定了网络类型,对应配置是下面的 ml2_type_vlan
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 vim /etc/neutron/plugins/ml2/ml2_conf.ini [ml2] type_drivers = flat,vlan,vxlan tenant_network_types = vlan mechanism_drivers = openvswitch,l2population extension_drivers = port_security [ml2_type_flat] flat_networks = provider [ml2_type_geneve] [ml2_type_gre] [ml2_type_vlan] network_vlan_ranges = huawei:10:1000 [ml2_type_vxlan] vim /etc/neutron/plugins/ml2/openvswitch_agent.ini [ovs] bridge_mappings = huawei:eth1 local_ip = OVERLAY_INTERFACE_IP_ADDRESS
段 id 就是 vlan id,vlanid 只是限制租户的 vlanid,admin vlanid 不受限
ovs 流标,优先级数值大优先级越高
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ovs-ofctl dump-flows br-int cookie=0x10c394b632250c4c, duration=81941.780s, table=0, n_packets=0, n_bytes=0, priority=65535,dl_vlan=4095 actions=drop cookie=0x10c394b632250c4c, duration=81941.769s, table=0, n_packets=0, n_bytes=0, priority=2,in_port="int-br-provider" actions=drop cookie=0x10c394b632250c4c, duration=81941.784s, table=0, n_packets=8, n_bytes=792, priority=0 actions=resubmit(,58) cookie=0x10c394b632250c4c, duration=81941.785s, table=23, n_packets=0, n_bytes=0, priority=0 actions=drop cookie=0x10c394b632250c4c, duration=81941.781s, table=24, n_packets=0, n_bytes=0, priority=0 actions=drop cookie=0x10c394b632250c4c, duration=81941.779s, table=30, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,58) cookie=0x10c394b632250c4c, duration=81941.779s, table=31, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,58) cookie=0x10c394b632250c4c, duration=81941.783s, table=58, n_packets=8, n_bytes=792, priority=0 actions=resubmit(,60) cookie=0x10c394b632250c4c, duration=3522.763s, table=60, n_packets=4, n_bytes=392, priority=100,in_port="tapbb45b827-28" actions=load:0x3->NXM_NX_REG5[],load:0x1->NXM_NX_REG6[],resubmit(,73) ovs-ofctl show br-int OFPT_FEATURES_REPLY (xid=0x2): dpid:00006aad96360649 n_tables:254, n_buffers:0 capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst 1(int-br-provider): addr:6e:ee:f9:c2:36:2f config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max 2(patch-tun): addr:9a:cd :9f:d6:ad:fb config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max 3(tapbb45b827-28): addr:fa:16:3e:fa:16:a6 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max LOCAL(br-int): addr:6a:ad:96:36:06:49 config: PORT_DOWN state: LINK_DOWN speed: 0 Mbps now, 0 Mbps max OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
在 vlan 模式下,vlan tag 的转换需要在 br-int 和 br-ethx 两个网桥上进行相互配合。即 br-int 负责从 int-br-ethX 过来的包(带外部 vlan)转换为内部 vlan,而 br-ethx 负责从 phy-br-ethx 过来的包(带内部 vlan)转化为外部的 vlan。
同节点上 vm 相同 vlan,只需要走内部 vlan 即可
vmware 中外层交换机是 vment,vmnet 不能放行带 vlan 的。导致 dhcp 到不了其他节点,获取不到 IP
vxlan :
1 2 3 4 5 6 7 8 9 10 11 12 [root@controller ml2] cookie=0x3dcfb0afa749164c, duration=84884.402s, table=0, n_packets=4, n_bytes=392, priority=1,in_port="patch-int" actions=resubmit(,2) cookie=0x3dcfb0afa749164c, duration=84884.402s, table=0, n_packets=0, n_bytes=0, priority=0 actions=drop cookie=0x3dcfb0afa749164c, duration=84884.400s, table=2, n_packets=0, n_bytes=0, priority=0,dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20) cookie=0x3dcfb0afa749164c, duration=84884.399s, table=2, n_packets=4, n_bytes=392, priority=0,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,22) cookie=0x3dcfb0afa749164c, duration=84884.398s, table=3, n_packets=0, n_bytes=0, priority=0 actions=drop cookie=0x3dcfb0afa749164c, duration=6467.440s, table=4, n_packets=0, n_bytes=0, priority=1,tun_id=0xf9 actions=mod_vlan_vid:1,resubmit(,10) cookie=0x3dcfb0afa749164c, duration=84884.398s, table=4, n_packets=0, n_bytes=0, priority=0 actions=drop cookie=0x3dcfb0afa749164c, duration=84884.397s, table=6, n_packets=0, n_bytes=0, priority=0 actions=drop cookie=0x3dcfb0afa749164c, duration=84884.395s, table=10, n_packets=0, n_bytes=0, priority=1 actions=learn(table=20,hard_timeout=300,priority=1,cookie=0x3dcfb0afa749164c,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:OXM_OF_IN_PORT[]),output:"patch-int" cookie=0x3dcfb0afa749164c, duration=84884.394s, table=20, n_packets=0, n_bytes=0, priority=0 actions=resubmit(,22) cookie=0x3dcfb0afa749164c, duration=84884.393s, table=22, n_packets=4, n_bytes=392, priority=0 actions=drop
# router
添加 public subnet 的时候不需要网关,公网 IP 不需要网关,也不需要 dhcp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 ip netns exec qrouter-a51268a3-68a6-47f0-a51d-03b98216b2f8 ip -c a s 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link /loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 11: qg-3faec10c-ad: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000 link /ether fa:16:3e:93:bb:1e brd ff:ff:ff:ff:ff:ff inet 192.168.0.203/24 brd 192.168.0.255 scope global qg-3faec10c-ad valid_lft forever preferred_lft forever inet 192.168.0.27/32 brd 192.168.0.27 scope global qg-3faec10c-ad valid_lft forever preferred_lft forever inet6 fe80::f816:3eff:fe93:bb1e/64 scope link valid_lft forever preferred_lft forever 13: qr-bab87452-44: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000 link /ether fa:16:3e:43:b9:2f brd ff:ff:ff:ff:ff:ff inet 192.168.100.254/24 brd 192.168.100.255 scope global qr-bab87452-44 valid_lft forever preferred_lft forever inet6 fe80::f816:3eff:fe43:b92f/64 scope link valid_lft forever preferred_lft forever ip netns exec qrouter-a51268a3-68a6-47f0-a51d-03b98216b2f8 iptables -t nat -nvxL Chain neutron-l3-agent-OUTPUT (1 references) pkts bytes target prot opt in out source destination 0 0 DNAT 0 -- * * 0.0.0.0/0 192.168.0.27 to:192.168.100.97 Chain neutron-l3-agent-POSTROUTING (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT 0 -- * !qg-3faec10c-ad 0.0.0.0/0 0.0.0.0/0 ! ctstate DNAT Chain neutron-l3-agent-PREROUTING (1 references) pkts bytes target prot opt in out source destination 0 0 REDIRECT 6 -- qr-+ * 0.0.0.0/0 169.254.169.254 tcp dpt:80 redir ports 9697 4 272 DNAT 0 -- * * 0.0.0.0/0 192.168.0.27 to:192.168.100.97 Chain neutron-l3-agent-float-snat (1 references) pkts bytes target prot opt in out source destination 16 1196 SNAT 0 -- * * 192.168.100.97 0.0.0.0/0 to:192.168.0.27 random-fully Chain neutron-l3-agent-snat (1 references) pkts bytes target prot opt in out source destination 31 2230 neutron-l3-agent-float-snat 0 -- * * 0.0.0.0/0 0.0.0.0/0 11 762 SNAT 0 -- * qg-3faec10c-ad 0.0.0.0/0 0.0.0.0/0 to:192.168.0.203 random-fully 0 0 SNAT 0 -- * * 0.0.0.0/0 0.0.0.0/0 mark match ! 0x2/0xffff ctstate DNAT to:192.168.0.203 random-fully
float ip 比 snat 优先级更高,按照 iptables 匹配规则
获取客户自己定义,但无法传送给虚拟机的数据
为了满足公有云虚拟机的差异化定制,虚拟机(overlay 网络)需要从控制面(underlay 网络)获取一些信息,但是虚拟机是不能够直接与控制面进行通信的,所以增加 metadata 来传递虚拟机和控制面的数据交换。目前实现数据类型有初始化(第一次创建密码,公钥,hostname 等注入),AssumeRole,重置密码 / 公钥。
metatdata 分为 neutron metadata 和 nova metadata
为了保证使用私有镜像创建的新云服务器可以通过 "用户数据注入" 功能注入初始化自定义信息 (例如为云服务器设置登录密码), 请在创建私有镜像前安装 Cloud-Init 工具。
1 2 [root@controller ~] cirros-0.4.0-x86_64-disk.img: QEMU QCOW2 Image (v3), 46137344 bytes
cloud-init 是 Linux 的一个工具,当系统启动时,cloud-init 可从 novametadata 服务或者 config drive 中获取 metadata
windows 安装 cloudbase-init
# 通过路由器获取
instance 通过默认网关到网络节点,网络节点通过管理网络到 nova 上获取 metadata
必须要有 router,不然没有办法到 gw
用户在发放云主机时,自定义主机名,密码等信息,发送给 novaapi-metadata
获取计算机名和密码流程
1. 云主机启动后,通过 DHCP 获得 IP 地址
2. 运行 cloud-init,cloud-init 开始去访问 http://169.254.169.254:80,meta-data 最后更新日期就是文件夹名字
3. 这个请求将丢给网关 (Router)
4.iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --t 9697
1 2 3 4 5 6 7 8 9 10 11 ip netns exec qrouter-a51268a3-68a6-47f0-a51d-03b98216b2f8 iptables -t nat -nvxL Chain neutron-l3-agent-PREROUTING (1 references) pkts bytes target prot opt in out source destination 0 0 REDIRECT 6 -- qr-+ * 0.0.0.0/0 169.254.169.254 tcp dpt:80 redir ports 9697 4 272 DNAT 0 -- * * 0.0.0.0/0 192.168.0.27 to:192.168.100.97 ip netns exec qrouter-a51268a3-68a6-47f0-a51d-03b98216b2f8 netstat -lntup Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp6 0 0 :::9697 :::* LISTEN 5673/haproxy
#ps aux |grep 9697
5. 请求会转发给 neutron-metadata
6.neutron-metadata 会通过管理网络访问 nova-api-metadata, 从而得到计算机名和密码
instance 通过 neutron network (Project 网络) 将 metadata 请求发送到 neutron-ns-metadata-proxy。
neutron-ns-metadata-proxy 通过 unixdomain socket 将请求发给 neutron-metadata-agento
3.neutron-metadata-agent 通过内部管理网络将请求发送给 nova-api-metadata。
各家云厂商会更改这个地址,比如 volc 的地址就是 http://100.96.0.96,在 ecs 中 curl
1 2 curl http://100.96.0.96/2021-07-01/hostname iv-yd5c3xliwwcva4f4b9cl
# 通过 dhcp 获取
1 2 3 4 vim /etc/neutron/dhcp_agent.ini enable_isolated_metadata = True systemctl restart neutron-dhcp-agent
dhcp 生成一条去往 network node 的路由 169.254.169.254 gw dhcp ,到网络节点后,通过管理网络发给 nova
# MQ
MQ 全称为 MessageQueue, 应用程序通过读写出入队列的消息 (针对应用程序的数据) 来通信,而无需专用连接来连接它们。
MQ 会处理服务内组件之间的消息,包括控制,查询,监控
不同服务之间不过消息队列
rabbitmqctl list_queues
华为云管理节点数目与规模
小型场景下,rabbitmq 部署在 controller 上作为一个进程
# cinder
提供持久化块存储服务
swift 提供对象存储
没有指定磁盘类型,由 scheduler 调度创建
分布式存储:兼容性好 低 TCO 可扩展性强
cinder 只用于做存储管理,数据写盘的时候不会经过 cinder
硬盘挂载给云主机的时候是 nova 操作
硬盘附加给云主机的时候,会挂载到云主机所在的宿主机,通过 kvm 映射给云主机
nova 挂载的时候向 cinder-api 请求卷信息
阵列侧添加主机和 lun 的映射
主机侧扫描 scsi 总线
多路径生成虚拟磁盘
Nova 调用 libvirt 接口将磁盘添加到 xml
experiment: use glusterfs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 gluster peer probe 192.168.9.88 gluster peer status gluster volume create aaa replica 2 192.168.9.77:/volume/node1 192.168.9.88:/volume/node2 gluster volume start aaa gluster volume info aaa yum install gluster-fuse vim /etcd/cinder/cinder.conf [DEFAULT] enabled_backends = glusterfs123 [glusterfs123] volume_driver = cinder.volume.drivers.glusterfs.GlusterfsDriver gluster_shares_config = /etc/cinder/haha volume_backend_name = rhs vim /etc/cinder/haha 192.168.9.77:/firstvol systemctl restart openstack-cinder-api.service . admin-openrc cinder tpye-create glusterfs cinder tpye-key glusterfs set volume_backend_name=rhs yum install gluster-fuse -y cinder create --display-name aaa nova volume-attache server1 volume disk1 如果执行bootstrap-servers 报错 xxxping 一般是ansible版本问题 ,换ansible或者aisible-core版本即可解决 执行完后可能会因为openssh版本升级导致ssh无法连接 yum remove openssh -y yum install openssh* -y 重装旧的ssh即可 在pre-check时,会有dbus报错, pip install dbus-python 如果在bootstrap-servers 提示docker 超时,可以自己先装docker,在跑这个
# keystone
Domain: 域,keystone 中资源 (project、user、group) 的持有:者
Project: 租户,其他组件中资源 (虚拟机、镜像等) 的持有者
User: 用户,云系统的使用者
Group: 用户组,可以把多个用户作为一个整体进行角色管理
Role: 角色,基于角色进行访问控制
Trust: 委托,把自己拥有的角色临时授权给别人
Service: 服务,一组相关功能的集合,比如计算服务、网络服务、镜像服务、存储服务等
Endpoint: 必须和一个服务关联,代表这个服务的访问地址,一般一个服务需要提供三种类型的访问地址:public、internal、adrmin
Region: 区域,在 keystone 里基本代表一个数据中心
Policy: 访问控制策略,定义接口访问控制规则
Assignment: 一个 (actor, target, role) 三元组叫一个 assignment,actor 包括 user、group,target 包括 domain、project。每个 assignment 代表一次赋权操作
Token: 令牌,用户访问服务的凭证,代表着用户的账户信息,一般需要包含 user 信息、scope 信息 (project、domain 或者 trust)、1role 信息。分为 PKI,UUID,PKIZ,Fernet 几种类型。
用户从 keystone 申请 token
用户使用 token 访问服务
被访问组件验证 token
用户得到返回消息
权限不是由 ksysone 决定的,而是服务本身决定的(policy.json)。keystone 只做身份验证
1 2 3 4 5 6 7 8 9 10 [root@controller openstack-dashboard] total 432 -rw-r----- 1 root apache 77821 Mar 18 15:47 cinder_policy.yaml drwxr-xr-x 2 root root 4096 May 16 16:38 default_policies -rw-r----- 1 root apache 21507 Mar 18 15:47 glance_policy.yaml -rw-r----- 1 root apache 95071 Mar 18 15:47 keystone_policy.yaml -rw-r----- 1 root apache 12009 May 16 16:38 local_settings -rw-r----- 1 root apache 111993 Mar 18 15:47 neutron_policy.yaml drwxr-xr-x 2 root root 4096 May 16 16:38 nova_policy.d -rw-r----- 1 root apache 104596 Mar 18 15:47 nova_policy.yaml
角色本身没有意义,需要授权
# openvswitch
对于一个 Linux 系统来说,可以分为用户空间(user space)和内核空间(kernel space),网络设备接入到内核空间。如果需要将数据传输到用户程序则需要通过内核空间将数据上送到用户空间,如果需要在网络设备之间转发数据,直接在内核空间就可以完成。
作为运行在 x86 服务器中的软件交换机,直观上来看,应该在内核空间来实现转发。因此,Open vSwitch 在最早期的时候,是在 Linux 内核模块实现了所有的 OpenFlow 的处理。当时的 OpenvSwitch 内核模块处理流程是接收网络数据包,根据 OpenFlow 规则一步步的 Match,并根据 Action 修改网络数据包,最后从某个网络设备送出。
但是这种方式很快就被认为是不能实际应用的。首先,虽然在内核实现可以缩短网络数据包在操作系统的路径,但是在内核进行程序开发和更新也更加困难,以 OpenvSwitch 的更新速度,完全在内核实现将变得不切实际。其次,完全按照 OpenFlow pipeline 去处理网络包,势必要消耗大量 CPU,进而降低网络性能。
因此,最新版本(2.x 版本)的 OpenVSwitch 采用了一种很不一样的方式来避免这些问题。
1 2 3 4 5 yum install @'Development Tools' rpm-build yum-utils yum install -y centos-release-openstack-train yum install openvswitch libibverbs -y systemctl enable --now openvswitch
# bridge
Bridge 代表一个以太网交换机 (Switch),一个主机中可以创建一个或者多个 Bridge。Bridge 的功能是根据一定规则,把从端口收到的数据包转发到另一个或多个端口,上面例子中有三个 Bridge,br-tun,br-int,br-ext
# Port
端口 Port 与物理交换机的端口概念类似,Port 是 OVS Bridge 上创建的一个虚拟端口,每个 Port 都隶属于一个 Bridge。Port 有以下几种类型:
# Normal
可以把操作系统中已有的网卡 (物理网卡 em1/eth0, 或虚拟机的虚拟网卡 tapxxx) 挂载到 ovs 上,ovs 会生成一个同名 Port 处理这块网卡进出的数据包。此时端口类型为 Normal。
如下,主机中有一块物理网卡 eth1,把其挂载到 OVS 网桥 br-ext 上,OVS 会自动创建同名 Port eth1
有一点要注意的是,挂载到 OVS 上的网卡设备不支持分配 IP 地址,因此若之前 eth1 配置有 IP 地址,挂载到 OVS 之后 IP 地址将不可访问。这里的网卡设备不只包括物理网卡,也包括主机上创建的虚拟网卡。
1 2 3 4 5 6 7 8 9 ovs-vsctl add-port br0 eth1 Bridge "br0" Port "eth1" Interface "eth1" Port "br0" Interface "br0" type : internal
# Internal
Internal 类型是 OVS 内部创建的虚拟网卡接口,每创建一个 Port,OVS 会自动创建一个同名接口 (Interface) 挂载到新创建的 Port 上。接口的概念下面会提到。
下面创建一个网桥 br0,并创建一个 Internal 类型的 Port p0。
1 2 3 4 5 6 7 8 9 10 11 12 ovs-vsctl add-br br1 ovs-vsctl add-port br1 p0 -- set Interface p0 type =internal [root@iv-yd5uco04qo5i3z39s0gj /] 24558780-9b54-41d2-8b8e-1a1dd7c5127e Bridge br-ext Port "p0" Interface "p0" type : internal Port br-ext Interface br-ext type : internal
可以看到有两个 Port。当 ovs 创建一个新网桥时,默认会创建一个与网桥同名的 Internal Port。在 OVS 中,只有”internal” 类型的设备才支持配置 IP 地址信息,因此我们可以为 br0 接口配置一个 IP 地址,当然 p0 也可以配置 IP 地址。
1 2 3 4 ip addr add 192.168.10.11/24 dev br0 ip link set br0 up ip route add default via 192.168.10.1 dev br0
上面两种 Port 类型区别在于,Internal 类型会自动创建接口 (Interface),而 Normal 类型是把主机中已有的网卡接口添加到 OVS 中。
# Patch
当主机中有多个 ovs 网桥时,可以使用 Patch Port 把两个网桥连起来。Patch Port 总是成对出现,分别连接在两个网桥上,从一个 Patch Port 收到的数据包会被转发到另一个 Patch Port,类似于 Linux 系统中的 veth。使用 Patch 连接的两个网桥跟一个网桥没什么区别,OpenStack Neutron 中使用到了 Patch Port。上面网桥 br-ext 中的 Port phy-br-ext 与 br-int 中的 Port int-br-ext 是一对 Patch Port。
可以使用 ovs-vsctl 创建 patch 设备,如下创建两个网桥 br0,br1,然后使用一对 Patch Port 连接它们。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ovs-vsctl add-br br10 ovs-vsctl add-br br20 ovs-vsctl -- add-port br10 patch0 -- set Interface patch0 type =patch options:peer=patch1 \ -- add-port br20 patch1 -- set Interface patch1 type =patch options:peer=patch0 Bridge "br20" Port "br20" Interface "br20" type : internal Port "patch1" Interface "patch1" type : patch options: {peer="patch0" } Bridge "br10" Port "br10" Interface "br10" type : internal Port "patch0" Interface "patch0" type : patch options: {peer="patch1" }
连接两个网桥不止上面一种方法,linux 中支持创建 Veth 设备对,我们可以首先创建一对 Veth 设备对,然后把这两个 Veth 分别添加到两个网桥上,其效果跟 OVS 中创建 Patch Port 一样
1 2 3 4 5 ip link add veth-a type veth peer name veth-b ovs-vsctl add-port br0 veth-a ovs-vsctl add-port br1 veth-b
# Tunnel
OVS 中支持添加隧道 (Tunnel) 端口,常见隧道技术有两种 gre 或 vxlan。隧道技术是在现有的物理网络之上构建一层虚拟网络,上层应用只与虚拟网络相关,以此实现的虚拟网络比物理网络配置更加灵活,并能够实现跨主机的 L2 通信以及必要的租户隔离。不同隧道技术其大体思路均是将以太网报文使用隧道协议封装,然后使用底层 IP 网络转发封装后的数据包,其差异性在于选择和构造隧道的协议不同。Tunnel 在 OpenStack 中用作实现大二层网络以及租户隔离,以应对公有云大规模,多租户的复杂网络环境。
OpenStack 是多节点结构,同一子网的虚拟机可能被调度到不同计算节点上,因此需要有隧道技术来保证这些同子网不同节点上的虚拟机能够二层互通,就像他们连接在同一个交换机上,同时也要保证能与其它子网隔离。
OVS 在计算和网络节点上建立隧道 Port 来连接各节点上的网桥 br-int,这样所有网络和计算节点上的 br-int 互联形成了一个大的虚拟的跨所有节点的逻辑网桥 (内部靠 tunnel id 或 VNI 隔离不同子网),这个逻辑网桥对虚拟机和 qrouter 是透明的,它们觉得自己连接到了一个大的 br-int 上。从某个计算节点虚拟机发出的数据包会被封装进隧道通过底层网络传输到目的主机然后解封装。
1 2 3 4 5 6 7 8 ovs-vsctl add-br br-vxlan ovs-vsctl add-br br-vxlan ovs-vsctl add-port br-vxlan tun0 -- set Interfacetun0 type =vxlan options:remote_ip=192.168.7.23 ovs-vsctl add-port br-vxlan tun0 -- set Interfacetun0 type =vxlan options:remote_ip=192.168.7.21
两个主机上桥接到 br-vxlan 的虚拟机就像连接到同一个交换机一样,可以实现跨主机的 L2 连接,同时又完全与物理网络隔离。
# Interface
Interface 是连接到 Port 的网络接口设备,是 OVS 与外部交换数据包的组件,在通常情况下,Port 和 Interface 是一对一的关系,只有在配置 Port 为 bond 模式后,Port 和 Interface 是一对多的关系。这个网络接口设备可能是创建 Internal 类型 Port 时 OVS 自动生成的虚拟网卡,也可能是系统的物理网卡或虚拟网卡 (TUN/TAP) 挂载在 ovs 上。 OVS 中只有”Internal” 类型的网卡接口才支持配置 IP 地址。
Interface 是一块网络接口设备,负责接收或发送数据包,Port 是 OVS 网桥上建立的一个虚拟端口,Interface 挂载在 Port 上。
# 命令行工具
我们可以修改和配置的是 OpenFlow flows。datapath flow 和”hidden” flows 由 OVS 自身管理,我们不必去修改它。当然,调试场景下还是可以使用工具修改的。
介绍下上面三种 flows 管理工具,不具体说明,具体使用可以查看相关 man 手册。
ovs-ofctl dump-flows 打印指定网桥内的所有 OpenFlow flows,可以存在多个流表 (flow tables),按表顺序显示。不包括”hidden” flows。这是最常用的查看 flows 命令,当然这条命令对所有 OpenFlow 交换机都有效,不单单是 OVS;
ovs-appctl bridge/dump-flows 打印指定网桥内所有 OpenFlow flows,包括”hidden” flows,in-band control 模式下排错可以用到;
ovs-dpctl dump-flows dp 打印内核模块中 datapath flows,dp 可以省略,默认主机中只有一个 datapath system@ovs-systemman 手册可以找到非常详细的用法说明,注意 ovs-ofctl 管理的是 OpenFlow flows;
# 2.4.1 ovs-vsctl
ovs-vsctl 是一个管理或配置 ovs-vswitchd 的高级命令行工具,高级是说其操作对用户友好,封装了对数据库的操作细节。它是管理 OVS 最常用的命令,除了配置 flows 之外,其它大部分操作比如 Bridge/Port/Interface/Controller/Database/Vlan 等都可以完成。
ovsdb-tool 是一个专门管理 OVS 数据库文件的工具,不常用,它不直接与 ovsdb-server 进程通信。
# 2.4.3 ovsdb-client
ovsdb-client 是 ovsdb-server 进程的命令行工具,主要是从正在运行的 ovsdb-server 中查询信息,操作的是数据库相关。
# 2.4.4 ovs-ofctl
ovs-ofctl 是专门管理配置 OpenFlow 交换机的命令行工具,我们可以用它手动配置 OVS 中的 OpenFlow flows,注意其不能操作 datapath flows 和”hidden” flows。
ovs-vsctl 是一个综合的配置管理工具,ovsdb-client 倾向于从数据库中查询某些信息,而 ovsdb-tool 是维护数据库文件工具
1 2 3 ps -ef | grep ovs openvsw+ 28481 1 0 15:58 ? 00:00:00 ovsdb-server /etc/openvswitch/conf.db -vconsole:emer -vsyslog:err -vfile:info --remote=punix:/var/run/openvswitch/db.sock --private-key=db:Open_vSwitch,SSL,private_key --certificate=db:Open_vSwitch,SSL,certificate --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert --user openvswitch:hugetlbfs --no-chdir --log-file=/var/log/openvswitch/ovsdb-server.log --pidfile=/var/run/openvswitch/ovsdb-server.pid --detach openvsw+ 28553 1 0 15:58 ? 00:00:03 ovs-vswitchd unix:/var/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfile:info --mlockall --user openvswitch:hugetlbfs --no-chdir --log-file=/var/log/openvswitch/ovs-vswitchd.log --pidfile=/var/run/openvswitch/ovs-vswitchd.pid --detach
ovs-vswitchd:守护程序,实现交换功能,和 Linux 内核兼容模块一起,实现基于流的交换 flow-based switching。
ovsdb-server:轻量级的数据库服务,主要保存了整个 OVS 的配置信息,包括接口,交换内容,VLAN 啊等等。ovs-vswitchd 会根据数据库中的配置信息工作。
ovs-dpctl:一个工具,用来配置交换机内核模块,可以控制转发规则。
ovs-vsctl:主要是获取或者更改 ovs-vswitchd 的配置信息,此工具操作的时候会更新 ovsdb-server 中的数据库。
ovs-appctl:主要是向 OVS 守护进程发送命令的,一般用不上。
ovsdbmonitor:GUI 工具来显示 ovsdb-server 中数据信息。
ovs-controller:一个简单的 OpenFlow 控制器.
ovs-ofctl:用来控制 OVS 作为 OpenFlow 交换机工作时候的流表内容。
https://cloud.tencent.com/developer/article/2046695
https://cloud.tencent.com/developer/article/2046698
使用 kolla-ansible 搭建 openstack 2023.1 中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 (openvswitch-vswitchd)[root@localhost /] d80e30f5-1368-4afa-905c-09ae9b71412c Manager "ptcp:6640:127.0.0.1" is_connected: true Bridge br-tun Controller "tcp:127.0.0.1:6633" is_connected: true fail_mode: secure datapath_type: system Port patch-int Interface patch-int type : patch options: {peer=patch-tun} Port br-tun Interface br-tun type : internal Bridge br-ex Controller "tcp:127.0.0.1:6633" is_connected: true fail_mode: secure datapath_type: system Port phy-br-ex Interface phy-br-ex type : patch options: {peer=int-br-ex} Port ens36 Interface ens36 Port br-ex Interface br-ex type : internal Bridge br-int Controller "tcp:127.0.0.1:6633" is_connected: true fail_mode: secure datapath_type: system Port patch-tun Interface patch-tun type : patch options: {peer=patch-int} Port br-int Interface br-int type : internal Port qg-3faec10c-ad tag: 1 Interface qg-3faec10c-ad type : internal Port qvof113dcab-b7 tag: 2 Interface qvof113dcab-b7 Port tap7bbd044b-ec tag: 2 Interface tap7bbd044b-ec type : internal Port int-br-ex Interface int-br-ex type : patch options: {peer=phy-br-ex} Port qvo7033fcef-a5 tag: 2 Interface qvo7033fcef-a5 Port qr-bab87452-44 tag: 2 Interface qr-bab87452-44 type : internal (openvswitch-vswitchd)[root@localhost /]