# openstack

# nova

image-20240804225801612

主机发放完之后可以把镜像删掉,因为系统盘是通过镜像复制的

image-20240804225814617

openstack 中实例快照是作为镜像使用的,可以直接作为云主机镜像,不能直接还原

硬盘快照是用于创建相同的云硬盘,可以挂载给主机,不能直接还原快照。也可以放做启动盘使用

# glance

所有服务的 API endpoint 地址均存放在 keystone 数据库中

image-20240804225828237

写操作会通过 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> # keystone address + port + version
swift_store_user = edu:user1 # 用户需要有上传swift权限
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

image-20240804225840863

L3 agent 部署在哪个节点,那个节点就是网络节点。可以和 controller 复用

1
2
3
4
5
6
7
8
9
10
[root@controller ~]# openstack network agent list 
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
| 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 |
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+

image-20240804225907860

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 场景:

image-20240804225920320

集中式路由场景,不同 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

#
# From neutron.ml2
#

# List of physical_network names with which flat networks can be created. Use
# default '*' to allow flat networks with arbitrary physical_network names. Use
# an empty list to disable flat networks. (list value)
#flat_networks = *


[ml2_type_geneve]

#
# From neutron.ml2
#

# Comma-separated list of <vni_min>:<vni_max> tuples enumerating ranges of
# Geneve VNI IDs that are available for tenant network allocation. Note OVN
# does not use the actual values. (list value)
#vni_ranges =

# The maximum allowed Geneve encapsulation header size (in bytes). Geneve
# header is extensible, this value is used to calculate the maximum MTU for
# Geneve-based networks. The default is 30, which is the size of the Geneve
# header without any additional option headers. Note the default is not enough
# for OVN which requires at least 38. (integer value)
#max_header_size = 30


[ml2_type_gre]

#
# From neutron.ml2
#

# Comma-separated list of <tun_min>:<tun_max> tuples enumerating ranges of GRE
# tunnel IDs that are available for tenant network allocation (list value)
#tunnel_id_ranges =


[ml2_type_vlan]
network_vlan_ranges = huawei:10:1000
# 标识,vlan range,标识可以有多个
# From neutron.ml2
#

# List of <physical_network>:<vlan_min>:<vlan_max> or <physical_network>
# specifying physical_network names usable for VLAN provider and tenant
# networks, as well as ranges of VLAN tags on each available for allocation to
# tenant networks. If no range is defined, the whole valid VLAN ID set [1,
# 4094] will be assigned. (list value)
#network_vlan_ranges =


[ml2_type_vxlan]
# vni_ranges = 1:1000
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]#  ovs-ofctl dump-flows br-tun 
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 匹配规则

image-20240804225939315

# metadata

获取客户自己定义,但无法传送给虚拟机的数据

为了满足公有云虚拟机的差异化定制,虚拟机(overlay 网络)需要从控制面(underlay 网络)获取一些信息,但是虚拟机是不能够直接与控制面进行通信的,所以增加 metadata 来传递虚拟机和控制面的数据交换。目前实现数据类型有初始化(第一次创建密码,公钥,hostname 等注入),AssumeRole,重置密码 / 公钥。

metatdata 分为 neutron metadata 和 nova metadata

为了保证使用私有镜像创建的新云服务器可以通过 "用户数据注入" 功能注入初始化自定义信息 (例如为云服务器设置登录密码), 请在创建私有镜像前安装 Cloud-Init 工具。

1
2
[root@controller ~]# file cirros-0.4.0-x86_64-disk.img 
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

image-20240804225950222

# 通过路由器获取

instance 通过默认网关到网络节点,网络节点通过管理网络到 nova 上获取 metadata

必须要有 router,不然没有办法到 gw

用户在发放云主机时,自定义主机名,密码等信息,发送给 novaapi-metadata

获取计算机名和密码流程

1. 云主机启动后,通过 DHCP 获得 IP 地址

2. 运行 cloud-init,cloud-init 开始去访问 http://169.254.169.254:80,meta-data 最后更新日期就是文件夹名字

image-20240804230000098

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, 从而得到计算机名和密码

image-20240804230016525

  1. instance 通过 neutron network (Project 网络) 将 metadata 请求发送到 neutron-ns-metadata-proxy。
  2. 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

image-20240804230031446

# MQ

MQ 全称为 MessageQueue, 应用程序通过读写出入队列的消息 (针对应用程序的数据) 来通信,而无需专用连接来连接它们。

MQ 会处理服务内组件之间的消息,包括控制,查询,监控

不同服务之间不过消息队列

image-20240804230045070

image-20240804230101851

rabbitmqctl list_queues

华为云管理节点数目与规模

image-20240804230119838

小型场景下,rabbitmq 部署在 controller 上作为一个进程

# cinder

提供持久化块存储服务

swift 提供对象存储

没有指定磁盘类型,由 scheduler 调度创建

分布式存储:兼容性好 低 TCO 可扩展性强

image-20240804230139344

image-20240804230153658

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
# 自己的ip不用probe,自己的ip是192.168.9.77
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

# controller node测试。 fuse 用户空间提供 ,不在内核空间
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

# compute
yum install gluster-fuse -y

# horizon 上创建glustefs存储,attach 到云主机上
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 几种类型。

image-20240804230207398

用户从 keystone 申请 token

用户使用 token 访问服务

被访问组件验证 token

用户得到返回消息

image-20240804230220039

权限不是由 ksysone 决定的,而是服务本身决定的(policy.json)。keystone 只做身份验证

1
2
3
4
5
6
7
8
9
10
[root@controller openstack-dashboard]# ll /etc/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

角色本身没有意义,需要授权

1
2
3
4
5
vim policy.json
# Publicize given image
# PATCH /v2/images/{image_id}
# Intended scope(s): project
#"publicize_image": "rule:context_is_admin"

image-20240804230230451

# 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 epel-release
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

1
ovs-vsctl add-br br0
# 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
# 这里eth1就是port

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 /]# ovs-vsctl show
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
#创建veth设备对veth-a,veth-b
ip link add veth-a type veth peer name veth-b
#使用Veth连接两个网桥
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
#主机192.168.7.21上
ovs-vsctl add-br br-vxlan
#主机192.168.7.23上
ovs-vsctl add-br br-vxlan
#主机192.168.7.21上添加连接到7.23的Tunnel Port
ovs-vsctl add-port br-vxlan tun0 -- set Interfacetun0 type=vxlan options:remote_ip=192.168.7.23
#主机192.168.7.23上添加连接到7.21的Tunnel Port
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 等都可以完成。

image-20240804230257830

# 2.4.2 ovsdb-tool

​ ovsdb-tool 是一个专门管理 OVS 数据库文件的工具,不常用,它不直接与 ovsdb-server 进程通信。

image-20240804230308517

# 2.4.3 ovsdb-client

​ ovsdb-client 是 ovsdb-server 进程的命令行工具,主要是从正在运行的 ovsdb-server 中查询信息,操作的是数据库相关。

image-20240804230318271

# 2.4.4 ovs-ofctl

​ ovs-ofctl 是专门管理配置 OpenFlow 交换机的命令行工具,我们可以用它手动配置 OVS 中的 OpenFlow flows,注意其不能操作 datapath flows 和”hidden” flows。

image-20240804230327538

​ 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

image-20240804230339043

  • 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 /]# ovs-vsctl show 
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 /]#
Edited on

Give me a cup of [coffee]~( ̄▽ ̄)~*

John Doe WeChat Pay

WeChat Pay

John Doe Alipay

Alipay

John Doe PayPal

PayPal