Istio-ServiceMesh解決方案: k8s安裝istio
https://www.servicemesher.com/tags/istio/page/3/
https://www.jianshu.com/p/e23e3e74538e
https://time.geekbang.org/article/2355
1 Service Mesh 概念
Service Mesh又譯作“服務網格”,作為服務間通信的基礎設施層。
Service Mesh 是一個基礎設施層,用於處理服務間通信。雲原生應用有着復雜的服務拓撲,Service Mesh 保證請求可以在這些拓撲中可靠地穿梭。在實際應用當中,Service Mesh 通常是由一系列輕量級的網絡代理組成的,它們與應用程序部署在一起,但應用程序不需要知道它們的存在。
Service Mesh 實際上就是處於 TCP/IP 之上的一個抽象層,它假設底層的 L3/L4 網絡能夠點對點地傳輸字節(當然,它也假設網絡環境是不可靠的,所以 Service Mesh 必須具備處理網絡故障的能力)。
Service mesh 有如下幾個特點:
- 應用程序間通訊的中間層;
- 輕量級網絡代理;
- 應用程序無感知;
- 解耦應用程序的重試、超時、監控、追蹤和服務發現;
2 原理
Service Mesh 基本原理
如果用一句話來解釋什么是 Service Mesh,可以將它比作是應用程序或者說微服務間的 TCP/IP,負責服務之間的網絡調用、限流、熔斷和監控。對於編寫應用程序來說一般無須關心 TCP/IP 這一層(比如通過 HTTP 協議的 RESTful 應用),同樣使用 Service Mesh 也就無須關系服務之間的那些原來是通過應用程序或者其他框架實現的事情,比如 Spring Cloud、OSS,現在只要交給 Service Mesh 就可以了。
Phil Calçado 在他的這篇博客 Pattern: Service Mesh 中詳細解釋了 Service Mesh 的來龍去脈:
- 從最原始的主機之間直接使用網線相連
- 網絡層的出現
- 集成到應用程序內部的控制流
- 分解到應用程序外部的控制流
- 應用程序的中集成服務發現和斷路器
- 出現了專門用於服務發現和斷路器的軟件包/庫,Twitter’s Finagle和 Facebook’s Proxygen。這時候還是集成在應用程序內部
- 出現了專門用於服務發現和斷路器的開源軟件,如:NetflixOSS ecosystem
- 最后作為微服務的中間層Service Mesh出現
Service Mesh 的架構如下圖所示
3 解決方案
目前社區Service Mesh的開源解決方案有:Buoyant 公司推出的 Linkerd 和 Google、IBM 等廠商牽頭的 Istio。Linkerd 更加成熟穩定些,Istio 功能更加豐富、設計上更為強大,社區相對也更加強大一些。所以普遍認為 Istio 的前景會更好,但是畢竟還處於項目的早期,問題還很多。
4 Istio介紹
Istio是由Google、IBM和Lyft開源的微服務管理、保護和監控框架。Istio為希臘語,意思是”起航“。官方中文文檔地址:https://istio.doczh.cn
https://blog.51cto.com/brucewang/2149104
4.1 什么是ISTIO
Istio 是一個用來連接、管理和保護微服務的開放平台。
Istio 提供一種簡單的方式來為已部署的服務建立網絡,該網絡具有負載均衡、服務間認證、監控等功能,而不需要對服務的代碼做任何改動。想要讓服務支持 Istio,只需要在您的環境中部署一個特殊的 sidecar,使用 Istio 控制平面功能配置和管理代理,攔截微服務之間的所有網絡通信。
- HTTP、gRPC、WebSocket 和 TCP 流量的自動負載均衡。
- 通過豐富的路由規則、重試、故障轉移和故障注入,可以對流量行為進行細粒度控制。
- 可插入的策略層和配置 API,支持訪問控制、速率限制和配額。
- 對出入集群入口和出口中所有流量的自動度量指標、日志記錄和跟蹤。
- 通過強大的基於身份的驗證和授權,在集群中實現安全的服務間通信。
4.2 ISTIO有什么用
Istio 提供了一個完整的解決方案,通過為整個服務網格提供行為洞察和操作控制來滿足微服務應用程序的多樣化需求。它在服務網絡中統一提供了許多關鍵功能:
- 流量管理。控制服務之間的流量和API調用的流向,使得調用更可靠,並使網絡在惡劣情況下更加健壯。
- 服務身份和安全。為網格中的服務提供可驗證身份,並提供保護服務流量的能力,使其可以在不同可信度的網絡上流轉。
- 策略執行。將組織策略應用於服務之間的互動,確保訪問策略得以執行,資源在消費者之間良好分配。可以通過通過配置網格而不是修改應用程序代碼來完成策略的更改。
- 遙測:了解服務之間的依賴關系,以及它們之間流量的本質和流向,從而提供快速識別問題的能力。
4.3 架構
Istio 服務網格邏輯上分為數據平面和控制平面。
- 數據平面由一組以 sidecar 方式部署的智能代理(Envoy)組成。這些代理可以調節和控制微服務及 Mixer 之間所有的網絡通信。
- 控制平面負責管理和配置代理來路由流量。此外控制平面配置 Mixer 以實施策略和收集遙測數據。
下圖顯示了構成每個面板的不同組件:
Envoy
- 動態服務發現
- 負載均衡
- TLS 終止
- HTTP/2 & gRPC 代理
- 熔斷器
- 健康檢查、基於百分比流量拆分的灰度發布
- 故障注入
- 豐富的度量指標
Envoy 被部署為 sidecar,和對應服務在同一個 Kubernetes pod 中。這允許 Istio 將大量關於流量行為的信號作為屬性提取出來,而這些屬性又可以在 Mixer 中用於執行策略決策,並發送給監控系統,以提供整個網格行為的信息。
Mixer
Mixer 是一個獨立於平台的組件,負責在服務網格上執行訪問控制和使用策略,並從 Envoy 代理和其他服務收集遙測數據。代理提取請求級屬性,發送到 Mixer 進行評估。
Pilot
Pilot 為 Envoy sidecar 提供服務發現功能,為智能路由(例如 A/B 測試、金絲雀部署等)和彈性(超時、重試、熔斷器等)提供流量管理功能。它將控制流量行為的高級路由規則轉換為特定於 Envoy 的配置,並在運行時將它們傳播到 sidecar。
Citadel
Citadel 通過內置身份和憑證管理可以提供強大的服務間和最終用戶身份驗證。可用於升級服務網格中未加密的流量,並為運維人員提供基於服務標識而不是網絡控制的強制執行策略的能力。從 0.5 版本開始,Istio 支持基於角色的訪問控制,以控制誰可以訪問您的服務
5 Istio與Kubernetes
http://blog.itpub.net/31543630/viewspace-2213615
Kubernetes 提供了部署、升級和有限的運行流量管理能力;利用service的機制來做服務注冊和發現,轉發,通過kubeproxy有一定的轉發和負載均衡能力。但並不具備上層如熔斷、限流降級、調用鏈治理等能力.
Istio 則很好的補齊了k8s在微服務治理上的這部分能力,同時是基於k8s構建的,但不是像SpringCloud Netflix等完全重新做一套。Istio是谷歌微服務治理上的非常關鍵的一環。
Istio 與k8s緊密結合,包括:Sicecar 運行在k8s pod里,作為一個proxy和業務容器部署在一起,部署過程對用戶透明。Mesh中要求業務程序的運行感知不到sidecar的存在,基於k8sd的pod的設計這部分做的更徹底,對用戶更透明,用戶甚至感知不到部署sidecar的這個過程。試想如果是通過VM上部署一個agent,不會有這么方便。
Pilot 中包含一個controller,通過list/watch kube-apiserver自動發現K8S中的services、endpoints。它通過在Kubernetes里面注冊一個controller來監聽事件,從而獲取Service和Kubernetes的Endpoint以及Pod的關系,但是在轉發層面,不再使用kube-proxy轉發了,而是將這些映射關系轉換成為pilot自己的轉發模型,下發到envoy進行轉發。
K8s 編排容器服務已經成為一種事實上的標准;因為微服務與容器在輕量、快速部署運維等特征的匹配,微服務運行在容器中也正成為一種標准實踐;對於雲原生應用,采用Kubernetes構建微服務部署和集群管理能力,采用Istio構建服務治理能力,將逐漸成為應用微服務轉型的標准配置。
6 基於k8s安裝istio
6.1 k8s環境
基於kubernetes(3):kubeadm安裝k8s1.15
# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready master 26h v1.15.3 k8s-node-1 Ready node 25h v1.15.3 k8s-node-2 Ready node 25h v1.15.3 k8s-node-3 Ready node 25h v1.15.3
6.2 下載和准備安裝
獲取最新的Istio安裝包
curl -L https://git.io/getLatestIstio | sh - # curl -L https://git.io/getLatestIstio | sh - % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0 100 3015 100 3015 0 0 997 0 0:00:03 0:00:03 --:--:-- 12108 Downloading istio-1.3.4 from https://github.com/istio/istio/releases/download/1.3.4/istio-1.3.4-linux.tar.gz ... % Total% Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 614 0 614 0 0 614 0 --:--:-- --:--:-- --:--:-- 614 1 36.3M 1 390k 0 0 2413 0 4:23:25 0:02:45 4:20:40 0 1 36.3M 1 390k 0 0 2408 0 4:23:58 0:02:46 4:21:12 0 …下載太慢了我按鏈接wget 了 wget https://github.com/istio/istio/releases/download/1.3.4/istio-1.3.4-linux.tar.gz [root@k8s-master istio]# tar -zxf istio-1.3.4-linux.tar.gz [root@k8s-master istio]# ls istio-1.3.4 istio-1.3.4-linux.tar.gz [root@k8s-master istio]# cp -r istio-1.3.4 /usr/local/istio [root@k8s-master istio]# echo 'PATH=$PATH:/usr/local/istio/bin:' >> /etc/profile
進入安裝包目錄后進入install/kubernetes/目錄安裝Kubernetes所需yaml文件
[root@k8s-master istio]# cd istio-1.3.4/ [root@k8s-master istio-1.3.4]# ls bin install istio.VERSION LICENSE README.md samples tools [root@k8s-master istio-1.3.4]# cd install/ [root@k8s-master install]# ls consul gcp kubernetes README.md tools [root@k8s-master install]# cd kubernetes/ [root@k8s-master kubernetes]# ls global-default-sidecar-scope.yaml istio-demo-auth.yaml mesh-expansion.yaml operator helm istio-demo.yaml namespace.yaml README.md [root@k8s-master kubernetes]#
6.3 安裝
此處選擇默認不啟用TLS身份驗證的安裝方式,啟用TLS安裝方式的yaml文件為istio-demo-auth.yaml)
kubectl create -f istio-demo.yaml
6.4 確認安裝
# kubectl get pod -n istio-system NAME READY STATUS RESTARTS AGE grafana-59d57c5c56-x6rqv 1/1 Running 0 17m istio-citadel-555bff45bf-nhxbw 1/1 Running 0 17m istio-egressgateway-7fd45cc845-rd5gs 1/1 Running 0 17m istio-galley-7f8b6db7d7-9x4rw 1/1 Running 0 17m istio-grafana-post-install-1.3.4-7frpb 0/1 Completed 0 17m istio-ingressgateway-64456bb8b-pg2cs 1/1 Running 0 17m istio-pilot-85894cd4f5-t9n6t 2/2 Running 0 17m istio-policy-7d8f44db64-8f6xv 2/2 Running 0 17m istio-security-post-install-1.3.4-rw55q 0/1 Completed 0 17m istio-sidecar-injector-65d5f8db56-7bk9g 1/1 Running 0 17m istio-telemetry-85c7c59b86-xgmdl 2/2 Running 0 17m istio-tracing-795c9c64c4-5f4kd 1/1 Running 0 17m kiali-8c9d6fbf6-9hp75 1/1 Running 0 17m prometheus-7d7b9f7844-p79gv 1/1 Running 0 17m # kubectl get svc -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE grafana ClusterIP 10.110.104.169 <none> 3000/TCP 18m istio-citadel ClusterIP 10.105.113.216 <none> 8060/TCP,15014/TCP 18m istio-egressgateway ClusterIP 10.98.158.85 <none> 80/TCP,443/TCP,15443/TCP 18m istio-galley ClusterIP 10.103.48.216 <none> 443/TCP,15014/TCP,9901/TCP 18m istio-ingressgateway LoadBalancer 10.110.13.142 <pending> 15020:32111/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:32114/TCP,15030:30450/TCP,15031:31750/TCP,15032:30788/TCP,15443:32083/TCP 18m istio-pilot ClusterIP 10.111.22.59 <none> 15010/TCP,15011/TCP,8080/TCP,15014/TCP 18m istio-policy ClusterIP 10.102.139.26 <none> 9091/TCP,15004/TCP,15014/TCP 18m istio-sidecar-injector ClusterIP 10.102.102.11 <none> 443/TCP,15014/TCP 18m istio-telemetry ClusterIP 10.106.211.184 <none> 9091/TCP,15004/TCP,15014/TCP,42422/TCP 18m jaeger-agent ClusterIP None <none> 5775/UDP,6831/UDP,6832/UDP 17m jaeger-collector ClusterIP 10.98.254.9 <none> 9411/TCP,14250/TCP,14267/TCP,14268/TCP 25h jaeger-collector-headless ClusterIP None <none> 9411/TCP,14250/TCP,14267/TCP,14268/TCP 25h jaeger-operator ClusterIP 10.109.247.90 <none> 8383/TCP 26h jaeger-query ClusterIP 10.111.157.104 <none> 16686/TCP 25h kiali ClusterIP 10.107.66.48 <none> 20001/TCP 18m prometheus ClusterIP 10.98.18.46 <none> 9090/TCP 18m tracing ClusterIP 10.97.13.237 <none> 80/TCP 17m zipkin ClusterIP 10.109.176.69 <none> 9411/TCP 17m
6.5 運行的組件
grafana
Grafana支持多種不同的時序數據庫數據源,Grafana對每種數據源提供不同的查詢方法,而且能很好的支持每種數據源的特性。
istio-citadel
實現istio的Citadel功能的組件
istio-egressgateway
控制內部訪問外部鏈接的代理,如果這里沒設置規則,Envoy將因為不能識別訪問規則而拋棄訪問請求。
istio-ingressgateway
控制外部訪問內部數據的策略,只有配置后外部(kubernetes集群外)業務才能訪問集群內業務。
istio-pilot
ISTIO的pilot組件
istio-policy
ISTIO的策略控制組件
istio-sidecar-injector
提供自動注入功能,這樣yaml文件就不需要再手動打補丁注入
istio-telemetry
ISTIO 實現遙測數據的組件
prometheus
替代heapster的一個監控數據收集工具
servicegraph
Istio網格中的服務生成一個圖。在這個task中,你將安裝Servicegraph 插件並使用基於web的界面來查看服務網格的服務圖。
tracing,zipkin
服務軌跡跟蹤,同時可以記錄到業務的訪問量等
7 Bookinfo示例
https://www.qikqiak.com/istio-book/install/1.Docker%20for%20Mac%E5%AE%89%E8%A3%85istio.html
https://blog.51cto.com/brucewang/2149104 https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/81571517
目前大部分 istio 的使用示例都是使用的官方的 Bookinfo 應用示例:
7.1 Bookinfo 應用分為四個單獨的微服務:
- productpage :productpage 微服務會調用 details 和 reviews 兩個微服務,用來生成頁面。
- details :這個微服務包含了書籍的信息。
- reviews :這個微服務包含了書籍相關的評論。它還會調用 ratings 微服務。
- ratings :ratings 微服務中包含了由書籍評價組成的評級信息。
reviews 微服務有 3 個版本:
- v1 版本不會調用 ratings 服務。
- v2 版本會調用 ratings 服務,並使用 1 到 5 個黑色星形圖標來顯示評分信息。
- v3 版本會調用 ratings 服務,並使用 1 到 5 個紅色星形圖標來顯示評分信息
這個示例是一個多語言開發的微服務應用。首先有一個 python 實現的 ProductPage 入口應用展示書籍的詳細信息和評價,它會調用 Ruby 實現的 Detail 應用獲取書籍詳情,同時調用 Java 實現的評價應用獲取書籍的評價。
上圖展示了使用 istio 后,整個應用實際的結構。所有的微服務都和一個 Envoy sidecar 封裝到一起,sidecar 攔截所有到達和離開服務的請求。
7.2 部署
首先進入解壓的istio目錄,執行如下命令:
kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml)
[root@k8s-master istio-1.3.4]# ls bin install istio.VERSION LICENSE README.md samples tools [root@k8s-master istio-1.3.4]# kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml) service/details created serviceaccount/bookinfo-details created deployment.apps/details-v1 created service/ratings created serviceaccount/bookinfo-ratings created deployment.apps/ratings-v1 created service/reviews created serviceaccount/bookinfo-reviews created deployment.apps/reviews-v1 created deployment.apps/reviews-v2 created deployment.apps/reviews-v3 created service/productpage created serviceaccount/bookinfo-productpage created deployment.apps/productpage-v1 created
其中 bookinfo.yaml 就是普通的 k8s 的 Deployment 和 Service 的 yaml 文件,而 istioctl kube-inject 會在這個文件的基礎上向其中的 Deployment 追加內容,通常會追加一個 initContainer(image:docker.io/istio/proxy_init) 作為 sidecar 的形式與應用的容器運行在同一個 pod 中。
過一會兒就可以看到如下 service 和 pod 啟動:
# kubectl get pod NAME READY STATUS RESTARTS AGE details-v1-5557659779-hlr52 2/2 Running 0 6m28s productpage-v1-58f967648c-vhtxx 2/2 Running 0 6m27s ratings-v1-68c58c7975-6fbkm 2/2 Running 0 6m27s reviews-v1-9cd479947-p44ln 2/2 Running 0 6m26s reviews-v2-567f5dcdfb-4klvt 2/2 Running 0 6m27s reviews-v3-86bdc9c869-24ppb 2/2 Running 0 6m27s # kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE details ClusterIP 10.109.59.71 <none> 9080/TCP 6m40s productpage ClusterIP 10.106.157.87 <none> 9080/TCP 6m39s ratings ClusterIP 10.107.134.22 <none> 9080/TCP 6m40s reviews ClusterIP 10.105.11.68 <none> 9080/TCP 6m39s
現在應用的服務都部署成功並啟動了,現在需要在集群外部訪問,需要添加一個 istio gateway。 gateway 相當於 k8s 的 ingress controller 和 ingress。它為 HTTP/TCP 流量配置 load balancer,通常在服務網格邊緣作為應用的 ingress trafic管理。
然后創建一個 gateway:
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
# kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml gateway.networking.istio.io/bookinfo-gateway created The VirtualService "bookinfo" is invalid: []: Invalid value: map[string]interface {}{"apiVersion":"networking.istio.io/v1alpha3", "kind":"VirtualService", "metadata":map[string]interface {}{"annotations":map[string]interface {}{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"networking.istio.io/v1alpha3\",\"kind\":\"VirtualService\",\"metadata\":{\"annotations\":{},\"name\":\"bookinfo\",\"namespace\":\"default\"},\"spec\":{\"gateways\":[\"bookinfo-gateway\"],\"hosts\":[\"*\"],\"http\":[{\"match\":[{\"uri\":{\"exact\":\"/productpage\"}},{\"uri\":{\"prefix\":\"/static\"}},{\"uri\":{\"exact\":\"/login\"}},{\"uri\":{\"exact\":\"/logout\"}},{\"uri\":{\"prefix\":\"/api/v1/products\"}}],\"route\":[{\"destination\":{\"host\":\"productpage\",\"port\":{\"number\":9080}}}]}]}}\n"}, "creationTimestamp":"2019-11-08T03:23:26Z", "generation":1, "name":"bookinfo", "namespace":"default", "uid":"819111f5-99ec-4db4-8182-dcbbb46e1f93"}, "spec":map[string]interface {}{"gateways":[]interface {}{"bookinfo-gateway"}, "hosts":[]interface {}{"*"}, "http":[]interface {}{map[string]interface {}{"match":[]interface {}{map[string]interface {}{"uri":map[string]interface {}{"exact":"/productpage"}}, map[string]interface {}{"uri":map[string]interface {}{"prefix":"/static"}}, map[string]interface {}{"uri":map[string]interface {}{"exact":"/login"}}, map[string]interface {}{"uri":map[string]interface {}{"exact":"/logout"}}, map[string]interface {}{"uri":map[string]interface {}{"prefix":"/api/v1/products"}}}, "route":[]interface {}{map[string]interface {}{"destination":map[string]interface {}{"host":"productpage", "port":map[string]interface {}{"number":9080}}}}}}}}: validation failure list: spec.http.route.weight in body is required
我在samples/bookinfo/networking/bookinfo-gateway.yaml 追加了一個
weight: 1
[root@k8s-master istio-1.3.1]# vim samples/bookinfo/networking/bookinfo-gateway.yaml [root@k8s-master istio-1.3.1]# kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml gateway.networking.istio.io/bookinfo-gateway unchanged virtualservice.networking.istio.io/bookinfo created #驗證 gateway 是否啟動成功: [root@k8s-master istio-1.3.4]# istioctl get gateway Command "get" is deprecated, Use `kubectl get` instead (see https://kubernetes.io/docs/tasks/tools/install-kubectl) GATEWAY NAME HOSTS NAMESPACE AGE bookinfo-gateway * default 1m [root@k8s-master istio-1.3.4]# kubectl get gateway NAME AGE bookinfo-gateway 2m [root@k8s-master istio-1.3.4]#
官方文檔中后面還會去獲取 ingress 的 ip 和端口,實際上不需要了,在 service 中我們可以看到有這樣的一條 service 信息:
# kubectl get svc -n istio-system | grep istio-ingressgateway istio-ingressgateway LoadBalancer 10.110.13.142 <pending> 15020:32111/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:32114/TCP,15030:30450/TCP,15031:31750/TCP,15032:30788/TCP,15443:32083/TCP 19h
這里使用的是 LoadBalancer 類型的服務,實際上是用來對接雲服務廠商的,如果我們沒有對接雲服務廠商的話,可以將這里類型改成 NodePort,但是這樣我們要訪問我們的服務就得加上 nodePort 端口了,我們這里其實直接使用 localhost 就可以訪問到 Bookinfo,在瀏覽器中打開地址:http://localhost/productpage
也可以通過以下方法驗證
#確定Ingress的IP和端口:
#port: export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}') # secure port: export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}') #host export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o 'jsonpath={.items[0].status.hostIP}') # GATEWAY_URL: export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT #測試 200為正常 curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/productpage
7.3 測試部署是否成功
可以通過上文的url200
也可以通過頁面查看
Bookinfo應用由4個微服務組成,即web微服務頁面productpage、頁面左邊部分為Book Details服務,右邊部分為Book Reviews服務, reviews服務目前為v1狀態即無星級評分。由於未設置請求路由,多刷新頁面幾次,請求路由流量會隨機的在reviews服務v1、v2、v3中切換。