在雲端進行變更操作的正確姿勢
本文為Oracle首席雲架構師-包光磊之作,但是由於篇幅較長,看完需多點耐心。
我想聊一聊雲端的運維自動化。並不涉及容器、CI/CD等話題,它們和雲像兄弟但不是雲端的必需品,今天只是談一談運維自動化的本源,順便思考一下雲的價值。同時,我們的討論會涉及到Oracle 公有雲 IaaS的一部分功能和特點,並且還是入門Oracle Cloud Java SDK的機會,您需要為閱讀本文分配一點時間。
有一個很常見的問題:你手機的系統圖標突然亮起一個紅點,表示寶寶又要更新啦,您點是不點呢?什麼時候點?點了之後看著進度條內心忐忑嗎?您有這些疑慮的主要原因是您在生產系統上做變更了,並且人工操作的不確定性(手機廠商已經把系統升級的人工干預項減到最低,但是很多IT系統還沒有做到)、硬體故障率的存在、生產系統的重要程度,這幾方面一交集後就足以讓人焦慮不安了,還有那甩不掉的墨菲定律…不行了,已經不能好好聊天了,感覺到壓力山大。
那麼如果生產系統需要變更(升級、配置修改等等)該怎麼辦?其實解決方案很簡單,這幾乎是一個「道理大家都懂的」的答案:不在生產系統做變更!永遠只在新的、不重要系統實現想要實現的變更,然後,切換到生產系統里去,整個流程做到不影響客戶訪問或影響的程度最小。同學們可能會說小包同志你不是在逗我們吧,這種實踐很多很多年前就有了,今天再提意義何在?我想說,在雲的時代,這個「不要在生產系統做變更」的實踐理應體現在每一處,而不是只在重大變更、重大系統割接時才採用,重申一次,在每一處變更時,您都應該偏執地執行。因為有了雲的支撐,沒有任何理由或借口不按照這個最佳實踐去操作。就算是一次簡單的「yum update」,也得這麼操作,你因該悲觀地認為再簡單的變更都可能會失敗,在變更推到生產系統里去之前必須驗證。在硬體不需要你管理、代碼即是基礎架構的雲的世界,有什麼理由不去這麼做呢?
在雲端(嚴格來說是公有雲)應該用怎樣的思路去構思這個變更操作的解決方案?
接下來的例子中,我們會有這樣一個架構:兩台Web Server,在其前端一個負載均衡器作為解耦組件接受客戶請求。現在,假設後端的web server需要執行」yum update」,以這個例子詳細聊聊在雲端這個操作可以怎麼做,或推薦的做法是怎樣的。同時為了避免造成一些依賴性上的誤解,不會使用到任何第三方工具(有的話也是一個簡單的Java小程序)。我們將會用到以下產品和服務:
? Oracle Cloud Infrastructure - https://cloud.oracle.com/en_US/infrastructure/architecture
? Oracle Cloud Infrastructure Java SDK - https://docs.us-phoenix-1.oraclecloud.com/Content/devtoolshome.htm
? Jiu, 一個基於Oracle Cloud Infrastructure Java SDK的學習與演示工具 - https://github.com/guangleibao/jiu。有效子程序都是類bglutil.main.Jiu里的方法。請按照README.MD的步驟安裝、運行。為了使用此工具的絕大部分功能還需要一個Oracle Cloud(測試)賬號。安裝完成後Jiu的執行通過現成的「runJiu.sh」腳本調用,本文中後續很多例子需要用到它。友情提示:Jiu僅做教學工具使用。
現在,請熟悉一下示例的生產環境,如圖所示,在某個Oracle Cloud區域里的一個VCN(虛擬雲網路)中,有一個託管的HTTP負載均衡器(兩個紅色節點,由於是託管的,用戶不必親自去搭建和運維),工作在兩個Public Subnet里。兩台VM(exampleweb0 和 exampleweb1)運行Apache作為WebServer,頁面上只是簡單顯示「Welcome to BMC !」,這是個最簡單的無狀態應用:
細心的同學馬上會注意到圖中有兩個可用域,可用域1和可用域2,我必須簡單介紹一下它的概念。Oracle Cloud在全球有多個區域,同區域里提供三個可用域,相隔幾十公里,每個可用域中至少有一個數據中心。
可用域相互之間做到地理、電網等故障隔離,通過高速低延遲的Oracle專用網路冗餘相連,放置在兩個可用域的伺服器實例互ping的延遲不會超過1ms,如下圖所示,exampleweb0和exampleweb1位於兩個不同的可用域:
登錄在exampleweb0上ping對面可用域中的exampleweb1的返回顯示如下,僅僅耗時0.25ms左右,要知道這可是幾十公里的間距:
低延遲、分散式的數據中心設計可以讓用戶輕鬆地搭建高可用、並且是容災的應用。
接下來請留意負載均衡器層,兩個紅色的Load Balance節點以及可以在節點間浮動的VIP其實是一套託管的負載均衡器集群,不需要用戶維護管理,兩節點間處於不同的可用域(默認容災),健康監控機制會讓VIP自動地漂浮到健康的節點上。Oracle採用VIP的機制可以讓客戶端不受網路TTL超時的影響敏捷迅速地訪問健康的節點,也可以排除DNS緩存、NS SOA記錄的干擾。這樣的窘況不會存在:明明健康的節點已經切換但一段時間內還是訪問不了,因為DNS緩存沒有超時。再聊下去就有些扯遠了,讓我們言歸正傳。
根據圖示,有兩個處於不同可用域的webserver,就是上文提到的exampleweb0和exampleweb1,地址分別是10.7.4.2與10.7.5.2。作為負載均衡器的backend:
兩個現有的Web Server,負載均衡器上顯示狀態健康
讓我們通過小程序「Jiu.urlTest」訪問負載均衡器的VIP,看一下結果(出於安全原因VIP的具體地址隱藏),這個程序在接下來的整個示例流程中會保持運行:
urlTest的輸出,該程序截取HTTP頁面內容的第一行
頁面的內容很簡單,只是顯示」Welcome to BMC !」,也可以看到在兩個webserver間負載均衡的效果。
至此,鋪墊總算是結束了,現在我們的主角 - 變更需求來了。exampleweb0和exampleweb1都需要執行「yum update」以更新系統,重申它們是生產系統,有兩個主要風格可供選擇。
風格一: 直截了當型。登錄到exampleweb0,執行」yum update」,驗證結果。整個流程雷厲風行,但這種方式過於樂觀了,槽點一堆,當你因為這種草率行動整癱系統(雖然不大可能)而背鍋時連酸都感覺不到,更別提爽了。
風格二:小心謹慎敬畏之心型。分配一個新的webserver,配置與現有的webserver相同,遊離於負載均衡器之外,在它身上執行「yum update」,單獨測試,通過驗證後再用它生成一個新的鏡像,交付這個新的鏡像為webserver鏡像的下一個版本,從這個鏡像啟動一個新的生產用webserver,測試其功能,測試通過後再註冊到生產負載均衡器以接受流量,待穩定後,從負載均衡器上移除舊的沒執行過「yum update」的webserver,完成整個流程時,舊的webserver上沒有發生過任何變更。
很明顯,你因該採用後者。可是,每次都人工地走這些流程必然令人心生厭煩。討厭的流程就別指望每次能被100%的執行。所以自動化是關鍵,Oracle Cloud 里的每個操作都有對應的REST Web Service調用,它們還有相應的SDK(目前有Java,Python和Ruby),一來提高操作效率消滅重複勞動,二來避免人為錯誤保證了一致性(防呆很重要,人會餓、會困、會失戀、會暴躁… 技術走型的原因永遠有無數種,猜不透也想不全… )。利用Oracle Cloud提供的各種介面,你不但可以把整個流程自動化,而且還能以非常細粒度的模式控制雲內的資源。
一旦自動化流程確定後,不斷改進這樣的流程,才是雲端運維的真正價值!
為了避免同學們看過此文之後走這個套路 - 「道理我都懂,但實際操作時我還是偷懶一點使用直接了當型的就行了」。在此,我利用前文提到的Oracle Cloud Infrastructure學習小工具 - Jiu - 以身作則地給同學們做一個演示。
Jiu的一個子程序「demoYumUpdateWebServer」,就是專門針對本文的例子寫的一個實施「yum update」的自動化流程demo,查看它的help會發現有6個參數:
$ ./runJiu.sh demoYumUpdateWebServer -h
$ demoYumUpdateWebServer
其含義分別是:
1. 需要執行「yum update」的webserver的名稱(在Oracle Cloud內)
2. webserver處於哪個VCN(VCN是Oracle Cloud里的網路隔離構件,在其它課程里我會詳細介紹)本例中名為examplevcn
3. webserver處於哪個子網,本例中exampleweb0在examplewebpri1子網
4. 前端的負載均衡器名稱,本例中名為examplelb
5. 負載均衡器backend set名稱(這是負載均衡器的組件,每個backend set有特定的負載均衡演算法、協議、證書等,在其它課程里我再詳細介紹),本例中名為examplelbbes
6. profile名稱,用來保存常用的雲端默認設置以及Oracle Cloud賬戶的憑證,詳細配置指導請參考:https://docs.us-phoenix-1.oraclecloud.com/Content/API/Concepts/sdkconfig.htm。
感謝您的耐心等待。該開始做正事了,看看demoYumUpdateWebServer具體怎麼乾的。
共11個步驟,分別對應源代碼里的「//Step1」到「//Step11」,以便對照閱讀)
步驟一:啟動一個鏡像製作實例。
Step1的輸出,userdata的腳本的部分內容,全部內容請查看源代碼
開始執行後的第一步是用舊的webserver的鏡像啟動一個新的webserver,並通過cloud-init的userdata向新的webserver傳入初始化腳本(截圖中userdata被縱向截斷,後續有講解),注意腳本的最後一段是一個較長的shell串聯命令。「&&」 符號的功能是如果緊前命令執行成功(返回值為0),才執行緊後命令。所以,在最後一條命令中,如果」yum -y update」執行失敗是不可能安裝httpd的,也不會有index.html文件和index-test.html文件,index-test.html文件的內容也不會是「_SUCCESS」。我把最後一行命令分行列出以便觀察:
yum -y update &&
yum -y install httpd &&
NAME=`curl -s http://169.254.169.254/opc/v1/instance/ grep displayName sed "s/ "displayName" : "//g" sed "s/", //g"` &&
echo Welcome to BMC $! > /var/www/html/index.html &&
chmod a+r /var/www/html/index.html &&
service httpd start &&
chkconfig httpd on &&
echo "_SUCCESS" > /var/www/html/index-test.html &&
chmod a+r /var/www/html/index-test.html
本例中的應用就是顯示一句「Welcome to BMC !」,內容在index.html里。從這裡可以看出userdata實際上完成了web應用的部署(雖然簡單了點
TAG:甲骨文雲技術 |