本文為您介紹了網易公司基于 OpenStack 開發的一套云計算管理平臺,以及在開發、運營、維護過程中遇到的問題和經驗分享。網易作為大型互聯網公司,IT 基礎架構需要支撐包括生產、開發、測試、管理等多方面的需要,而且需求和請求的變化幾乎每天都存在,這就需要內部的 IT 基礎架構能夠足夠靈活和健壯來滿足各部門和團隊的實際需要。網易私有云平臺團隊也希望通過本文和廣大的 OpenStack 使用者進行一個交流,分享他們在實際項目中收獲的成果。
OpenStack 簡介
OpenStack 是一個開源的 IaaS 實現,它由一些相互關聯的子項目組成,主要包括計算、存儲、網絡。由于以 Apache 協議發布,自 2010 年項目成立以來,超過 200 個公司加入了 OpenStack 項目,其中包括 AT&T、AMD、Cisco、Dell、IBM、Intel、Red Hat 等。目前參與 OpenStack 項目的開發人員有 17,000+,來自 139 個國家,這一數字還在不斷增長中。
OpenStack 兼容一部分 AWS 接口,同時為了提供更強大的功能,也提供 OpenStack 風格的接口(RESTFul API)。和其他開源 IaaS 相比,架構上松耦合、高可擴展、分布式、純 Python 實現,以及友好活躍的社區使其大受歡迎,每半年一次的開發峰會也吸引了來自全世界的開發者、供應商和客戶。
OpenStack 的主要子項目有:
Compute(Nova)提供計算虛擬化服務,是 OpenStack 的核心,負責管理和創建虛擬機。它被設計成方便擴展,支持多種虛擬化技術,并且可以部署在標準硬件上。
Object Storage(Swift)提供對象存儲服務,是一個分布式,可擴展,多副本的存儲系統。
Block Storage(Cinder),提供塊存儲服務,為 OpenStack 的虛擬機提供持久的塊級存儲設備。支持多種存儲后端,包括 Ceph,EMC 等。
Networking(Neutron)提供網絡虛擬化服務,是一個可拔插,可擴展,API 驅動的服務。
Dashboard 提供了一個圖形控制臺服務,讓用戶方便地訪問,使用和維護 OpenStack 中的資源。
Image(glance)提供鏡像服務,它旨在發現,注冊和交付虛擬機磁盤和鏡像。支持多種后端。
Telemetry(Ceilometer)提供用量統計服務,通過它可以方便地實現 OpenStack 計費功能。
Orchestration(Heat)整合了 OpenStack 中的眾多組件,類似 AWS 的 CloudFormation,讓用戶能夠通過模板來管理資源。
Database(Trove)基于 OpenStack 構建的 database-as-a-service。
網易私有云使用了 Nova、Glance、Keystone、Neutron 這 4 個組件。
網易私有云平臺概況
圖 1.網易私有云架構
網易私有云平臺由網易杭州研究院負責研發,主要提供基礎設施資源、數據存儲處理、應用開發部署、運維管理等功能以滿足公司產品測試/上線的需求。
圖 1 展示了網易私有云平臺的整體架構。整個私有云平臺可分為三大類服務:核心基礎設施服務(IaaS)、基礎平臺服務(PaaS)以及運維管理支撐服務,目前一共包括了:云主機(虛擬機)、云網絡、云硬盤、對象存儲、對象緩存、關系型數據庫、分布式數據庫、全文檢索、消息隊列、視頻轉碼、負載均衡、容器引擎、云計費、云監控、管理平臺等 15 個服務。網易私有云平臺充分利用云計算開源的最新成果,我們基于 OpenStack 社區的 keystone、glance、nova、neutron 組件研發部署了云主機和云網絡服務。
為了與網易私有云平臺其他服務(云硬盤、云監控、云計費等)深度整合以及滿足公司產品使用和運維管理的特定需求,我們團隊在社區 OpenStack 版本的基礎上獨立研發了包括:云主機資源質量保障(計算、存儲、網絡 QoS)、鏡像分塊存儲、云主機心跳上報、flat-dhcp 模式下租戶內網隔離等 20 多個新功能。同時,我們團隊在日常運維 OpenStack 以及升級社區新版本中,也總結了一些部署、運維規范以及升級經驗。兩年多來,網易私有云平臺 OpenStack 團隊的研發秉承開源、開放的理念,始終遵循"來源社區,回饋社區"的原則。在免費享受 OpenStack 社區不斷研發新功能以及修復 bug 的同時,我們團隊也積極向社區做自己的貢獻,從而幫助 OpenStack 社區的發展壯大。兩年來,我們團隊一共向社區提交新功能開發/bug 修復的 commits 近 100 個,修復社區 bug 50 多個,這些社區貢獻涉及 OpenStack 的 Essex、Folsom、Havana、Icehouse、Juno 等版本。
得益于 OpenStack 的日益穩定成熟,私有云平臺目前已經穩定運行了 2 年多時間,為網易公司多達 30 個互聯網和游戲產品提供服務。從應用的效果來看,基于 OpenStack 研發的網易私有云平臺已經達到了以下目標:
提高了公司基礎設施資源利用率,從而降低了硬件成本。以物理服務器 CPU 利用率為例,私有云平臺將 CPU 平均利用率從不到 10% 提升到 50%。
提高了基礎設施資源管理與運維自動化水平,從而降低了運維成本。借助于 Web 自助式的資源申請和分配方式以及云平臺自動部署服務,系統運維人員減少了 50%。
提高了基礎設施資源使用彈性,從而增強了產品業務波動的適應能力。利用虛擬化技術將物理基礎設施做成虛擬資源池,通過有效的容量規劃以及按需使用,私有云平臺可以很好適應產品突發業務。
網易 OpenStack 部署參考方案介紹
在具體的生產環境中,我們為了兼顧性能和可靠性,keystone 后端使用 Mysql 存儲用戶信息,使用 memcache 存放 token。為了減少對 keystone 的訪問壓力,所有服務(nova,glance,neutron)的 keystoneclient 均配置使用 memcache 作為 token 的緩存。
由于網易私有云需要部署在多個機房之中,每個機房之間在地理位置上自然隔離,這對上層的應用來說是天然的容災方法。另外,為了滿足私有云的功能和運維需求,網易私有云需要同時支持兩種網絡模式:nova-network 和 neutron。針對這些需求,我們提出了一個面向企業級的多區域部署方案,如圖 2 所示。從整體上看,多個區域之間的部署相對獨立,但可通過內網實現互通,每個區域中包括了一個完整的 OpenStack 部署,所以可以使用獨立的鏡像服務和獨立的網絡模式,例如區域 A 使用 nova-network,區域 B 使用 neutron,互不影響,另外為了實現用戶的單點登錄,區域之間共享了 keystone,區域的劃分依據主要是網絡模式和地理位置。
圖 2.多區域部署方法
和典型 OpenStack 部署將硬件劃分為計算節點和控制節點不同的是,為了充分利用硬件資源,我們努力把部署設計成對稱的,即任意一個節點下線對整體服務不會照成影響。因此我們將硬件分為兩類:計算節點,控制計算節點。計算節點部署 nova-network,nova-compute,nova-api-metadata,nova-api-os-compute。控制計算節點除了計算節點的服務外還部署了 nova-scheduler,nova-novncproxy,nova-consoleauth,glance-api,glance- registry 和 keystone,如圖 3 所示。
對外提供 API 的服務有 nova-api-os-compute,nova-novncproxy ,glance-api,keystone。這類服務的特點是無狀態,可以方便地橫向擴展,故此類服務均部署在負載均衡 HAProxy 之后,并且使用 Keepalived 做高可用。為了保證服務質量和便于維護,我們沒有使用 nova-api,而是分為 nova-api-os-compute 和 nova-api-metadata 分別管理。外部依賴方面,網易私有云部署了高可用 RabbitMQ 集群和主備 MySQL,以及 memcache 集群。
圖 3.計算節點,控制計算節點
網絡規劃方面,網易私有云主要使用 nova-network 的 FlatDHCPManager+multi-host 網絡模式,并劃分了多個 Vlan,分別用于虛擬機 fixed-ip 網絡、內網浮動 IP 網絡、外網網絡。
運維上使用網易自主研發的運維平臺做監控和報警,功能類似 Nagios,但是更加強大。其中較重要的監控報警包括日志監控和進程監控。日志監控保證服務發生異常時第一時間發現,進程監控保證服務正常運行。另外網易私有云使用 Puppet 做自動部署,以及使用 StackTach 幫助定位 bug。
OpenStack 各組件配置
OpenStack Havana 的配置項成百上千,大部分配置項都是可以使用默認值的,否則光是理解這么多的配置項的含義就足以讓運維人員崩潰,尤其是對那些并不熟悉源碼的運維人員來說更是如此。下文將列舉若干網易私有云中較關鍵的配置項,并解釋它們如何影響到服務的功能,安全性,以及性能等問題。
Nova 關鍵配置
my_ip = 內網地址
此項是用來生成宿主機上的 nova metadata api 請求轉發 iptables 規則,如果配置不當,會導致虛擬機內部無法通過 169.254.169.254 這個 IP 獲取 ec2/OpenStack metadata 信息;生成的 iptable 規則形如:
-A nova-network-PREROUTING -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination ${my_ip}:8775
它另外的用途是虛擬機在 resize、cold migrate 等操作時,與目的端宿主機進行數據通信。該項的默認值為宿主機的外網 IP 地址,建議改為內網地址以避免潛在的安全風險。
metadata_listen = 內網地址
此項是 nova-api-metadata 服務監聽的 IP 地址,可以從上面的 iptables 規則里面看出它與 my_ip 的配置項有一定的關聯,保持一致是最明智的選擇。
novncproxy_base_url = vncserver_proxyclient_address = ${private_ip_of_compute_host} vncserver_listen = ${private_ip_of_compute_host} novncproxy_host = ${private_ip_of_host}
我們僅在部分節點上部署 novncproxy 進程,并把這些進程加入到 HAProxy 服務中實現 novnc 代理進程的高可用,多個 HAProxy 進程使用 Keepalived 實施 HAProxy 的高可用,對外只需要暴露 Keepalived 管理的虛擬 IP 地址即可:
這種部署方式好處是:
1)實現 novnc 代理服務的高可用
2)不會暴露云平臺相關節點的外網地址
3)易于 novnc 代理服務的擴容
但也有不足:
1)虛擬機都監聽在其所在的計算節點的內網 IP 地址,一旦虛擬機與宿主機的網絡隔離出現問題,會導致所有虛擬機的 VNC 地址接口暴露出去
2)在線遷移時會遇到問題,因為 VNC 監聽的內網 IP 在目的端計算節點是不存在的,不過這個問題 nova 社區已經在解決了,相信很快就會合入 J 版本。
resume_guests_state_on_host_boot = true
在 nova-compute 進程啟動時,啟動應該處于運行狀態的虛擬機,應該處于運行狀態的意思是 nova 數據庫中的虛擬機記錄是運行狀態,但在 Hypervisor 上該虛擬機沒有運行,在計算節點重啟時,該配置項具有很大的用處,它可以讓節點上所有虛擬機都自動運行起來,節省運維人員手工處理的時間。
api_rate_limit = false
不限制 API 訪問頻率,打開之后 API 的并發訪問數量會受到限制,可以根據云平臺的訪問量及 API 進程的數量和承受能力來判斷是否需要打開,如果關閉該選項,則大并發情況下 API 請求處理時間會比較久。
osapi_max_limit = 5000
nova-api-os-compute api 的最大返回數據長度限制,如果設置過短,會導致部分響應數據被截斷。
scheduler_default_filters = RetryFilter, AvailabilityZoneFilter, RamFilter, ComputeFilter, ImagePropertiesFilter, JsonFilter, EcuFilter, CoreFilter
nova-scheduler 可用的過濾器,Retry 是用來跳過已經嘗試創建但是失敗的計算節點,防止重調度死循環;AvailabilityZone 是過濾那些用戶指定的 AZ 的,防止用戶的虛擬機創建到未指定的 AZ 里面;Ram 是過濾掉內存不足的計算節點;Core 是過濾掉 VCPU 數量不足的計算節點;Ecu 是我們自己開發的過濾器,配合我們的 CPU QoS 功能開發的,用來過濾掉 ecu 數量不足的計算節點;ImageProperties 是過濾掉不符合鏡像要求的計算節點,比如 QEMU 虛擬機所用的鏡像不能在 LXC 計算節點上使用;Json 是匹配自定義的節點選擇規則,比如不可以創建到某些 AZ,要與那些虛擬機創建到相同 AZ 等。其他還有一些過濾器可以根據需求進行選擇。
running_deleted_instance_action = reap
nova-compute 定時任務發現在數據庫中已經刪除,但計算節點的 Hypervisor 中還存在的虛擬機(也即野虛擬機審計操作方式)后的處理動作,建議是選擇 log 或者 reap。log 方式需要運維人員根據日志記錄找到那些野虛擬機并手工執行后續的動作,這種方式比較保險,防止由于 nova 服務出現未知異常或者 bug 時導致用戶虛擬機被清理掉等問題,而 reap 方式則可以節省運維人員的人工介入時間。
until_refresh = 5
用戶配額與 instances 表中實際使用量的同步閾值,也即用戶的配額被修改多少次后強制同步一次使用量到配額量記錄
max_age = 86400
用戶配額與實際使用量的同步時間間隔,也即距上次配額記錄更新多少秒后,再次更新時會自動與實際使用量同步。
眾所周知,開源的 nova 項目目前仍然有很多配額方面的 bug 沒有解決,上面兩個配置項可以在很大程度上解決用戶配額使用情況與實際使用量不匹配的問題,但也會帶來一定的數據庫性能開銷,需要根據實際部署情況進行合理設置。
### 計算節點資源預留 ###
vcpu_pin_set = 4-$
虛擬機 vCPU 的綁定范圍,可以防止虛擬機爭搶宿主機進程的 CPU 資源,建議值是預留前幾個物理 CPU,把后面的所有 CPU 分配給虛擬機使用,可以配合 cgroup 或者內核啟動參數來實現宿主機進程不占用虛擬機使用的那些 CPU 資源。
cpu_allocation_ratio = 4.0
物理 CPU 超售比例,默認是 16 倍,超線程也算作一個物理 CPU,需要根據具體負載和物理 CPU 能力進行綜合判斷后確定具體的配置。
ram_allocation_ratio = 1.0
內存分配超售比例,默認是 1.5 倍,生產環境不建議開啟超售。
reserved_host_memory_mb = 4096
內存預留量,這部分內存不能被虛擬機使用
reserved_host_disk_mb = 10240
磁盤預留空間,這部分空間不能被虛擬機使用
service_down_time = 120
服務下線時間閾值,如果一個節點上的 nova 服務超過這個時間沒有上報心跳到數據庫,api 服務會認為該服務已經下線,如果配置過短或過長,都會導致誤判。
rpc_response_timeout = 300
RPC 調用超時時間,由于 Python 的單進程不能真正的并發,所以 RPC 請求可能不能及時響應,尤其是目標節點在執行耗時較長的定時任務時,所以需要綜合考慮超時時間和等待容忍時間。
multi_host = True
是否開啟 nova-network 的多節點模式,如果需要多節點部署,則該項需要設置為 True。
Keystone
配置項較少,主要是要權衡配置什么樣的后端驅動,來存儲 token,一般是 SQL 數據庫,也可以是 memcache。sql 可以持久化存儲,而 memcache 則速度更快,尤其是當用戶要更新密碼的時候,需要刪除所有過期的 token,這種情況下 SQL 的速度與 memcache 相差很大很大。
glance
包括兩個部分,glance-api 和 glance-registry,:
workers = 2
glance-api 處理請求的子進程數量,如果配置成 0,則只有一個主進程,相應的配置成 2,則有一個主進程加 2 個子進程來并發處理請求。建議根據進程所在的物理節點計算能力和云平臺請求量來綜合確定。
api_limit_max = 1000
與 nova 中的配置 osapi_max_limit 意義相同
limit_param_default = 1000
一個響應中最大返回項數,可以在請求參數中指定,默認是 25,如果設置過短,可能導致響應數據被截斷。
OpenStack 底層依賴軟件版本、配置以及性能調優
虛擬化技術選型
在私有云平臺的體系架構中, OpenStack 依賴一些底層軟件,如虛擬化軟件,虛擬化管理軟件和 Linux 內核。這些軟件的穩定性以及性能關系著整個云平臺的穩定性和性能。因此,這些軟件的版本選擇和配置調優也是網易私有云開發中的一個重要因素。
在網易私有云平臺中,我們選用的是 Linux 內核兼容最好的 KVM 虛擬化技術。相對于 Xen 虛擬化技術,KVM 虛擬化技術與 Linux 內核聯系更為緊密,更容易維護。選擇 KVM 虛擬化技術后,虛擬化管理驅動采用了 OpenStack 社區為 KVM 配置的計算驅動 libvirt,這也是一套使用非常廣泛,社區活躍度很高的一套開源虛擬化管理軟件,支持 KVM 在內的各種虛擬化管理。
另一方面,網易采用開源的 Debian 作為自己的宿主機內核,源使用的是 Debian 的 wheezy 穩定分支,KVM 和 libvirt 采用的也是 Debian 社區 wheezy 源里面的包版本:
qemu-kvm 1.1.2+dfsg-6+deb7u3 libvirt-bin 0.9.12
內核選型
在內核的選型方面,我們主要考慮如下兩方面的因素:
穩定性:在開發私有云平臺的一開始,穩定性就是網易私有云開發的一大基本原則。我們采用 Debian Linux 版本,相對來說,Debian 的原生內核無疑更為穩定。這也是我們最開始的一個選擇。
功能需求:在網易的定制開發中,為了保證虛擬機的服務性能,我們開發了 CPU QoS 技術和磁盤 QoS,它依賴底層的 CPU 和 blkio cgroup 支持。因此,我們需要打開內核中的 cgroup 配置選項。另一方面,網易私有云綜合各方面考慮,將支持 LXC 這種容器級別的虛擬化,除了 cgroup 外,LXC 還依賴 Linux 內核中的 namespace 特性。
綜合上述因素的考慮,我們選擇了 Debian 社區的 Linux 3.10.40 內核源代碼,并且打開了 CPU/mem/blkio 等 cgroup 配置選項以及 user namespace 等 namespace 選項,自己編譯了一個適配網易私有云的 Linux 內核。從使用情況來看,選擇上述版本的 OpenStack 底層依賴軟件后,網易私有云運行還比較穩定,我們后續還會適時的對這些軟件進行更新。
配置優化
在網易私有云的穩定性得到了保障之后,我們開始了性能方面的調優工作。這一方面,我們參考了 IBM 公司的一些優秀實踐,在 CPU、內存、I/O 等方面做了一些配置方面的優化。整體而言,網易私有云在注重穩定性的基礎上,也會積極借鑒業界優秀實踐來優化私有云平臺的整體性能。
CPU 配置優化
為了保障云主機的計算能力,網易私有云開發了 CPU QoS 技術,具體來說就是采用 cfs 的時間片均勻調度,外加 process pinning 的綁定技術。
參考 IBM 的分析,我們了解到了 process pinning 技術的優缺點,并且經過測試也驗證了不同綁定方式的云主機間的性能存在較大的差異。比如,2 個 VCPU 分別綁定到不同 numa 節點的非超線程核上和分配到一對相鄰的超線程核上的性能相差有 30%~40%(通過 SPEC CPU2006 工具測試)。另一方面,CPU0 由于處理中斷請求,本身負荷就較重,不宜再用于云主機。因此,綜合上面的因素考慮以及多輪的測試驗證,我們最終決定將 0-3 號 CPU 預留出來,然后讓云主機在剩余的 CPU 資源中由宿主機內核去調度。最終的 CPU 配置如下所示(libvirt xml 配置):
1102410000057499
內存配置優化
內存配置方面,網易私有云的實踐是關閉 KVM 內存共享,打開透明大頁:
echo 0 > /sys/kernel/mm/ksm/pages_shared echo 0 > /sys/kernel/mm/ksm/pages_sharing echo always > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag echo 0 > /sys/kernel/mm/transparent_hugepage/khugepaged/defrag
經過 SPEC CPU2006 測試,這些配置對云主機 CPU 性能大概有 7%左右的提升。
I/O 配置優化
1)磁盤 I/O 的配置優化主要包含如下方面:
KVM 的 disk cache 方式:借鑒 IBM 的分析,網易私有云采用 none 這種 cache 方式。
disk io scheduler:目前網易私有云的宿主機磁盤調度策略選用的是 cfq。在實際使用過程中,我們發現 cfq 的調度策略,對那些地低配置磁盤很容易出現 I/O 調度隊列過長,utils 100% 的問題。后續網易私有云也會借鑒 IBM 的實踐,對 cfq 進行參數調優,以及測試 deadline 調度策略。
磁盤 I/O QoS:面對日漸突出的磁盤 I/O 資源緊缺問題,網易私有云開發了磁盤 I/O QoS,主要是基于 blkio cgroup 來設置其 throttle 參數來實現。由于 libvirt-0.9.12 版本是在 QEMU 中限制磁盤 I/O,并且存在波動問題,所以我們的實現是通過 Nova 執行命令方式寫入到 cgroup 中。同時我們也開發并向 libvirt 社區提交了 blkiotune 的 throttle 接口設置 patch(已在 libvirt-1.2.2 版本中合入)來徹底解決這個問題。
2)網絡 I/O 的配置優化
我們主要是開啟了 vhost_net 模式,來減少網絡延時和增加吞吐量。
運維經驗
使用經驗
開源軟件 bug 在所難免,但是新版本比舊版本會好用很多,尤其是對于 OpenStack 這種正在迅速成長壯大的開源軟件來說更是如此,這一點在我們使用過 Essex、Folsom 和 Havana 版本后深有體會,所以建議各種 OpenStack 用戶能及時的跟進社區版本,與社區保持同步。
不要輕易的對社區版本進行各類所謂的功能性能方面的"優化",尤其是在沒有與社區專家交換意見之前,千萬不要輕易下手,否則此類"優化"極有可能演變成故障點或者性能瓶頸點,最終可能導致無法與社區同步,畢竟一個公司或團隊(尤其是小公司、小團隊)的能力和知識儲備,是很難與社區成百上千的各類專家相提并論的。
多參考各類大型公司分享的部署架構方案,盡量不要自己閉門造車,尤其是對于開源軟件來說,各類公司、團隊的使用場景千差萬別,各種周邊組件也是應有盡有,多參考業界實踐是最好的方式。
一些細節實現可能有很多途徑,但每種方式都有優缺點,需要經過充分的論證、分析、測試驗證后,才能考慮部署到生產環境使用。
所有的部署方案、功能設計都要考慮到平滑升級問題,即使你得到的信息是升級時可以停服,仍然要盡量避免這種情況,因為停服的影響范圍很難界定。
運維準則
OpenStack 也是一個后端系統服務,所有系統運維相關的基本準則都適用,這里簡單的提幾點實際運維過程中根據遇到的問題總結的一些經驗:
配置項默認值與實際環境不匹配可能導致各種問題,尤其是網絡相關配置與硬件有很強的關聯性,生產環境和開發環境硬件異構,導致部分默認值在生產環境不適用。應對準則:每個版本都必須在與線上硬件相同的環境測試過才能上線。
做好容量規劃,已分配的配額量要小于云平臺總容量,否則會出現各種問題,導致運維開發耗費很多不必要的精力去定位分析問題。
配置項過多容易出錯,需要與開發人員一起仔細核對,上線時首先要通過 puppet 的 noop 功能驗證改動是否正確后,才能真正上線。
網絡規劃要提前做好,如固定 IP、浮動 IP、VLAN 數量等,網絡擴容難度和風險都比較大,所以提前規劃好是最保險的,一個原則是大比小好,多比少好。
網絡隔離要做好,否則用戶網絡安全沒辦法保證。
信息安全問題要重視,這個是老生常談的問題了,每個平臺都有相同問題,但還是要重視再重視,一旦出現安全漏洞,所有虛擬機都面臨嚴重威脅。