istio基础详解
1.Istio介紹?
官方文檔:https://istio.io/docs/concepts/what-is-istio/
中文官方文檔:https://istio.io/zh/docs/concepts/what-is-istio/
Github地址:https://github.com/istio/istio/releases
1.1 Istio是什么?
官當(dāng)解釋:
An open platform to connect, secure, control and observe services.
翻譯過來,就是”連接、安全加固、控制和觀察服務(wù)的開放平臺(tái)“。開放平臺(tái)就是指它本身是開源的,服務(wù)對(duì)應(yīng)的是微服務(wù),也可以粗略地理解為單個(gè)應(yīng)用。
1、連接(Connect):智能控制服務(wù)之間的調(diào)用流量,能夠?qū)崿F(xiàn)灰度升級(jí)、AB 測(cè)試和藍(lán)綠部署等功能
2、安全加固(Secure):自動(dòng)為服務(wù)之間的調(diào)用提供認(rèn)證、授權(quán)和加密。
3、控制(Control):應(yīng)用用戶定義的 policy,保證資源在消費(fèi)者中公平分配。
4、觀察(Observe):查看服務(wù)運(yùn)行期間的各種數(shù)據(jù),比如日志、監(jiān)控和 tracing,了解服務(wù)的運(yùn)行情況。
Istio是ServiceMesh的產(chǎn)品化落地,可以通過在現(xiàn)有的服務(wù)器新增部署邊車代理(sidecar proxy),應(yīng)用程序不用改代碼,或者只需要改很少的代碼,就能實(shí)現(xiàn)如下基礎(chǔ)功能:
1、幫助微服務(wù)之間建立連接,幫助研發(fā)團(tuán)隊(duì)更好的管理與監(jiān)控微服務(wù),并使得系統(tǒng)架構(gòu)更加安全;
2、幫助微服務(wù)分層解耦,解耦后的proxy層能夠更加專注于提供基礎(chǔ)架構(gòu)能力,例如:
(1)服務(wù)發(fā)現(xiàn)(discovery);
(2)負(fù)載均衡(load balancing);
(3)故障恢復(fù)(failure recovery);
(4)服務(wù)度量(metrics);
(5)服務(wù)監(jiān)控(monitoring);
(6)A/B測(cè)試(A/B testing);
(7)灰度發(fā)布(canary rollouts);
(8)限流限速(rate limiting);
(9)訪問控制(access control);
(10)身份認(rèn)證(end-to-end authentication)。
1.1.1 服務(wù)注冊(cè)和發(fā)現(xiàn)
RPC:RPC(Remote Procedure Call)遠(yuǎn)程過程調(diào)用,簡(jiǎn)單的理解是一個(gè)節(jié)點(diǎn)請(qǐng)求另一個(gè)節(jié)點(diǎn)提供的服務(wù)
1.1.2 負(fù)載均衡?
把前端的請(qǐng)求分發(fā)到后臺(tái)多個(gè)服務(wù)器
1.1.3 故障恢復(fù)
出現(xiàn)故障具備自恢復(fù)的能力
1.1.4 服務(wù)度量
對(duì)于 HTTP,HTTP/2 和 GRPC 流量,Istio 生成以下指標(biāo):
1、請(qǐng)求計(jì)數(shù)(istio_requests_total):這是一個(gè)用于累加每個(gè)由 Istio 代理所處理請(qǐng)求的 COUNTER 指標(biāo)。
2、請(qǐng)求持續(xù)時(shí)間(istio_request_duration_seconds):這是一個(gè)用于測(cè)量請(qǐng)求的持續(xù)時(shí)間的 DISTRIBUTION 指標(biāo)。
3、請(qǐng)求大小(istio_request_bytes):這是一個(gè)用于測(cè)量 HTTP 請(qǐng)求 body 大小的 DISTRIBUTION 指標(biāo)。
4、響應(yīng)大?。╥stio_response_bytes):這是一個(gè)用于測(cè)量 HTTP 響應(yīng) body 大小的 DISTRIBUTION 指標(biāo)。
對(duì)于 TCP 流量,Istio 生成以下指標(biāo):
1、Tcp 發(fā)送字節(jié)數(shù)(istio_tcp_sent_bytes_total):這是一個(gè)用于測(cè)量在 TCP 連接下響應(yīng)期間發(fā)送的總字節(jié)數(shù)的 COUNTER 指標(biāo)。
2、Tcp 接收字節(jié)數(shù)(istio_tcp_received_bytes_total):這是一個(gè)用于測(cè)量在 TCP 連接下請(qǐng)求期間接收的總字節(jié)數(shù)的COUNTER指標(biāo)。
3、Tcp 打開連接數(shù)(istio_tcp_connections_opened_total):這是一個(gè)用于累加每個(gè)打開連接的 COUNTER 指標(biāo)。
4、Tcp 關(guān)閉連接數(shù) (istio_tcp_connections_closed_total) : 這是一個(gè)用于累加每個(gè)關(guān)閉連接的 COUNTER 指標(biāo)。
1.1.5 灰度發(fā)布
灰度發(fā)布也叫金絲雀發(fā)布,起源是,礦井工人發(fā)現(xiàn),金絲雀對(duì)瓦斯氣體很敏感,礦工會(huì)在下井之前,先放一只金絲雀到井中,如果金絲雀不叫了,就代表瓦斯?jié)舛雀摺?/p>
在灰度發(fā)布開始后,先啟動(dòng)一個(gè)新版本應(yīng)用,但是并不直接將流量切過來,而是測(cè)試人員對(duì)新版本進(jìn)行線上測(cè)試,啟動(dòng)的這個(gè)新版本應(yīng)用,就是我們的金絲雀。如果沒有問題,那么可以將少量的用戶流量導(dǎo)入到新版本上,然后再對(duì)新版本做運(yùn)行狀態(tài)觀察,收集各種運(yùn)行時(shí)數(shù)據(jù),如果此時(shí)對(duì)新舊版本做各種數(shù)據(jù)對(duì)比,就是所謂的A/B測(cè)試。
當(dāng)確認(rèn)新版本運(yùn)行良好后,再逐步將更多的流量導(dǎo)入到新版本上,在此期間,還可以不斷地調(diào)整新舊兩個(gè)版本的運(yùn)行的服務(wù)器副本數(shù)量,以使得新版本能夠承受越來越大的流量壓力。直到將100%的流量都切換到新版本上,最后關(guān)閉剩下的老版本服務(wù),完成灰度發(fā)布。
如果在灰度發(fā)布過程中(灰度期)發(fā)現(xiàn)了新版本有問題,就應(yīng)該立即將流量切回老版本上,這樣,就會(huì)將負(fù)面影響控制在最小范圍內(nèi)。
1.2 Istio核心特性
1、流控(traffic management)
斷路器(circuit breakers)、超時(shí)、重試、多路由規(guī)則、AB測(cè)試、灰度發(fā)布、按照百分比分配流量等。
2、安全(security)
加密、身份認(rèn)證、服務(wù)到服務(wù)的權(quán)限控制、K8S里容器到容器的權(quán)限控制等。
3、可觀察(observability)
追蹤、監(jiān)控、數(shù)據(jù)收集,通過控制后臺(tái)全面了解上行下行流量,服務(wù)鏈路情況,服務(wù)運(yùn)行情況,系統(tǒng)性能情況,國(guó)內(nèi)微服務(wù)架構(gòu)體系,這一塊做得比較缺乏。
4、平臺(tái)無關(guān)系(platform support)
K8s,物理機(jī),自己的虛機(jī)都沒問題。
5、集成與定制(integration and customization)
可定制化擴(kuò)展功能。
1.2.1 斷路器
互動(dòng)1:舉個(gè)生活中的例子解釋斷路器
當(dāng)電路發(fā)生故障或異常時(shí),伴隨著電流不斷升高,并且升高的電流有可能能損壞電路中的某些重要器件,也有可能燒毀電路甚至造成火災(zāi)。若電路中正確地安置了保險(xiǎn)絲,那么保險(xiǎn)絲就會(huì)在電流異常升高到一定的高度和熱度的時(shí)候,自身熔斷切斷電流,從而起到保護(hù)電路安全運(yùn)行的作用。
很多技術(shù)都是來源生活的,隨著社會(huì)進(jìn)步,科技發(fā)展
斷路器也稱為服務(wù)熔斷,在多個(gè)服務(wù)調(diào)用的時(shí)候,服務(wù)A依賴服務(wù)B,服務(wù)B依賴服務(wù)C,如果服務(wù)C響應(yīng)時(shí)間過長(zhǎng)或者不可用,則會(huì)讓服務(wù)B占用太多系統(tǒng)資源,而服務(wù)A也依賴服B,同時(shí)也在占用大量的系統(tǒng)資源,造成系統(tǒng)雪崩的情況出現(xiàn)。 Istio 斷路器通過網(wǎng)格中的邊車對(duì)流量進(jìn)行攔截判斷處理,避免了在代碼中侵入控制邏輯,非常方便的就實(shí)服務(wù)熔斷的能力。
在微服務(wù)架構(gòu)中,在高并發(fā)情況下,如果請(qǐng)求數(shù)量達(dá)到一定極限(可以自己設(shè)置閾值),超出了設(shè)置的閾值,斷路器會(huì)自動(dòng)開啟服務(wù)保護(hù)功能,然后通過服務(wù)降級(jí)的方式返回一個(gè)友好的提示給客戶端。假設(shè)當(dāng)10個(gè)請(qǐng)求中,有10%失敗時(shí),熔斷器就會(huì)打開,此時(shí)再調(diào)用此服務(wù),將會(huì)直接返回失敗,不再調(diào)遠(yuǎn)程服務(wù)。直到10s鐘之后,重新檢測(cè)該觸發(fā)條件,判斷是否把熔斷器關(guān)閉,或者繼續(xù)打開。
互動(dòng)2:服務(wù)降級(jí)(提高用戶體驗(yàn)效果)
比如電商平臺(tái),在針對(duì)618、雙11的時(shí)候會(huì)有一些秒殺場(chǎng)景,秒殺的時(shí)候請(qǐng)求量大,可能會(huì)返回報(bào)錯(cuò)標(biāo)志“當(dāng)前請(qǐng)求人數(shù)多,請(qǐng)稍后重試”等,如果使用服務(wù)降級(jí),無法提供服務(wù)的時(shí)候,消費(fèi)者會(huì)調(diào)用降級(jí)的操作,返回服務(wù)不可用等信息,或者返回提前準(zhǔn)備好的靜態(tài)頁面寫好的信息。
1.2.2 超時(shí)
什么時(shí)候需要用到超時(shí)?
在生產(chǎn)環(huán)境中經(jīng)常會(huì)碰到由于調(diào)用方等待下游的響應(yīng)過長(zhǎng),堆積大量的請(qǐng)求阻塞了自身服務(wù),造成雪崩的情況,通過超時(shí)處理來避免由于無限期等待造成的故障,進(jìn)而增強(qiáng)服務(wù)的可用性。
通過例子來理解
nginx 服務(wù)設(shè)置了超時(shí)時(shí)間為3秒,如果超出這個(gè)時(shí)間就不在等待,返回超時(shí)錯(cuò)誤
httpd 服務(wù)設(shè)置了響應(yīng)時(shí)間延遲5秒,任何請(qǐng)求都需要等待5秒后才能返回
client 通過訪問 nginx 服務(wù)去反向代理 httpd 服務(wù),由于 httpd 服務(wù)需要5秒后才能返回,但nginx 服務(wù)只等待3秒,所以客戶端會(huì)提示超時(shí)錯(cuò)誤。
1.2.3 重試
istio 重試機(jī)制就是如果調(diào)用服務(wù)失敗,Envoy 代理嘗試連接服務(wù)的最大次數(shù)。而默認(rèn)情況下,Envoy 代理在失敗后并不會(huì)嘗試重新連接服務(wù)。
舉個(gè)例子:
客戶端調(diào)用 nginx,nginx 將請(qǐng)求轉(zhuǎn)發(fā)給 tomcat。tomcat 通過故障注入而中止對(duì)外服務(wù),nginx 設(shè)置如果訪問 tomcat 失敗則會(huì)重試 3 次。
1.2.4 多路由規(guī)則
1、HTTP重定向(HTTPRedirect)
2、HTTP重寫(HTTPRewrite)
3、HTTP重試(HTTPRetry)
4、HTTP故障注入(HTTPFaultInjection)
5、HTTP跨域資源共享(CorsPolicy)
2.Istio架構(gòu)
istio服務(wù)網(wǎng)格從邏輯上分為數(shù)據(jù)平面和控制平面。
1、數(shù)據(jù)平面由一組以Sidecar方式部署的智能代理(Envoy+Polit-agent)組成。這些代理承載并控制微服務(wù)之間的所有網(wǎng)絡(luò)通信,管理入口和出口流量,類似于一線員工。 Sidecar 一般和業(yè)務(wù)容器綁定在一起(在Kubernets中以自動(dòng)注入的方式注入到到業(yè)務(wù)pod中),來劫持業(yè)務(wù)應(yīng)用容器的流量,并接受控制面組件的控制,同時(shí)會(huì)向控制面輸出日志、跟蹤及監(jiān)控?cái)?shù)據(jù)。
Envoy 和 pilot-agent 打在同一個(gè)鏡像中,即sidecar Proxy。
2、控制平面負(fù)責(zé)管理和配置代理來路由流量。
istio1.5+中使用了一個(gè)全新的部署模式,重建了控制平面,將原有的多個(gè)組件整合為一個(gè)單體結(jié)構(gòu)istiod,這個(gè)組件是控制平面的核心,管理Istio的所有功能,主要包括Pilot、Mixer、Citadel等服務(wù)組件。
istiod是新版本中最大的變化,以一個(gè)單體組件替代了原有的架構(gòu),降低了復(fù)雜度和維護(hù)難度,但原有的多組件并不是被完全移除,而是在重構(gòu)后以模塊的形式整合在一起組成了istiod。
結(jié)合下圖我們來理解Istio的各組件的功能及相互之間的協(xié)作方式。
1. 自動(dòng)注入:在創(chuàng)建應(yīng)用程序時(shí)自動(dòng)注入 Sidecar代理Envoy程序。在 Kubernetes中創(chuàng)建 Pod時(shí),Kube-apiserver調(diào)用控制面組件的 Sidecar-Injector服務(wù),自動(dòng)修改應(yīng)用程序的描述信息并注入Sidecar。在真正創(chuàng)建Pod時(shí),在創(chuàng)建業(yè)務(wù)容器的Pod中同時(shí)創(chuàng)建Sidecar容器。
2. 流量攔截:在Pod初始化時(shí)設(shè)置iptables 規(guī)則,基于配置的iptables規(guī)則攔截業(yè)務(wù)容器的Inbound流量和Outbound流量到Sidecar上。而應(yīng)用程序感知不到Sidecar的存在,還以原本的方式 進(jìn)行互相訪問。上圖中,流出frontend服務(wù)的流量會(huì)被 frontend服務(wù)側(cè)的 Envoy攔截,而當(dāng)流量到達(dá)forecast容器時(shí),Inbound流量被forecast 服務(wù)側(cè)的Envoy攔截。
3. 服務(wù)發(fā)現(xiàn):服務(wù)發(fā)起方的
Envoy 調(diào)用控制面組件 Pilot 的服務(wù)發(fā)現(xiàn)接口獲取目標(biāo)服務(wù)的實(shí)例列表。上圖中,frontend 服務(wù)側(cè)的 Envoy 通過 Pilot 的服務(wù)發(fā)現(xiàn)接口得到forecast服務(wù)各個(gè)實(shí)例的地址。
4. 負(fù)載均衡:服務(wù)發(fā)起方的Envoy根據(jù)配置的負(fù)載均衡策略選擇服務(wù)實(shí)例,并連接對(duì)應(yīng)的實(shí)例地址。上圖中,數(shù)據(jù)面的各個(gè)Envoy從Pilot中獲取forecast服務(wù)的負(fù)載均衡配置,并執(zhí)行負(fù)載均衡動(dòng)作。
5. 流量治理:Envoy 從 Pilot 中獲取配置的流量規(guī)則,在攔截到 Inbound 流量和Outbound 流量時(shí)執(zhí)行治理邏輯。上圖中, frontend 服務(wù)側(cè)的 Envoy 從 Pilot 中獲取流量治理規(guī)則,并根據(jù)該流量治理規(guī)則將不同特征的流量分發(fā)到forecast服務(wù)的v1或v2版本。
6. 訪問安全:在服務(wù)間訪問時(shí)通過雙方的Envoy進(jìn)行雙向認(rèn)證和通道加密,并基于服務(wù)的身份進(jìn)行授權(quán)管理。上圖中,Pilot下發(fā)安全相關(guān)配置,在frontend服務(wù)和forecast服務(wù)的Envoy上自動(dòng)加載證書和密鑰來實(shí)現(xiàn)雙向認(rèn)證,其中的證書和密鑰由另一個(gè)管理面組件
Citadel維護(hù)。
7. 服務(wù)監(jiān)測(cè):在服務(wù)間通信時(shí),通信雙方的Envoy都會(huì)連接管理面組件Mixer上報(bào)訪問數(shù)據(jù),并通過Mixer將數(shù)據(jù)轉(zhuǎn)發(fā)給對(duì)應(yīng)的監(jiān)控后端。上圖中,frontend服務(wù)對(duì)forecast服務(wù)的訪問監(jiān)控指標(biāo)、日志和調(diào)用鏈都可以通過這種方式收集到對(duì)應(yīng)的監(jiān)控后端。
8. 策略執(zhí)行:在進(jìn)行服務(wù)訪問時(shí),通過Mixer連接后端服務(wù)來控制服務(wù)間的訪問,判斷對(duì)訪問是放行還是拒絕。上圖中,Mixer 后端可以對(duì)接一個(gè)限流服務(wù)對(duì)從frontend服務(wù)到forecast服務(wù)的訪問進(jìn)行速率控制等操作。
9. 外部訪問:在網(wǎng)格的入口處有一個(gè)Envoy扮演入口網(wǎng)關(guān)的角 色。上圖中,外部服務(wù)通過Gateway訪問入口服務(wù) frontend,對(duì) frontend服務(wù)的負(fù)載均衡和一些流量治理策略都在這個(gè)Gateway上執(zhí)行。
問題1:為什么代理會(huì)叫sidecar proxy?
看了上圖就容易懂了,sidecar和proxy相生相伴,就像摩托車(motor)與旁邊的車廂(sidecar)。未來,sidecar和proxy就指微服務(wù)進(jìn)程解耦成兩個(gè)進(jìn)程之后,提供基礎(chǔ)能力的那個(gè)代理進(jìn)程。
3.istio組件詳解
Istio服務(wù)組件有很多,從上面的流程中基本能看出每個(gè)組件如何協(xié)作的,下面具體講解每個(gè)組件的具體用途和功能。
[root@xianchaomaster1 ~]# kubectl get svc -n istio-system |awk '{print $1}'
istio-egressgateway
istio-ingressgateway
istiod
3.1 Pilot
Pilot 是 Istio 的主要控制組件,下發(fā)指令控制客戶端。在整個(gè)系統(tǒng)中,Pilot 完成以下任務(wù):
1、從 Kubernetes 或者其他平臺(tái)的注冊(cè)中心獲取服務(wù)信息,完成服務(wù)發(fā)現(xiàn)過程。
2、讀取 Istio 的各項(xiàng)控制配置,在進(jìn)行轉(zhuǎn)換之后,將其發(fā)給數(shù)據(jù)面進(jìn)行實(shí)施。
Pilot 將配置內(nèi)容下發(fā)給數(shù)據(jù)面的 Envoy,Envoy 根據(jù) Pilot 指令,將路由、服務(wù)、監(jiān)聽、集群等定義信息轉(zhuǎn)換為本地配置,完成控制行為的落地。
1)Pilot為Envoy提供服務(wù)發(fā)現(xiàn)
2)提供流量管理功能(例如,A/B 測(cè)試、金絲雀發(fā)布等)以及彈性功能(超時(shí)、重試、熔斷器等);
3)生成envoy配置
4)啟動(dòng)envoy
5)監(jiān)控并管理envoy的運(yùn)行狀況,比如envoy出錯(cuò)時(shí)pilot-agent負(fù)責(zé)重啟envoy,或者envoy配置變更后reload envoy
3.2 Envoy
Envoy是什么?
Envoy是用 C++ 開發(fā)的高性能代理,用于協(xié)調(diào)服務(wù)網(wǎng)格中所有服務(wù)的入站和出站流量。
Envoy有許多強(qiáng)大的功能,例如:
動(dòng)態(tài)服務(wù)發(fā)現(xiàn)
負(fù)載均衡
TLS終端
HTTP/2與gRPC代理
斷路器
健康檢查
流量拆分
灰度發(fā)布
故障注入
Istio中Envoy與服務(wù)什么關(guān)系?
為了便于理解Istio中Envoy與服務(wù)的關(guān)系,下圖為Envoy的拓?fù)鋱D,如圖所示:
Envoy和Service A同屬于一個(gè)Pod,共享網(wǎng)絡(luò)和命名空間,Envoy代理進(jìn)出Pod A的流量,并將流量按照外部請(qǐng)求的規(guī)則作用于Service A中。
Pilot-agent是什么?
Envoy不直接跟k8s交互,通過 pilot-agent管理的
Pilot-agent進(jìn)程根據(jù)K8S APIserver中的配置信息生成Envoy的配置文件,并負(fù)責(zé)啟動(dòng)Envoy進(jìn)程。
Envoy由Pilot-agent進(jìn)程啟動(dòng),啟動(dòng)后,Envoy讀取Pilot-agent為它生成的配置文件,然后根據(jù)該文件的配置獲取到Pilot的地址,通過數(shù)據(jù)面從pilot拉取動(dòng)態(tài)配置信息,包括路由(route),監(jiān)聽器(listener),服務(wù)集群(cluster)和服務(wù)端點(diǎn)(endpoint)。
3.3 Citadel
負(fù)責(zé)處理系統(tǒng)上不同服務(wù)之間的TLS通信。 Citadel充當(dāng)證書頒發(fā)機(jī)構(gòu)(CA),并生成證書以允許在數(shù)據(jù)平面中進(jìn)行安全的mTLS通信。
Citadel是 Istio的核心安全組件,提供了自動(dòng)生 成、分發(fā)、輪換與撤銷密鑰和證書功能。Citadel一直監(jiān)聽 Kube- apiserver,以 Secret的形式為每個(gè)服務(wù)都生成證書密鑰,并在Pod創(chuàng)建時(shí)掛載到Pod上,代理容器使用這些文件來做服務(wù)身份認(rèn)證,進(jìn)而代 理兩端服務(wù)實(shí)現(xiàn)雙向TLS認(rèn)證、通道加密、訪問授權(quán)等安全功能。如圖 所示,frontend 服 務(wù)對(duì) forecast 服務(wù)的訪問用到了HTTP方式,通過配置即可對(duì)服務(wù)增加認(rèn)證功能,雙方的Envoy會(huì)建立雙向認(rèn)證的TLS通道,從而在服務(wù)間啟用雙向認(rèn)證的HTTPS。
3.4 Galley
Galley是istio的配置驗(yàn)證、提取、處理和分發(fā)的組件。Galley是提供配置管理的服務(wù)。實(shí)現(xiàn)原理是通過k8s提供的ValidatingWebhook對(duì)配置進(jìn)行驗(yàn)證。
Galley使Istio可以與Kubernetes之外的其他環(huán)境一起工作,因?yàn)樗梢詫⒉煌呐渲脭?shù)據(jù)轉(zhuǎn)換為Istio可以理解的通用格式。
3.5 Ingressgateway
Ingressgateway 就是入口處的 Gateway,從網(wǎng)格外訪問網(wǎng)格內(nèi)的服務(wù)就是通過這個(gè)Gateway進(jìn)行的。istio-ingressgateway是一個(gè)Loadbalancer類型的Service,不同于其他服務(wù)組件只有一兩個(gè)端 口,istio-ingressgateway 開放了一組端口,這些就是網(wǎng)格內(nèi)服務(wù)的外部訪問端口。如下圖所示,網(wǎng)格入口網(wǎng)關(guān)istio-ingressgateway的負(fù)載和網(wǎng)格內(nèi)的Sidecar是同樣的執(zhí)行流程,也和網(wǎng)格內(nèi)的其他 Sidecar一樣從 Pilot處接收流量規(guī)則并執(zhí)行。
3.6 Sidecar-injector
Sidecar-injector是負(fù)責(zé)自動(dòng)注入的組件,只要開啟了自動(dòng)注 入,在Pod創(chuàng)建時(shí)就會(huì)自動(dòng)調(diào)用istio-sidecar-injector向Pod中注入Sidecar 容器。
在 Kubernetes環(huán)境下,根據(jù)自動(dòng)注入配置,Kube-apiserver在攔截到 Pod創(chuàng)建的請(qǐng)求時(shí),會(huì)調(diào)用自動(dòng)注入服務(wù) istio-sidecar-injector 生成 Sidecar 容器的描述并將其插入原 Pod的定義中,這樣,在創(chuàng)建的 Pod 內(nèi)除了包括業(yè)務(wù)容器,還包括 Sidecar容器,這個(gè)注入過程對(duì)用戶透明。
3.7 其他組件
除了以“istio”為前綴的Istio自有組件,在集群中一般還安裝Jaeger-agent、Jaeger-collector、Jaeger-query、Kiali、Prometheus、Grafana、
Tracing、Zipkin等組件,這些組件提供了Istio的調(diào)用鏈、監(jiān)控等功能,可以選擇安裝來完成完整的服務(wù)監(jiān)控管理功能。
4.在k8s平臺(tái)安裝Istio
4.1 準(zhǔn)備安裝Istio是要的壓縮包
官網(wǎng)下載地址: https://github.com/istio/istio/ 官方訪問相對(duì)較慢,我在課件提供了壓縮包,大家最好用我的壓縮包,這樣做實(shí)驗(yàn)才不會(huì)出問題 1、把壓縮包上傳到k8s的控制節(jié)點(diǎn)xianchaomaster1。手動(dòng)解壓: [root@xianchaomaster1 ~]# tar zxvf istio-1.10.1-linux-amd64.tar.gz 2、切換到istio包所在目錄下。tar zxvf istio-1.10.1-linux-amd64.tar.gz解壓的軟件包包名是istio-1.10.1,則: cd istio-1.10.1 安裝目錄包含如下內(nèi)容: 2)samples/目錄下,有示例應(yīng)用程序 3)bin/目錄下,包含istioctl的客戶端文件。istioctl工具用于手動(dòng)注入Envoy sidecar代理。 3、將istioctl客戶端路徑增加到path環(huán)境變量中,macOS 或 Linux 系統(tǒng)的增加方式如下: export PATH=$PWD/bin:$PATH 4、把istioctl這個(gè)可執(zhí)行文件拷貝到/usr/bin/目錄 cd /root/istio-1.10.1/bin/ cp -ar istioctl /usr/bin/
4.2 安裝istio
1.下載鏡像: 安裝istio需要的鏡像默認(rèn)從官網(wǎng)拉取,但是官網(wǎng)的鏡像我們拉取會(huì)有問題,可以從課件下載鏡像,然后上傳到自己k8s集群的各個(gè)節(jié)點(diǎn),通過docker load -i手動(dòng)解壓鏡像: docker load -i examples-bookinfo-details.tar.gz docker load -i examples-bookinfo-reviews-v1.tar.gz docker load -i examples-bookinfo-productpage.tar.gz docker load -i examples-bookinfo-reviews-v2.tar.gz docker load -i examples-bookinfo-ratings.tar.gz docker load -i examples-bookinfo-reviews-v3.tar.gz docker load -i istio-1-10-1.tar.gz docker load -i engress-proxyv2-1-10-1.tar.gz docker load -i httpbin.tar.gz 2.安裝 在k8s的控制節(jié)點(diǎn)xianchaomaster1操作 istioctl install --set profile=demo -y 看到如下,說明istio初始化完成: Detected that your cluster does not support third party JWT authentication. Falling back to less secure first party JWT. See https://istio.io/docs/ops/best-practices/security/#configure-third-party-service-account-tokens for details. - Applying manifest for component Base... ✔ Finished applying manifest for component Base. - Applying manifest for component Pilot... ✔ Finished applying manifest for component Pilot. Waiting for resources to become ready... Waiting for resources to become ready... - Applying manifest for component EgressGateways... - Applying manifest for component IngressGateways... - Applying manifest for component AddonComponents... ✔ Finished applying manifest for component EgressGateways. ✔ Finished applying manifest for component IngressGateways. ✔ Finished applying manifest for component AddonComponents. ✔ Installation complete 3.驗(yàn)證istio是否部署成功 kubectl get pods -n istio-system 顯示如下,說明部署成功 istio-egressgateway-d84f95b69-5gtdc 1/1 Running 0 15h istio-ingressgateway-75f6d79f48-fhxjj 1/1 Running 0 15h istiod-c9f6864c4-nrm82 1/1 Running 0 15h 4.卸載istio集群,暫時(shí)不執(zhí)行,記住這個(gè)命令即可 istioctl manifest generate --set profile=demo | kubectl delete -f -
5、通過Istio部署在線書店bookinfo
5.1 在線書店功能介紹
在線書店-bookinfo
該應(yīng)用由四個(gè)單獨(dú)的微服務(wù)構(gòu)成,這個(gè)應(yīng)用模仿在線書店的一個(gè)分類,顯示一本書的信息,頁面上會(huì)顯示一本書的描述,書籍的細(xì)節(jié)(ISBN、頁數(shù)等),以及關(guān)于這本書的一些評(píng)論
Bookinfo應(yīng)用分為四個(gè)單獨(dú)的微服務(wù)
1)productpage這個(gè)微服務(wù)會(huì)調(diào)用details和reviews兩個(gè)微服務(wù),用來生成頁面;
2)details這個(gè)微服務(wù)中包含了書籍的信息;
3)reviews這個(gè)微服務(wù)中包含了書籍相關(guān)的評(píng)論,它還會(huì)調(diào)用ratings微服務(wù);
4)ratings這個(gè)微服務(wù)中包含了由書籍評(píng)價(jià)組成的評(píng)級(jí)信息。
reviews微服務(wù)有3個(gè)版本
1)v1版本不會(huì)調(diào)用ratings服務(wù);
2)v2版本會(huì)調(diào)用ratings服務(wù),并使用1到5個(gè)黑色星形圖標(biāo)來顯示評(píng)分信息;
3)v3版本會(huì)調(diào)用ratings服務(wù),并使用1到5個(gè)紅色星形圖標(biāo)來顯示評(píng)分信息。
下圖展示了這個(gè)應(yīng)用的端到端架構(gòu)
Bookinfo應(yīng)用中的幾個(gè)微服務(wù)是由不同的語言編寫的。這些服務(wù)對(duì)istio并無依賴,但是構(gòu)成了一個(gè)有代表性的服務(wù)網(wǎng)格的例子:它由多個(gè)服務(wù)、多個(gè)語言構(gòu)成,并且reviews服務(wù)具有多個(gè)版本。
5.2 部署應(yīng)用
要在Istio中運(yùn)行這一應(yīng)用,無需對(duì)應(yīng)用自身做出任何改變。 只要簡(jiǎn)單的在 Istio 環(huán)境中對(duì)服務(wù)進(jìn)行配置和運(yùn)行,具體一點(diǎn)說就是把 Envoy sidecar 注入到每個(gè)服務(wù)之中。 最終的部署結(jié)果將如下圖所示:
所有的微服務(wù)都和Envoy sidecar集成在一起,被集成服務(wù)所有的出入流量都被envoy sidecar 所劫持,這樣就為外部控制準(zhǔn)備了所需的 Hook,然后就可以利用Istio控制平面為應(yīng)用提供服務(wù)路由、遙測(cè)數(shù)據(jù)收集以及策略實(shí)施等功能。
5.3 啟動(dòng)應(yīng)用服務(wù)
1.進(jìn)入istio安裝目錄。
2.istio默認(rèn)自動(dòng)注入 sidecar,需要??為default命名空間打上標(biāo)簽istio-injection=enabled
kubectl label namespace default istio-injection=enabled
3.使用kubectl部署應(yīng)用
cd istio-1.10.1
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
上面的命令會(huì)啟動(dòng)全部的四個(gè)服務(wù),其中也包括了 reviews 服務(wù)的三個(gè)版本(v1、v2 以及 v3)。
4.確認(rèn)所有的服務(wù)和 Pod 都已經(jīng)正確的定義和啟動(dòng):
kubectl get services
顯示如下
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
details ClusterIP 10.109.124.202 <none> 9080/TCP
productpage ClusterIP 10.102.89.129 <none> 9080/TCP
ratings ClusterIP 10.101.97.75 <none> 9080/TCP
reviews ClusterIP 10.100.105.33 <none> 9080/TCP
kubectl get pods
顯示如下
NAME READY STATUS RESTARTS AGE
details-v1-78d78fbddf-qssjb 2/2 Running 0 73m
productpage-v1-85b9bf9cd7-r699f 2/2 Running 0 73m
ratings-v1-6c9dbf6b45-77kv7 2/2 Running 0 73m
reviews-v1-564b97f875-2jtxq 2/2 Running 0 73m
reviews-v2-568c7c9d8f-f5css 2/2 Running 0 73m
reviews-v3-67b4988599-fxfzx 2/2 Running 0 73m
tomcat-deploy-59664bcb6f-5z4nn 1/1 Running 0 22h
tomcat-deploy-59664bcb6f-cgjbn 1/1 Running 0 22h
tomcat-deploy-59664bcb6f-n4tqq 1/1 Running 0 22h
5.確認(rèn) Bookinfo 應(yīng)用是否正在運(yùn)行,在某個(gè)Pod中用curl命令對(duì)應(yīng)用發(fā)送請(qǐng)求,例如ratings:
kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
顯示如下:
6.確定Ingress的IP和端口 現(xiàn)在Bookinfo服務(wù)已經(jīng)啟動(dòng)并運(yùn)行,你需要使應(yīng)用程序可以從Kubernetes集群外部訪問,例如從瀏覽器訪問,那可以用Istio Gateway來實(shí)現(xiàn)這個(gè)目標(biāo)。 1)為應(yīng)用程序定義gateway網(wǎng)關(guān): kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml 2)確認(rèn)網(wǎng)關(guān)創(chuàng)建完成: kubectl get gateway 顯示如下: NAME AGE bookinfo-gateway 2m18s 3)確定ingress ip和端口 執(zhí)行如下指令,明確自身 Kubernetes 集群環(huán)境支持外部負(fù)載均衡: kubectl get svc istio-ingressgateway -n istio-system
如果EXTERNAL-IP值已設(shè)置,說明環(huán)境正在使用外部負(fù)載均衡,可以用其為ingress gateway 提供服務(wù)。 如果EXTERNAL-IP值為<none>(或持續(xù)顯示<pending>), 說明環(huán)境沒有提供外部負(fù)載均衡,無法使用ingress gateway。在這種情況下,你可以使用服務(wù)的NodePort訪問網(wǎng)關(guān)。
若自身環(huán)境未使用外部負(fù)載均衡器,需要通過 node port 訪問??梢酝ㄟ^以下命令獲取Istio Gateway的地址:
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
4)設(shè)置GATEWAY_URL
INGRESS_HOST=192.168.40.180
#192.168.40.180是安裝istio的機(jī)器,即k8s控制節(jié)點(diǎn)xianchaomaster1的ip
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
echo $GATEWAY_URL 顯示如下:
192.168.40.180:30871
確認(rèn)可以從集群外部訪問應(yīng)用
可以用curl命令來確認(rèn)是否能夠從集群外部訪問 Bookinfo 應(yīng)用程序:
curl -s http://${GATEWAY_URL}/productpage | grep -o "<title>.*</title>"
顯示如下:
還可以用瀏覽器打開網(wǎng)址http://$GATEWAY_URL/productpage,也就是192.168.40.180:30871/productpage來瀏覽應(yīng)用的 Web 頁面。如果刷新幾次應(yīng)用的頁面,就會(huì)看到 productpage 頁面中會(huì)隨機(jī)展示 reviews 服務(wù)的不同版本的效果(紅色、黑色的星形或者沒有顯示)。
通過istio的ingressgateway訪問,官網(wǎng):
https://istio.io/docs/examples/bookinfo/
擴(kuò)展:添加外部IP-extertal-IP
[root@xianchaomaster1 ~]# kubectl edit svc istio-ingressgateway -n istio-system
[root@xianchaomaster1 ~]# kubectl get service istio-ingressgateway -n istio-system
在windows機(jī)器上的C:WindowsSystem32driversetchosts里面最后一行加上如下域名解析: 192.168.40.180 productpage.xianchao.cn 在瀏覽器訪問: http://productpage.xianchao.cn/productpage
5.4 卸載bookinfo服務(wù) 可以使用下面的命令來完成應(yīng)用的刪除和清理了: 1.刪除路由規(guī)則,并銷毀應(yīng)用的 Pod sh samples/bookinfo/platform/kube/cleanup.sh 2.確認(rèn)應(yīng)用已經(jīng)關(guān)停 kubectl get virtualservices #-- there should be no virtual services kubectl get destinationrules #-- there should be no destination rules kubectl get gateway #-- there should be no gateway kubectl get pods #-- the Bookinfo pods should be deleted
6、通過Istio實(shí)現(xiàn)灰度發(fā)布
6.1 什么是灰度發(fā)布?
灰度發(fā)布也叫金絲雀部署 ,是指通過控制流量的比例,實(shí)現(xiàn)新老版本的逐步更替。
比如對(duì)于服務(wù)A 有 version1、 version2 兩個(gè)版本 , 當(dāng)前兩個(gè)版本同時(shí)部署,但是version1比例90% ,version2比例10% ,看運(yùn)行效果,如果效果好逐步調(diào)整流量占比 80~20 ,70~30 ·····10~90 ,0,100 ,最終version1版本下線。
灰度發(fā)布的特點(diǎn):
1)新老板共存
2)可以實(shí)時(shí)根據(jù)反饋動(dòng)態(tài)調(diào)整占比
3)理論上不存在服務(wù)完全宕機(jī)的情況。
4)適合于服務(wù)的平滑升級(jí)與動(dòng)態(tài)更新。
6.2 使用istio進(jìn)行金絲雀發(fā)布
下面實(shí)驗(yàn)需要的鏡像包在課件,把canary-v2.tar.gz和canary-v1.tar.gz上傳到k8s工作節(jié)點(diǎn),手動(dòng)解壓:
[root@xianchaonode1 ~]# docker load -i canary-v2.tar.gz
[root@xianchaonode1 ~]# docker load -i canary-v1.tar.gz
創(chuàng)建金絲雀服務(wù)
cat deployment.yaml,內(nèi)容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: appv1
labels:
app: v1
spec:
replicas: 1
selector:
matchLabels:
app: v1
apply: canary
template:
metadata:
labels:
app: v1
apply: canary
spec:
containers:
- name: nginx
image: xianchao/canary:v1
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: appv2
labels:
app: v2
spec:
replicas: 1
selector:
matchLabels:
app: v2
apply: canary
template:
metadata:
labels:
app: v2
apply: canary
spec:
containers:
- name: nginx
image: xianchao/canary:v2
ports:
- containerPort: 80
更新:
kubectl apply -f deployment.yaml
創(chuàng)建service
cat service.yaml文件,內(nèi)容如下:
apiVersion: v1
kind: Service
metadata:
name: canary
labels:
apply: canary
spec:
selector:
apply: canary
ports:
- protocol: TCP
port: 80
targetPort: 80
更新service.yaml文件
kubectl apply -f service.yaml
創(chuàng)建gateway
cat gateway.yaml文件,內(nèi)容如下:
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: canary-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
更新gateway.yaml
kubectl apply -f gateway.yaml
創(chuàng)建virtualservice
cat virtual.yaml,內(nèi)容如下:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: canary
spec:
hosts:
- "*"
gateways:
- canary-gateway
http:
- route:
- destination:
host: canary.default.svc.cluster.local
subset: v1
weight: 90
- destination:
host: canary.default.svc.cluster.local
subset: v2
weight: 10
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: canary
spec:
host: canary.default.svc.cluster.local
subsets:
- name: v1
labels:
app: v1
- name: v2
labels:
app: v2
更新virtual.yaml文件
kubectl apply -f virtual.yaml
(5)獲取Ingress_port:
kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}'
顯示結(jié)果是30871
驗(yàn)證金絲雀發(fā)布效果:
for i in `seq 1 100`; do curl 192.168.40.180:30871;done > 1.txt
打開1.txt可以看到結(jié)果有90次出現(xiàn)v1,10次出現(xiàn)canary-v2,符合我們預(yù)先設(shè)計(jì)的流量走向。
7、istio核心資源解讀
官網(wǎng):
https://istio.io/latest/docs/concepts/traffic-management/
7.1 Gateway
在Kubernetes環(huán)境中,Ingress controller用于管理進(jìn)入集群的流量。在Istio服務(wù)網(wǎng)格中 Istio Ingress Gateway承擔(dān)相應(yīng)的角色,它使用新的配置模型(Gateway 和 VirtualServices)完成流量管理的功能。通過下圖做一個(gè)總的描述
1、用戶向某端口發(fā)出請(qǐng)求
2、負(fù)載均衡器監(jiān)聽端口,并將請(qǐng)求轉(zhuǎn)發(fā)到集群中的某個(gè)節(jié)點(diǎn)上。Istio Ingress Gateway Service 會(huì)監(jiān)聽集群節(jié)點(diǎn)端口的請(qǐng)求
3、Istio Ingress Gateway Service 將請(qǐng)求交給Istio Ingress Gateway Pod 處理。IngressGateway Pod 通過 Gateway 和 VirtualService 配置規(guī)則處理請(qǐng)求。其中,Gateway 用來配置端口、協(xié)議和證書;VirtualService 用來配置一些路由信息(找到請(qǐng)求對(duì)應(yīng)處理的服務(wù)App Service)
4、Istio Ingress Gateway Pod將請(qǐng)求轉(zhuǎn)給App Service
5、最終的請(qǐng)求會(huì)交給App Service 關(guān)聯(lián)的App Deployment處理
cat gateway.yaml
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: canary-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
網(wǎng)關(guān)是一個(gè)運(yùn)行在網(wǎng)格邊緣的負(fù)載均衡器,用于接收傳入或傳出的HTTP/TCP連接。主要工作是接受外部請(qǐng)求,把請(qǐng)求轉(zhuǎn)發(fā)到內(nèi)部服務(wù)。網(wǎng)格邊緣的Ingress 流量,會(huì)通過對(duì)應(yīng)的 Istio IngressGateway Controller 進(jìn)入到集群內(nèi)部。
在上面這個(gè)yaml里我們配置了一個(gè)監(jiān)聽80端口的入口網(wǎng)關(guān),它會(huì)將80端口的http流量導(dǎo)入到集群內(nèi)對(duì)應(yīng)的Virtual Service上。
注意:hosts:
- "*"
*表示通配符,通過任何域名都可以訪問
7.2 VirtualService
VirtualService是Istio流量治理的一個(gè)核心配置,可以說是Istio流量治理中最重要、最復(fù)雜的。VirtualService在形式上表示一個(gè)虛擬服務(wù),將滿足條件的流量都轉(zhuǎn)發(fā)到對(duì)應(yīng)的服務(wù)后端,這個(gè)服務(wù)后端可以是一個(gè)服務(wù),也可以是在DestinationRule中定義的服務(wù)的子集。
cat virtual.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: canary
spec:
hosts:
- "*"
gateways:
- canary-gateway
http:
- route:
- destination:
host: canary.default.svc.cluster.local
subset: v1
weight: 90
- destination:
host: canary.default.svc.cluster.local
subset: v2
weight: 10
這個(gè)虛擬服務(wù)會(huì)收到上一個(gè)gateway中所有80端口來的http流量。
VirtualService 主要由以下部分組成
1、hosts:虛擬主機(jī)名稱,如果在 Kubernetes 集群中,則這個(gè)主機(jī)名可以是service服務(wù)名。
hosts字段列出了virtual service的虛擬主機(jī)。它是客戶端向服務(wù)發(fā)送請(qǐng)求時(shí)使用的一個(gè)或多個(gè)地址,通過該字段提供的地址訪問virtual service,進(jìn)而訪問后端服務(wù)。在集群內(nèi)部(網(wǎng)格內(nèi))使用時(shí)通常與kubernetes的Service同名;當(dāng)需要在集群外部(網(wǎng)格外)訪問時(shí),該字段為gateway請(qǐng)求的地址,即與gateway的hosts字段相同。
hosts:
- reviews
virtual service的主機(jī)名可以是IP地址、DNS名稱,也可以是短名稱(例如Kubernetes服務(wù)短名稱),該名稱會(huì)被隱式或顯式解析為全限定域名(FQDN),具體取決于istio依賴的平臺(tái)??梢允褂们熬Y通配符(“*”)為所有匹配的服務(wù)創(chuàng)建一組路由規(guī)則。virtual service的hosts不一定是Istio服務(wù)注冊(cè)表的一部分,它們只是虛擬目的地,允許用戶為網(wǎng)格無法路由到的虛擬主機(jī)建立流量模型。
virtual service的hosts短域名在解析為完整的域名時(shí),補(bǔ)齊的namespace是VirtualService所在的命名空間,而非Service所在的命名空間。如上例的hosts會(huì)被解析為:reviews.default.svc.cluster.local。
hosts:
- "*"
*表示通配符,任何域名都可以
如在虛擬機(jī)配置hosts文件
192.168.40.180 xianchaomaster1 hello.com.cn
這樣就可以在虛擬機(jī)通過域名hello.com.cn訪問istio內(nèi)部的服務(wù)了
擴(kuò)展:virtualservice配置路由規(guī)則
路由規(guī)則的功能是:滿足http.match條件的流量都被路由到http.route.destination,執(zhí)行重定向(HTTPRedirect)、重寫(HTTPRewrite)、重試(HTTPRetry)、故障注入(HTTPFaultInjection)、跨站(CorsPolicy)策略等。HTTPRoute不僅可以做路由匹配,還可以做一些寫操作來修改請(qǐng)求本身。
如下:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v3
在 http 字段包含了虛擬服務(wù)的路由規(guī)則,用來描述匹配條件和路由行為,它們把 HTTP/1.1、HTTP2 和 gRPC 等流量發(fā)送到 hosts 字段指定的目標(biāo)。
示例中的第一個(gè)路由規(guī)則有一個(gè)條件,以 match 字段開始。此路由接收來自 ”jason“ 用戶的所有請(qǐng)求,把請(qǐng)求發(fā)送到destination指定的v2子集。
7.2.1 路由規(guī)則優(yōu)先級(jí)
在上面例子中,不滿足第一個(gè)路由規(guī)則的流量均流向一個(gè)默認(rèn)的目標(biāo),該目標(biāo)在第二條規(guī)則中指定。因此,第二條規(guī)則沒有 match 條件,直接將流量導(dǎo)向 v3 子集。
7.2.2 多路由規(guī)則解讀
詳細(xì)配置可參考:
https://istio.io/latest/zh/docs/reference/config/networking/virtual-service/
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- bookinfo.com
http:
- match:
- uri:
prefix: /reviews
route:
- destination:
host: reviews
- match:
- uri:
prefix: /ratings
route:
- destination:
host: ratings
路由規(guī)則是將特定流量子集路由到指定目標(biāo)地址的工具。可以在流量端口、header 字段、URI 等內(nèi)容上設(shè)置匹配條件。例如,上面這個(gè)虛擬服務(wù)讓用戶發(fā)送請(qǐng)求到兩個(gè)獨(dú)立的服務(wù):ratings 和 reviews,相當(dāng)于訪問http://bookinfo.com/ratings 和http://bookinfo.com/ reviews,虛擬服務(wù)規(guī)則根據(jù)請(qǐng)求的 URI 把請(qǐng)求路由到特定的目標(biāo)地址。
2、Gateway:流量來源網(wǎng)關(guān)。
3、路由:
路由的destination字段指定了匹配條件的流量的實(shí)際地址。與virtual service的主機(jī)不同,該host必須是存在于istio的服務(wù)注冊(cè)表(如kubernetes services,consul services等)中的真實(shí)目的地或由ServiceEntries聲明的hosts,否則Envoy不知道應(yīng)該將流量發(fā)送到哪里。它可以是一個(gè)帶代理的網(wǎng)格服務(wù)或使用service entry添加的非網(wǎng)格服務(wù)。在kubernetes作為平臺(tái)的情況下,host表示名為kubernetes的service名稱:
- destination:
host: canary.default.svc.cluster.local
subset: v1
weight: 90
7.3 DestinationRule
destination rule是istio流量路由功能的重要組成部分。一個(gè)virtual service可以看作是如何將流量分發(fā)給特定的目的地,然后調(diào)用destination rule來配置分發(fā)到該目的地的流量。destination rule在virtual service的路由規(guī)則之后起作用(即在virtual service的math->route-destination之后起作用,此時(shí)流量已經(jīng)分發(fā)到真實(shí)的service上),應(yīng)用于真實(shí)的目的地。
可以使用destination rule來指定命名的服務(wù)子集,例如根據(jù)版本對(duì)服務(wù)的實(shí)例進(jìn)行分組,然后通過virtual service的路由規(guī)則中的服務(wù)子集將控制流量分發(fā)到不同服務(wù)的實(shí)例中。
cat DestinationRule.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: canary
spec:
host: canary.default.svc.cluster.local
subsets:
- name: v1
labels:
app: v1
- name: v2
labels:
app: v2
在虛擬服務(wù)中使用Hosts配置默認(rèn)綁定的路由地址,用http.route字段,設(shè)置http進(jìn)入的路由地址,可以看到,上面導(dǎo)入到了目標(biāo)規(guī)則為v1和v2的子集。
v1子集對(duì)應(yīng)的是具有如下標(biāo)簽的pod:
selector:
matchLabels:
app: v1
流量控制流程:
Gateway->VirtaulService->TCP/HTTP Router->DestinationWeight->Subset:Port
8、istio核心功能演示
8.1 斷路器
官網(wǎng):
https://istio.io/latest/zh/docs/tasks/traffic-management/circuit-breaking/
斷路器是創(chuàng)建彈性微服務(wù)應(yīng)用程序的重要模式。斷路器使應(yīng)用程序可以適應(yīng)網(wǎng)絡(luò)故障和延遲等網(wǎng)絡(luò)不良影響。
測(cè)試斷路器:
1、在k8s集群創(chuàng)建后端服務(wù)
[root@xianchaomaster1 istio-1.10.1]# cat samples/httpbin/httpbin.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
service: httpbin
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
serviceAccountName: httpbin
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 80
#把httpbin.tar.gz上傳到xianchaonode1節(jié)點(diǎn),手動(dòng)解壓: [root@xianchaonode1 ~]# docker load -i httpbin.tar.gz [root@xianchaomaster1 istio-1.10.1]# kubectl apply -f samples/httpbin/httpbin.yaml #該httpbin應(yīng)用程序充當(dāng)后端服務(wù)。
2、配置斷路器
#創(chuàng)建一個(gè)目標(biāo)規(guī)則,在調(diào)用httpbin服務(wù)時(shí)應(yīng)用斷路器設(shè)置:
[root@xianchaomaster1 istio-1.10.1]# vim destination.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy:
connectionPool:
#連接池(TCP | HTTP)配置,例如:連接數(shù)、并發(fā)請(qǐng)求等
tcp:
maxConnections: 1
#TCP連接池中的最大連接請(qǐng)求數(shù),當(dāng)超過這個(gè)值,會(huì)返回503代碼。如兩個(gè)請(qǐng)求過來,就會(huì)有一個(gè)請(qǐng)求返回503。
http:
http1MaxPendingRequests: 1
#連接到目標(biāo)主機(jī)的最大掛起請(qǐng)求數(shù),也就是待處理請(qǐng)求數(shù)。這里的目標(biāo)指的是 virtualservice 路由規(guī)則中配置的 destination。
maxRequestsPerConnection: 1
#連接池中每個(gè)連接最多處理1個(gè)請(qǐng)求后就關(guān)閉,并根據(jù)需要重新創(chuàng)建連接池中的連接
outlierDetection:
#異常檢測(cè)配置,傳統(tǒng)意義上的熔斷配置,即對(duì)規(guī)定時(shí)間內(nèi)服務(wù)錯(cuò)誤數(shù)的監(jiān)測(cè)
consecutiveGatewayErrors: 1
#連續(xù)錯(cuò)誤數(shù)1,即連續(xù)返回502-504狀態(tài)碼的Http請(qǐng)求錯(cuò)誤數(shù)
interval: 1s
#錯(cuò)誤異常的掃描間隔1s,即在interval(1s)內(nèi)連續(xù)發(fā)生consecutiveGatewayErrors(1)個(gè)錯(cuò)誤,則觸發(fā)服務(wù)熔斷
baseEjectionTime: 3m
#基本驅(qū)逐時(shí)間3分鐘,實(shí)際驅(qū)逐時(shí)間為baseEjectionTime*驅(qū)逐次數(shù)
maxEjectionPercent: 100
#最大驅(qū)逐百分比100%
[root@xianchaomaster1 istio-1.10.1]# kubectl apply -f destination.yaml
destinationrule.networking.istio.io/httpbin created
3、添加客戶端訪問httpbin服務(wù)
創(chuàng)建一個(gè)客戶端以將流量發(fā)送給httpbin服務(wù)。該客戶端是一個(gè)簡(jiǎn)單的負(fù)載測(cè)試客戶端,F(xiàn)ortio可以控制連接數(shù),并發(fā)數(shù)和HTTP調(diào)用延遲。使用此客戶端來“跳閘”在DestinationRule中設(shè)置的斷路器策略。
#通過執(zhí)行下面的命令部署fortio客戶端:
#把fortio.tar.gz上傳到xianchaonode1節(jié)點(diǎn),手動(dòng)解壓:
[root@xianchaonode1 ~]# docker load -i fortio.tar.gz
[root@xianchaomaster1 istio-1.10.1]# kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml
#通過kubectl執(zhí)行下面的命令,使用fortio客戶端工具調(diào)用httpbin:
[root@xianchaomaster1 istio-1.10.1]# kubectl get pods
NAME READY STATUS RESTARTS AGE
appv1-77b5cbd5cc-bmch2 2/2 Running 0 28m
appv2-f78cb577-n7rhc 2/2 Running 0 28m
details-v1-847c7999fb-htd2z 2/2 Running 0 28m
fortio-deploy-576dbdfbc4-z28m7 2/2 Running 0 3m32s
httpbin-74fb669cc6-hqtzl 2/2 Running 0 15m
productpage-v1-5f7cf79d5d-6d4lx 2/2 Running 0 28m
ratings-v1-7c46bc6f4d-sfqnz 2/2 Running 0 28m
reviews-v1-549967c688-pr8gh 2/2 Running 0 28m
reviews-v2-cf9c5bfcd-tn5z5 2/2 Running 0 28m
reviews-v3-556dbb4456-dxt4r 2/2 Running 0 28m
[root@xianchaomaster1 istio-1.10.1]# kubectl exec fortio-deploy-576dbdfbc4-z28m7 -c fortio -- /usr/bin/fortio curl http://httpbin:8000/get
#顯示如下:
HTTP/1.1 200 OK
server: envoy
date: Mon, 03 May 2021 02:28:06 GMT
content-type: application/json
content-length: 622
access-control-allow-origin: *
access-control-allow-credentials: true
x-envoy-upstream-service-time: 2
{
"args": {},
"headers": {
"Content-Length": "0",
"Host": "httpbin:8000",
"User-Agent": "fortio.org/fortio-1.11.3",
"X-B3-Parentspanid": "4631e62a6cd0b167",
"X-B3-Sampled": "1",
"X-B3-Spanid": "6d20afff1671aa89",
"X-B3-Traceid": "6f4ddb61363d04d54631e62a6cd0b167",
"X-Envoy-Attempt-Count": "1",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=498edf0dcb7f6e74f40735869a9912eca62d61fb21dbc190943c1c19dbf01c18;Subject="";URI=spiffe://cluster.local/ns/default/sa/default"
},
"origin": "127.0.0.1",
"url": "http://httpbin:8000/get"
}
4、觸發(fā)斷路器
在DestinationRule設(shè)置中,指定了maxConnections: 1和http1MaxPendingRequests: 1。這些規(guī)則表明,如果超過一個(gè)以上的連接并發(fā)請(qǐng)求,則istio-proxy在為進(jìn)一步的請(qǐng)求和連接打開路由時(shí),應(yīng)該會(huì)看到下面的情況。
以兩個(gè)并發(fā)連接(-c 2)和發(fā)送20個(gè)請(qǐng)求(-n 20)調(diào)用服務(wù):
[root@xianchaomaster1 istio-1.10.1]# kubectl exec -it fortio-deploy-576dbdfbc4-z28m7 -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get #顯示如下: 02:31:00 I logger.go:127> Log level is now 3 Warning (was 2 Info) Fortio 1.11.3 running at 0 queries per second, 6->6 procs, for 20 calls: http://httpbin:8000/get Starting at max qps with 2 thread(s) [gomax 6] for exactly 20 calls (10 per thread + 0) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 02:31:00 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) Ended after 69.506935ms : 20 calls. qps=287.74 Aggregated Function Time : count 20 avg 0.0054352091 +/- 0.01077 min 0.000474314 max 0.04968864 sum 0.108704183 # range, mid point, percentile, count >= 0.000474314 <= 0.001 , 0.000737157 , 35.00, 7 > 0.001 <= 0.002 , 0.0015 , 50.00, 3 > 0.002 <= 0.003 , 0.0025 , 65.00, 3 > 0.004 <= 0.005 , 0.0045 , 75.00, 2 > 0.005 <= 0.006 , 0.0055 , 85.00, 2 > 0.007 <= 0.008 , 0.0075 , 90.00, 1 > 0.016 <= 0.018 , 0.017 , 95.00, 1 > 0.045 <= 0.0496886 , 0.0473443 , 100.00, 1 # target 50% 0.002 # target 75% 0.005 # target 90% 0.008 # target 99% 0.0487509 # target 99.9% 0.0495949 Sockets used: 16 (for perfect keepalive, would be 2) Jitter: false Code 200 : 4 (20.0 %) Code 503 : 16 (80.0 %) #只有20%成功了,其余的都斷開了 Response Header Sizes : count 20 avg 46 +/- 92 min 0 max 230 sum 920 Response Body/Total Sizes : count 20 avg 292.8 +/- 279.6 min 153 max 852 sum 5856 All done 20 calls (plus 0 warmup) 5.435 ms avg, 287.7 qps
8.2 超時(shí)
在生產(chǎn)環(huán)境中經(jīng)常會(huì)碰到由于調(diào)用方等待下游的響應(yīng)過長(zhǎng),堆積大量的請(qǐng)求阻塞了自身服務(wù),造成雪崩的情況,通過通過超時(shí)處理來避免由于無限期等待造成的故障,進(jìn)而增強(qiáng)服務(wù)的可用性,Istio 使用虛擬服務(wù)來優(yōu)雅實(shí)現(xiàn)超時(shí)處理。
下面例子模擬客戶端調(diào)用 nginx,nginx 將請(qǐng)求轉(zhuǎn)發(fā)給 tomcat。nginx 服務(wù)設(shè)置了超時(shí)時(shí)間為2秒,如果超出這個(gè)時(shí)間就不在等待,返回超時(shí)錯(cuò)誤。tomcat服務(wù)設(shè)置了響應(yīng)時(shí)間延遲10秒,任何請(qǐng)求都需要等待10秒后才能返回。client 通過訪問 nginx 服務(wù)去反向代理 tomcat服務(wù),由于 tomcat服務(wù)需要10秒后才能返回,但nginx 服務(wù)只等待2秒,所以客戶端會(huì)提示超時(shí)錯(cuò)誤。
#把busybox.tar.gz、 nginx.tar.gz、 tomcat-app.tar.gz上傳到xianchaonode1節(jié)點(diǎn),手動(dòng)解壓:
[root@xianchaonode1 ~]# docker load -i nginx.tar.gz
[root@xianchaonode1 ~]# docker load -i busybox.tar.gz
[root@xianchaonode1 ~]# docker load -i tomcat-app.tar.gz
[root@xianchaomaster1 ~]# mkdir /root/timeout
[root@xianchaomaster1 ~]# cd /root/timeout/
[root@xianchaomaster1 timeout]# cat nginx-deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
server: nginx
app: web
spec:
replicas: 1
selector:
matchLabels:
server: nginx
app: web
template:
metadata:
name: nginx
labels:
server: nginx
app: web
spec:
containers:
- name: nginx
image: nginx:1.14-alpine
imagePullPolicy: IfNotPresent
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat
labels:
server: tomcat
app: web
spec:
replicas: 1
selector:
matchLabels:
server: tomcat
app: web
template:
metadata:
name: tomcat
labels:
server: tomcat
app: web
spec:
containers:
- name: tomcat
image: docker.io/kubeguide/tomcat-app:v1
imagePullPolicy: IfNotPresent
[root@xianchaomaster1 timeout]# cat nginx-tomcat-svc.yaml
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
server: nginx
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-svc
spec:
selector:
server: tomcat
ports:
- name: http
port: 8080
targetPort: 8080
protocol: TCP
[root@xianchaomaster1 timeout]# cat virtual-tomcat.yaml
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: nginx-vs
spec:
hosts:
- nginx-svc
http:
- route:
- destination:
host: nginx-svc
timeout: 2s
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: tomcat-vs
spec:
hosts:
- tomcat-svc
http:
- fault:
delay:
percentage:
value: 100
fixedDelay: 10s
route:
- destination:
host: tomcat-svc
#virtual-tomcat.yaml資源清單重點(diǎn)知識(shí)講解
第一:故障注入:
http:
- fault:
delay:
percentage:
value: 100
fixedDelay: 10s
該設(shè)置說明每次調(diào)用 tomcat-svc 的 k8s service,都會(huì)延遲10s才會(huì)調(diào)用。
第二:調(diào)用超時(shí):
hosts:
- nginx-svc
http:
- route:
- destination:
host: nginx-svc
timeout: 2s
該設(shè)置說明調(diào)用 nginx-svc 的 k8s service,請(qǐng)求超時(shí)時(shí)間是 2s。
#部署tomcat、nginx服務(wù)
需要對(duì)nginx-deployment.yaml資源文件進(jìn)行 Istio 注入,將 nginx、tomcat 都放入到網(wǎng)格中。可以采用手工注入 Istio 方式。
[root@xianchaomaster1 timeout]# kubectl apply -f nginx-deployment.yaml
執(zhí)行成功后,通過 kubectl get pods 查看 Istio 注入情況:
[root@xianchaomaster1 timeout]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-tomcat-7dd6f74846-48g9f 2/2 Running 0 6m36s
tomcat-86ddb8f5c9-h6jdl 2/2 Running 0 53s
#部署nginx和tomcat的service
[root@xianchaomaster1 timeout]# kubectl apply -f nginx-tomcat-svc.yaml
#部署虛擬服務(wù)
[root@xianchaomaster1 timeout]# kubectl apply -f virtual-tomcat.yaml
#設(shè)置超時(shí)時(shí)間
[root@xianchaomaster1 timeout]# kubectl exec -it nginx-tomcat-7dd6f74846-48g9f -- sh # apt-get update # apt-get install vim -y / # vim /etc/nginx/conf.d/default.conf
proxy_pass http://tomcat-svc:8080; proxy_http_version 1.1; 編輯完后,再執(zhí)行如下語句驗(yàn)證配置和讓配置生效: / # nginx -t / # nginx -s reload 這樣,整個(gè)樣例配置和部署都完成了。 #驗(yàn)證超時(shí) 登錄client,執(zhí)行如下語句: [root@xianchaomaster1 timeout]# kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox -- sh / # time wget -q -O - http://nginx-svc wget: server returned error: HTTP/1.1 408 Request Timeout Command exited with non-zero status 1 real 0m 2.02s user 0m 0.00s sys 0m 0.00s / # while true; do wget -q -O - http://nginx-svc; done wget: server returned error: HTTP/1.1 504 Gateway Timeout wget: server returned error: HTTP/1.1 504 Gateway Timeout wget: server returned error: HTTP/1.1 504 Gateway Timeout wget: server returned error: HTTP/1.1 504 Gateway Timeout wget: server returned error: HTTP/1.1 408 Request Timeout 每隔2秒,由于 nginx 服務(wù)的超時(shí)時(shí)間到了而 tomcat未有響應(yīng),則提示返回超時(shí)錯(cuò)誤。 驗(yàn)證故障注入效果,執(zhí)行如下語句: / # time wget -q -O - http://tomcat-svc wget: server returned error: HTTP/1.1 503 Service Unavailable Command exited with non-zero status 1 real 0m 10.02s user 0m 0.00s sys 0m 0.01s 執(zhí)行之后10s才會(huì)有結(jié)果
8.3 故障注入和重試
Istio 重試機(jī)制就是如果調(diào)用服務(wù)失敗,Envoy 代理嘗試連接服務(wù)的最大次數(shù)。而默認(rèn)情況下,Envoy 代理在失敗后并不會(huì)嘗試重新連接服務(wù),除非我們啟動(dòng) Istio 重試機(jī)制。
下面例子模擬客戶端調(diào)用 nginx,nginx 將請(qǐng)求轉(zhuǎn)發(fā)給 tomcat。tomcat 通過故障注入而中止對(duì)外服務(wù),nginx 設(shè)置如果訪問 tomcat 失敗則會(huì)重試 3 次。
[root@xianchaomaster1 attemp]# cd /root/timeout/
[root@xianchaomaster1 timeout]# kubectl delete -f .
[root@xianchaomaster1 timeout]# kubectl apply -f nginx-deployment.yaml
[root@xianchaomaster1 timeout]# kubectl apply -f nginx-tomcat-svc.yaml
[root@xianchaomaster1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
busybox 2/2 Running 0 55m
nginx-7f6496574c-zbtqj 2/2 Running 0 10m
tomcat-86ddb8f5c9-dqxcq 2/2 Running 0 35m
[root@xianchaomaster1 timeout]# cat virtual-attempt.yaml
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: nginx-vs
spec:
hosts:
- nginx-svc
http:
- route:
- destination:
host: nginx-svc
retries:
attempts: 3
perTryTimeout: 2s
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: tomcat-vs
spec:
hosts:
- tomcat-svc
http:
- fault:
abort:
percentage:
value: 100
httpStatus: 503
route:
- destination:
host: tomcat-svc
[root@xianchaomaster1 timeout]# kubectl apply -f virtual-attempt.yaml
虛擬服務(wù)資源清單解讀:
第一:故障注入。該虛擬服務(wù)的作用對(duì)象就是 tomcat-svc。使用此故障注入后,在網(wǎng)格中該 tomcat 就是不可用的。
abort:
percentage:
value: 100
httpStatus: 503
abort是模擬tomcat服務(wù)始終不可用,該設(shè)置說明每次調(diào)用 tomcat-svc 的 k8s service,100%都會(huì)返回錯(cuò)誤狀態(tài)碼503。
第二:調(diào)用超時(shí):
hosts:
- nginx-svc
http:
- route:
- destination:
host: nginx-svc
reties:
attempts: 3
perTryTimeout: 2s
該設(shè)置說明調(diào)用 nginx-svc 的 k8s service,在初始調(diào)用失敗后最多重試 3 次來連接到服務(wù)子集,每個(gè)重試都有 2 秒的超時(shí)。
[root@xianchaomaster1 timeout]# kubectl exec -it nginx-tomcat-7dd6f74846-rdqqf -- /bin/sh
# apt-get update
# apt-get install vim -y
/ # vi /etc/nginx/conf.d/default.conf
/ # nginx -t / # nginx -s reload #驗(yàn)證重試是否生效 [root@xianchaomaster1 timeout]# kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox -- sh / # wget -q -O - http://nginx-svc [root@xianchaomaster1 timeout]# kubectl logs -f nginx-tomcat-7dd6f74846-rdqqf -c istio-proxy #執(zhí)行結(jié)果如下:
由上圖可知,重試設(shè)置生效。
9、分布式追蹤系統(tǒng)-jaeger
1.什么是分布式追蹤?
分布式追蹤最早由谷歌的Dapper普及開來,它本質(zhì)上是具有在微服務(wù)的整個(gè)生命周期中追蹤請(qǐng)求的能力。分布式追蹤(Distributed Tracing)主要用于記錄整個(gè)請(qǐng)求鏈的信息。
2.為什么要分布式追蹤?
當(dāng)業(yè)務(wù)微服務(wù)化后,一次業(yè)務(wù)請(qǐng)求,可能會(huì)涉及到多個(gè)微服務(wù),分布式跟蹤可以對(duì)跨多個(gè)分布式服務(wù)網(wǎng)格的1個(gè)請(qǐng)求進(jìn)行追蹤分析,并通過可視化的方式深入地了解請(qǐng)求的延遲,序列化和并發(fā),充分地了解服務(wù)流量實(shí)況,從而快速地排查和定位問題。在微服務(wù)應(yīng)用中,一個(gè)完整的業(yè)務(wù)往往需要調(diào)用多個(gè)服務(wù)才能完成,服務(wù)之間就產(chǎn)生了交互。當(dāng)出現(xiàn)故障時(shí),如何找到問題的根源非常重要。追蹤系統(tǒng)可以清晰地展示出請(qǐng)求的整個(gè)調(diào)用鏈以及每一步的耗時(shí),方便查找問題所在。
3.分布式追蹤系統(tǒng)-jaeger
Jaeger是一個(gè)開源的分布式追蹤系統(tǒng),它可以在復(fù)雜的分布式系統(tǒng)中進(jìn)行監(jiān)控和故障排查。Jaeger的主要功能包括分布式請(qǐng)求監(jiān)控、性能調(diào)優(yōu)、故障分析和服務(wù)依賴分析等。
Jaeger組件介紹:
jaeger-agent:
負(fù)責(zé)發(fā)送的進(jìn)程,對(duì)spans進(jìn)行處理并發(fā)送給collector,監(jiān)聽spans的UDP 發(fā)送。這層作為基礎(chǔ)組件部署在主機(jī)上,Agent將Client Library和Collector解耦,為ClientLibrary屏蔽了路由和發(fā)現(xiàn)Collector的細(xì)節(jié)。
jaeger-collector:
收集追蹤 spans,并通過管道對(duì)追蹤數(shù)據(jù)進(jìn)行處理。當(dāng)前的管道支持追蹤的驗(yàn)證、索引、轉(zhuǎn)換,最后存儲(chǔ)數(shù)據(jù)
jaeger-query:
從存儲(chǔ)中檢索追蹤信息并通過 UI 展示
data store:
追蹤信息的存儲(chǔ)
4.使用jaeger
kubectl get svc -n istio-system | grep jaeger 顯示如下: jaeger-agent ClusterIP None <none> 5775/UDP,6831/UDP,6832/UDP 55d jaeger-collector ClusterIP 10.99.194.57 <none> 14267/TCP,14268/TCP,14250/TCP 55d jaeger-collector-headless ClusterIP None <none> 14250/TCP 55d jaeger-query ClusterIP 10.107.192.115 <none> 16686/TCP 修改jaeger-query的type類型為nodePort kubectl edit svc jaeger-query -n istio-system 把type: ClusterIP變成type: NodePort kubectl get svc -n istio-system | grep jaeger-query 顯示如下: jaeger-query NodePort 10.107.192.115 <none> 16686:31450/TCP 在瀏覽器訪問: 192.168.40.180:31450 5.查看追蹤數(shù)據(jù) 在Jaeger左側(cè)版面的Service下拉列表中選擇v1.default,單擊Find Traces按鈕,會(huì)看到如下圖
單擊右側(cè)的URL進(jìn)入詳細(xì)頁,可以看到具體的服務(wù)調(diào)用情況,并且能夠了解每個(gè)服務(wù)的耗時(shí)
6. 追蹤上下文傳遞
Istio 利用 Envoy 的分布式追蹤功能提供了開箱即用的追蹤集成。確切地說,Istio 提供了安裝各種追蹤后端服務(wù)的選項(xiàng),并且通過配置代理來自動(dòng)發(fā)送追蹤 span 到追蹤后端服務(wù)。盡管 Istio 代理能夠自動(dòng)發(fā)送 span,但是他們需要一些附加線索才能將整個(gè)追蹤鏈路關(guān)聯(lián)到一起。所以當(dāng)代理發(fā)送 span 信息的時(shí)候,應(yīng)用需要附加適當(dāng)?shù)?HTTP 請(qǐng)求頭信息,這樣才能夠把多個(gè) span 正確的關(guān)聯(lián)到同一個(gè)追蹤上。
要做到這一點(diǎn),應(yīng)用程序從傳入請(qǐng)求到任何傳出的請(qǐng)求中需要包含以下請(qǐng)求頭參數(shù):
x-request-id
x-b3-traceid
x-b3-spanid
x-b3-parentspanid
x-b3-sampled
x-b3-flags
x-ot-span-context
10、分布式追蹤系統(tǒng)-kiali
Kiali是Istio服務(wù)網(wǎng)格的可視化工具,它主要的功能是用可視化的界面來觀察微服務(wù)系統(tǒng)以及服務(wù)之間的關(guān)系。Kiali功能如下。
1)服務(wù)拓?fù)鋱D:這是Kiali最主要的功能,提供了一個(gè)總的服務(wù)視圖,可以實(shí)時(shí)地顯示命名空間下服務(wù)之間的調(diào)用和層級(jí)關(guān)系,以及負(fù)載情況。·
2)服務(wù)列表視圖:展示了系統(tǒng)中所有的服務(wù),以及它們的健康狀況和出錯(cuò)率?!?工作負(fù)載視圖:展示服務(wù)的負(fù)載情況。
3)Istio配置視圖:展示了所有的Istio配置對(duì)象。
Kiali的架構(gòu)比較簡(jiǎn)單,如下圖,它分為前端和后端兩部分。后端以容器的方式運(yùn)行在應(yīng)用平臺(tái),負(fù)責(zé)獲取和處理數(shù)據(jù),并發(fā)送給前端;前端是一個(gè)典型的Web應(yīng)用,由React和TypeScript實(shí)現(xiàn),負(fù)責(zé)展示后端發(fā)送過來的數(shù)據(jù)。對(duì)Kiali來說Istio是必須存在的系統(tǒng),它類似于Kiali的宿主。雖然它們可以分開部署,但沒有了Istio,Kiali是不能工作的。
2.使用: kubectl get svc -n istio-system | grep kiali 顯示如下: kiali ClusterIP 10.106.61.5 <none> 20001/TCP 修改kiali的type類型為nodePort kubectl edit svc kiali -n istio-system 把type: ClusterIP變成type: NodePort kubectl get svc -n istio-system | grep kiali 顯示如下: kiali NodePort 10.106.61.5 <none> 20001:32514/TCP 在瀏覽器訪問192.168.40.180:32514
Username:admin
Password: admin
輸入用戶名和密碼之后出現(xiàn)如下界面:
Kiali是一個(gè)非常強(qiáng)大的可視化工具,可以讓用戶清晰和直觀地了解到Istio服務(wù)網(wǎng)格中的服務(wù)以及服務(wù)之間的關(guān)系。除了服務(wù)拓?fù)鋱D外,它還提供了健康檢查、指標(biāo)數(shù)據(jù)顯示和配置驗(yàn)證等功能。強(qiáng)烈推薦把Kiali作為必選項(xiàng)添加到服務(wù)網(wǎng)格中,來幫助監(jiān)控和觀測(cè)網(wǎng)格中服務(wù)的工作情況。
總結(jié)
- 上一篇: 采用数字签名的机制 USBKey与服务器
- 下一篇: js回车键事件