OpenStack Neutron部署三大核心支点:Keystone认证、消息队列与Linux内核调优
1. 项目概述:这不是在装一个“网络插件”,而是在Linux内核里重建一套通信神经系统
你打开OpenStack控制节点,敲下openstack network list,看到几个子网和路由器——这背后没有魔法,只有一套精密运转的、横跨内核空间与用户空间的分布式网络服务系统。Neutron不是传统意义上的“网络管理工具”,它本质上是一套面向云环境的网络抽象层+事件驱动型服务总线+策略执行引擎的三重混合体。我带过十几期OpenStack实训,最常被低估的误区就是:学生以为配好neutron-server就完事了,结果一跑虚拟机,端口状态卡在BUILD,日志里满屏Connection refused to 127.0.0.1:9696或Failed to bind port——问题从来不在Neutron本身,而在它赖以呼吸的三个支点:Keystone认证链路是否真正打通、消息队列是否完成语义级可靠性配置、Linux内核参数是否为高并发连接与锁竞争做好了底层准备。
这个实训项目标题里那个看似普通的“七”,恰恰是整个OpenStack网络服务从单机调试迈向生产可用的关键分水岭。前六个实训可能让你学会创建网络、子网、端口,但第七个必须直面真实世界:当100台虚拟机同时启动,当DHCP Agent重启时租约表错乱,当L3 Agent因ARP缓存风暴丢包——这些都不是报错信息,而是系统在向你发出求救信号。而所有信号的接收器,都指向三个关键词:Keystone(不是登录界面,而是每个API请求背后毫秒级完成的token校验与策略决策)、消息队列(不是简单的“发消息”,而是RabbitMQ或Pulsar中每条port.update.end事件必须被至少一个Agent精确消费一次,且不能重复)、Linux内核参数(不是sysctl.conf里随便改的几行,而是net.core.somaxconn决定新连接排队长度、fs.inotify.max_user_watches影响DHCP监听效率、kernel.sem直接约束Neutron Server能持有的IPC锁数量)。至于lock path,它根本不是个路径配置项,而是Neutron在多进程协作时用oslo.concurrency实现分布式锁的落盘锚点——一旦你把它设在NFS共享目录,整个集群的端口绑定就会进入不可预测的等待地狱。所以这个实训,表面是部署Neutron,实质是训练你像系统工程师一样思考:每一行配置背后,是内核调度器、内存管理子系统、网络协议栈、文件系统、进程间通信机制的协同作战。
2. 整体设计思路拆解:为什么必须放弃“照着文档敲命令”的惯性思维
2.1 不是部署服务,而是构建三层可信通信环
很多学员把Neutron部署理解成“安装几个包+改几行配置+启动服务”,这是导致后续排错成本飙升的根本原因。真实生产环境中,Neutron的稳定运行依赖于三个严格嵌套的通信环,缺一不可:
第一环:身份可信环(Keystone)
这不是简单的HTTP Basic Auth。当你执行openstack server create,CLI先向Keystone申请token,该token携带project_id、user_id、roles及expires_at时间戳;Neutron Server收到请求后,不直接查数据库,而是调用Keystone的/v3/auth/tokens/{token}/validate接口实时校验——这意味着Keystone服务必须比Neutron更早启动、更高可用。我见过太多案例:Keystone用SQLite做后端,50并发请求下token校验延迟飙到8秒,Neutron Server的api_workers线程池瞬间耗尽,所有API请求排队超时。所以实训第一步,必须验证Keystone的/v3端点响应时间是否稳定在50ms内(用time curl -H "X-Auth-Token: $TOKEN" http://keystone:5000/v3实测),否则后续所有配置都是空中楼阁。第二环:事件可靠环(消息队列)
Neutron Server与各类Agent(L2、L3、DHCP、Metadata)之间零直接通信。所有状态变更都通过消息队列广播:Server发布port.create.start,DHCP Agent订阅并执行dnsmasq配置生成,完成后发布port.create.end。这里的关键陷阱在于“可靠”二字。RabbitMQ默认的auto_ack=True模式下,Agent处理失败消息即丢失;而Pulsar的at-least-once语义若未配置ackTimeoutMs,崩溃的Agent会无限重发同一条消息。实训中必须强制启用ack机制,并设置heartbeat=60(避免TCP空闲断连)和prefetch_count=10(防止单个Agent积压消息拖垮集群)。这不是可选项,是Neutron事件模型的生存底线。第三环:内核支撑环(Linux参数与锁路径)
当Neutron Server处理端口绑定请求时,它要同时操作:①调用OVSDB更新流表(需/var/run/openvswitch/db.sockUnix域套接字);②写入ML2插件数据库(MySQL连接);③在/var/lib/neutron/locks/下创建临时锁文件防止并发冲突。这三个动作分别消耗:Unix socket文件描述符、MySQL连接数、本地磁盘I/O与inode。如果fs.file-max=8192(默认值),100个并发端口创建请求会直接触发Too many open files错误;如果vm.swappiness=60,内存压力下内核频繁swap,OVSDB响应延迟导致端口状态卡死。lock path配置的本质,是告诉Neutron:“把所有分布式锁的临时文件放在这里”,而这个路径必须满足:①本地文件系统(禁止NFS);②足够inodes(df -i检查);③无SELinux上下文冲突(ls -Z确认system_u:object_r:neutron_var_lib_t:s0)。忽略任一环节,系统就在“看似正常”中慢性死亡。
2.2 为什么必须亲手调优内核参数,而非依赖发行版默认值
CentOS/RHEL默认的/etc/sysctl.conf是为通用服务器设计的,而Neutron节点是高度特化的网络数据平面控制器。我们来算一笔硬账:
net.core.somaxconn:决定TCP连接请求队列长度。默认128,意味着当130个客户端同时发起API请求,第129个起直接被内核丢弃(返回ECONNREFUSED)。Neutron Server的api_workers通常设为CPU核心数×2,假设8核机器即16个worker,每个worker处理请求平均耗时200ms,则理论最大QPS为16÷0.2=80。但突发流量下,连接队列必须容纳至少3倍峰值(240),因此somaxconn至少设为512。实测中,我们将此值调至2048,配合net.ipv4.tcp_max_syn_backlog=4096,彻底消除连接拒绝现象。fs.inotify.max_user_watches:DHCP Agent使用inotify监听/var/lib/dhcp/目录下租约文件变化。默认8192,当子网超过200个时,inotify句柄耗尽,DHCP服务静默失效。我们按公式计算:max_user_watches ≥ 子网数 × 50(每个子网监控的文件数),实训环境设为524288(512K),确保万无一失。kernel.sem:Neutron Server使用System V信号量实现进程间同步。格式为SEMMSL SEMMNS SEMOPM SEMMNI,其中SEMMNS是系统信号量总数。默认250 32000 32 128,SEMMNS=32000仅支持约200个并发锁请求。我们按SEMMNS = api_workers × 100计算,16个worker需1600,但为冗余设为65536。
提示:所有内核参数修改后必须执行
sysctl -p并验证sysctl -a | grep 参数名,仅改配置文件不生效。更关键的是,重启Neutron服务前必须systemctl daemon-reload,否则旧参数仍被继承。
2.3 Keystone集成不是“填URL”,而是建立双向信任链
新手常犯的致命错误:在/etc/neutron/neutron.conf里填上auth_url = http://controller:5000/v3就认为OK。但Keystone的v3端点要求显式声明认证方式。Neutron必须配置:
[DEFAULT] auth_strategy = keystone [keystone_authtoken] www_authenticate_uri = http://controller:5000 auth_url = http://controller:5000 memcached_servers = controller:11211 auth_type = password project_domain_name = default user_domain_name = default project_name = service username = neutron password = NEUTRON_PASS注意www_authenticate_uri与auth_url的区别:前者用于获取初始token,后者用于token校验。若两者指向不同地址(如www_authenticate_uri用IP而auth_url用域名),Keystone会因Invalid token拒绝请求。更隐蔽的坑是memcached_servers——Neutron用Memcached缓存token解析结果,若Memcached未启动或防火墙阻断11211端口,每次API请求都要走完整Keystone校验流程,延迟从5ms暴涨至2s。实训中必须用echo "stats items" | nc controller 11211验证Memcached连通性。
3. 核心细节解析与实操要点:从配置文件到内核态的逐层穿透
3.1 Neutron Server配置的“三明治”结构:外层认证、中层插件、内层数据库
Neutron的配置文件/etc/neutron/neutron.conf不是扁平列表,而是分层嵌套的“三明治”:
外层:认证与服务发现(
[DEFAULT]与[keystone_authtoken])
这是Neutron的“身份证”。auth_strategy = keystone是开关,关闭则降级为noauth模式(仅测试用);service_plugins必须包含router(否则无法创建路由器),若用OVS则core_plugin = ml2是铁律。这里最容易被忽略的是notify_nova_on_port_status_changes = true——它让Neutron在端口状态变为ACTIVE时主动通知Nova,否则虚拟机网卡永远显示“正在获取IP”。中层:ML2插件深度配置(
/etc/neutron/plugins/ml2/ml2_conf.ini)
ML2是Neutron的“神经中枢”,其配置决定网络能力上限。关键参数:[ml2] type_drivers = flat,vlan,vxlan # 支持的网络类型,vxlan必须启用 tenant_network_types = vxlan # 租户网络默认类型 mechanism_drivers = openvswitch,linuxbridge # OVS与Linux Bridge双驱动 extension_drivers = port_security,qos,rbac # 安全与QoS扩展 [ml2_type_vxlan] vni_ranges = 1001:2000 # VXLAN网络标识范围,避免与物理网络冲突 max_mtu = 1450 # VXLAN封装后MTU=1500-50,必须显式声明 [securitygroup] enable_security_group = true # 启用安全组(依赖iptables) firewall_driver = iptables_hybrid # 混合驱动,兼容OVS流表与iptables规则注意:
vni_ranges若设为1:1000,可能与物理网络VNI冲突导致跨租户通信;max_mtu不设会导致虚拟机ping大包失败(ICMP Fragmentation Needed但DF位被置位)。内层:数据库与消息队列(
[database]与[oslo_messaging_rabbit])
数据库连接字符串必须包含?charset=utf8,否则中文项目名入库乱码;消息队列配置中rabbit_ha_queues = true是高可用关键——它让RabbitMQ将队列镜像到所有节点,单节点宕机不丢消息。但必须配合rabbit_retry_interval = 1(重试间隔1秒)和rabbit_max_retries = 0(无限重试),否则Agent启动时RabbitMQ未就绪,服务直接退出。
3.2 消息队列选型实战:RabbitMQ vs Pulsar的场景化抉择
当前热词中“Pulsar消息队列”频现,但实训中是否该替换RabbitMQ?答案取决于你的目标:
选RabbitMQ(推荐实训首选):
优势:成熟度高、文档丰富、与OpenStack集成最深。rabbitmqctl list_queues可实时查看各队列消息积压量;rabbitmq-plugins enable rabbitmq_management开启Web管理界面,直观监控neutron虚拟主机下的q-plugin,q-dhcp,q-l3等队列。
实操要点:必须创建专用虚拟主机/neutron(rabbitmqctl add_vhost /neutron)并授权:rabbitmqctl set_permissions -p /neutron 'neutron' '.*' '.*' '.*'若权限不足,Neutron Server日志会出现
ACCESS_REFUSED - Login was refused using authentication mechanism AMQPLAIN。选Pulsar(仅限进阶探索):
优势:天然支持多租户、分区Topic、精确一次语义。但OpenStack对Pulsar的支持始于Wallaby版本,需额外安装python-pulsar-client。配置/etc/neutron/neutron.conf:[oslo_messaging_pulsar] pulsar_client_service_url = pulsar://controller:6650 pulsar_client_topic = persistent://public/default/neutron-events pulsar_client_subscription_name = neutron-sub关键陷阱:Pulsar的
subscription_name必须全局唯一,若多个Neutron Server使用相同名称,消息会被轮询分发到不同Server,造成状态不一致。实训中建议用neutron-server-$(hostname)动态生成。
实操心得:无论选哪种,必须用
neutron-status upgrade check验证消息队列连通性。该命令会尝试发布/消费测试消息,比手动curl更贴近真实场景。
3.3 Linux内核参数调优:从/proc/sys到/etc/sysctl.conf的落地闭环
内核参数调优不是“改完就跑”,必须形成“配置→验证→压测→固化”闭环。以net.core.somaxconn为例:
- 临时生效:
echo 2048 > /proc/sys/net/core/somaxconn - 验证生效:
sysctl net.core.somaxconn应返回net.core.somaxconn = 2048 - 压测验证:用
ab -n 1000 -c 200 http://controller:9696/v2.0/networks模拟并发,观察ss -lnt | grep :9696的Recv-Q值是否始终为0(队列无积压) - 永久固化:在
/etc/sysctl.conf追加net.core.somaxconn = 2048,并执行sysctl -p
其他关键参数实操清单:
| 参数 | 默认值 | 实训推荐值 | 验证命令 | 调优原理 |
|---|---|---|---|---|
fs.file-max | 8192 | 65536 | cat /proc/sys/fs/file-max | Neutron Server+Agents+OVSDB共需>2000文件描述符 |
vm.swappiness | 60 | 1 | cat /proc/sys/vm/swappiness | 强制内核优先使用物理内存,避免OVSDB swap延迟 |
net.ipv4.ip_forward | 0 | 1 | sysctl net.ipv4.ip_forward | L3 Agent转发IP包必需,否则路由器无法工作 |
kernel.pid_max | 32768 | 65536 | cat /proc/sys/kernel/pid_max | 防止高并发下进程ID耗尽,影响Agent fork |
注意:
net.ipv4.ip_forward=1必须在所有网络节点(Controller+Compute)启用,否则虚拟机跨子网通信失败。这是比Neutron配置更底层的“开关”。
3.4lock path的生死逻辑:为什么它必须是本地高速存储
lock path在/etc/neutron/neutron.conf中配置为:
[oslo_concurrency] lock_path = /var/lib/neutron/locks这个路径绝非随意指定,它承载着Neutron多进程协作的原子性保障:
为什么不能是NFS?
NFS的open()系统调用不保证O_EXCL标志的原子性。当两个Neutron Server进程同时执行open("/nfs/locks/port-123", O_CREAT\|O_EXCL),NFS服务器可能返回相同文件描述符,导致双重写入冲突。实测中,NFS挂载的lock path会使端口绑定成功率从99.9%暴跌至60%。为什么必须预分配inodes?
每个锁文件占用1个inode。Neutron在高并发下每秒创建/删除数百个锁文件。若/var/lib/neutron分区inodes耗尽(df -i显示100%),touch /var/lib/neutron/locks/test会报No space left on device——注意,这不是磁盘空间满,而是inode耗尽!解决方案:创建独立分区/var/lib/neutron,格式化时指定-i 1024(每1024字节1个inode),或用mkfs.ext4 -N 1000000 /dev/sdb1预分配100万个inode。SELinux上下文修复:
在Enforcing模式下,/var/lib/neutron/locks默认上下文为system_u:object_r:var_lib_t:s0,而Neutron进程需要neutron_var_lib_t。必须执行:semanage fcontext -a -t neutron_var_lib_t "/var/lib/neutron/locks(/.*)?" restorecon -Rv /var/lib/neutron/locks否则
setroubleshoot日志会记录avc: denied { write } for comm="neutron-server"。
4. 实操过程与核心环节实现:从零开始构建可验证的Neutron服务
4.1 环境初始化:绕过所有“默认陷阱”的10分钟准备
在开始安装前,必须执行以下初始化步骤,跳过则后续90%问题源于此:
时间同步强制校准:
# 所有节点执行 systemctl stop chronyd ntpdate controller # 假设controller为时间源 systemctl start chronyd timedatectl set-ntp true为什么?Keystone token有效期基于UTC时间,若节点时间偏差>1分钟,token校验必失败。
timedatectl status必须显示System clock synchronized: yes。防火墙精准放行:
# Controller节点 firewall-cmd --permanent --add-port={9696,5672,11211,5000}/tcp firewall-cmd --reload # Compute节点(仅需OVS端口) firewall-cmd --permanent --add-port=6640/tcp # OVSDB manager端口 firewall-cmd --reload注意:
5672是RabbitMQ客户端端口,6640是OVSDB端口,漏掉任一端口,Agent无法注册。创建专用数据库与用户:
mysql -u root -p CREATE DATABASE neutron; GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' \ IDENTIFIED BY 'NEUTRON_DBPASS'; GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' \ IDENTIFIED BY 'NEUTRON_DBPASS'; FLUSH PRIVILEGES;密码
NEUTRON_DBPASS必须与/etc/neutron/neutron.conf中connection = mysql+pymysql://neutron:NEUTRON_DBPASS@controller/neutron完全一致,大小写敏感。
4.2 Neutron Server部署:四步验证法确保核心服务就绪
部署不是yum install后systemctl start,而是分四步逐层验证:
第一步:数据库迁移验证
su -s /bin/bash neutron -c "neutron-db-manage --config-file /etc/neutron/neutron.conf \ --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head"成功标志:输出末尾显示INFO [alembic.runtime.migration] Context impl MySQLImpl.且无ERROR。若报Table 'neutron.ml2_vlan_allocations' doesn't exist,说明迁移未执行。
第二步:服务注册验证
openstack user create --domain default --password-prompt neutron openstack role add --project service --user neutron admin openstack service create --name neutron \ --description "OpenStack Networking" network openstack endpoint create --region RegionOne \ network public http://controller:9696 openstack endpoint create --region RegionOne \ network internal http://controller:9696 openstack endpoint create --region RegionOne \ network admin http://controller:9696验证:openstack endpoint list | grep neutron应显示三条endpoint,URL均为http://controller:9696。
第三步:配置文件语法验证
# 检查neutron.conf语法 python -m py_compile /etc/neutron/neutron.conf # 检查ml2_conf.ini语法 python -m py_compile /etc/neutron/plugins/ml2/ml2_conf.ini若报SyntaxError,说明配置文件有非法字符(如Windows换行符\r\n),用dos2unix转换。
第四步:服务启动与端口监听验证
systemctl enable neutron-server.service systemctl start neutron-server.service # 验证9696端口监听 ss -tlnp | grep :9696 # 应显示neutron-server进程 # 验证服务健康 curl -H "X-Auth-Token: $ADMIN_TOKEN" http://controller:9696/v2.0/networks
$ADMIN_TOKEN通过openstack token issue -f value -c id获取。若返回{"networks":[]},说明服务已就绪;若返回{"NeutronError":{...}},检查/var/log/neutron/server.log中ERROR行。
4.3 Agent部署与注册:让网络能力真正落地到物理节点
Neutron Server只是大脑,Agent才是四肢。必须在Controller和Compute节点分别部署:
Controller节点部署L3/DHCP/Metadata Agent:
编辑/etc/neutron/l3_agent.ini:[DEFAULT] interface_driver = openvswitch external_network_bridge = # 留空,由ovs-vsctl自动创建br-ex [ovs] integration_bridge = br-int启动服务:
systemctl enable neutron-l3-agent.service systemctl start neutron-l3-agent.serviceCompute节点部署Open vSwitch Agent:
编辑/etc/neutron/plugins/ml2/openvswitch_agent.ini:[ovs] local_ip = 10.0.0.31 # Compute节点管理IP(用于VXLAN隧道) bridge_mappings = provider:br-provider # 映射物理网卡 [agent] tunnel_types = vxlan l2_population = true # 启用L2 population优化ARP泛洪创建OVS网桥:
ovs-vsctl add-br br-int ovs-vsctl add-br br-provider ovs-vsctl add-port br-provider eth1 # eth1为物理网卡
Agent注册验证黄金标准:
openstack network agent list输出中必须包含:
neutron-openvswitch-agent(Compute节点,状态UP)neutron-dhcp-agent(Controller节点,状态UP)neutron-l3-agent(Controller节点,状态UP)neutron-metadata-agent(Controller节点,状态UP)
若某Agent状态为DOWN,立即检查:
systemctl status neutron-*-agent查看服务状态journalctl -u neutron-*-agent -n 50 --no-pager查看最后50行日志ss -tlnp | grep :9696确认Server端口监听正常
实操心得:Agent注册失败90%源于
local_ip配置错误。local_ip必须是Compute节点上用于VXLAN隧道的IP(通常是管理网络IP),且该IP必须能被Controller节点ping通。用ip addr show确认IP存在,用ping -c 3 controller测试连通性。
4.4 网络功能端到端验证:用真实业务流检验系统健壮性
配置完成不等于可用,必须用真实业务流验证:
创建提供者网络(Provider Network):
openstack network create --share --provider-physical-network provider \ --provider-network-type flat provider-net openstack subnet create --network provider-net \ --allocation-pool start=10.0.0.100,end=10.0.0.200 \ --dns-nameserver 8.8.8.8 --gateway 10.0.0.1 \ provider-subnet --subnet-range 10.0.0.0/24验证:
ip netns exec qdhcp-$(openstack network list | grep provider-net | awk '{print $2}') ip a应看到10.0.0.1/24。创建租户网络(Self-Service Network):
openstack network create selfservice-net openstack subnet create --network selfservice-net \ --dns-nameserver 8.8.8.8 --gateway 172.16.1.1 \ selfservice-subnet --subnet-range 172.16.1.0/24 openstack router create selfservice-router openstack router add subnet selfservice-router selfservice-subnet openstack router set --external-gateway provider-net selfservice-router验证:
ip netns exec qrouter-$(openstack router list | grep selfservice-router | awk '{print $2}') ip r应包含default via 10.0.0.1 dev qg-xxxx。启动虚拟机并验证网络:
openstack server create --image cirros --flavor m1.tiny \ --nic net-id=$(openstack network list | grep selfservice-net | awk '{print $2}') \ --security-group default test-vm登录虚拟机:
openstack console url show test-vm,执行:ping -c 3 10.0.0.1 # 测试到网关 ping -c 3 8.8.8.8 # 测试外网连通性成功标志:全部ping通,且
ip a显示172.16.1.x/24地址。
注意:若虚拟机无法获取IP,检查
/var/log/neutron/dhcp-agent.log中是否有dnsmasq启动失败记录;若无法访问外网,检查/var/log/neutron/l3-agent.log中qrouter命名空间路由表是否正确。
5. 常见问题与排查技巧实录:来自127次故障现场的血泪总结
5.1 “Connection refused to 127.0.0.1:9696” —— 表象是端口不通,根因在认证链断裂
这是实训中最高频报错,90%学员第一反应是firewall-cmd没开9696端口。但真实根因往往更深:
排查路径1:Keystone token校验失败
查/var/log/neutron/server.log,搜索keystone,若出现:ERROR neutron.api.v2.resource Traceback ... ConnectionRefusedError: [Errno 111] Connection refused
则说明Neutron Server调用Keystone校验token时被拒绝。执行:curl -v http://controller:5000/v3 # 应返回HTTP 300重定向 echo $ADMIN_TOKEN | xargs -I{} curl -H "X-Auth-Token: {}" http://controller:5000/v3/auth/tokens/validate若返回
{"error": {"code": 401, "title": "Unauthorized"}},证明token无效,需重新openstack token issue。排查路径2:Neutron Server未监听IPv4
ss -tlnp | grep :9696若只显示:::9696(IPv6),说明配置了bind_host = ::。编辑/etc/neutron/neutron.conf:[DEFAULT] bind_host = 0.0.0.0 # 强制监听IPv4排查路径3:SELinux阻止网络连接
ausearch -m avc -ts recent | grep neutron若出现avc: denied { name_connect } for comm="neutron-server" name="9696",执行:setsebool -P neutron_can_network on
5.2 “Port binding failed” —— 锁竞争、内核参数、OVS状态的三重绞杀
端口状态卡在DOWN或BUILD,日志中反复出现Failed to bind port:
锁路径争用:
ls -l /var/lib/neutron/locks/若文件数>1000且持续增长,说明锁未释放。执行:find /var/lib/neutron/locks/ -type f -mmin +5 -delete # 清理5分钟前的锁文件 systemctl restart neutron-serverOVSDB连接超时:
ovs-vsctl show若卡住或返回unable to connect to ovsdb,检查:systemctl status openvswitch ovs-appctl -t /var/run/openvswitch/db.sock exit # 强制重启OVSDB systemctl restart openvswitch内核参数
net.core.somaxconn不足:ss -lnt | grep :9696若Recv-Q值>0,证明连接队列积压。立即执行:echo 2048 > /proc/sys/net/core/somaxconn sysctl -p
5.3 DHCP Agent不分配IP —— inotify失效、dnsmasq配置、租约文件的隐秘战场
虚拟机启动后ip a无IP,/var/log/neutron/dhcp-agent.log无错误:
inotify句柄耗尽:
cat /proc/sys/fs/inotify/max_user_watches若<524288,执行:echo 524288 > /proc/sys/fs/inotify/max_user_watches sysctl -p systemctl restart neutron-dhcp-agentdnsmasq配置错误:
ps aux | grep dnsmasq查看进程参数,若无--dhcp-hostsfile=/var/lib/neutron/dhcp/*/host,说明ML2配置中enable_isolated_metadata = true未启用。编辑/etc/neutron/dhcp_agent.ini:[DEFAULT] enable_isolated_metadata = true租约文件权限错误:
ls -l /var/lib/neutron/dhcp/*/leases若属主不是neutron,执行:chown -R neutron:neutron /var/lib/neutron/dhcp/ systemctl restart neutron-dhcp-agent
5.4 L3 Agent无法路由 —— ARP缓存、iptables规则、命名空间路由的立体排查
虚拟机可获取IP但无法访问外网,ping 10.0.0.1失败:
ARP缓存污染:
ip netns exec qrouter-xxx arp -a查看网关MAC,若为incomplete,执行:ip netns exec qrouter-xxx arping -c 3 -I qr-xxx 10.0.0.1iptables DROP规则拦截:
ip netns exec qrouter-xxx iptables -L FORWARD -n查看neutron-l3-agent-FORWARD链,若DROP规则在ACCEPT之前,说明enable_security_group = false未配置。编辑/etc/neutron/l3_agent.ini:[DEFAULT] enable_security_group = false # L3 Agent不