版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、 Kubernetes 在知名互聯(lián)網(wǎng)公司的落地實(shí)踐 容器化背景本來生活網(wǎng)()是一家生鮮電商平臺,公司很早就停止了燒錢模式,開始追求盈利。既然要把利潤最大化,那就要開源節(jié)流,作為技術(shù)可以在省錢的方面想想辦法。我們的生產(chǎn)環(huán)境是由 IDC 機(jī)房的 100 多臺物理機(jī)所組成,占用率高達(dá) 95%,閑置資源比較多,于是我們考慮借助 k8s 來重構(gòu)我們的基礎(chǔ)設(shè)施,提高我們資源的利用率。容器化項目團(tuán)隊最初加上我就只有三個人,同時我們還有各自的工作任務(wù)要做,留給容器化的時間較少,因此我們要考慮如何快速的搭建容器平臺,避免走全部自研這條路,這對我們來說是個巨大的挑戰(zhàn)。在經(jīng)歷了一年的容器化之旅后,分享下我們這一年所
2、踩過的坑和獲得的經(jīng)驗(yàn)。面臨的問題在搭建 k8s 集群前,有很多問題擺在我們面前:l人手不足,時間也不充裕,不能有太多自研的需求l我們目前的發(fā)布是由測試人員完成的,不可能要求他們?nèi)懸粋€ yaml 或執(zhí)行 kubectl 做發(fā)布,這個學(xué)習(xí)成本太高也容易出錯,因此我們必須構(gòu)建一個用戶體驗(yàn)良好的可視化平臺給發(fā)布人員使用l我們有大量的 .NET 項目,而 .NET 環(huán)境又依賴 WindowslConfigMap/Secret 不支持版本控制,同時用來存業(yè)務(wù)配置也不是很方便lk8s 集群和外部的通信如何打通容器平臺作為小團(tuán)隊去構(gòu)建一個容器平臺,自研的工作量太大了。前期我們調(diào)研過很多可視化平臺,比如 k8
3、sdashboard 和 rancher 等等,但是要操作這些平臺得需要專業(yè)的 k8s 運(yùn)維知識,這對我們的測試人員不太友好。后來我們嘗試了 KubeSphere(kubesphere.io)平臺,各方面都比較符合我們的需求,于是決定使用該平臺作為我們?nèi)萜髌脚_的基礎(chǔ),在這之上構(gòu)建我們自己的發(fā)布流程。感興趣的朋友可以去了解下這個平臺。.NET 項目我們的項目有 Java 也有 .NET 的,.NET 項目占了 80% 以上。要支持.NET 意味著要支持 Windows。在我們?nèi)ツ觊_始啟動項目的時候,k8s 剛升級到 1.14 版本,是支持Windows 節(jié)點(diǎn)的第一個版本,同時功能也比較弱。經(jīng)過實(shí)
4、驗(yàn),我們成功對 .NET Framework 的程序進(jìn)行了容器化,在不改代碼的前提下運(yùn)行在了 Windows 服務(wù)器上,并通過 k8s 進(jìn)行管理。不過我們也遇到了一些比較難處理的問題,使用下來的總結(jié)如下:lKubernetes 版本必須是 1.14 版本或以上l大多數(shù) Linux 容器若不做處理會自動調(diào)度到 Windows 節(jié)點(diǎn)上lWindows 基礎(chǔ)鏡像體積普遍比較大l必須使用 Windows Server 2019 及以上版本lk8s 關(guān)鍵性組件以 Windows 服務(wù)形式運(yùn)行,而非 Podl存儲和網(wǎng)絡(luò)的支持有局限性l部署步驟復(fù)雜,易出錯我們調(diào)研了一段時間后決定放棄使用 Linux 和Wi
5、ndows 的混合集群,因?yàn)檫@些問題會帶來巨大的運(yùn)維成本,而且也無法避免 Windows 的版權(quán)費(fèi)。我們也考慮過把這些項目轉(zhuǎn)換成 Java,但其中包含大量的業(yè)務(wù)邏輯代碼,把這些重構(gòu)為 Java 會消耗巨大的研發(fā)和測試的人力成本,顯然這對我們來說也是不現(xiàn)實(shí)的。那么有沒有一種方案是改動很少的代碼,卻又能支持 Linux 的呢?答案很明顯了,就是把 .NET 轉(zhuǎn) .NET Core。我們采用了這種方案,并且大多數(shù)情況能很順利的轉(zhuǎn)換一個項目而不需要修改一行業(yè)務(wù)邏輯代碼。當(dāng)然這個方案也有它的局限性,比如遇到如下情況就需要修改代碼無法直接轉(zhuǎn)換:l項目里使用了依賴 Windows API 的代碼l引用的第三
6、方庫無 .NET Core 版本lWCF 和 Web Forms 的代碼這些修改的成本是可控的,也是我們可以接受的。到目前為止我們已經(jīng)成功轉(zhuǎn)換了許多 .NET 項目,并且已運(yùn)行在 k8s 生產(chǎn)環(huán)境之上。集群暴露由于我們是基于物理機(jī)部署也就是裸金屬(Bare Metal)環(huán)境,所以無論基于什么平臺搭建,最終還是要考慮如何暴露 k8s 集群這個問題。暴露方式lLoadBalancer, 是 Kubernetes 官方推薦的暴露方式,很可惜官方支持的方式都需要部署在云上。我們公司全部是裸機(jī)環(huán)境部署,無法使用云方案。lNodePort,端口范圍一般是 30000 以上,每個端口只能對應(yīng)一種服務(wù)。如果應(yīng)
7、用越來越多,那端口可能就不夠用了。它最大的問題是如果你暴露某一個節(jié)點(diǎn)給外部訪問,那么這個節(jié)點(diǎn)會成為單點(diǎn)。如果你要做高可用,這幾個節(jié)點(diǎn)都暴露出去,前面一樣也要加一個負(fù)載均衡,這樣事情就復(fù)雜了。lIngress,可以解決 NodePort 端口復(fù)用的問題,它一般工作在7層上可以復(fù)用 80 和 443 端口。使用 Ingress 的前提是必須要有 Ingress Controller 配合,而 Ingress Controller 同樣會出現(xiàn)你需要暴露端口并公開的問題。這時候如果你用 HostNetwork 或 HostPort 把端口暴露在當(dāng)前的節(jié)點(diǎn)上,就存在單點(diǎn)問題;如果你是暴露多個節(jié)點(diǎn)的話,同
8、樣需要在前面再加一個LB。lHostNetwork/HostPort,這是更暴力的方式,直接把 Pod 的端口綁定到宿主機(jī)的端口上。這時候端口沖突會是一個很大的問題,同時單點(diǎn)問題依舊存在。裸金屬方案我們分別試用了兩套方案 MetalLB(metallb.universe.tf)和 Porter(/kubesphere/porter),這兩個都是以 LoadBalancer 方式暴露集群的。我們測試下來都能滿足需求。Porter 是 KubeSphere 的子項目,和 KubeSphere 平臺兼容性更好,但是目前 Porter 沒有如何部署高可用的文檔,我在這里簡單分享下:前置條件l首先你的路
9、由器,必須是三層交換機(jī),需要支持 BGP 協(xié)議。現(xiàn)在大多數(shù)路由設(shè)備都會支持這個協(xié)議,所以這個條件一般都能滿足l其次集群節(jié)點(diǎn)上不能有建立 BGP 通信的其他服務(wù)。舉例來說,當(dāng)使用 Calico 時,開啟了BGP模式。它的 BGP 端口運(yùn)行在每個集群節(jié)點(diǎn),Calico 和 Porter 同時啟用BGP 協(xié)議,會有部分節(jié)點(diǎn)同時運(yùn)行兩個組件與交換機(jī)建立 BGP 協(xié)議造成沖突。而 KubeSphere 默認(rèn)安裝的 Calico 是 ipip 模式的,所以我們沒有遇到?jīng)_突問題l最后一定要有網(wǎng)絡(luò)運(yùn)維人員支持,配合你完成路由器配置以及了解整個網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)。了解網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)是非常重要的,否則會遇到很多問題配置和
10、部署架構(gòu)和邏輯Porter有兩個插件:Porter-Manager 和 Porter-AgentPorter-Manager 是使用Deployment 部署到 Master 節(jié)點(diǎn)上的,但默認(rèn)只部署1個副本,它負(fù)責(zé)同步 BGP 路由到物理交換機(jī)(單向 BGP 路由,只需將 kubernetes 私有路由發(fā)布給交換機(jī)即可,無需學(xué)習(xí)交換機(jī)內(nèi)物理網(wǎng)絡(luò)路由)。還有一個組件,Porter-Agent,它以 DaemonSet 的形式在所有節(jié)點(diǎn)都部署一個副本,功能是維護(hù)引流規(guī)則。高可用架構(gòu)部署好后,你可能會有疑問:l單個路由器掛了怎么辦l單個 porter-manager 掛了怎么辦lporter-man
11、ager 和路由器網(wǎng)絡(luò)斷了怎么辦lEIP 下一跳地址所在的節(jié)點(diǎn)掛了怎么辦l某個 EIP 流量突然飆升,一個節(jié)點(diǎn)扛不住怎么辦一般路由器或交換機(jī)都會準(zhǔn)備兩臺做 VSU (Virtual Switching Unit) 實(shí)現(xiàn)高可用,這個是網(wǎng)絡(luò)運(yùn)維擅長的,這里不細(xì)講了。主要說下其他幾點(diǎn)怎么解決l確保一個 EIP 有多條 BGP 路由規(guī)則,交換機(jī)和 Manager 是多對多部署的l確保交換機(jī)開啟等價路由(ECMP)l要做好故障演練和壓力測試MetalLB 的高可用部署也是類似思路,雖然架構(gòu)稍有不同,比如它和路由器進(jìn)行 BGP 通信的組件是 Speaker,對應(yīng) Porter 的 Manager;它與Po
12、rter 的區(qū)別在于高可用目前做的比較好;但是 Local 引流規(guī)劃不如 Porter,EIP 的下一跳節(jié)點(diǎn)必須是 BGP 對等體(鄰居)。配置中心Kubernetes 的 ConfigMap 和 Secret 在一定程度上解決了配置的問題,我們可以很輕松的使用它們進(jìn)行更改配置而不需要重新生成鏡像,但我們在使用的過程中還是會遇到一些痛點(diǎn):1.不支持版本控制Deployment 和 StatefulSet 都有版本控制,我們可以使用 rollout 把應(yīng)用回滾到老的版本,但是 ConfigMap/Secret 卻沒有版本控制,這會產(chǎn)生一個問題就是當(dāng)我們的Deployment 要進(jìn)行回滾時,使用的
13、 ConfigMap 還是最新的,我們必須把 ConfigMap 改回上一個 Deployment 版本所使用的 ConfigMap 內(nèi)容,再進(jìn)行回滾,但是這樣的操作是很危險的,假設(shè)改完 ConfigMap 后有個 Pod 出了問題自動重啟了,又或者 ConfigMap 以文件形式掛載到 Pod 中,都會造成程序讀取到了錯誤的配置。一個折中的做法是每個版本都關(guān)聯(lián)一個單獨(dú)的 ConfigMap。2.不太適合管理業(yè)務(wù)配置一個應(yīng)用有時候會需要加很多業(yè)務(wù)配置,在維護(hù)大量業(yè)務(wù)配置時,我們可能需要搜索關(guān)鍵字、查看某個 key 的備注、對 value 的格式進(jìn)行校驗(yàn)、批量更新配置等等,但是如果使用了Conf
14、igMap ,我們就不得不再做一些工具來滿足這些需求,而這些需求對于配置的維護(hù)效率是有非常大的影響。3.熱更新我們知道如果 ConfigMap 是以文件形式進(jìn)行掛載,那么當(dāng)修改了 ConfigMap 的值后,過一會所有的 Pod 里相應(yīng)的文件都會變更,可是如果是以環(huán)境變量的方式掛載卻不會更新。為了讓我們的程序支持熱更新,我們需要把 ConfigMap 都掛載成文件,而當(dāng)配置有很多時麻煩就來了,如果 Key 和文件是一對一掛載,那么 Pod 里會有很多小文件;如果所有 Key 都放到一個文件里,那么維護(hù)配置就成了噩夢。4.配置大小限制ConfigMap 本身沒有大小限制,但是 etcd 有,默認(rèn)
15、情況下一個 ConfigMap 限制為 1MB,我們估算了下,有個別應(yīng)用的配置加起來真有可能突破這個限制,為了繞過這個大小限制,目前也只有切割成多個 ConfigMap 的方法了。為了解決這些痛點(diǎn),我們綜合考慮了很多方案,最終決定還是使用一套開源的配置中心作為配置的源,先通過Jenkins 把配置的源轉(zhuǎn)換成 ConfigMap,以文件形式掛載到 Pod 中進(jìn)行發(fā)布,這樣以上的問題都可以迎刃而解。我們選擇了攜程的 Apollo(/ctripcorp/apollo)作為配置中心 ,其在用戶體驗(yàn)方面還是比較出色的,能滿足我們?nèi)粘>S護(hù)配置的需求。微服務(wù)在遷移微服務(wù)到 k8s 集群的時候基本都會遇到一個
16、問題,服務(wù)注冊的時候會注冊成 Pod IP,在集群內(nèi)的話沒有問題,在集群外的服務(wù)可就訪問不到了。我們首先考慮了是否要將集群外部與 Pod IP 打通,因?yàn)檫@樣不需要修改任何代碼就能很平滑的把服務(wù)遷移過來,但弊端是這個一旦放開,未來是很難收回來的,并且集群內(nèi)部的 IP 全部可訪問的話,等于破壞了 k8s 的網(wǎng)絡(luò)設(shè)計,思考再三覺得這不是一個好的方法。我們最后選擇了結(jié)合集群暴露的方式,把一個微服務(wù)對應(yīng)的 Service 設(shè)置成 LoadBalancer,這樣得到的一個 EIP 作為服務(wù)注冊后的 IP,手動注冊的服務(wù)只需要加上這個 IP 即可,如果是自動注冊的話就需要修改相關(guān)的代碼。這個方案有個小小的
17、問題,因?yàn)橐粋€微服務(wù)會有多個 Pod,而在遷移的灰度過程中,外部集群也有這個微服務(wù)的實(shí)例在跑,這時候服務(wù)調(diào)用的權(quán)重會不均衡,因?yàn)榧簝?nèi)的微服務(wù)只有一個 IP,通常會被看作是一個實(shí)例。因此如果你的業(yè)務(wù)對負(fù)載均衡比較敏感,那你需要修改這里的邏輯。調(diào)用鏈監(jiān)控我們一直使用的是點(diǎn)評的 CAT(/dianping/cat)作為我們的調(diào)用鏈監(jiān)控,但是要把 CAT 部署到 k8s 上比較困難,官方也無相關(guān)文檔支持??偨Y(jié)部署 CAT 的難點(diǎn)主要有以下幾個:lCAT 每個實(shí)例都是有狀態(tài)的,并且根據(jù)功能不同,相應(yīng)的配置也會不同,因此每個實(shí)例的配置是需要不一樣的,不能簡單的掛載 ConfigMap 來解決lCAT 每
18、個實(shí)例需要綁定一個 IP 給客戶端使用,不能使用 Service 做負(fù)載均衡。lCAT 每個實(shí)例必須事先知道所有實(shí)例的 IP 地址lCAT 每個實(shí)例會在代碼層面獲取自己的 IP,這時候獲取到的是可變的 Pod IP,與綁定的 IP 不一致,這就會導(dǎo)致集群內(nèi)部通信出問題為了把 CAT 部署成一個 StatefulSet 并且支持?jǐn)U容,我們參考了 Kafka 的 Helm 部署方式,做了以下的工作:l我們?yōu)槊總€ Pod 創(chuàng)建了一個 Service,并且啟用 LoadBalancer 模式綁定了 IP,使每個 Pod 都會有一個獨(dú)立的對外 IP 地址,稱它為 EIP;l我們把所有實(shí)例的信息都保存在配
19、置中心,并且為每個實(shí)例生成了不同的配置,比如有些實(shí)例是跑 Job,有些實(shí)例是跑監(jiān)控的;l我們會預(yù)先規(guī)劃好 EIP,并把這些 EIP 列表通過動態(tài)生成配置的方式傳給每個實(shí)例;l最后我們給每個實(shí)例里塞了一個特殊的文件,這個文件里存的是當(dāng)前這個實(shí)例所綁定的 EIP 地址。接著我們修改了 CAT 的代碼,把所有獲取本地 IP 地址的代碼改成了讀取這個特定文件里的 IP 地址,以此欺騙每個實(shí)例認(rèn)為這個 EIP 就是它自己的本地 IP。擴(kuò)容很簡單,只需要在配置中心里添加一條實(shí)例信息,重新部署即可。CI/CD由于 KubeSphere 平臺集成了 Jenkins,因此我們基于 Jenkins 做了很多 CI
20、/CD 的工作。發(fā)布流程起初我們?yōu)槊總€應(yīng)用都寫了一個 Jenkinsfile,里面的邏輯有拉取代碼、編譯應(yīng)用、上傳鏡像到倉庫和發(fā)布到 k8s 集群等。接著我為了結(jié)合現(xiàn)有的發(fā)布流程,通過 Jenkins 的動態(tài)參數(shù)實(shí)現(xiàn)了完全發(fā)布、制作鏡像、發(fā)布配置、上線應(yīng)用、回滾應(yīng)用這樣五種流程。處理配置由于前面提到了 ConfigMap 不支持版本控制,因此配置中心拉取配置生成 ConfigMap 的事情就由 Jenkins 來實(shí)現(xiàn)了。我們會在 ConfigMap 名稱后加上當(dāng)前應(yīng)用的版本號,將該版本的 ConfigMap 關(guān)聯(lián)到 Deployment 中。這樣在執(zhí)行回滾應(yīng)用時 ConfigMap 也可以一起
21、回滾。同時 ConfigMap 的清理工作也可以在這里完成。復(fù)用代碼隨著應(yīng)用的增多,Jenkinsfile 也越來越多,如果要修改一個部署邏輯將會修改全部的 Jenkinsfile,這顯然是不可接受的,于是我們開始優(yōu)化 Jenkinsfile。首先我們?yōu)椴煌愋偷膽?yīng)用創(chuàng)建了不同的 yaml 模板,并用模板變量替換了里面的參數(shù)。接著我們使用了 Jenkins Shared Library 來編寫通用的 CI/CD 邏輯,而 Jenkinsfile 里只需要填寫需要執(zhí)行什么邏輯和相應(yīng)的參數(shù)即可。這樣當(dāng)一個邏輯需要變更時,我們直接修改通用庫里的代碼就全部生效了。數(shù)據(jù)落地隨著越來越多的應(yīng)用接入到容器發(fā)布中,不可避免的要對這些應(yīng)用的發(fā)布及部署上線的發(fā)布效率、失敗率、發(fā)布次數(shù)等指標(biāo)進(jìn)行分析;其次我們當(dāng)前的流程雖然實(shí)現(xiàn)了 CI/CD 的流程代碼復(fù)用,但是很多參數(shù)還是要去改對應(yīng)應(yīng)用的 Jenkinsfile 進(jìn)行調(diào)整,這也很不方便。于是我們決定將所有應(yīng)用的基本信息、發(fā)布信息
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 掃地機(jī)器人市場前景總結(jié)
- Spiromesifen-Standard-生命科學(xué)試劑-MCE
- 《體育心理學(xué)》教案
- Sisomicin-sulfate-Standard-生命科學(xué)試劑-MCE
- 城市立體農(nóng)業(yè)栽培項目可行性研究
- 高中歷史教學(xué)中地方史課程的開發(fā)應(yīng)用
- 病理學(xué)理論2024學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 骨科??茟?yīng)急預(yù)案
- 生物技術(shù)工藝學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 腫瘤的腸內(nèi)營養(yǎng)治療
- 老年人中常見呼吸系統(tǒng)疾病的診斷與治療
- 胺碘酮臨床應(yīng)用
- 雨水泵站及配套工程施工組織設(shè)計樣本
- 成長生涯發(fā)展展示
- T-ZJFS 010-2024 銀行業(yè)金融機(jī)構(gòu)轉(zhuǎn)型貸款實(shí)施規(guī)范
- 六年級數(shù)學(xué)課件-圓的面積【全國一等獎】
- 食管炎的護(hù)理查房
- 老年人的火災(zāi)預(yù)防與自救技巧課件
- 新時代魯班精神
- 《教育的初心》讀書分享
- 軟件工程生涯發(fā)展展示
評論
0/150
提交評論