概述
Neutron dhcp實現了爲虛機提供動態分配IP的服務,dhcp功能由neutron-server和dhcp-agent配合實現。其中server負責接收請求並向agent發送網絡、子網、端口等數據;agent接收數據,創建、配置dhcp實例。社區的dhcp功能由dnsmasq軟件實現,即由該軟件充當dhcp server。
常用dhcp相關的配置
表1 neutron-server所使用的dhcp配置(/etc/neutron/neutron.conf)
配置項 | 用途 | 默認值 |
dhcp_lease_duration | IP租期,-1爲IP永久有效 | 86400 (24小時) |
dhcp_agent_notification | 是否向dhcp-agent發送消息 | true |
network_scheduler_driver | Dhcp-agent的調度算法 | neutron.scheduler.dhcp_agent_scheduler.ChanceScheduler |
dhcp_load_type | 調度dhcp-agent時的依據,一般使用WeightScheduler算法時使用的配置 | networks(number of networks hosted on the agent) |
allow_automatic_dhcp_failover | Dhcp down時,網絡時候重新調度 | true |
dhcp_agents_per_network | 爲網絡提供dhcp服務的dhcp-agent數量,通過冗餘的方式,爲一個網絡提供多個dhcp namespace | 1 |
表2 dhcp-agent使用的配置(/etc/neutron/ dhcp_agent.ini)
配置項 | 用途 | 默認值 |
dhcp_driver | 底層實現dhcp功能所用的驅動 | neutron.agent.linux.dhcp.Dnsmasq |
interface_driver | 爲dhcp提供二層接口的驅動 | neutron.agent.linux.interface.BridgeInterfaceDriver |
創建子網和dhcp調度
在創建子網的時候,用戶通過選擇dhcp功能,來決定是否爲網絡創建dhcp-server。
圖1 創建帶dhcp功能的子網
圖2展示了在Neutron-server中涉及創建子網、dhcp功能的類,主要有Controller類和Ml2plugin類。其中Controller類中包含了一個_plugin類,該類是Ml2plugin。Controller主要執行用戶發送的rest請求,對於創建二層資源的操作,一般會調用Ml2plugin的create_RESOURCE方法(RESOURCE有network、subnet、port等)。對於創建子網的請求,最終會調用ml2plugin的create_subnet函數。
圖2 neutron-server中與dhcp功能有關的類
如圖3展示了創建子網的流程,主要包括controller接受rest請求並調用ml2plugin的具體函數;ml2plugin對象操作數據庫,創建相關資源的數據;選擇一定數量的dhcp-agent,向它們發送subnet_create_end消息。
圖3 創建子網的過程
實現dhcp功能的時候,還涉及到dhcp-agent的調度問題,這是因爲在一套openstack系統中,爲了保證dhcp功能的可靠,需要部署多個dhcp-agent。Ml2plugin根據配置的dhcp_agents_per_network值和實際可用的dhcp-agents數量(數據庫中active的agent個數),確定能夠實現dhcp功能的agent個數(Min(dhcp_agents_per_network,active agents)),然後使用調度算法,決定最終在哪些dhcp agent啓動dhcp實例。常用的調度算法有:
ChanceScheduler:隨機選擇可用的agents。
WeightScheduler:選擇負載最少的agents。
Dhcp-agent創建Dhcp namespace的創建流程
Dhcp-agent接受到subnet_create_end消息,首先會向neutron-server請求子網所屬網絡的信息,然後創建qdhcp namespace並啓動dnsmasq進程。圖4展示了這一過程中涉及到的類,圖5展示了這一過程的主要調用流程。
圖4 dhcp-agent類結構
圖5 dhcp-agent創建dnsmasq的流程
Dhcp-agent根據dhcp_driver配置,加載實現dhcp-server功能的驅動;根據interface_driver的配置,加載爲dhcp提供二層服務的驅動,這裏我們使用ovsinterfacedriver,它會執行ovs命令,配置dhcp namespace的tap端口。
底層的dhcp實現
neutron的dhcp功能藉助於dnsmasq軟件和networknamespace技術。
Dnsmasq是一個開源的輕量級DNS和DHCP服務器,針對小型局域網設計,資源佔用低,易於配置。
Network namespace主要實現了網絡資源的隔離,網絡資源包括網絡設備、IPv4和IPv6協議棧、IP路由表、防火牆、socket等。給一個或多個進程私有的網絡資源。
使用namespace實現dhcp的原因是,使一個dnsmasq進程獨立的爲一個租戶網絡提供dhcp服務。
Dhcp-agent收到neutron-server的消息後,會構建一個名爲qdhcp-networkid的namespace,並使用veth pair將其和ovs br-int網橋相連。圖6展示了一個dhcpnamespace。
圖6 dhcp namespace
最後在namespace中啓動一個dnsmasq程序:
ip netns exec qdhcp-3d722176-f319-4afe-b26b-025fead744a1dnsmqsqdnsmasq --no-hosts --no-resolv --strict-order --bind-interfaces--interface=tap523e7156-00 --except-interface=lo--pid-file=/var/lib/neutron/dhcp/3d722176-f319-4afe-b26b-025fead744a1/pid --dhcp-hostsfile=/var/lib/neutron/dhcp/3d722176-f319-4afe-b26b-025fead744a1/host--addn-hosts=/var/lib/neutron/dhcp/3d722176-f319-4afe-b26b-025fead744a1/addn_hosts--dhcp-optsfile=/var/lib/neutron/dhcp/3d722176-f319-4afe-b26b-025fead744a1/opts--dhcp-leasefile=/var/lib/neutron/dhcp/3d722176-f319-4afe-b26b-025fead744a1/leases--dhcp-range=set:tag1,10.190.91.0,static,infinite --dhcp-lease-max=256--conf-file=/etc/neutron/dnsmasq-neutron.conf
其中bind-interfaces指dnsmasq進程監聽的端口,進程可以通過該端口接受和發送dhcp報文。host文件包含了虛機的ip和mac對應信息,爲虛機dhcp請求提供了依據。圖7展示了一個host文件的內容。
圖7 dnsmasq host文件
圖8展示了一個dnsmasq進程。
圖8 dnsmasq進程
當新建port時,dhcp-agent會在相應的dnsmasq host文件中增加一條記錄,並給dnsmasq進程發送一個HUP信號,dnsmasq會重新讀取host文件。當VM發出DHCP-request後,dnsmasq根據host文件的內容爲VM分配IP地址。