《又拍云運維總監邵海楊詳解 DevOps “八榮八恥”》要點:
本文介紹了又拍云運維總監邵海楊詳解 DevOps “八榮八恥”,希望對您有用。如果有疑問,可以聯系我們。
邵海楊老專家在Tech Minds No.5中根據自己10余年的研發、運維經驗,總結并分享了DevOps的“八榮八恥”、Herku PaaS的12要素宣言.
又拍云運維總監 邵海楊
以下是分享全文:
今天我講的是DevOps的八榮八恥,和后面Herku PaaS的12要素宣言相呼應,大家可以一起對照的來看,這其實是一個互相印證的過程.
DevOps這個思想提出來已經五六年了,一直都是呼聲很高,落地很難,為什么呢?
這可能與各個公司的業務情況和技術發展路線有或多或少的關系:
所以,DevOps的推進一定要自上而下,憑借挑戰自我,顛覆傳統的勇氣才能去落實.
好的,下面我正式開始.
DevOps的八榮八恥
一、以可配置為榮,以硬編碼為恥
△ 以可配置為榮,以硬編碼為恥
做過開發的朋友都知道,程序跟變量分離會出現單獨的配置文件,所以運維要像開發學習,學會把軟件和配置分離.
舉個例子,我們公司第一個版本自動化運維時,把所有的硬參數配置到upyun.cfg,如上圖.它的好處在于,只要編寫一個config函數,就可以把這種文本的運行方式,變成右邊nginx所能運行的格式.
并且可以用同樣一份配置去適用不同的后端軟件,如用haproxy替換nginx,只要重新寫一下config函數即可,運維和開發仍然可以使用同一份參數.
本地配置的文本格式有txt、ini、cfg,但是這些格式都沒有沒有硬性要求,如ini在php里用的多一點,cfg在mysql里用的多一些.
一般配置的文件里面會包括開關變量,調試參數、可變參數、權重,以及關聯上下游的參數,這些都可以放在配置里面,通過程序生成程序的方式完成.
第二代就不再使用它了.我們現在使用Yaml來定義配置文件,通過它動態生成配置文件,這兩者的思路是相同的,都是通過程序生成程序.
除此之外,現在也有一些更加流行的技術,比如通過etcd或者是consul來實現服務的自動發現、自動注冊.
?二、以互備為榮,以單點為恥
△ 以互備為榮,以單點為恥
互容互備一直是優良架構的設計重點.
我們早期做架構設計,使用了LVS+Keeplived+VRRP做轉換,這樣可以方便負載均衡,動態升級,隔離故障.現在第二代,已經在部分大節點使用OSPF和Quagga做等價路由的負載均衡和冗余保障.
Nginx可以加Haproxy或LVS做負載均衡.MySQL可以做主從切換,或者是MMM的高可用成熟解決方案.
我們的消息隊列之前用rabbitmq做,現在主要是redis和kafka集群化,其中kafka已經遷到了Mesos容器平臺里.
服務的自動發現、注冊,我們可以使用consul、etcd、doozer(Heroku公司產品),還有zookeeper.
主要區別是算法不一樣,zookeeper用的是paxos算法,而consul用的是raft算法.目前看來consul比較流行,因為consul的自動發現和自動注冊更加容易使用.
etcd主要是CoreOS在主推,CoreOS本身就是一個滾動發布的針對分布式部署的操作系統,大家可以去關注一下它.還有一個是hadoop和elk,大數據平臺的可擴展性是標配,很容易互備.
上面是舉了一些常見互備的軟件組件的選型,那我們應該如何設計一個無單點的架構呢?主要掌握以下幾點:
1. 無狀態
無狀態意味著沒有競爭,很容易做負載均衡,負載均衡的方式有很多種,F5,LVS,Haproxy,總能找到一種適合你的方式.
2. 無共享
以前我們很喜歡用內存來保持臨時信息,如進程間的交換,這種方式雖然效率很高,但是對程序的擴展性沒什么好處,尤其是現在的互聯網體量,光靠單機或者高性能機器是明顯玩不轉的.
所以我們現在就需要使用類似消息隊列的組件,把數據共享出去,利用多臺機器把負載給承擔下來.
3. 松耦合/異步處理
以前我們用Gearman這樣的任務框架.大家可以把任務丟進任務池里,生成多個消費者去取任務.當我的消費不夠用時,可以平滑增加我的work資源,讓他從更快的去拿任務.運維平臺這邊以python/celery的組合使用更多.
4. 分布式/集群協作
像Hadoop這樣的天生大數據/數據倉庫解決方案,由于先前設計比較成熟,一般都是通過很多臺機器擴容來實現map/reduce的擴展計算能力.
三、以隨時重啟為榮,以不能遷移為恥
△ 以隨時重啟為榮,以不能遷移為恥
關于這個點,我們講三個方面:
1. Pet到Cow觀念的轉變
以前我們說機器是pet,也就是寵物模式,然后花了幾萬塊錢去買的服務器,當寶一般供奉.但事實上卻并不是這樣,任何電子設備、服務器只要一上線,便開始了一個衰老的過程.
你根本不知道在運行過程中會發生什么事,比如說質量差的電容會老化爆漿,電子元器件在機房的惡劣環境里會加速損壞,這些變化都是我們無法參與控制的,所以無論我們怎么努力,都無法保障機器有多么的牢靠.
谷歌指出的Cow模式就是指農場模式.就是要把機器發生故障當做常態,打個比方,比如說這頭牛死了,那我就不要了,因為我有很多這樣的牛,或者是再拉一頭新的牛.這就是我們軟件開發和運維需要做的轉變,去適應這種變化.
2. OpenStack虛擬機的編排
虛擬化是個好東西,通過OpenStack我們很容易就可以做出一些存儲或者遷移的操作,但是在實施的過程中,也是一波三折的.
我們從2014年開始在內部推動OpenStack,當然我們也踩過OpenStack網絡的坑.
那時候我們用雙千兆的卡做內網通訊,因為使用OpenStack實現虛擬化后,一切都變成了文件,在網絡上傳輸的話,對網絡的壓力會非常大,結果就導致部分服務響應緩慢.
因為本身就是實驗性質,所以在硬件上沒有足夠投入,內測時也沒有推廣,所以影響不大.
2015年我們再上的OpenStack,全部都用雙萬兆的網卡做bonding,交換機也是做了端口聚合和堆疊.目前來說,只有云存儲沒有上線,其它云處理,云網絡的使用還是能夠滿足要求.
3. Docker的導入導出
Docker是更輕量級的資源隔離和復用技術,從2016年開始,又拍云同時也在嘗試使用Mesos/Docker來實現云處理的業務遷移.
四、以整體交付為榮,以部分交付為恥
△ 以整體交付為榮,以部分交付為恥
以往開發運維要安裝一個機器,首先要去申請采購,購買完了還要等待運輸,在運輸中要花去一天的時間,之后還需要配交換機和網絡.
在這個過程中你會發現,簡單的給開發配臺機器,光上架就涉及到運維的很多環節,更不要說系統安裝,優化,軟件配置等剩余工作了,所以大多數情況下你只能做到部分交付.
要如何解決這些問題?
通過OpenStack可以做到云計算、云網絡、云存儲這三塊搭建完成之后,進行整體交付.
根據一些經驗總結,在整個云平臺當中,云存儲的坑最多,云計算、云網絡相對來說比較成熟.現在云計算的硬件基本上是基于英特爾CPU的虛擬化技術來硬件指令穿透的,損耗大概2%~5%,這是可以接受的.
至于云網絡,剛才胡凱(B站運維總監)提到內網包轉發效率,我做過一個測試,在OpenStack的內網中,如果MTU默認是1500,萬兆網卡的轉發率大概為6.7xxGbps.
后來我在優化的過程中,也翻查一些文檔,看到的數據是可以達到9.5xxGbps,通過不斷的摸索,對比測試后發現,如果把內網的MTU搞成大包,如9000時,萬兆網卡的存儲量直接達到了9.72Gbps左右的.
不過,這個MTU需要提前在宿主機上調整好,需要重啟生效.所以,這個問題發現得越早越好,這樣就可以做到統一調度,分配資源.
Docker的好處是可以做到Build、Shipand Run,一氣呵成.無論是對開發,測試,還是運維來說,Docker都是同一份Dockerfile清單,所以使用Docker在公司里的推動就很順暢.
雖然OpenStack也可以一站式交付,整體交付,使用時非常方便.但是對開發來說,他還是拿到一臺機器,還是需要去安裝軟件環境,配置,上線,運行,除了得到機器快一些,對上線服務沒有什么大的幫助.
所以我們現在的Openstack集群一般對內申請開發測試用,外網生產環境還是以Docker容器化部署為主,這也是大家都喜聞樂見的方式.
但前提是開發那邊能夠適應編寫Dockerfile(目前是我在內部推動這種變革,如新的項目就強制要求用docker).
五、以無狀態為榮,以有狀態為恥
△ 以無狀態為榮,以有狀態為恥
有狀態的服務真的很麻煩,無論是存在數據庫、磁盤開銷,還有各種鎖等資源的競爭,橫向擴展也很差,不能重啟,也不能互備.
所以,有狀態的服務對于擴展原則來說,就是一場惡夢.如何解決我們說的這個問題,那就要使用解耦和負載均衡的方法去解決問題.
1. 使用可靠的中間件
中間件其實最早出現在金融公司、證券公司,后來隨著互聯網行業不斷壯大以后,就出現了一些高可靠性的號稱工業級的消息隊列出現,如RabbitMQ,一出來以后,就把中間件拉下神壇.
隨著中間件民用化,互聯網蓬勃發展,是可以把一些服務變成無狀態,方便擴展.
2. 公共資源池
我們可以通過各種云,容器云、彈性云,做計算單元的彈性擴展.
3. 能夠被計算
如果你不想存狀態,那也可以被計算,比如說Ceph存儲,它的創新在于每個數據塊都是可計算出來的,這就類似無狀態的,每次都算,反正現在的cpu都這么強悍了.
所以,無狀態是一個命題,在做架構的時候,你腦海里一定要有這個意念,然后再看你用什么樣的方式開動腦筋,預先的跟開發,運維溝通好,把應用拆分成一種無狀態的最佳組合.
六、以標準化為榮,以特殊化為恥
△ 以標準化為榮,以特殊化為恥
在標準化方面,我們在這幾個方面改良:
1. 統一輸入輸出
統一入口是我加入公司后做的第一件事情,我們用一個統一的文本,到現在也在用,然后推送到所有的邊緣,服務器上面的組件,要用到的參數,都能從配置里讀出來.
代碼管理方面我們也使用git,git wiki,批量部署我們用ansible(早在2012年,我做了一些比較后,就在公司里推行ansible,看來還是很明智的決定).
2. 統一的流程管理
運維中使用python最多,所以我們使用了yaml和playbook.我們有自己的跳板機,通過VPN登陸,目前我們也在試用一個帶有審計功能的堡壘機,可以把每個人的操作錄制下來,然后再去回放觀察,改進我們的工作流程.
3. 抽象底層設計和復用組件
如果是開發者的話,就會寫很多的復用函數,對于優秀的運維人員來說,也要有優秀的抽象業務的能力,也要去做一些重復工作的復用準備,如頻繁的,繁瑣易出錯的手工操作抽象成若干運維的腳本化.
最后是巧妙的利用虛擬化、容器服務、server-less微服務,這些服務是可以被備份,還原的,可以保持一個相對穩定的狀態,我們要拒絕多的特殊管理操作.
香農-信息熵理論里說,變量的不確定性越大,熵就越大,把它搞清楚所需要的信息量也就越大.理論上來說,如果是一個孤立的系統,他就會變得越來越亂.
七、以自動化工具為榮,以手動和人肉為恥
△ 以自動化工具為榮,以手動和人肉為恥
公司早期,用的是bash、sed、awk,因為我之前有搞嵌入式的背景和經驗,對一個十幾兆的嵌入式系統來說,上面是不可能有python/perl/nodejs等環境.
所以我們把服務器批量安裝,部署,上線,做成了嵌入式的系統后,只要點亮以后,運行一個硬件檢測的程序,會把機器的CPU、內存、硬盤大小等都打印出來,供貨商截圖給我看,這個機器是否合格.
合格的機器可以直接發到機房去,在機器到了機房通上網線以后會有一個ansibleplaybook的推動.
自從用了這種方法以后,我們在公司里面基本上沒有見到服務器,一般直接產線上檢測通過后發到機房.
然后我們運維人員就可以連上去遠程管理,在過去的三年里我們服務器平均每年翻了三倍,節點翻了六倍多,但是人手并沒有增加.
關于tgz、rpm、pkg的打包部署,我們用的是tgz的打包及docker鏡像.優勢在于,我們自有CDN網絡,軟件通過推動到CDN網絡下可以加速下發.
關于集成測試、自動測試的發布,像ELK集中日志的分析、大數據的分析,我們現在使用ELK以后,只要有基礎的運維技術知識便可看懂,不需要高深的運維知識和腳本編輯知識,大多數人都可以完成這份工作,好處就是你多了好多眼睛幫你一起來發現問題,定位問題.
最后是不要圖形,不要交互,不要終端.一旦有了圖形以后,很難實現自動化.原則就是,不要手工hack,最好是用程序生成程序的方式去完成這個步驟.
八、以無人值守為榮,以人工介入為恥
△ 以無人值守為榮,以人工介入為恥
運維部門要做的事情有三件:
1. 運維自動化
要有一定的業務抽象能力,要有標準化的流程.沒有好的自動化,就很難把運維的工作效率提升了,只要做好這些,就可以節省時間,從容應對業務增長.
而且運維自動化的另一個好處就是運維不會因為人的喜怒哀樂而受到影響穩定性,比如說我今天心情不好,你讓我裝一臺機器我還可以忍,你讓我裝十臺一百臺就不行了.但如果公司有了運維自動化的流程,這個事情就可以避免,因為誰做都一樣.
2. 監控要常態
2016年年初,我們特別成立大數據分析部門,我們把日志做了采樣收集和過濾,通過大數據平臺做日志的同構數據分析,重點關注4xx/5xx/2xx比例,響應時間分析如100毫秒、200毫秒、500毫秒,還有區域性的速率分布,講真,這真是一個好東西.
3. 性能可視化
數據的有效展示.現在ELK對我們的幫助很大,從監控圖上來看相關的數據指標,一目了然.這里就不反復贅述了.
DevOps的本質
最后,我們談一談DevOps的本質.
1. 彈性
像亞馬遜推云時,那個單詞叫elastic,意思是,你要能夠擴展,如橫向擴展;你要能負載均衡,如果你是基于openstack/docker資源池,你的資源就可以復用,可以編排回滾.
比如說OpenStack有模板,我打一個鏡像包,稍微重了一點,Docker的就輕一點,Docker可以做一個滾動發布,可以保留原來的程序、原來的容器,你可以做快速切換,這也是一種變化的彈性.
2. 無關性
如果是虛擬化資源,一切都可以在模板里面設置,可以把底層的硬件、系統、網絡撫平差異,比如說不管物理磁盤是1T(市面上缺貨)/4T/6T的盤,都可以劃分100G容量,所以當把一切變成按需申請的服務,無論是開發還是運維,工作都會比較簡單,因為它的無關性.
3. 不可變的基礎設施
這個對傳統運維可能是一種打擊,因為基礎鏡像可能已經做的足夠安全,足夠完美,足夠精干,不需要基礎運維過多的人工參與.
但我認為恰恰能幫助傳統運維減輕工作量,反而有更多的精力去迎接虛擬化、容器化,SDN的挑戰,掌握了新技能后,就可以隨取隨用.
我現在是用比較開放的心態去接受這些變革,比如說像CoreOS這個操作系統,你到里面去看一下,真的沒什么各種組件,除了最基礎的就只有docker/RKT運行環境.
當然,這個是很極端的例子,但是我覺得當底層的操作系統,他可以做到自我更新,足夠安全的時候,確實不需要你去操心這個事情.這跟我們用小U盤做整體升級的思路是一樣的,但是它那個更先進,更徹底,更值得我們去學習.
Heroku PaaS的12要素宣言
Heroku是業內知名的云應用平臺,從對外提供服務以來,他們已經有上百萬應用的托管和運營經驗.前不久,創始人AdamWiggins根據這些經驗,發布了一個“十二要素應用宣言(TheTwelve-Factor App)”
1. 基準代碼
一份基準代碼多處部署,這個就是剛才講的標準化,還有復用組件,這些是吻合的.
2. 顯式聲明依賴關系
比如說像nodejs、go、maven,在提供的配置文件上,要標明上下游的關系,標明可配參數.
3. 必須要在環境中存儲配置
這一點我覺得可以保留,雖然文本文件也適用,但環境變量有它的好處,一是語言無侵害性,二是代碼無關性.比如說OpenStack里也有環境變量,它是會導入環境變量的那份文件.
4. 要把后端服務當做一個附加資源
這就是我們一直在強調的松耦合,要把后端服務變成一個url去調用,像Mysql,或者是通過消息隊列或任務框架.或者更加智能一點,做自動的服務發現、服務注冊,把后端服務剝離開去.
這樣做的還有一個好處,就是能夠區分運維工作中哪些是重點資源,哪些是需要更多的人去監控后端的服務,當知道這是重中之重的時候,就可以把有限的運維力量投到上面去.
5. 構建、發布和運行
用了Docker以后就很容易實現這個標準,關鍵是統一性、標準化和模板或容器格式.
6. 進程必須是無狀態而且無共享
任何需要持久化的數據都要存儲在后端服務里.
7. 要做端口綁定
要通過端口綁定來服務,你可以基于Restful,也可以基于rpc或者是http,這樣的好處是松耦合和方便負載均衡,做水平擴展.
8. 并發
要通過進程模型進行擴展,方便擴展.
9. 易處理
快速啟動和優雅終止可最大化健壯性.參考雅虎原則.
對雅虎來說,如果開發需要上線服務,就必須向運維提供start、stop、status、reload/restart這幾個開關,如果你不提供這些開關的話,雅虎的運維是不允許這個服務上線的.
因為能提供stop,那就說明服務是能被隨時重啟的最好證明.
10. 開發環境與線上環境等價
盡可能保持開發、預發布和線上環境相同.用了Docker以后,這個事情就不是個事情.
11. 把日志當做一個事件流
我們現在用logstash和heka去做一些處理.對云服務來說,我們現在發現,日志越來越重要,日志收集對我們來說價值非常大.
通過大數據分析平臺,可以做到秒級分析,秒級監控報警,秒級定位問題,甚至我們可以比客戶更早發現問題,我覺得這是一件非常有意義,值得我們投入精力去做的事情.
12. 管理進程
后臺管理任務可以當做一次性的進程運行,相當于微服務.
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/4359.html