1. 程式人生 > >PaaS雲平臺在企業落地的 8 大關鍵點_Kubernetes中文社群

PaaS雲平臺在企業落地的 8 大關鍵點_Kubernetes中文社群

5月26日,時速雲企業級容器 PaaS 技術沙龍第9期在深圳成功舉辦,時速雲聯合創始人兼技術總監楊樂就 PaaS 平臺落地實施所關注的一些問題、Kubernetes 核心元件、Kubernetes 資源物件以及 Devops 體系、微服務治理等方面做出了深入的探討和分享。

以下是本次分享的實錄:

楊樂:非常感謝大家,在這個天氣炎熱的週六來到這裡。在這裡給大家帶來的是關於 PaaS 雲平臺在企業中落地的經驗分享,其中包括了生產環境中關注的問題,Kubernetes 的架構和資源物件的利用,以及我們在實際實施過程中遇到的一些問題。另外 PaaS 平臺體系構建完成,是如何在容器雲上進行的應用實踐的,以及我們基於

Docker、Kubernetes 所構建 DevOps 體系持續整合,測試環境和生產環境是如何應用 Kubernetes 去構建執行使用的,我們還會介紹微服務治理相關的架構,以及我們部署架構的知識。

基於Docker和K8S的平臺建設
1、PaaS 容器雲平臺落地實施關注的問題

在 PaaS 雲平臺落地的時候,會有一些關注點,我們在企業落地實施的過程中,首先關注架構執行的方式,也就是說我們最初架構的選型,以及它的核心元件,比如說我們的日誌如何去收集,監控和報警元件是如何執行的。在 PaaS 平臺上執行的應用,相關的應用服務是如何釋出出去的,是以何種方式代理出去的。以及我們在落地實施的時候,平臺自身的元件以及 Kubernetes 本身的元件如何實現它的高可用,真正實現生產執行體系。

為了執行有狀態應用,需要分散式儲存進行支援。如何構建叢集的網路型別,如何將容器服務進行叢集內的網路打通。持續整合體系是我們基於 Kubernetes 相關的資源物件去構建的開發測試運維一體化的子產品。而最終要去注重使用者應用的釋出、執行,同時需要以容器的方式在部署到 PaaS 平臺,如何將應用容器進行互聯。

我們會關注真正落地實施之後,從它的架構運營、高可用性,到最終成體系的構建、應用的部署。而這幾個關鍵點,會在後面每一個對應到 Kubernetes 架構體系上,一一介紹。

在場的各位對 Docker 和 Kubernetes 有沒有一些瞭解,Docker  是單機容器的執行引擎。而 Kubernetes 是將容器以及 Docker 做叢集架構的體系,它的架構方式是 Master、Slave 的方式。也就是說 Master 作為中控調動中心,去控制我的 Slave 結點。而 Slave 節點上面,所有的這些結點去執行相關的容器。應用服務都會用容器的方式執行在 Slave 節點之上。而它的釋出是通過 Service 以及外部代理的方式向外釋出。而每一個容器可以通過設定後端儲存的方式進行持久的儲存。

在 Kubernetes 元件裡,需要關注日誌元件。當容器執行在 Kubernetes 架構體系的時候,我需要關心應用本身產生的日誌有沒有問題。測試和開發人員需要獲取一些除錯的資訊,然後去判斷它的問題在哪裡。而運維人員也需要檢視發生問題的應用,它的日誌在哪裡。

當容器的 CPU 或者是記憶體發生了一些變動,超出負載的閾值時,需要做及時的報警。在內網進行服務發現的時,需要一個 DNS 的配置,以此各個應用間可進行探測和呼叫。

我們後面會有一些儲存和網路,網路需要支援我們整個叢集之內所有的結點,容器之間需要網路的打通,可以讓容器在內網之間做一個互聯,做一個架構的連線。

2、Kubernetes核心元件

Kubernetes 核心元件包括日誌、監控、kube-dns。從日誌來說,Kubernetes 這些日誌元件是從 ElsaticSearch 構建的。它會從節點裡面收集相關的容器日誌資訊。會把這些資訊傳送到中控的 ElsaticSearch 元件裡面去。當這些資訊收集完了之後,會通過外部的 UI、開發的UI的元件或者是用 Kibana 展示元件去進行合理的展示。

運維人員和開發人員可以通過視覺化的展示元件去檢索對應的日誌。對於日誌來說,Docker logs 是預設的日誌輸出的位置。但是通過一些特定的設定,不單單可以收集 Docker logs 本身產生的日誌,還能夠指定應用所能夠達到日誌的位置,指定相關的目錄,並能夠隨意收集容器內部日誌的資訊。

在監控體系方面,第一種方式,Kubernetes 本身是使用 Kubelet 以及 Heapster、Influxdb 構建的。Influxdb 會把相關監控資訊儲存起來,監控資料從kubelet中通過heapster遠端獲取的。通過 Grafana 去展示相關的監控資訊。使用者通過一個集中化監控展示平臺,可以檢視到指定的容器服務所用的 CPU、記憶體相關的監控資訊。

第二種監控體系是使用 Prometheus 元件,這兩種體系是分別獨立的。它的方式也是通過收集每一個節點相關的 CPU、記憶體等等監控資訊,儲存到一箇中心化儲存體系裡面去,然後再把相應的監控資訊展示出來。

對於報警體系,可以通過 Prometheus 本身的一些規則的設定,可以設定達到我 CPU 預值20% 的時候會觸發報警事件。它可以呼叫外部相關操作的動作,比如說呼叫我們的平臺,呼叫我們平臺 API 裡面所整合的簡訊或者郵件 API。就可實現從我們平臺發生的監控,比如說超過了預值的 CPU,自動發出報警給我們的管理員,管理員就可以在及時檢測到CPU、容器以及節點它的問題所在。

Kubernetes 一個核心元件就是 kube-DNS,它是為 Kubernetes 內部應用之間做服務發現。什麼是服務發現,當我們把我們的應用去執行到 Kubernetes 體系裡面去的時候,每一個應用中需要有一定的機制發現對方。我需要知道我周圍的這些應用執行的名字是什麼,它的執行位置在哪裡,它的 IP 是多少。我需要這樣一套發現機制,而 Kubernetes 本身提供的一方面把每一個應用和容器的資訊記錄到 Master 裡面去。同時用 Kubernetes DNS 的方式展現給其它的應用工具。

當用戶建立應用後,會在內網 kube-dns 裡面記錄一個域名。 每一個域名對應我一個應用,當其它的應用容器想要連線指定的應用的時候,只需要通過 DNS 域名就可以連線到。DNS 的 Kubedns 元件,不停的跟 Master Apiserver 進行互動,實時獲取所建立或者是刪除的這些應用的狀態,獲取IP地址、名稱,並記錄在 DNS 儲存空間裡,形成一條條 DNS 記錄。而 DNS 會把相應的記錄資訊整合成DNS的服務出口。這樣其它的應用服務可以通過DNS的53埠,進行查詢,和DNS記錄檢索。這樣就實現在整個聯網範圍之內,通過DNS去查詢到指定的應用服務的功能。

Kube-DNS 是可以應用到 Kubernetes 本身的編排體系裡面去。也就是說當我們執行應用到Kubernetes 架構體系裡面之後,它不單是一個應用,而是多應用需要編排在一起。編排在一起就需要每一個應用互相之間進行一個發現和連線,而連線就需要用IP地址或者是域名,這裡面就是用域名的方式。

所以我在編排的時候,通過一個編排檔案,把編排檔案每一個應用之間,它是用域名的方式設計到裡面去。通過編排檔案它可以統一的建立所有的應用,讓它同時去啟動或者是順序啟動,進行一個架構的建設。

高可用性,高可用對於系統平臺來說,包括 Kubernetes 本身的高可用,還有我們提供自身產品的高可用,還有各種其它元件和儲存的高可用。Kubernetes 本身高可用提供的這種方式,首先 Master高可用,Master 高可用通過多個 Master 的方式讓它多活,然後通過統一的 Keepalived 的方式跟 Service 進行一個互聯。

而相應的服務對外發布出口的時候,需要有一個對外的出口。底層儲存的方式是通過多活的方式進行高可用的設定。平臺本身每一個涉及到單點故障問題的元件都設定了高可用性,這個也是在生產環境中必要考慮的。

3、Kubernetes的資源物件
Kubernetes 的一些資源物件, Kubernetes 的 Pod 的概念,對容器本身來說,一個 Pod 裡面可以包含多個容器,而多個容器在同一個 Pod 裡面是可以共享網路和儲存的。這就實現了在多個容器進行編排的時候,每一個容器都可以進行非常緊密的連線。Deployment 可以對 Pod 進行副本的管理,或者是進行滾動升級的識別。

而 Service 這個概念就是一個抽象的服務出口,這就是為了將我的 Pod 或者是我的容器執行在 Kubernetes 之後,如何將它釋出出去,如何讓使用者從外部進行一個訪問,讓 Service  做這件事情,它實際上是在我們的節點上做了一個負載均衡器。一個基於 IOS 一個負載均衡器。它會把使用者外部訪問的流量分發到內部多個 Pod 或者是容器上面進行一個負載均衡。

Labels 實際上是指在我 Kubernetes 本身資源物件裡面作為一個標籤,以及標籤選擇的方式。

ConfigMap 實際上是對資料的管理,我可以通過把我的一些外部配置資訊放在 Kubernetes  儲存裡面的一種方式。然後去解決我在構建完我的容器進項之後,我希望把我的這些進項放在不同的環境裡面,而不同的環境外部配置資訊反而不一樣。而我又不希望更改我容器裡面的這些內容。那就用外部的方式,將外接的配置資訊載入到容器裡面。

而這個 ConfigMap 就起外部配置資訊載入到容器裡面的作用的。Secret 本身是解決密碼以及 token 相關的問題。Job 是任務以及定時任務,我可以設定一個應用程式或者是一個程序讓它執行一次,或者我可以設定定時進行。這些可以把它思考成一個 cronjob,也就是說一些定時任務會去做。

水平伸縮也就是說 HPA,在 Kubernetes 裡面,它可以做到應用容器的一些自動伸縮。可以根據我們的 CPU 或者是記憶體、網路或者是磁碟 AIO,它的引數,進行一個例項的伸縮。如果我們設定了一個預值,如果 CPU 超過了 50%,那麼我的容器自動擴充套件到 10 個或者是 20 個。當 CPU 低於百分之多少的時候,我可以讓他自動回縮到指定的數量。這就是在負載變化的情況下,對例項伸縮的功能。

而下面的 Stateful、Volumes 以及 Ingress,Stateful 是為了解決有狀態服務,以及可以做叢集模式物件。Volumes 是為了解決相關磁碟儲存,還有 Ingress 是 Kubernetes 本身指定的負載均衡代理。

對於 Kubernetes 資源物件 Stateful 首先是為了解決有狀態儲存的一些應用。如果需要手動設定多個 Pod 之間的儲存配置,就會出現一個問題,Pod 重啟之後就消失了。所以如果我們手動配置的話,就很難做到他們之間主從的配置

而 Stateful 是為了解決這個問題,Stateful 第一個特點是可以掛載相應的動態儲存。第二他可以將起來的這些 Pod 進行有序的標號,也就是說普通的 Pod 的話,它的標號是隨機的。但是這種 Stateful 是有序的,從 0 開始一直到 N 為止。也就是說這幾個 Pod 之間是可以用有序的名字互相發現。這就帶來一個可能,我在執行 Stateful 的時候,我可以設定一些引數或者是指令碼,讓他們按照這個名字互相發現。這樣你通過互相發現的方式,再進行主從之間一些動態設定。這就可以實現我起了多個容器,通過 Stateful 進行一些動態設定。他們可以完成主從,進行叢集的配置。也就是說 Stateful 可以實現各個需要進行主從配置應用軟體的叢集設定。

Ingress 我們之前提到作為一個服務出口,當我們的應用執行在 Kubernetes 的時候,我們需要把它進行對外的釋出,釋出的方式可以通過代理的方式,也可以通過 Ingress 的方式。

實際上 Ingress 對應的就是我們所關注的服務出口的問題,而 Ingress 是解決出口的方式之一,實際上還有其它很多種方式,也可以自研去做這個事情。

Volumes 是解決整個 PaaS 平臺它的儲存問題,我們應用容器在執行的時候,如果我們用過 Kubernetes,如果 Pod 起來以後,如果不進行持久化儲存的話,重啟以後很多內容丟失。為了防止關鍵資訊丟失,我們需要掛在分部式的儲存。

一種方式就是我們通過 PVC 的方式,掛在一些檔案體系上面。這樣 Pod 在進行遷移的時候,其中一個 Pod 在機器上掛掉以後。它的儲存會跟隨我們的 Pod 從另外一個可用的機器上起來。這樣的話,它原來的內容可以在新的 Pod 裡面讀取到,這樣就達到儲存可用性的效果。

Kubernetes 網路型別也有很多種方式,現在我們常用或者是我們現在支援的方式就是包括讓 Calico、Flannel、Weave 的方式。實際上一種是隧道的方式,或者是用路由的方式去實現。

4、Kubernetes生產環境的實施

從上圖我們可以看到生產環境實施的整個架構模式圖,首先對於 Kubernetes 來說,整個叢集各個元件模組是需要多副本的,整個控制檯對 API 呼叫的控制端需要多個節點,以及映象倉庫、檔案儲存,以及相關的 Slave 都是需要多節點的。

而在叢集內部,需要一組服務出口。在應用的時候,持續整合所需要執行一組叢集,這些都需要高可用去做。每一個功能元件,可以通過一種方式進行合理的分組。每種型別的元件或者應用,可以執行到指定的伺服器節點上去。

容器雲平臺在企業中的應用場景
1、容器雲平臺功能體系
下面給大家介紹一下容器雲平臺在企業中應用場景,首先可以看一下整個容器雲平臺功能體系,首先是最基本的應用管理。可以通過 Kubernetes 去建立應用,去管理應用。可以通過 Kubernetes job 去實現持續整合的體系,包括程式碼倉庫、映象構建以及持續部署這些功能。微服務體系包括服務發現、負載均衡等,應用之間可以進行服務監控。可以通過Stateful 資源物件一鍵建立一套叢集體系。包括我們分散式的儲存,相應佇列,大資料的一些元件等等。

 而 Kubernetes 本身部署起來,可以是虛擬機器,也可以是物理機,也就是說它的底層架構可以是偶合的。

2、Devops體系

通過 Kubernetes job 的方式來進行持續整合,也就是說持續整合構建的框架。通過這個框架,我們啟動我們的持續整合的時候,我們會調動 API。通過 job 的方式,啟動多個構建服務,每一個 job 對應一個任務去完成它指定的工作。當它完成以後,會通過程式碼的構建以及映象的生成。結束以後,它會把相應的映象放在指定的映象倉庫裡面去。。

通過對映象倉庫以及 API 的設定,它可以自動從映象倉庫裡再次部署到 Kubernetes 的環境裡面。

開發人員可以通過程式碼提交的方式去觸發持續整合。同時進行單元測試。測試結束之後做一些審計,然後把這些結果傳送。掃描結束之後會對它進行一個編輯,編譯的結果會傳到下一步裡面,進行一個程式碼構建,程式碼構建會生成相應的映象,它會推送到我的映象中心,然後會接受一些安全掃描。掃描映象裡面是否存在一些安全風險,它有沒有一些漏洞。在漏洞掃描結束之後,會經過部門的審批流程。如果部門審批流程通過,它就可以進行下一個映象釋出或者是釋出到我們的平臺,或者是讓它上傳到我們的應用商店裡面。

這樣當映象進行一個釋出之後,會執行到測試環境,可以交給測試團隊進行一個部署的測試。當測試團隊發現問題之後,會交給開發人員進行再一次迭代。這樣就會形成從研發體系到程式碼提交到研發開發測試,到最終的部署執行以及再次迴環的迭代,整個迴環體系就構建起來了。

3、測試生產執行體系

這是測試環境以及生產環境的執行體系,在給客戶部署實施的時候,一般情況下,很多使用者都是按不同的部門或者是按不同的網路環境的多個叢集。在這個圖上可以看到左邊是測試環境叢集,也就是說這是一套獨立的 Kubernetes 叢集體系,右邊是生產環境的一些叢集。這裡面是所有生產環境的應用都在執行。

從構建體系來說,持續整合體系可以在這裡面跑。也就是說從程式碼的生成到持續整合部署到映象生成,自動把業務應用上去,開發測試人員通過測試環境對它進行一個測試。最終當測試完畢之後,這些映象可以通過定版的方式同步到生產環境的映象中心裡面。

然後再通過運維或者是專案經理的管理,進行一個生產環境的部署。這樣的話它就形成整套從生產環境到測試環境整體的運維體系。當我們在真正生產運維的時候,可以通過生產環境中的日誌管理、監控管理、審計系統,通過這些元件進行生產環境的運維。

4、微服務治理

微服務治理是基於 Kubernetes 的特性基礎上,將 SpringCloud 架構結合在一起。集成了  SpringCloud 的服務發現、負載均衡、配置管理等元件,可以用容器的方式執行到  Kubernetes 平臺裡面。使用者可以把基於 springboot 開發的應用執行到平臺裡面,執行上去之後,應用將註冊到服務註冊中心,並可使用 SpringCloud 的相關元件。

生產環境落地實施後,最終要實現的是使用者的應用要上雲,真正的部署上去。部署的環節需要首先把應用程式進行容器化。需要構建應用的生產環境,將應用程式進行打包,然後將應用的映象部署到我們的 Kubernetes 裡,讓 Kubernetes 對應用程式進行生命週期的管理,當整個架構體系和服務體系上雲以後,可以進行多個元件之間的編排,元件直接進行互聯,並且通過配置管理進行相同應用多個環境的部署。

當涉及到資料庫的儲存時,需要使用 Stateful 物件進行管理。當應用架構部署完成以後,對外發布的時候,需要進行負載均衡出口的管理。最終以如圖這種方式,通過負載均衡訪問到 APP,以及資料儲存通過儲存塊進行有狀態保持,在運維的過程中,對其進行配置管理,以及監控、日誌的檢視、操作,這樣一整套運維體系就可以構建起來。

Q&A

Q:使用者隔離怎麼做?

A:使用者隔離是基於使用者名稱空間的體系做的網路隔離。Calico本身是負責網路隔離的,再就是一些使用者體系的資源隔離,都可以通過kubernetes 的名稱空間進行隔離。

Q:我剛才看有大資料相關的元件,我不知道你這邊大資料有沒有用到ES等效能要求比較高的應用。在這種情況下,你們的效能表現是什麼樣的。第二個問題是在Kubernetes有三種service模式,你這邊是哪一種模式?

A:大資料相關的元件實際上如果你要執行的話,跟效能相關的,還是基於底層硬體體系。也就是說 Kubernetes 本身是需要架設在 IaaS 或者是物理基上的。如果說底層效能不夠優的話,你構建那些 SDN 網路,它的效能也會受到連累。因為本身它訪問的效能以及儲存的效能,都是涉及到我用 ios 這種軟體定義網路的方式去做的。最終是要打到物理環境裡的。

第一建議網路做的比較優,再就是要用高效能,高 IO 的儲存元件。

第二個問題是 Service,通過 Service nodeport 對外發布的時候,但是對於企業管理來說,你可能涉及到要釋出到哪一個節點上,以及這些節點上的關口如何去管理。如果你這一套系統自用的話,這個方式是沒有問題的。但是如果是一個企業或者是公有云,就會涉及到這些埠對於管理人員來說,管理起來是比較困難的。

所以最好集中的方式用這種指定節點,並且讓它只是在幾個節點上開埠的方式,或者是用 externalIP 這種方式做比較好。