Kubernetes+Docker+Istio 容器雲實踐

宜信技術學院發表於2019-10-17

隨著社會的進步與技術的發展,人們對資源的高效利用有了更為迫切的需求。近年來,網際網路、移動網際網路的高速發展與成熟,大應用的微服務化也引起了企業的熱情關注,而基於Kubernetes+Docker的容器雲方案也隨之進入了大眾的視野。開普勒雲是一個基於Kubernetes+Docker+Istio的微服務治理解決方案。

一、Microservices

1.1 解決大應用微服務化後的問題

現在各大企業都在談論微服務,在微服務的大趨勢之下技術圈裡逢人必談微服務,及微服務化後的各種解決方案。

1.2 當我們在討論微服務的時候我們在討論什麼?

使用微服務架構有很多充分的理由,但天下沒有免費的午餐,微服務雖有諸多優勢,同時也增加了複雜性。團隊應該積極應對這種複雜性,前提是應用能夠受益於微服務。

1.2.1 如何微服務化的問題

  • 微服務要如何拆分
  • 業務API規則
  • 資料一致性保證
  • 後期可擴充套件性考慮

當然這不是本文主要討論的問題,我不講微服務具體要如何拆分,每個企業每個應用的情況都不太一樣,適合自己的方案就是最好的拆分方案。我們主要來解決微服務化後所帶來的一些問題。

1.2.2 微服務化後帶來的問題

  • 環境一致性
  • 如何對資源快速分配
  • 如何快速度部署
  • 怎麼做基本監控
  • 服務註冊與發現
  • 負載均衡如何做

以上都是大應用微服務化所需要解決的基礎問題,如果還按照傳統的方式使用虛擬機器來實現,資源開支將會非常大。那麼這些問題要怎麼解決呢?比如:  

  • 流量管理
  • 服務降級
  • 認證、授權

當然面對上述這些問題我們廣大的猿友們肯定是有解決方案的。

1.3 Service governance

1.3.1 Java 體系

假設我們是Java體系的應用,那解決起來就很方便了,比如我們可以考慮使用SpringCloud全家桶系列。也可以拆分使用:  

  • Eureka
  • Hystrix
  • Zuul
  • Spring-cloud
  • Spring-boot
  • ZipKin

Java體系下能很方便的做以我們微服務化後的基礎部分,但依然不能非常舒服地解決環境一致性,並且如果有其他語系的服務將很難融入進去。

我們來看基礎程式語言一般有什麼組合方式來解決基礎問題。

1.3.2 其他體系

  • Consul
  • Kong
  • Go-kit
  • Jaeger/Zipkin

假設我們是使用Golang語言,這裡再捧一下Golang語言。go語言簡直就是天生為微服務而生的語言,實在不要太方便了。高效的開發速度及相當不錯的效能,簡單精悍。

跑題了~我們使用上面這些工具也可以組成一套還不錯的微服務架構。

  • Consul: 當作服務發現及配置中心來使
  • Kong: 作為服務閘道器
  • Jaeger: 作為鏈路追蹤來使
  • Go-kit: 開發元件

但是這種方案也有問題,對服務的侵入性太強了,每個服務都需要嵌入大量程式碼,這還是很頭疼的。

二、Docker & Kubernetes

基於Docker+k8s搭建平臺的實踐方案。

2.1 Docker

Docker 是一個非常強大的容器。

  • 資源利用率的提升
  • 環境一致性、可移植性
  • 快速度擴容伸縮
  • 版本控制

使用了Docker之後,我們發現可玩的東西變多了,更加靈活了。不僅僅是資源利用率提升、環境一致性得到了保證,版本控制也變得更加方便了。

以前我們使用Jenkins進行構建,需要回滾時,又需要重新走一次jenkins Build過程,非常麻煩。如果是Java應用,它的構建時間將會變得非常長。

使用了Docker之後,這一切都變得簡單了,只需要把某個版本的映象拉下來啟動就完事了(如果本地有快取直接啟動某個版本就行了),這個提升是非常高效的。

(圖片來源網路)

既然使用了Docker容器作為服務的基礎,那我們肯定需要對容器進行編排,如果沒有編排那將是非常可怕的。而對於Docker容器的編排,我們有多種選擇:Docker Swarm、Apache Mesos、Kubernetes,在這些編排工具之中,我們選擇了服務編排王者Kubernetes。

2.1.1 Docker VS VM

  • VM: 建立虛擬機器需要1分鐘,部署環境3分鐘,部署程式碼2分鐘。
  • Docker: 啟動容器30秒內。

2.2 Why choose Kubernetes

我們來對比這三個容器編排工具。

2.2.1 Apache Mesos

Mesos的目的是建立一個高效可擴充套件的系統,並且這個系統能夠支援各種各樣的框架,不管是現在的還是未來的框架,它都能支援。這也是現今一個比較大的問題:類似Hadoop和MPI這些框架都是獨立開的,這導致想要在框架之間做一些細粒度的分享是不可能的。

但它的基礎語言不是Golang,不在我們的技術棧裡,我們對它的維護成本將會增高,所以我們首先排除了它。

2.2.2 Docker Swarm

Docker Swarm是一個由Docker開發的排程框架。由Docker自身開發的好處之一就是標準Docker API的使用。Swarm的架構由兩部分組成:

(圖片來源網路)

它的使用,這裡不再具體進行介紹。

2.2.3 Kubernetes

Kubernetes是一個Docker容器的編排系統,它使用label和pod的概念來將容器換分為邏輯單元。Pods是同地協作(co-located)容器的集合,這些容器被共同部署和排程,形成了一個服務,這是Kubernetes和其他兩個框架的主要區別。相比於基於相似度的容器排程方式(就像Swarm和Mesos),這個方法簡化了對叢集的管理.

不僅如此,它還提供了非常豐富的API,方便我們對它進行操作,及玩出更多花樣。其實還有一大重點就是符合我們的Golang技術棧,並且有大廠支援。

Kubernetes 的具體使用這裡也不再過多介紹,網站上有大把資料可以參考。

2.3 Kubernetes in kubernetes

kubernetes(k8s)是自動化容器操作的開源平臺,這些操作包括部署、排程和節點叢集間擴充套件。

  • 自動化容器的部署和複製
  • 隨時擴充套件或收縮容器規模
  • 將容器組織成組,並且提供容器間的負載均衡
  • 很容易地升級應用程式容器的新版本
  • 提供容器彈性,如果容器失效就替換它,等等...

2.4 Kubernetes is not enough either

到這裡我們解決了以下問題:

  • Docker: 環境一致性、快速度部署。
  • Kubernetes: 服務註冊與發現、負載均衡、對資源快速分配。

當然還有監控,這個我們後面再說。我們先來看要解決一些更高層次的問題該怎麼辦呢?

在不對服務進行侵入性的程式碼修改的情況下,服務認證、鏈路追蹤、日誌管理、斷路器、流量管理、錯誤注入等等問題要怎麼解決呢?

這兩年非常流行一種解決方案:Service Mesh。

三、Service Mesh

處理服務間通訊的基礎設施層,用於在雲原生應用複雜的服務拓撲中實現可靠的請求傳遞。

  • 用來處理服務間通訊的專用基礎設施層,透過複雜的拓撲結構讓請求傳遞的過程變得更可靠。
  • 作為一組輕量級高效能網路代理,和程式部署在一起,應用程式不需要知道它的存在。

在雲原生應用中可靠地傳遞請求可能非常複雜,透過一系列強大技術來管理這種複雜性: 鏈路熔斷、延遲感知、負載均衡,服務發現、服務續約及下線與剔除。

市面上的ServiceMesh框架有很多,我們選擇了站在風口的Istio。

3.1 Istio

連線、管理和保護微服務的開放平臺。

  • 平臺支援: Kubernetes, Mesos, Cloud Foundry。
  • 可觀察性:Metrics, logs, traces, dependency 。visualisation。
  • Service Identity & Security: 為服務、服務到服務的身份驗證提供可驗證的標識。
  • Traffic 管理: 動態控制服務之間的通訊、入口/出口路由、故障注入。
  • Policy 執行: 前提檢查,服務之間的配額管理。

3.2 我們為什麼選擇Istio?

因為有大廠支援~其實主要還是它的理念是相當好的。

雖然它才到1.0版本,我們是從 0.6 版本開始嘗試體驗,測試環境跑,然後0.7.1版本出了,我們升級到0.7.1版本跑,後來0.8.0LTS出了,我們開始正式使用0.8.0版本,並且做了一套升級方案。

目前最新版已經到了1.0.4, 但我們並不準備升級,我想等到它升級到1.2之後,再開始正式大規模應用。0.8.0LTS在現在來看小規模還是可以的。

3.3 Istio 架構

我們先來看一下Istio的架構。

其中Istio控制皮膚主要分為三大塊,Pilot、Mixer、Istio-Auth。

  • Pilot: 主要作為服務發現和路由規則,並且管理著所有Envoy,它對資源的消耗是非常大的。
  • Mixer: 主要負責策略請求和配額管理,還有Tracing,所有的請求都會上報到Mixer。
  • Istio-Auth: 升級流量、身份驗證等等功能,目前我們暫時沒有啟用此功能,需求並不是特別大,因為叢集本身就是對外部隔離的。

每個Pod都會被注入一個Sidecar,容器裡的流量透過iptables全部轉到Envoy進行處理。

四、Kubernetes & Istio

Istio可以獨立部署,但顯然它與Kuberntes結合是更好的選擇。基於Kubernetes的小規模架構。有人擔心它的效能,其實經過生產測試,上萬的QPS是完全沒有問題的。

4.1 Kubernetes Cluster

在資源緊缺的情況下,我們的k8s叢集是怎麼樣的?

4.1.1 Master叢集

  • Master Cluster:

    • ETCD、Kube-apiserver、kubelet、Docker、kube-proxy、kube-scheduler、kube-controller-manager、Calico、 keepalived、 IPVS。

4.1.2 Node節點

  • Node:

    • Kubelet、 kube-proxy 、Docker、Calico、IPVS。

(圖片來源網路)

我們所呼叫的Master的API都是透過 keepalived 進行管理,某一master發生故障,能保證順滑的飄到其他master的API,不影響整個叢集的執行。

當然我們還配置了兩個邊緣節點。

4.1.3 Edge Node

  • 邊緣節點
  • 流量入口

邊緣節點的主要功能是讓叢集提供對外暴露服務能力的節點,所以它也不需要穩定,我們的IngressGateway 就是部署在這兩個邊緣節點上面,並且透過Keeplived進行管理。

4.2 外部服務請求流程

最外層是DNS,透過泛解析到Nginx,Nginx將流量轉到叢集的VIP,VIP再到叢集的HAproxy,將外部流量發到我們的邊緣節點Gateway。

每個VirtualService都會繫結到Gateway上,透過VirtualService可以進行服務的負載、限流、故障處理、路由規則及金絲雀部署。再透過Service最終到服務所在的Pods上。

這是在沒有進行Mixer跟策略檢測的情況下的過程,只使用了Istio-IngressGateway。如果使用全部Istio元件將有所變化,但主流程還是這樣的。

4.3 Logging

日誌收集我們採用的是低耦合、擴充套件性強、方便維護和升級的方案。

  • 節點Filebeat收集宿主機日誌。
  • 每個Pods注入Filebeat容器收集業務日誌。

Filebeat會跟應用容器部署在一起,應用也不需要知道它的存在,只需要指定日誌輸入的目錄就可以了。Filebeat所使用的配置是從ConfigMap讀取,只需要維護好收集日誌的規則。

上圖是我們可以從Kibana上看到所採集到的日誌。

4.4 Prometheus + Kubernetes

  • 基於時間序列的監控系統。
  • 與kubernetes無縫整合基礎設施和應用等級。
  • 具有強大功能的鍵值資料模型。
  • 大廠支援。

4.4.1 Grafana

4.4.2 Alarm

目前我們支援的報警有Wechat、kplcloud、Email、IM。所有報警都可在平臺上配置傳送到各個地方。

4.4.3 整體架構

整個架構由外圍服務及叢集內的基礎服務組成,外圍服務有:

  • Consul作為配置中心來使用。
  • Prometheus+Grafana用來監控K8s叢集。
  • Zipkin提供自己定義的鏈路追蹤。
  • ELK日誌收集、分析,我們叢集內的所有日誌會推送到這裡。
  • Gitlab程式碼倉庫。
  • Jenkins用來構建程式碼及打包成Docker映象並且上傳到倉庫。
  • Repository 映象倉庫。

叢集有:

  • HAProxy+keeprlived 負責流量轉發。
  • 網路是Calico, Calico對kube-proxy的ipvs代理模式有beta級支援。如果Calico檢測到kube-proxy正在該模式下執行,則會自動啟用Calico ipvs支援,所以我們啟用了IPVS。
  • 叢集內部的DNS是 CoreDNS。
  • 我們部署了兩個閘道器,主要使用的是Istio的 IngressGateway,TraefikIngress備用。一旦IngressGateway掛了我們可以快速切換到TraefikIngress。
  • 上面是Istio的相關元件。
  • 最後是我們的APP服務。
  • 叢集透過Filebeat收集日誌發到外部的ES。
  • 叢集內部的監控有:
    • State-Metrics 主要用來自動伸縮的監控元件
    • Mail&Wechat 自研的報警服務
    • Prometheus+Grafana+AlertManager 叢集內部的監控,主要監控服務及相關基礎元件
    • InfluxDB+Heapster 流資料庫儲存著所有服務的監控資訊

4.5 有了Kubernetes那怎麼部署應用呢?

4.5.1 研發打包成映象、傳倉庫、管理版本

  • 學習Docker。
  • 學習配置倉庫、手動打包上傳麻煩。
  • 學習k8s相關知識。

4.5.2 用Jenkins來負責打包、傳映象、更新版本

  • 運維工作增加了不少,應用需要進行配置、服務需要做變更都得找運維。
  • 需要管理一堆的YAML檔案。

有沒有一種傻瓜式的,不需要學習太多的技術,可以方便使用的解決方案?

五、Kplcloud platform

5.1 開普勒雲平臺

開普勒雲平臺是一個輕量級的PaaS平臺。

  • 為微服務化的專案提供一個可控的管理平臺。
  • 實現每個服務獨立部署、維護、擴充套件。
  • 簡化流程,不再需要繁瑣的申請流程,最大限度的自動化處理。
  • 實現微服務的快速釋出、獨立監控、配置。
  • 實現對微服務專案的零侵入式的服務發現、服務閘道器、鏈路追蹤等功能。
  • 提供配置中心,統一管理配置。
  • 研發、產品、測試、運維甚至是老闆都可以自己釋出應用。

5.2 在開普勒平臺部署服務

為了降低學習成本及部署難度,在開普勒平臺上部署應用很簡單,只需要增加一個Dockerfile 就好了。

Dockerfile 參考:

以上是普通模式,Jenkins程式碼Build及Docker build。

這是一種相對自由的部署方式,可以根據自己的需求進行定製,當然有學習成本。

5.2.1 為什麼不自動生成Dockerfile呢?

其實完全可以做到自動生成Dockerfile,但每個服務的要求可能不一樣,有些需要增加檔案、有些在Build時需要增加引數等等。我們不能要求所有的專案都是一樣的,這會阻礙技術的發展。所以退而求其次,我們給出模版,研發根據自己的需求調整。

5.3 工具整合

  • 開普勒雲平臺整合了 gitlab,Jenkins,repo,k8s,istio,promtheus,email,WeChat 等API。
  • 實現對服務的整個生命週期的管理。
  • 提供服務管理、建立、釋出、版本、監控、報警、日誌已及一些周邊附加功能,訊息中心、配置中心、還能登陸到容器,服務下線等等。
  • 可對服務進行一健調整服務模式、服務型別、一鍵擴容伸縮,回滾服務API管理以及儲存的管理等操作。

5.4 釋出流程

使用者把自己的Dockerfile跟程式碼提交到Gitlab,然後在開普勒雲平臺填寫一些引數建立自己的應用。

應用建立完後會在Jenkins建立一個Job,把程式碼拉取下來並執行Docker build(如果沒有選擇多階構建會先執行go build或mvn),再把打包好的Docker image推送到映象倉庫,最後回撥平臺API或呼叫k8s通知拉取最新的版本。

使用者只需要在開普勒雲平臺上管理好自己的應用就可以,其他的全部自動化處理。

5.5 從建立一個服務開始

我們從建立一個服務開始介紹平臺。

平臺主介面:

點選“建立服務”後進入建立頁面。

填寫基本資訊:

填寫詳細資訊:  

基本資訊以Golang為例,當選擇其他語言時所需填寫的引數會略有不同。

如果選擇了對外提供服務的話,會進入第三步,第三步是填寫路由規則,如沒有特殊需求直接預設提交就行了。

5.5.1 服務詳情

Build 升級應用版本:  

呼叫服務模式,可以在普通跟服務網格之間調整。

服務是否提供對外服務的能力:  

擴容調整CPU、記憶體:

調整啟動的Pod數量:

網頁版本的終端:

5.5.2 定時任務

5.5.3 持久化儲存

管理員建立StorageClass跟PersistentVolumeClaim,使用者只需要在自己服務選擇相關的PVC進行綁寫就行了。

儲存使用的是NFS。

5.5.4 Tracing

5.5.5 Consul

Consul當作配置中心來使用,並且我們提供Golang的客戶端。

$ go get github.com/lattecake/consul-kv-client

它會自動同步consul的目錄配置存在記憶體,獲取配置只需要直接從記憶體拿就行了。

5.5.6 Repository

  • Github:  
  • Document:  
  • Demo:  

作者:王聰

首發:宜技之長


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69918724/viewspace-2660360/,如需轉載,請註明出處,否則將追究法律責任。

相關文章