OpenStack虚拟机网络不通的几个思路[2]

2018年六月份已经过去,刚过去的两个月是入市以来回撤最大的两个月,虽然资金量不大,但依然对未来抱有希望,说不定哪天走狗屎运咸鱼翻身了呢。本质上来说,股市也好,人生中的各种选择也好,都是一种赌博,就看你的筹码有多大,未来到底看的有多清,当然我从不屑于直接参与赌博,只是厌倦了一辈子都是如此谨谨慎慎,按部就班的生活。

2018年下半年祝福自己依然有颗勇敢的心,怀抱希望的走下去,Get busy living, Or get busy dying!

回来继续做些笔记,之前提到过OpenStack 虚拟机网络不通的几个思路,这篇笔记对其中iptable的规则来做个深入的了解:

sudo iptables -t nat -A POSTROUTING -s 192.168.42.0/24 -o eno1 -j MASQUERADE

为什么???

首先我们假设floating IP的地址和物理机的IP地址不在同一个网段,而是一个自定义的网段(后面我会探讨不同的应用场景,比如floating IP和物理机器的IP地址在需要在同一个网段的情况如何做网络配置),比如:
- 物理机的IP地址为: 192.168.18.0/24
- floating IP地址定义为: 192.168.42.0/24
这里floating IP地址其实是一个不存在的网络,是需要通过OpenStack去创建的一个网络。和之前的定义不一样,这里我们只对192.168.42.0/24网段的IP进行地址伪装,伪装为eno1的IP地址出去,192.168.42.0/24是floating IP地址。如果没有上面定义的这个规则,虚拟机则无法访问外网(公司内网),因为外部网络是不知道floating IP地址存在的,通过这个规则,从虚拟机出来的流量
将得以访问外网。

假设OpenStack的环境是通过DevStack安装起来的,那么你可以看到DevStack脚本已经帮你创建好了这个规则:

$ sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 192.168.42.0/24 -o eno1 -j MASQUERADE  <- 看这里
-A DOCKER -i docker0 -j RETURN

应用场景

我们来想这样一个场景,物理机上有多个网卡,比方说eno1连接的是公司内部的网络,eno2连的是公网,通过在DevStack的localrc文件里做如下的配置

FLAT_INTERFACE=eno1

注:

新版本中已经不建议采用nova network, 而是用neutron来提供网络服务,这样FLAT_INTERFACE将 不再起作用,取而代之的是PUBLIC_INTERFACE这个属性,而这两个属性所代表的意思是不同的,参考后面的源码分析。

DevStack会自动配置好了iptables,我们假设网络没有绑定任何物理网卡,那么应该走的是系统的默认路由,一般情况下,物理机上会配置一个默认路由,像下面这样:

$ sudo ip route
default via 192.168.18.1 dev eno1  proto static  metric 100
default via 192.168.8.1 dev eno2  proto static  metric 101
...
192.168.16.0/21 dev eno1  proto kernel  scope link  src 192.168.20.132
192.168.42.0/24 dev br-ex  proto kernel  scope link  src 192.168.42.1

这样虚拟机通过floating IP应该可以访问公司的内网了,但是有一天,虚拟机需要访问外部的公网了,怎么办?
修改物理机的默认路由?例如默认路由修改为:

default via 192.168.8.1 dev eno2 proto static metric 100
default via 192.168.18.1 dev eno1 proto static metric 101

是否可以了呢?做个测试,在虚拟机里ping 8.8.8.8,然后通过tcpdump可以来检测eno2看的网络请求:

$ sudo tcpdump -n -i eno2 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eno2, link-type EN10MB (Ethernet), capture size 262144 bytes
18:26:57.424083 IP 192.168.42.20 > 8.8.8.8: ICMP echo request, id 5155, seq 1, length 64
18:26:58.432816 IP 192.168.42.20 > 8.8.8.8: ICMP echo request, id 5155, seq 2, length 64
18:26:59.440803 IP 192.168.42.20 > 8.8.8.8: ICMP echo request, id 5155, seq 3, length 64
18:27:00.448842 IP 192.168.42.20 > 8.8.8.8: ICMP echo request, id 5155, seq 4, length 64
18:27:01.456825 IP 192.168.42.20 > 8.8.8.8: ICMP echo request, id 5155, seq 5, length 64
18:27:02.464842 IP 192.168.42.20 > 8.8.8.8: ICMP echo request, id 5155, seq 6, length 64

虽然eno2上能检测测ping请求,但是没有reply,虚拟机无法ping通外部网络!
所以,手动修改iptables的规则就该上场了:

sudo iptables -t nat -A POSTROUTING -s 192.168.42.0/24 -o eno2 -j MASQUERADE

再ping一次试试:

$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=38 time=99.6 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=38 time=97.7 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=38 time=83.0 ms
...

看看系统上的iptables的规则:

$ sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 192.168.42.0/24 -o eno1 -j MASQUERADE
-A POSTROUTING -s 192.168.42.0/24 -o eno2 -j MASQUERADE   <- 看这里
-A DOCKER -i docker0 -j RETURN

看来虽然我们对网段192.168.42.0/24加了两个MASQUERADE规则,但它们并不互斥,这周就到这里吧。

源码分析

这里的源码来自于pike release版本,上面所讲的都是我们能看到的现象,我们看看代码里是如何实现的。
打开DevStack里这个文件,我们可以看的一清二楚:

# /lib/neutron_plugins/services/l3
98 default_v4_route_devs=$(ip -4 route | grep ^default | awk '{print $5}')
...
126     if [[ -n "$PUBLIC_INTERFACE" ]]; then
127         _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" True False "inet"
128
129         if [[ $(ip -f inet6 a s dev "$PUBLIC_INTERFACE" | grep -c 'global') != 0 ]]; then
130             _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" False False "inet6"
131         fi
132     else
133         for d in $default_v4_route_devs; do
134             sudo iptables -t nat -A POSTROUTING -o $d -s $FLOATING_RANGE -j MASQUERADE
135         done
136     fi
137 }

所以,当有设置这个PUBLIC_INTERFACE这个属性时,将会对应的物理网卡绑定到bridge上去,如果没有设置,则会对系统的默认路由对应的所有的所有物理网卡设备定义MASQUERADE规则,以实现虚拟机与外网访问的目的。

从这里我们可以看出,配置OpenStack需要至少配置两个不同的网络的原因所在:

  • 集群内部需要一个可以连接的外部网络,每个节点都有配置一个该网段的IP地址,网络节点需要将此网卡绑定到bridge上,这样虚拟机可以通过此网络访问外网,floating IP也可以配置在同一个网络里,这样其它物理节点可以直接访问虚拟机(比如虚拟机提供一些web服务那么可以直接在其它节点访问)。

  • 还需要一个可以让终端用户去访问的管理机器的网络,此网络可以是内部管理网即OpenStack API服务所在的网络。实际生产环境比这个要复杂的多,比如需要一个存储网络,租户网络,部署(Provision)网络等。

附:

  1. 查看某个table上的rules
    sudo iptables -nL -t nat –line-number

  2. 删除某个规则
    sudo iptables -D POSTROUTING 3 -t nat


个人博客:http://www.jungler.cn/

<think>好的,我现在需要帮助用户了解如何使用OpenStack命令行界面(CLI)。首先,用户提供了几个引用链接,我需要先查看这些引用内容是否相关。引用[1]是OpenStack的词汇表,可能对术语解释有帮助;引用[2]是停止Nova服务的命令,可能与CLI操作相关;引用[3]讨论OpenStack设计,可能不直接涉及CLI使用,但需要确认。 接下来,用户需要的是OpenStack CLI的使用指南或文档。我应该先确定官方文档的位置,通常OpenStack的CLI工具每个项目都有各自的客户端,比如Nova、Neutron等,但现在已经统一为openstack客户端。所以需要推荐用户安装openstack客户端,并指导基本步骤:安装、认证、常用命令。 然后,需要检查引用中的内容是否可以用来支持回答。例如,引用[2]中的停止服务的命令是使用systemctl,属于系统服务管理,而用户需要的是OpenStack自身的CLI命令,可能不直接相关。但可能用户在使用CLI前需要确保相关服务运行,所以可以提及服务状态管理,但需要明确区分CLI和系统命令的区别。 另外,引用[1]的词汇表可能在解释术语时有用,比如解释project、tenant等概念,帮助用户理解CLI中的参数。引用[3]关于设计决策,可能不太相关,但可能需要提到CLI在云系统管理中的角色。 接下来,我需要组织回答结构:安装CLI、配置认证、常用命令示例、获取帮助、参考文档链接。确保每个步骤都清晰,使用代码块显示命令,并符合用户要求的格式,比如行内公式用$...$,但这里可能不涉及数学公式,但需要注意其他格式要求,如独立公式用$$...$$,但CLI指南可能不需要数学表达式,所以可能可以忽略这部分,但需确保其他格式正确。 然后生成相关问题,可能需要围绕安装问题、认证配置、常用操作、故障排除等方面提问。例如,如何安装CLI,如何获取API凭证,常见错误处理等。 最后,确保所有引用都正确标注,引用[1]、[2]、[3]是否在回答中被使用。例如,在解释认证时可能需要引用[1]的术语表链接,或者在说明服务状态时引用[2]中的命令,但需要自然衔接,避免突兀。 现在需要将这些思路整理成结构化的回答,符合用户的要求,使用中文,正确使用引用标记,并生成相关问题。</think>以下是OpenStack命令行界面(CLI)的使用指南,基于官方文档和最佳实践整理: ### 1. **安装OpenStack客户端** OpenStack CLI工具已整合为统一的`openstack`命令,支持Nova、Neutron、Cinder等所有服务。安装步骤如下: ```bash # 通过Python包管理工具安装 pip install python-openstackclient ``` ### 2. **配置认证信息** 使用CLI前需加载云平台的认证信息,通常通过`clouds.yaml`文件或环境变量配置。 示例环境变量配置: ```bash export OS_AUTH_URL=https://api.example.com:5000/v3 export OS_PROJECT_NAME="my-project" export OS_USERNAME="my-user" export OS_PASSWORD="my-password" export OS_USER_DOMAIN_NAME="Default" export OS_PROJECT_DOMAIN_NAME="Default" ``` ### 3. **常用命令示例** - **查看所有可用服务** ```bash openstack service list ``` - **管理虚拟机实例** 创建实例: ```bash openstack server create --image ubuntu-22.04 --flavor m1.small my-instance ``` - **管理网络** 列出所有网络: ```bash openstack network list ``` - **管理存储卷** 创建存储卷: ```bash openstack volume create --size 10 my-volume ``` ### 4. **获取帮助** - 查看所有命令:`openstack --help` - 查看子命令帮助:`openstack server create --help` ### 5. **官方文档参考** - [OpenStack CLI完整文档](https://docs.openstack.org/python-openstackclient/latest/) - [OpenStack客户端配置指南](https://docs.openstack.org/os-client-config/latest/user/configuration.html)[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值