
做网络这行DHCP大概是每个人都在用、又经常被忽视的东西。上班打开电脑能直接上网手机连Wi-Fi不用填IP背后都是DHCP在干活。但真让你从头搭一套DHCP从原理讲到中继从全局讲到接口再把手动配置的细节撸一遍不少人会卡壳。这篇文章我把这事整个捋一遍适合刚入行的网络工程师也适合被各种DHCP问题折腾过的运维。1. DHCP这东西到底解决什么问题1.1 没有DHCP的日子想象一下公司有500台电脑如果没有DHCP网络管理员要手动给每台电脑填IP地址、子网掩码、网关、DNS。这还不算完过半年要改一次网段你就得半夜去机房把所有设备重配一遍谁落下一台谁就上不了网。更恐怖的是手滑把两台机器填成同一个IP其中一台就会反复提示“地址冲突”内网瞬间鸡飞狗跳。DHCP全称是Dynamic Host Configuration Protocol动态主机配置协议它做的事情很简单把IP地址、子网掩码、网关、DNS这些网络参数通过网络自动发给设备。设备插上网线、连上Wi-Fi什么都不用管地址就自己到手了。你不需要知道服务器在哪也不需要理解广播和子网的区别这就是DHCP的价值——把“手工填表”变成“自动发牌”。1.2 DHCP的核心交互不是一步到位的很多新手以为DHCP就是“设备喊一嗓子服务器回一句”这么简单实际过程比这要严谨得多。完整的IP地址分配过程分四步统称DORA过程Discover发现客户端不知道DHCP服务器在哪所以它向整个广播域的广播地址255.255.255.255发一个Discover报文相当于“有人吗我需要一个IP”。Offer提供服务器收到Discover后在地址池里挑一个可用IP通过Offer报文回复客户端相当于“我这里有地址你要不要”。Request请求客户端可能同时收到多个Offer它会选择其中一个一般是最先收到的然后广播一条Request报文告诉所有服务器“我要用某台服务器的地址”。Ack确认被选中的服务器收到Request后返回Ack报文确认这个地址租给你。客户端这才正式把IP配置到网卡上。这个过程中有个关键点Request是广播发出去的原因是让其他没被选中的服务器也能听到“我被淘汰了”它们就可以把预留的地址重新放回地址池。这个机制避免了一次分配后其他地址被白白扣住的情况。1.3 租期和续租为什么重要DHCP分配的IP不是永久的而是有一个租期默认通常是24小时。客户端在租期过去一半左右也就是12小时时会直接向当初分配的服务器单播Request请求续租。如果服务器没理它客户端继续用到租期还剩12.5%时也就是大概21小时左右它改成广播Request希望任何服务器都能回应如果还是没人理租期到了就放弃这个IP重新走一遍DORA。我遇到过不少“为什么设备过一阵子就断网”的案例排查到最后全是租期问题。比如服务器时间漂移、客户端休眠太久错过了续租窗口或者地址池里的IP被其他设备抢走这些都会导致租约到期后拿不回原来的地址。所以做网络的人一定要把租期当成一个正式参数去设计而不是不管它。2. 两种主流部署模式全局与接口2.1 全局地址池与接口地址池到底差在哪部署DHCP的时候交换机或路由器上有两种建地址池的方式全局地址池和接口地址池。名字看上去差不多用起来却有本质区别。全局地址池是在设备上创建一个独立命名的地址池比如叫pool_vlan10里面定义网段、网关、DNS、租期。它本身不绑定任何端口或VLAN需要通过配置把某个VLAN或某个接口的DHCP服务“关联”到这个池子上。一个全局地址池可以同时服务于多个接口也可以只服务一个。接口地址池则是直接“长在”某个三层接口或VLANIF接口下的。只要接口上启用了DHCP这个接口就会自动拿自己接口的IP地址所在网段来分配地址不需要额外指定网段网关就是接口的IP。接口地址池的服务范围天然就是这一个接口下的用户逻辑非常清楚。这两者的核心区别在于“池子和接口的绑定关系”。全局池是先造池子再手动挂接口接口池是池子跟着接口走接口在哪池子就在哪。理解了这个你看到命令就能明白设计者的意图。2.2 怎么选看组网不看心情我在实际项目里总结了一个简单粗暴的选择逻辑如果一个接口下只有一个网段地址规划简单优先用接口地址池。配置最少少一个环节就少一个出错的可能。如果一个网段需要由多个不同的接口或设备来分配比如同一个VLAN在三台交换机上做VLANIF冗余的场景优先用全局地址池因为全局池可以同时被多个接口引用。如果客户端跨网段访问DHCP服务器在核心层下边交换机只是做二层转发那就几乎所有场景都是全局池加DHCP中继的组合。说白了接口池适合小规模、单点接入全局池适合规模化、集中式管理。别一上来就套模板先问清楚网络拓扑是收敛型还是扁平型再决定用哪种。2.3 实例华为交换机全局DHCP配置以华为S交换机为例全局池的配置步骤其实不多但每一步都有讲究。先看一下基本命令# 开启DHCP服务这步容易漏全局不打开后边配了池子也不生效 dhcp enable # 创建一个全局地址池 ip pool pool_vlan10 network 10.10.10.0 mask 255.255.255.0 gateway-list 10.10.10.1 dns-list 114.114.114.114 8.8.8.8 lease day 1 hour 0 minute 0 excluded-ip-address 10.10.10.1 10.10.10.50 # 进入VLANIF接口把DHCP关联到这个池子 interface Vlanif 10 ip address 10.10.10.1 255.255.255.255.0 dhcp select global注意几个细节gateway-list要和VLANIF接口的IP一致否则客户端拿到地址后网关不通会上不了网。dns-list要写运营商或内网能用的DNS别只写一个。excluded-ip-address把网关、服务器等静态设备占用的地址排掉避免DHCP把地址发给了不该发的设备。dhcp select global是接口侧命令意思是“这个接口用全局地址池分配”。这句不敲客户端就收不到地址。2.4 实例基于接口的DHCP配置与适用场景接口池配置更短华为设备上典型配置是这样interface Vlanif 20 ip address 192.168.20.1 255.255.255.0 dhcp select interface dns-list 114.114.114.114 lease day 1只要接口配了IP并敲了dhcp select interface它就自动拿192.168.20.0/24这个网段做地址池网关就是192.168.20.1。你甚至不需要写network和gateway因为它们都直接从接口IP推导。接口池的好处在配置量上体现得淋漓尽致。我做过一个小型办公区改造三栋楼各一个VLAN每栋楼单独分网段设备只做三层转发。那时候就是用接口池每个VLANIF三两行命令就搞定后续排查也特别方便看到接口就想到池子。但接口池也有个坑如果一个VLANIF接口上需要排除多个静态地址你得在接口下用dhcp exclude-address一条条排除不如全局池用excluded-ip-address一下排一个范围来得方便。如果排除地址很多接口池的配置会显得零碎。3. 跨网段分配DHCP中继3.1 为什么必须中继DHCP的Discover报文是广播而广播默认不会被路由器转发到其他网段。如果公司员工在VLAN 10DHCP服务器却在VLAN 100的服务器区中间隔着一层三层交换机客户端的广播根本到不了服务器。你说那我干脆每个VLAN都配一台DHCP服务器行是行但服务器太多管理成本高IP地址池也难统一。解决办法就是DHCP中继。中继部署在三层设备上它把广播的Discover报文听下来改成单播报文发给指定的DHCP服务器再把服务器回给你的Offer单播转成广播/单播发给客户端。这样客户端完全感知不到中间有转发过程它以为服务器就在自己的网段里。用大白话说中继就是一个“传话筒”让广播请求能跨过VLAN边界送给真正的服务器再把服务器的回复原路带回来。3.2 中继工作原理只是改个广播包吗很多人以为中继就是简单的转发实际上它干的事情精确得多。当交换机接口收到广播的Discover时中继功能会做三件事在报文转成单播发给DHCP服务器时把报文里的giaddr网关IP地址字段填成自己接口的IP也就是客户端所在网段的网关地址。这个字段至关重要服务器靠它才能判断应该从哪个地址池给客户端分IP。服务器看到giaddr10.10.10.1就会在地址池里找包含10.10.10.0/24的池子然后从里面挑地址通过Offer报文回复给中继。中继收到Offer后会根据giaddr信息把回复转给对应的客户端并填上目的MAC。所以中继并不是把广播原样转发而是把你这个转发者的身份“签名”在报文里。giaddr是服务器选池子的唯一依据如果中继忘了填或填错服务器就只能按默认池子发地址客户端就会拿到完全对不上的网关这种故障特别隐蔽。3.3 实战配置交换机做中继华为交换机做中继全局开启DHCP后在VLANIF接口下配一条命令就行dhcp enable interface Vlanif 10 ip address 10.10.10.1 255.255.255.0 dhcp select relay dhcp relay server-ip 10.100.1.10这里dhcp select relay表示接口工作在DHCP中继模式dhcp relay server-ip指定真正的DHCP服务器地址。如果有备机还可以配多个server-ip设备依次尝试。需要注意的是接口切换到relay模式后就不会再使用本机地址池了而是把所有DHCP请求交给外部服务器。如果你想在核心交换机上既做中继又用本机池子给另一个VLAN服务那就要区分清楚每个接口的模式有的接口用dhcp select global有的接口用dhcp select relay两者互不影响。3.4 一个DHCP服务器发多个网段的坑热搜词里有一条“一个DHCP服务器发几个网段”这是很典型的集中式部署场景。一个服务器确实可以同时给多个网段发地址关键在于服务器如何区分客户端属于哪个网段。基于接口的DHCP不需要你额外声明服务器收到中继请求时看giaddr找对应的接口地址池就行。基于全局池你需要在服务器上为每个网段单独建一个全局地址池并且确保池子的network和对应网段匹配。比如VLAN10对应池pool_10VLAN20对应pool_20各有各的网关和DNS这样中继过来时服务器会按giaddr自动匹配正确的池子。实际操作中我见过很多“跨网段拿到错误IP”的情况排查后发现是地址池的gateway-list写错了或者两个池子的network有重叠服务器匹配到了错误的池子。所以建立一个清晰的命名规范很重要。我习惯用“pool_vlan号”命名一眼就能看出这个池子服务哪个VLAN。4. 交换机直接做DHCP服务器部署实操4.1 交换机做服务器的限制不是所有交换机都能当DHCP服务器。盒式接入交换机大多只支持DHCP snooping和中继只有中高端框式交换机或者支持DHCP Server功能的盒式设备才行。即使支持也要考虑设备CPU性能。DHCP分配的报文虽然不大但如果一个交换机要处理上千客户端的Discover、Offer、Request、Ack对CPU还是有一定压力的。做过大规模园区网络的人应该都懂DHCP服务器尽量放在服务器或者核心设备上低端接入交换机老老实实做二层透传就好了。4.2 配置一个完整可用的地址池我们在华为交换机上用全局池做一个完整配置顺便把地址池管理的细节交代清楚。dhcp enable ip pool pool_office network 192.168.50.0 mask 255.255.255.0 gateway-list 192.168.50.1 dns-list 192.168.50.10 114.114.114.114 lease day 2 hour 0 minute 0 excluded-ip-address 192.168.50.1 192.168.50.20 static-bind ip-address 192.168.50.100 mac-address 00e0-fc12-3456这段配置里有个static-bind它为特定MAC地址保留固定的IP适合打印机、安防摄像头这类需要固定IP但不想手动配置的设备。它和excluded-ip-address不冲突排除的地址段内不能用DHCP分配给普通客户端但static-bind可以直接指定排除段内的地址因为它本质上是静态绑定不参与动态分配。地址池建好后需要一个关联动作。如果只服务一个VLAN可以在VLANIF下用dhcp select global关联如果需要多个VLAN都用这个池子那就让每个VLANIF都执行dhcp select global。注意同一个全局池可以被多个接口引用但要注意地址池容量够不够。比如地址池只有254个地址你让两个VLAN同时引用实际能分配的地址总数不会增加只会导致其中一个或两个网段地址都不够用。4.3 地址池管理查看、改参数、排错地址池不是配完就不管的尤其是中大型网络你得知道如何查询、调整、回收地址。华为交换机上常用这些命令# 查看DHCP全局状态 display dhcp enable # 查看所有地址池概况 display ip pool # 查看某个地址池的详细使用情况 display ip pool name pool_office # 查看地址池中哪些IP被租出去了、租给谁 display ip pool name pool_office used # 查看接口与地址池的绑定关系 display dhcp server interface Vlanif 10其中最常用的是display ip pool name pool_office used它会列出每个已分配IP的MAC、客户端ID、租期和剩余时间。排查“某个IP不知道被谁占用”时这条命令比跑到服务器上翻日志还快。调整地址池参数时比如改租期长短、增加DNS直接在ip pool视图下修改即可已经分配的地址不会自动更新需要客户端重新续租或者强制释放后重新申请。批量释放时可以在用户视图执行reset ip pool name pool_office但这会把整个池子所有租约清空我一般只用在对业务影响可控的维护窗口内。4.4 内网已有物理DHCP服务器时交换机的正确姿势热搜里有句话叫“内网有物理DHCP服务器交换机如何配置”这个问题在真实环境里非常典型。很多公司已经有一台独立的DHCP服务器比如Windows Server或者Linux上跑的dnsmasq、isc-dhcp-server交换机只需要负责转发请求不需要开地址池。如果物理服务器和三层的VLANIF在同一个网段客户端和服务器二层可达交换机基本不用做什么只要保证DHCP广播能到达服务器所在VLAN就行。但多数情况是服务器在服务器区终端分布在各个业务VLAN中间隔着三层这时候交换机需要做两件事在各业务VLAN的VLANIF接口下启用DHCP中继指向物理服务器的IP。确认物理服务器上已经建好对应网段的地址池并且交换机上的中继接口IP能和服务器路由互通。这里最容易被忽略的是服务器上的防火墙。Windows Server自带的防火墙如果不开DHCP流量放行交换机即使中继做了服务器也会默默丢弃报文。我碰到过一个案例中继配置全对端口通就是分不到地址最后关了防火墙立刻就好。所以给服务器放行UDP 67/68端口这个动作要写进上线检查清单。5. 排查实录常见问题与避坑技巧5.1 拿不到地址的排查顺序客户端显示“正在获取IP地址”转几圈后拿不到了这是最经典的故障。很多同学上来就抓包其实应该按顺序快速定位。先看交换机接口是否upVLAN是否正确DHCP是否已经开启。再看客户端所在VLAN的VLANIF接口有没有启用DHCP功能display dhcp server interface。然后看地址池是否还有剩余地址很大概率是地址池写满了。接着看是否有排除地址遗漏导致网关地址被分配给别人。最后再抓包看Discover有没有到服务器服务器有没有回Offer。抓包时要注意客户端侧和服务器侧抓到的包是不同的因为中间有中继改动。我看到过有人拿着客户端侧收到的包就断定服务器没响应结果只是Offer在传输过程中被中继丢弃。所以出现跨网段问题时最好在三层交换机和服务器侧同时抓包对比报文。5.2 华为交换机查看DHCP配置的命令“华为交换机查看dhcp配置”是另一个高频需求。配合上面提到过的命令我再补充几条# 查看所有接口上的DHCP工作模式global/interface/relay display dhcp server interface # 查看中继配置 display dhcp relay interface Vlanif 10 # 查看DHCP报文收发统计看有没有丢弃 display dhcp statistics # 查看DHCP snooping表项如果开启 display dhcp snooping user binding alldisplay dhcp statistics能帮你快速判断是请求没到还是回复没到。如果Discover计数一直在涨但Offer计数为0说明服务器那边有问题或者中继没把包发给服务器如果Offer有但Ack没有多半是Reply路由不通。5.3 两台虚拟机用同一个DHCP服务器的设置细节很常见的实验场景电脑上用VMware或VirtualBox开两台虚拟机想让它们都从宿主机或者另一台虚拟机上的DHCP服务器获取地址。这里最常见的坑是虚拟网络模式选错。如果两台虚拟机要通过同一个DHCP服务器拿地址最好保证它们在同一张虚拟网卡对应的网络里比如都在VMnet8NAT模式或者都在VMnet1Host-only模式下。如果你把一台放在Host-only、一台放在NAT它们不在同一个广播域一个DHCP服务器即使能分配地址也覆盖不到两个网络。有些人在一台虚拟机上起DHCP服务另外两台接进来结果发现只有其中一部分能获取就是这个原因。另外如果虚拟机里装了DHCP服务宿主机有多个虚拟网卡DHCP服务默认会监听所有接口导致它可能给Host-only网卡和NAT网卡都发地址而你不是每个网卡都想要。这时候要把DHCP服务的监听地址监听到指定的虚拟网卡IP上同时关闭Windows防火墙的DHCP阻断否则虚拟机收不到地址。我建议把这些步骤写成一个checklist因为虚拟环境的问题经常不是网络原理而是“服务绑定错了网卡”。5.4 几个容易踩的坑第一地址池和VLANIF网关地址冲突。全局池如果不写gateway-list或者写了别的地址客户端的网关就会是空或者指向错误设备结果能拿到地址却上不了网。这比拿不到地址更坑因为表面看IP是正常的。第二DHCP服务与无类域间路由的地址池不匹配。有的地址池掩码写错比如实际规划是192.168.1.0/24地址池里却写了255.255.255.128这样地址池只会分配128个地址另一半直接“消失”排查起来很容易忽略。第三跨VLAN的中继地址写错。中继server-ip如果指向一个不可达的地址报文发了没人理经常被误认为服务器宕机。先用ping确认中继到服务器的网络是通的再谈后续配置。第四dhcp snooping的干扰。如果交换机同时开了DHCP snooping但没把中继接口或上联口设为信任口客户端发来的Discover报文会被误判为非法请求而被丢弃。这种问题往往是“前脚开了中继后脚忘了调snooping信任口”。第五客户端数量超过地址池容量。地址池有254个地址实际终端有300个表现就是一部分能分到一部分分不到而且分不到的时间随机。这种情况不完全是DHCP问题而是需要扩容地址段或者划分VLAN单纯调租期解决不了根本。最后再分享一个我自己的习惯每次上线DHCP前先在设备上清空一次租约确认无残留然后从客户端连续重启网卡三次看是否每次都能稳定拿到地址。这个简单动作能帮你把大部分配置问题挡在上线之前。如果后续还想扩展可以把DHCP地址池的告警阈值接上监控地址池用量超过80%就提醒你扩容而不是等用户投诉才去查display ip pool。