生活随笔
收集整理的這篇文章主要介紹了
neutron-metering解读分析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
metering簡介
metering是l3層流量監控的插件,通過統計iptables規則的流量計數達到流量監控的目的。
與iptables類似,創建metering label即創建一條自定義鏈,這條鏈被Forward表引用,針對某個ip創建metering label rule則生成相應的規則,進出方向的流量會留下它的痕跡。
metering配置
路徑/etc/neutron,新增配置文件metering_agent.ini
interface_driver
=neutron.agent.linux.interface.OVSInterfaceDriver
driver
= neutron.services.metering.drivers.iptables.iptables_driver.IptablesMeteringDriver
文件/etc/neutron/neutron.conf,新增services_plugins
metering_agnet是一個單獨的進程,負責與qrouter交互,創建iptables規則,執行命令:
/var/lib/openstack/bin/python /var/lib/openstack/bin/neutron-metering-agent --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/metering_agent.ini
metering_plugin
API路徑在neutron_lib/api/definitionsneutron-server接收請求后交給plugin處理,路徑neutron/services/metering/metering_plugin.pyMeteringPlugin類存在以下方法:
def start_rpc_listeners
def create_metering_label
def delete_metering_label
def create_metering_label_rule
def delete_metering_label_rule
這些方法都按照一定的格式執行,先調用metering_plugin操作db,在通過rpc發送消息讓agent端處理
def create_metering_label(self
, context
, metering_label
):label
= super(MeteringPlugin
, self
).create_metering_label
(context
, metering_label
)data
= self
.get_sync_data_metering
(context
)self
.meter_rpc
.add_metering_label
(context
, data
)return label
以create_metering_label 為例,MeteringPlugin調用父類metering_db.MeteringDbMixin的方法create_metering_label 創建label的db,get_sync_data_metering 調用MeteringDbMixin的方法同步router數據,拿到的data是一個字典,對象是routers,每個router都帶上了_metering_label 的標簽add_metering_label 則通過rpc消息隊列發送給metering_agent端,讓agent端執行實際的操作,rpc的接口定義在neutron/api/rpc/agentnotifiers/metering_rpc_agent_api.py
metering_agent
agent端可以分為三塊主要內容:
同步router、labels,labelrules的內容,進程拉起時會同步一次qrouter iptables的自定義鏈和規則,往后每隔一段時間會再次獲取routers的內容,更新緩存
def _sync_router_namespaces(self
, context
, routers
):LOG
.debug
("Sync router namespaces")return self
._invoke_driver
(context
, routers
, 'sync_router_namespaces')
接受來自metering_plugin的請求,創建/刪除labels、rules
metering_agent調用driver獲取iptables的流量監控信息,并發送給上層應用。原版的openstack通過ceilometer獲取metering收集的流量信息并對外展示,但各大廠商可以設計自己的流量監控方案,例如通過消息隊列kafka、rabbitmq等將監控信息轉發到自己的流量監控平臺上
metering_agent的代碼都遵循同一個范式,即收到上層的消息后,經過處理或者不處理,去調用_invoke_driver 的函數,這其實是個調用driver的通用方法,用戶可以定義自己的driver,并在配置文件中指定,agent拉起時會自動加載相應的driver,而_invoke_driver 的調用則會拉起對應driver中的方法
def _invoke_driver(self
, context
, meterings
, func_name
):try:return getattr(self
.metering_driver
, func_name
)(context
, meterings
)except AttributeError
:LOG
.exception
("Driver %(driver)s does not implement %(func)s",{'driver': self
.conf
.driver
,'func': func_name
})except RuntimeError
:LOG
.exception
("Driver %(driver)s:%(func)s runtime error",{'driver': self
.conf
.driver
,'func': func_name
})
self.metering_driver 是已經加載好的驅動,通過獲取對應的func_name 映射到相應的函數體,并執行
metering driver
neutron(R版本)中暫時只實現了iptables driver,路徑在neutron/services/metering/drivers/iptablesneutron metering其實存在第二種noop driver,以我淺薄的認知目前還不知道noop具體是個啥玩意,源碼中也沒有實現具體的方法,但是給我們新增driver打了個樣以添加rule為例,_add_metering_label_rule 直接調用方法_process_metering_rule_action
def _process_metering_rule_action(self
, router
, action
):rm
= self
.routers
.get
(router
['id'])if not rm
:returnext_dev
, ext_snat_dev
= self
.get_external_device_names
(rm
)for (im
, dev
) in [(rm
.iptables_manager
, ext_dev
),(rm
.snat_iptables_manager
, ext_snat_dev
)]:if im
and dev
:self
._process_metering_rule_action_based_on_ns
(router
, action
, dev
, im
)
get_external_device_names 是獲取所需監控的qrouter內的網絡設備,這一點需要注意,legacy router、ha router以及dvr router中相應的qrouter網關前綴未必是相同的,雖然源碼中對qrouter內的網絡設備設置唯一前綴“qr-”,但這一點的確應該注意。如果網絡設備前綴并非都是“qr-”,可能會導致rule無法收集到監控數據dvr router與ha router應該分別區分獲取到網絡設備名字后,調用_process_metering_rule_action_based_on_ns 方法,首先分析router帶下來的_metering_labels 字段,分析label是否發生變化,如果發生變化則同步一次,并更新緩存,如果rule字段存在,則調用具體的方法更新rule
def _add_rule_to_chain(self
, ext_dev
, rule
, im
,label_chain
, rules_chain
):ipt_rule
= self
._prepare_rule
(ext_dev
, rule
, label_chain
)if rule
['excluded']:im
.ipv4
['filter'].add_rule
(rules_chain
, ipt_rule
,wrap
=False, top
=True)else:im
.ipv4
['filter'].add_rule
(rules_chain
, ipt_rule
,wrap
=False, top
=False)def _prepare_rule(self
, ext_dev
, rule
, label_chain
):remote_ip
= rule
['remote_ip_prefix']if rule
['direction'] == 'egress':dir_opt
= '-s %s -o %s' % (remote_ip
, ext_dev
)else:dir_opt
= '-d %s -i %s' % (remote_ip
, ext_dev
)if rule
['excluded']:ipt_rule
= '%s -j RETURN' % dir_opt
else:ipt_rule
= '%s -j %s' % (dir_opt
, label_chain
)return ipt_rule
新增規則是以字符串的方式生成,兩個方向:出方向egress,入方向ingress,不同的方向生成的規則也有差異,最終調用neutron/agent/linux/iptables_mamager.py執行命令行
收集數據的方法是get_traffic_counters ,這個方法調用iptables_manager類的get_traffic_counters 執行以下命令
sudo ip netns
exec qrouter-namespace-id iptables -t filter -L chain-name -n -v -x -w xlock_wait_time -Z
get_traffic_counters 通過參數zero開啟每次計數后歸零的功能,因此metering生成的規則流量計數會定時清零
總結
以上是生活随笔為你收集整理的neutron-metering解读分析的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。