# Service Mesh 服務網格
**注意:本書中的 Service Mesh 章節已不再維護,請轉到 [istio-handbook](https://jimmysong.io/istio-handbook) 中瀏覽。**
Service mesh 又譯作 ”服務網格“,作為服務間通信的基礎設施層。Buoyant 公司的 CEO Willian Morgan 在他的這篇文章 [WHAT’S A SERVICE MESH? AND WHY DO I NEED ONE?](https://buoyant.io/2017/04/25/whats-a-service-mesh-and-why-do-i-need-one/) 中解釋了什么是 Service Mesh,為什么云原生應用需要 Service Mesh。
> A service mesh is a dedicated infrastructure layer for handling service-to-service communication. It’s responsible for the reliable delivery of requests through the complex topology of services that comprise a modern, cloud native application. In practice, the service mesh is typically implemented as an array of lightweight network proxies that are deployed alongside application code, without the application needing to be aware.
今年來以 [Istio](https://istio.io) 和 [Linkderd](https://linkerd.io) 為代表的 Service Mesh 蓬勃發展,大有成為下一代語言異構微服務架構的王者之范,今天又碰巧看到了 Red Hat 的 [Burr Sutter](https://twitter.com/burrsutter) 提出了**8 Steps to Becoming Awesome with Kubernetes**,整個PPT一共60多頁,很有建設性,[點此](https://github.com/rootsongjc/cloud-native-slides-share/blob/master/kubernetes/8-Steps-to-Becoming-Awesome-with-Kubernetes-readhat-burrsutter.pdf)跳轉到我的GitHub上下載,我將其歸檔到[cloud-native-slides-share](https://github.com/rootsongjc/cloud-native-slides-share)中了。

自我6月份初接觸Istio依賴就發覺service mesh很好的解決了異構語言中的很多問題,而且是kuberentes service 上層不可或缺的服務間代理。關于istio的更多內容請參考 [istio中文文檔](https://istio.io/zh/)。
## 什么是 service mesh?
Service mesh 有如下幾個特點:
- 應用程序間通訊的中間層
- 輕量級網絡代理
- 應用程序無感知
- 解耦應用程序的重試/超時、監控、追蹤和服務發現
目前兩款流行的 service mesh 開源軟件 [Istio](https://istio.io) 和 [Linkerd](https://linkerd.io) 都可以直接在 kubernetes 中集成,其中 Linkerd 已經成為 CNCF 成員。
## 理解 Service Mesh
如果用一句話來解釋什么是 Service Mesh,可以將它比作是應用程序或者說微服務間的 TCP/IP,負責服務之間的網絡調用、限流、熔斷和監控。對于編寫應用程序來說一般無須關心 TCP/IP 這一層(比如通過 HTTP 協議的 RESTful 應用),同樣使用 Service Mesh 也就無須關系服務之間的那些原來是通過應用程序或者其他框架實現的事情,比如 Spring Cloud、OSS,現在只要交給 Service Mesh 就可以了。
[Phil Cal?ado](http://philcalcado.com/) 在他的這篇博客 [Pattern: Service Mesh](http://philcalcado.com/2017/08/03/pattern_service_mesh.html) 中詳細解釋了 Service Mesh 的來龍去脈:
1. 從最原始的主機之間直接使用網線相連
2. 網絡層的出現
3. 集成到應用程序內部的控制流
4. 分解到應用程序外部的控制流
5. 應用程序的中集成服務發現和斷路器
6. 出現了專門用于服務發現和斷路器的軟件包/庫,如 [Twitter 的 Finagle](https://finagle.github.io/) 和 [Facebook 的 Proxygen](https://code.facebook.com/posts/1503205539947302),這時候還是集成在應用程序內部
7. 出現了專門用于服務發現和斷路器的開源軟件,如 [Netflix OSS](http://netflix.github.io/)、Airbnb 的 [synapse](https://github.com/airbnb/synapse) 和 [nerve](https://github.com/airbnb/nerve)
8. 最后作為微服務的中間層 service mesh 出現
Service mesh 的架構如下圖所示:

圖片來自:[Pattern: Service Mesh](http://philcalcado.com/2017/08/03/pattern_service_mesh.html)
Service mesh 作為 sidecar 運行,對應用程序來說是透明,所有應用程序間的流量都會通過它,所以對應用程序流量的控制都可以在 serivce mesh 中實現。
## Service mesh如何工作?
下面以 Linkerd 為例講解 service mesh 如何工作,Istio 作為 service mesh 的另一種實現原理與 linkerd 基本類似,后續文章將會詳解 Istio 和 Linkerd 如何在 kubernetes 中工作。
1. Linkerd 將服務請求路由到目的地址,根據中的參數判斷是到生產環境、測試環境還是 staging 環境中的服務(服務可能同時部署在這三個環境中),是路由到本地環境還是公有云環境?所有的這些路由信息可以動態配置,可以是全局配置也可以為某些服務單獨配置。
2. 當 Linkerd 確認了目的地址后,將流量發送到相應服務發現端點,在 kubernetes 中是 service,然后 service 會將服務轉發給后端的實例。
3. Linkerd 根據它觀測到最近請求的延遲時間,選擇出所有應用程序的實例中響應最快的實例。
4. Linkerd 將請求發送給該實例,同時記錄響應類型和延遲數據。
5. 如果該實例掛了、不響應了或者進程不工作了,Linkerd 將把請求發送到其他實例上重試。
6. 如果該實例持續返回 error,Linkerd 會將該實例從負載均衡池中移除,稍后再周期性得重試。
7. 如果請求的截止時間已過,Linkerd 主動失敗該請求,而不是再次嘗試添加負載。
8. Linkerd 以 metric 和分布式追蹤的形式捕獲上述行為的各個方面,這些追蹤信息將發送到集中 metric 系統。
## 為何使用 service mesh?
Service mesh 并沒有給我們帶來新功能,它是用于解決其他工具已經解決過的問題,只不過這次是在 Cloud Native 的 kubernetes 環境下的實現。
在傳統的 MVC 三層 Web 應用程序架構下,服務之間的通訊并不復雜,在應用程序內部自己管理即可,但是在現今的復雜的大型網站情況下,單體應用被分解為眾多的微服務,服務之間的依賴和通訊十分復雜,出現了 twitter 開發的 [Finagle](https://twitter.github.io/finagle/)、Netflix 開發的 [Hystrix](https://github.com/Netflix/Hystrix) 和 Google 的 Stubby 這樣的 ”胖客戶端“ 庫,這些就是早期的 service mesh,但是它們都近適用于特定的環境和特定的開發語言,并不能作為平臺級的 service mesh 支持。
在 Cloud Native 架構下,容器的使用給予了異構應用程序的更多可行性,kubernetes 增強的應用的橫向擴容能力,用戶可以快速的編排出復雜環境、復雜依賴關系的應用程序,同時開發者又無須過分關心應用程序的監控、擴展性、服務發現和分布式追蹤這些繁瑣的事情而專注于程序開發,賦予開發者更多的創造性。
## Istio VS Linkerd
當前的Service Mesh實現主要有兩大陣營,要給是Linkerd(也是最初提出該概念的),另一個是Istio,當然還有很多其他號稱也是Service Mesh,比如Nginx出品的[Nginmesh](https://github.com/nginmesh/nginmesh)。
| **Feature** | **Istio** | **Linkerd** |
| ----------- | ------------- | ---------------------------- |
| 部署架構 | Envoy/Sidecar | DaemonSets |
| 易用性 | 復雜 | 簡單 |
| 支持平臺 | kuberentes | kubernetes/mesos/Istio/local |
| 當前版本 | 0.3.0 | 1.3.3 |
| 是否已有生產部署 | 否 | 是 |
下圖是Istio和Linkerd架構的不同,Istio是使用Sidecar模式,將Envoy植入到Pod中,而Linkerd則是在每臺node上都以DaemonSet的方式運行。

關于Istio和Linkerd的詳細信息請參考 [安裝并試用Istio service mesh](istio-installation.md) 與 [Linkerd 使用指南](linkerd-user-guide.md)。
另外出品Linkerd的公司buoyant又推出了[conduit](https://conduit.io),這是一種更輕量級的Service Mesh。
## 參考
- [WHAT’S A SERVICE MESH? AND WHY DO I NEED ONE?](https://buoyant.io/2017/04/25/whats-a-service-mesh-and-why-do-i-need-one/)
- [So what even is a Service Mesh? Hot take on Istio and Linkerd](http://redmonk.com/jgovernor/2017/05/31/so-what-even-is-a-service-mesh-hot-take-on-istio-and-linkerd)
- [linkerd: A service mesh for AWS ECS](https://medium.com/attest-engineering/linkerd-a-service-mesh-for-aws-ecs-937f201f847a)
- [Introducing Istio: A robust service mesh for microservices](https://istio.io/blog/istio-service-mesh-for-microservices.html)
- [Application Network Functions With ESBs, API Management, and Now.. Service Mesh?](http://blog.christianposta.com/microservices/application-network-functions-with-esbs-api-management-and-now-service-mesh/)
- [Pattern: Service Mesh](http://philcalcado.com/2017/08/03/pattern_service_mesh.html)
- [Istio官方中文文檔](https://istio.io/zh/)
- 序言
- 云原生
- 云原生(Cloud Native)的定義
- CNCF - 云原生計算基金會簡介
- CNCF章程
- 云原生的設計哲學
- Play with Kubernetes
- 快速部署一個云原生本地實驗環境
- Kubernetes與云原生應用概覽
- 云原生應用之路——從Kubernetes到Cloud Native
- 云原生編程語言
- 云原生編程語言Ballerina
- 云原生編程語言Pulumi
- 云原生的未來
- Kubernetes架構
- 設計理念
- Etcd解析
- 開放接口
- CRI - Container Runtime Interface(容器運行時接口)
- CNI - Container Network Interface(容器網絡接口)
- CSI - Container Storage Interface(容器存儲接口)
- Kubernetes中的網絡
- Kubernetes中的網絡解析——以flannel為例
- Kubernetes中的網絡解析——以calico為例
- 具備API感知的網絡和安全性管理開源軟件Cilium
- Cilium架構設計與概念解析
- 資源對象與基本概念解析
- Pod狀態與生命周期管理
- Pod概覽
- Pod解析
- Init容器
- Pause容器
- Pod安全策略
- Pod的生命周期
- Pod Hook
- Pod Preset
- Pod中斷與PDB(Pod中斷預算)
- 集群資源管理
- Node
- Namespace
- Label
- Annotation
- Taint和Toleration(污點和容忍)
- 垃圾收集
- 控制器
- Deployment
- StatefulSet
- DaemonSet
- ReplicationController和ReplicaSet
- Job
- CronJob
- Horizontal Pod Autoscaling
- 自定義指標HPA
- 準入控制器(Admission Controller)
- 服務發現
- Service
- Ingress
- Traefik Ingress Controller
- 身份與權限控制
- ServiceAccount
- RBAC——基于角色的訪問控制
- NetworkPolicy
- 存儲
- Secret
- ConfigMap
- ConfigMap的熱更新
- Volume
- Persistent Volume(持久化卷)
- Storage Class
- 本地持久化存儲
- 集群擴展
- 使用自定義資源擴展API
- 使用CRD擴展Kubernetes API
- Aggregated API Server
- APIService
- Service Catalog
- 資源調度
- QoS(服務質量等級)
- 用戶指南
- 資源對象配置
- 配置Pod的liveness和readiness探針
- 配置Pod的Service Account
- Secret配置
- 管理namespace中的資源配額
- 命令使用
- Docker用戶過度到kubectl命令行指南
- kubectl命令概覽
- kubectl命令技巧大全
- 使用etcdctl訪問kubernetes數據
- 集群安全性管理
- 管理集群中的TLS
- kubelet的認證授權
- TLS bootstrap
- 創建用戶認證授權的kubeconfig文件
- IP偽裝代理
- 使用kubeconfig或token進行用戶身份認證
- Kubernetes中的用戶與身份認證授權
- Kubernetes集群安全性配置最佳實踐
- 訪問Kubernetes集群
- 訪問集群
- 使用kubeconfig文件配置跨集群認證
- 通過端口轉發訪問集群中的應用程序
- 使用service訪問群集中的應用程序
- 從外部訪問Kubernetes中的Pod
- Cabin - Kubernetes手機客戶端
- Kubernetic - Kubernetes桌面客戶端
- Kubernator - 更底層的Kubernetes UI
- 在Kubernetes中開發部署應用
- 適用于kubernetes的應用開發部署流程
- 遷移傳統應用到Kubernetes中——以Hadoop YARN為例
- 最佳實踐概覽
- 在CentOS上部署Kubernetes集群
- 創建TLS證書和秘鑰
- 創建kubeconfig文件
- 創建高可用etcd集群
- 安裝kubectl命令行工具
- 部署master節點
- 安裝flannel網絡插件
- 部署node節點
- 安裝kubedns插件
- 安裝dashboard插件
- 安裝heapster插件
- 安裝EFK插件
- 生產級的Kubernetes簡化管理工具kubeadm
- 使用kubeadm在Ubuntu Server 16.04上快速構建測試集群
- 服務發現與負載均衡
- 安裝Traefik ingress
- 分布式負載測試
- 網絡和集群性能測試
- 邊緣節點配置
- 安裝Nginx ingress
- 安裝配置DNS
- 安裝配置Kube-dns
- 安裝配置CoreDNS
- 運維管理
- Master節點高可用
- 服務滾動升級
- 應用日志收集
- 配置最佳實踐
- 集群及應用監控
- 數據持久化問題
- 管理容器的計算資源
- 集群聯邦
- 存儲管理
- GlusterFS
- 使用GlusterFS做持久化存儲
- 使用Heketi作為Kubernetes的持久存儲GlusterFS的external provisioner
- 在OpenShift中使用GlusterFS做持久化存儲
- GlusterD-2.0
- Ceph
- 用Helm托管安裝Ceph集群并提供后端存儲
- 使用Ceph做持久化存儲
- 使用rbd-provisioner提供rbd持久化存儲
- OpenEBS
- 使用OpenEBS做持久化存儲
- Rook
- NFS
- 利用NFS動態提供Kubernetes后端存儲卷
- 集群與應用監控
- Heapster
- 使用Heapster獲取集群和對象的metric數據
- Prometheus
- 使用Prometheus監控kubernetes集群
- Prometheus查詢語言PromQL使用說明
- 使用Vistio監控Istio服務網格中的流量
- 分布式跟蹤
- OpenTracing
- 服務編排管理
- 使用Helm管理Kubernetes應用
- 構建私有Chart倉庫
- 持續集成與發布
- 使用Jenkins進行持續集成與發布
- 使用Drone進行持續集成與發布
- 更新與升級
- 手動升級Kubernetes集群
- 升級dashboard
- 領域應用概覽
- 微服務架構
- 微服務中的服務發現
- 使用Java構建微服務并發布到Kubernetes平臺
- Spring Boot快速開始指南
- Service Mesh 服務網格
- 企業級服務網格架構
- Service Mesh基礎
- Service Mesh技術對比
- 采納和演進
- 定制和集成
- 總結
- Istio
- 安裝并試用Istio service mesh
- 配置請求的路由規則
- 安裝和拓展Istio service mesh
- 集成虛擬機
- Istio中sidecar的注入規范及示例
- 如何參與Istio社區及注意事項
- Istio教程
- Istio免費學習資源匯總
- 深入理解Istio Service Mesh中的Envoy Sidecar注入與流量劫持
- 深入理解Istio Service Mesh中的Envoy Sidecar代理的路由轉發
- Linkerd
- Linkerd 使用指南
- Conduit
- Condiut概覽
- 安裝Conduit
- Envoy
- Envoy的架構與基本術語
- Envoy作為前端代理
- Envoy mesh教程
- SOFAMesh
- SOFAMesh中的Dubbo on x-protocol
- SOFAMosn
- 使用 SOFAMosn 構建 SOFAMesh
- 大數據
- Spark standalone on Kubernetes
- 運行支持Kubernetes原生調度的Spark程序
- Serverless架構
- 理解Serverless
- FaaS-函數即服務
- OpenFaaS快速入門指南
- 邊緣計算
- 人工智能