網易OpenStack部署運維實戰

developerworks中國發表於2014-08-26

本文為您介紹了網易公司基於 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 的主要子專案有:

網易私有云使用了 Nova、Glance、Keystone、Neutron 這 4 個元件。

  • 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。

網易私有云平臺概況

圖 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 研發的網易私有云平臺已經達到了以下目標:

  1. 提高了公司基礎設施資源利用率,從而降低了硬體成本。以物理伺服器 CPU 利用率為例,私有云平臺將 CPU 平均利用率從不到 10% 提升到 50%。
  2. 提高了基礎設施資源管理與運維自動化水平,從而降低了運維成本。藉助於 Web 自助式的資源申請和分配方式以及雲平臺自動部署服務,系統運維人員減少了 50%。
  3. 提高了基礎設施資源使用彈性,從而增強了產品業務波動的適應能力。利用虛擬化技術將物理基礎設施做成虛擬資源池,通過有效的容量規劃以及按需使用,私有云平臺可以很好適應產品突發業務。

網易 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 配置):

<vcpu placement='static' cpuset='4-23'>1</vcpu>
<cputune>
    <shares>1024</shares>
    <period>100000</period>
    <quota>57499</quota>
</cputune>

記憶體配置優化

記憶體配置方面,網易私有云的實踐是關閉 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 數量等,網路擴容難度和風險都比較大,所以提前規劃好是最保險的,一個原則是大比小好,多比少好。
  • 網路隔離要做好,否則使用者網路安全沒辦法保證。
  • 資訊保安問題要重視,這個是老生常談的問題了,每個平臺都有相同問題,但還是要重視再重視,一旦出現安全漏洞,所有虛擬機器都面臨嚴重威脅。

相關文章