從Kubernetes到Cloud Native——雲原生應用之路

從Kubernetes到Cloud Native——雲原生應用之路,這是我最近在 ArchSummit2017北京站 和 數人云&TalkingData合辦的Service Mesh is comming meetup 中分享的話題。

本文簡要介紹了容器技術發展的路徑,為何Kubernetes的出現是容器技術發展到這一步的必然選擇,而為何Kuberentes又將成為雲原生應用的基石。

我的分享按照這樣的主線展開:容器->Kubernetes->微服務->Cloud Native(雲原生)->Service Mesh(服務網格)->使用場景->Open Source(開源)。

容器

容器——Cloud Native的基石

容器最初是通過開發者工具而流行,可以使用它來做隔離的開發測試環境和持續集成環境,這些都是因為容器輕量級,易於配置和使用帶來的優勢,docker和docker-compose這樣的工具極大的方便的了應用開發環境的搭建,開發者就像是化學家一樣在其中小心翼翼的進行各種調試和開發。

隨著容器的在開發者中的普及,已經大家對CI流程的熟悉,容器周邊的各種工具蓬勃發展,儼然形成了一個小生態,在2016年達到頂峰,下面這張是我畫的容器生態圖:

該生態涵蓋了容器應用中從鏡像倉庫、服務編排、安全管理、持續集成與發布、存儲和網路管理等各個方面,隨著在單主機中運行容器的成熟,集群管理和容器編排成為容器技術亟待解決的問題。譬如化學家在實驗室中研究出來的新產品,如何推向市場,進行大規模生產,成了新的議題。

為什麼使用Kubernetes

Kubernetes——讓容器應用進入大規模工業生產。

Kubernetes是容器編排系統的事實標準

在單機上運行容器,無法發揮它的最大效能,只有形成集群,才能最大程度發揮容器的良好隔離、資源分配與編排管理的優勢,而對於容器的編排管理,Swarm、Mesos和Kubernetes的大戰已經基本宣告技術,kubernetes成為了無可爭議的贏家。

下面這張圖是Kubernetes的架構圖(圖片來自網路),其中顯示了組件之間交互的介面CNI、CRI、OCI等,這些將Kubernetes與某款具體產品解耦,給用戶最大的定製程度,使得Kubernetes有機會成為跨雲的真正的雲原生應用的操作系統。

隨著Kubernetes的日趨成熟,「Kubernetes is becoming boring」,基於該「操作系統」之上構建的適用於不同場景的應用將成為新的發展方向,就像我們將石油開採出來後,提煉出汽油、柴油、瀝青等等,所有的材料都將找到自己的用途,Kubernetes也是,畢竟我們誰也不是為了部署和管理容器而用Kubernetes,承載其上的應用才是價值之所在。

雲原生的核心目標

雲已經可以為我們提供穩定可以唾手可得的基礎設施,但是業務上雲成了一個難題,Kubernetes的出現與其說是從最初的容器編排解決方案,倒不如說是為了解決應用上雲(即雲原生應用)這個難題。

包括微服務和FaaS/Serverless架構,都可以作為雲原生應用的架構。

但就2017年為止,kubernetes的主要使用場景也主要作為應用開發測試環境、CI/CD和運行Web應用這幾個領域,如下圖TheNewStack的Kubernetes生態狀況調查報告所示。

另外基於Kubernetes的構建PaaS平台和Serverless也處於爆發的準備的階段,如下圖中Gartner的報告中所示:

當前各大公有雲如Google GKE、微軟Azure ACS、亞馬遜EKS(2018年上線)、VmWare、Pivotal、騰訊雲、阿里雲等都提供了Kuberentes服務。

微服務

微服務——Cloud Native的應用架構。

下圖是Bilgin Ibryam給出的微服務中應該關心的主題,圖片來自RedHat Developers。

微服務帶給我們很多開發和部署上的靈活性和技術多樣性,但是也增加了服務調用的開銷、分散式系統管理、調試與服務治理方面的難題。

當前最成熟最完整的微服務框架可以說非Spring莫屬,而Spring又僅限於Java語言開發,其架構本身又跟Kubernetes存在很多重合的部分,如何探索將Kubernetes作為微服務架構平台就成為一個熱點話題。

就拿微服務中最基礎的服務註冊發現功能來說,其方式分為客戶端服務發現服務端服務發現兩種,Java應用中常用的方式是使用Eureka和Ribbon做服務註冊發現和負載均衡,這屬於客戶端服務發現,而在Kubernetes中則可以使用DNS、Service和Ingress來實現,不需要修改應用代碼,直接從網路層面來實現。

Cloud Native

DevOps——通向雲原生的雲梯

CNCF(雲原生計算基金會)給出了雲原生應用的三大特徵:

  • 容器化包裝:軟體應用的進程應該包裝在容器中獨立運行。
  • 動態管理:通過集中式的編排調度系統來動態的管理和調度。
  • 微服務化:明確服務間的依賴,互相解耦。

下圖是我整理的關於雲原生所需要的能力和特徵。

CNCF所託管的應用(目前已達12個),即朝著這個目標發展,其公布的Cloud Native Landscape,給出了雲原生生態的參考體系。

使用Kubernetes構建雲原生應用

我們都是知道Heroku推出了適用於PaaS的12 factor app的規範,包括如下要素:

  1. 基準代碼
  2. 依賴管理
  3. 配置
  4. 後端服務
  5. 構建,發布,運行
  6. 無狀態進程
  7. 埠綁定
  8. 並發
  9. 易處理
  10. 開發環境與線上環境等價
  11. 日誌作為事件流
  12. 管理進程

另外還有補充的三點:

  • API聲明管理
  • 認證和授權
  • 監控與告警

如果落實的具體的工具,請看下圖,使用Kubernetes構建雲原生架構:

結合這12因素對開發或者改造後的應用適合部署到Kubernetes之上,基本流程如下圖所示:

遷移到雲架構

遷移到雲端架構,相對單體架構來說會帶來很多挑戰。比如自動的持續集成與發布、服務監控的變革、服務暴露、許可權的管控等。這些具體細節請參考Kubernetes-handbook中的說明:jimmysong.io/kubernetes,在此就不細節展開,另外推薦一本我翻譯的由Pivotal出品的電子書——Migrating to Cloud Native Application Architectures,地址:jimmysong.io/migrating-

Service Mesh

Services for show, meshes for a pro.

Kubernetes中的應用將作為微服務運行,但是Kuberentes本身並沒有給出微服務治理的解決方案,比如服務的限流、熔斷、良好的灰度發布支持等。

Service mesh可以用來做什麼

  • Traffic Management:API網關
  • Observability:服務調用和性能分析
  • Policy Enforcment:控制服務訪問策略
  • Service Identity and Security:安全保護

Service mesh的特點

  • 專用的基礎設施層
  • 輕量級高性能網路代理
  • 提供安全的、快速的、可靠地服務間通訊
  • 擴展kubernetes的應用負載均衡機制,實現灰度發布
  • 完全解耦於應用,應用可以無感知,加速應用的微服務和雲原生轉型

使用Service Mesh將可以有效的治理Kuberentes中運行的服務,當前開源的Service Mesh有:

  • Linkderd:https://linkerd.io,由最早提出Service Mesh的公司Buoyant開源,創始人來自Twitter
  • Envoy:envoyproxy.io/,Lyft開源的,可以在Istio中使用Sidecar模式運行
  • Istio:https://istio.io,由Google、IBM、Lyft聯合開發並開源
  • Conduit:https://conduit.io,同樣由Buoyant開源的輕量級的基於Kubernetes的Service Mesh

此外還有很多其它的Service Mesh魚貫而出,請參考awesome-cloud-native。

Istio VS Linkerd

Linkerd和Istio是最早開源的Service Mesh,它們都支持Kubernetes,下面是它們之間的一些特性對比。

FeatureIstioLinkerd部署架構Envoy/SidecarDaemonSets易用性複雜簡單支持平台kuberenteskubernetes/mesos/Istio/local當前版本0.3.01.3.3是否已有生產部署否是

關於兩者的架構可以參考各自的官方文檔,我只從其在kubernetes上的部署結構來說明其區別。

Istio的組件複雜,可以分別部署的kubernetes集群中,但是作為核心路由組件Envoy是以Sidecar形式與應用運行在同一個Pod中的,所有進入該Pod中的流量都需要先經過Envoy。

Linker的部署十分簡單,本身就是一個鏡像,使用Kubernetes的DaemonSet方式在每個node節點上運行。

更多信息請參考kubernetes-handbook。

使用場景

Cloud Native的大規模工業生產

GitOps

給開發者帶來最大配置和上線的靈活性,踐行DevOps流程,改善研發效率,下圖這樣的情況將更少發生。

我們知道Kubernetes中的所有應用的部署都是基於YAML文件的,這實際上就是一種Infrastructure as code,完全可以通過Git來管控基礎設施和部署環境的變更。

Big Data

Spark現在已經非官方支持了基於Kuberentes的原生調度,其具有以下特點:

  • Kubernetes原生調度:與yarn、mesos同級
  • 資源隔離,粒度更細:以namespace來劃分用戶
  • 監控的變革:單次任務資源計量
  • 日誌的變革:pod的日誌收集

FeatureYarnKubernetesqueuequeuenamespaceinstanceExcutorContainerExecutor PodnetworkhostpluginheterogeneousnoyessecurityRBACACL

下圖是在Kubernetes上運行三種調度方式的spark的單個節點的應用部分對比:

從上圖中可以看到在Kubernetes上使用YARN調度、standalone調度和kubernetes原生調度的方式,每個node節點上的Pod內的spark Executor分布,毫無疑問,使用kubernetes原生調度的spark任務才是最節省資源的。

提交任務的語句看起來會像是這樣的:

./spark-submit n --deploy-mode cluster n --class com.talkingdata.alluxio.hadooptest n --master k8s://https://172.20.0.113:6443 n --kubernetes-namespace spark-cluster n --conf spark.kubernetes.driverEnv.SPARK_USER=hadoop n --conf spark.kubernetes.driverEnv.HADOOP_USER_NAME=hadoop n --conf spark.executorEnv.HADOOP_USER_NAME=hadoop n --conf spark.executorEnv.SPARK_USER=hadoop n --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark n --conf spark.driver.memory=100G n --conf spark.executor.memory=10G n --conf spark.driver.cores=30 n --conf spark.executor.cores=2 n --conf spark.driver.maxResultSize=10240m n --conf spark.kubernetes.driver.limit.cores=32 n --conf spark.kubernetes.executor.limit.cores=3 n --conf spark.kubernetes.executor.memoryOverhead=2g n --conf spark.executor.instances=5 n --conf spark.app.name=spark-pi n --conf spark.kubernetes.driver.docker.image=spark-driver:v2.1.0-kubernetes-0.3.1-1 n --conf spark.kubernetes.executor.docker.image=spark-executor:v2.1.0-kubernetes-0.3.1-1 n --conf spark.kubernetes.initcontainer.docker.image=spark-init:v2.1.0-kubernetes-0.3.1-1 n --conf spark.kubernetes.resourceStagingServer.uri=http://172.20.0.114:31000 n ~/Downloads/tendcloud_2.10-1.0.jarn

關於支持Kubernetes原生調度的Spark請參考:jimmysong.io/spark-on-k

Open Source

Contributing is Not only about code, it is about helping a community.

下圖是我們剛調研準備使用Kubernetes時候的調研方案選擇。

對於一個初次接觸Kubernetes的人來說,看到這樣一個龐大的架構選型時會望而生畏,但是Kubernetes的開源社區幫助了我們很多。

我組建了K8S&Cloud Native實戰微信群,參與了k8smeetup、KEUC2017、kubernetes-docs-cn Kubernetes官方中文文檔項目。

有用的資料和鏈接

  • 我的博客: https://jimmysong.io
  • 微信群:k8s&cloud native實戰群(見:jimmysong.io/about
  • Meetup:k8smeetup
  • Cloud Native Go - 基於Go和React雲原生Web應用開發:jimmysong.io/cloud-nati
  • Gitbook:jimmysong.io/kubernetes
  • Cloud native開源生態:jimmysong.io/awesome-cl
  • 資料分享整理:github.com/rootsongjc/c
  • 遷移到雲原生架構:jimmysong.io/migrating-
  • KubeCon + CloudNativeCon 2018年11月14-15日 上海

推薦閱讀:

TAG:cloudnative | Kubernetes | 微服务架构 |