掃二維碼與項(xiàng)目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
作者: 阿丸筆記 2020-12-22 07:42:05
開發(fā)
前端
云原生 本文將重點(diǎn)分享阿里開源項(xiàng)目otter適配k8s部署的改造過程,其中的改造過程和技巧應(yīng)該適用于將大多數(shù)開源項(xiàng)目改造到k8s進(jìn)行部署。

專注于為中小企業(yè)提供成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)威遠(yuǎn)免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了成百上千企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
k8s以及云原生相關(guān)概念近年來一直比較火熱,阿丸最近搞了個相關(guān)項(xiàng)目,小結(jié)一下。
本文將重點(diǎn)分享阿里開源項(xiàng)目otter適配k8s部署的改造過程,其中的改造過程和技巧應(yīng)該適用于將大多數(shù)開源項(xiàng)目改造到k8s進(jìn)行部署。
1.背景
otter是阿里開源的分布式數(shù)據(jù)庫同步系統(tǒng),基于數(shù)據(jù)庫增量日志解析,并準(zhǔn)實(shí)時同步到本機(jī)房或異地機(jī)房的mysql/oracle數(shù)據(jù)庫(相關(guān)內(nèi)容可以參考https://github.com/alibaba/otter,本文不做過多贅述)。
為了充分利用物理資源、快速擴(kuò)容同步節(jié)點(diǎn)、擁抱云原生,決定使用k8s部署otter。
otter的項(xiàng)目整體上自成一體,出于改造成本考慮,盡量在項(xiàng)目已有基礎(chǔ)上,做一些適配,不改動源代碼。
本文將重點(diǎn)分享對于otter適配k8s部署的改造過程,有不當(dāng)之處,還請多多指教。
涉及到幾個核心內(nèi)容:
2.otter的基本架構(gòu)
典型管理系統(tǒng)架構(gòu),manager(web管理)+node(工作節(jié)點(diǎn))
基于以上部署架構(gòu),我們只需要將otter-manager和otter-node部署到k8s上。
尤其是otter-node,需要利用k8s實(shí)現(xiàn)節(jié)點(diǎn)快速水平擴(kuò)展、計算性能彈性擴(kuò)縮容。
2.Dockerfile編寫
2.1 otter-manager的Dockerfile
otter-manager比較簡單,包括幾個步驟:
具體如下所示:
2.2 otter-node的Dockerfile
otter-node稍微有所不同,根據(jù)官方文檔說明,需要安裝aria2來做文件傳輸。
注意注意,由于aria2安裝非常慢,因此,我們需要先安裝aria2作為一個新的基礎(chǔ)鏡像,然后在新的基礎(chǔ)鏡像上構(gòu)建otter-node鏡像,能大大提高后續(xù)鏡像構(gòu)建速度。
新的基礎(chǔ)鏡像如下,命名為 registry.xxx.com/xxx/otter-node-base:1.0。
然后在此基礎(chǔ)上構(gòu)建新的otter-node鏡像。
注意,otter-node的配置方式比較特殊,需要先在otter-admin上獲取一個nid,然后才能運(yùn)行一個otter-node。
所以,我們在dockerfile中以ARG 聲明一個nid,然后在后續(xù)構(gòu)建鏡像的時候,通過 --docker-arg 傳入nid具體的值。
當(dāng)然,如果把nid看作一個配置文件的話,也可以用下文提到的ConfigMap的形式在Deployment中掛載進(jìn)去
3.Deployment編寫
什么是Deployment?
具體關(guān)于Deployment的知識不展開說明,可以參考k8s官方文檔。
我們需要部署測試環(huán)境與生產(chǎn)環(huán)境兩套集群,而無論是otter-manager還是otter-node,都依賴于讀取 conf/otter.properties 作為配置。
因此,我們需要根據(jù)環(huán)境,修改不同的otter.properties。
那么,對于k8s部署來說,可以采用同一份鏡像,然后在不同環(huán)境(k8s的不同namespace)中將otter.properties作為ConfigMap寫入,最后通過volume的形式掛載到pod的指定路徑上。
這里對幾個名詞做簡單介紹,詳細(xì)內(nèi)容可以參考k8s官方文檔。
所以,首先在指定環(huán)境(namespace中)創(chuàng)建configmap,以otter.properties作為key,以文件內(nèi)容作為value。
具體命令如下
kubectl create configmap otter-manager-dev-config --from-file=otter.properties=conf/otter-dev.properties -n otter-system
產(chǎn)生的ConfigMap如下圖所示
最后,將這個ConfigMap在Deployment中用volume進(jìn)行引用,然后通過volumeMounts掛載到指定目錄,Deployment具體如下所示。
這里需要特別注意volumeMounts的路徑覆蓋問題,需要在volumeMounts中配置subPath為具體文件名。
4.啟動腳本改造
Otter包括兩個部分,管理控制臺manager和工作運(yùn)行節(jié)點(diǎn)node,正常情況下都是用各自的啟動腳本startup.sh啟動的。
為了適配k8s,我們需要對啟動腳本做改造,本文以otter-manager的啟動腳本為例,otter-node也是類似。
將啟動腳本startup.sh改造為 startup-moon.sh,重點(diǎn)解決兩個問題
4.1 前臺進(jìn)程保持運(yùn)行
由于容器中用entrypoint啟動的進(jìn)程為1號進(jìn)程,一旦1號進(jìn)程執(zhí)行結(jié)束,容器就會退出了。
而原本的startup.sh中,用java啟動后,使用 “&” 將java進(jìn)程轉(zhuǎn)換為后臺進(jìn)程,所以startup.sh作為1號進(jìn)程會很快執(zhí)行結(jié)束,容器就會自動退出了。
所以我們需要將1號進(jìn)程保持住,不要退出。
這里考慮了兩個方案:
后來考慮了一下,還是選擇了方案二。主要原因是為了利用pod自動重啟的特性。
如果Java進(jìn)程意外退出了,那么方案二就能使得1號進(jìn)程也結(jié)束,然后pod就能自動重啟了。而方案一的話,由于startup.sh腳本仍然在執(zhí)行tail,所以即使java進(jìn)程退出,1號進(jìn)程也不會結(jié)束。
具體修改如下:
最終pod中的進(jìn)程如圖所示
4.2 虛擬機(jī)大小自定義配置
由于otter項(xiàng)目中,將jvm的啟動參數(shù)配置在了start.sh中,不方便進(jìn)行手動配置。
因此,將start.sh的配置jvm參數(shù)的邏輯注釋掉,采用自己配置的環(huán)境變量JAVA_OPTIONS進(jìn)行注入。
這個環(huán)境變量的注入方式也比較簡單,就是在Deployment中的env配置的(藍(lán)色框部分),方便以后手動修改jvm參數(shù)大小而不用修改鏡像。
5.k8s上固定IP/Port訪問
otter-node的部署中,有個比較特殊的地方。
不同于普通的微服務(wù)的無狀態(tài)擴(kuò)展,otter-node的部署必須指定nid、ip、port,這種設(shè)計據(jù)說是為解決單機(jī)部署多實(shí)例而設(shè)計的,允許單機(jī)多node指定不同的端口(具體可以參考官方wiki,https://github.com/alibaba/otter/wiki/Node_Quickstart,這里不展開說明)。
還是直接看看如何在k8s上進(jìn)行適配吧。
這里采用了k8s的NodePort進(jìn)行處理。
NodePort 服務(wù)是引導(dǎo)外部流量到你的服務(wù)的最原始方式。NodePort,正如這個名字所示,在所有節(jié)點(diǎn)(虛擬機(jī))上開放一個特定端口,任何發(fā)送到該端口的流量都被轉(zhuǎn)發(fā)到對應(yīng)服務(wù)。如下圖所示。
在上面的配置中,可以使用IP1:3000 或者 IP2:3000 或者 IP3:3000 訪問service。
當(dāng)然,為了保證不綁定特定KVM的IP,我們在前面掛一個SLB服務(wù),通過訪問SLB的 虛擬IP:PORT 的形式訪問。
對于otter部署來說,otter-manager需要兩組 IP:PORT、每個node需要三組 IP:PORT。
注意,由于otter部署中,每個node需要暴露的port都是不同的,所以每次新增一個otter-node,都需要新增三組 IP:PORT。
我們以otter-node為例,來看下NodePort類型的Service的yml文件吧。
6.總結(jié)
經(jīng)過這樣的改造,我們就能用k8s的部署otter-manager和otter-node了,并且能夠快速擴(kuò)容節(jié)點(diǎn)、彈性使用機(jī)器資源。
我們回顧一下其中的關(guān)鍵問題和技巧:
其他開源項(xiàng)目如果有需要上k8s的,這些技巧應(yīng)該都能用上。

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流