當配置一個生產級別的Istio時,須要解決一些問題:如網格是單集羣使用,仍是跨集羣使用?全部的服務會放到一個徹底可達的網絡中,仍是須要網關來鏈接跨網絡的服務?使用一個控制面(可能會跨集羣共享一個控制面),仍是使用多個控制面來實現高可用(HA)?全部的集羣都鏈接到一個多集羣服務網格,仍是聯合成一個多網格形態。git
全部這些問題,以及他外因素,都表明了Istio部署的各個配置維度。github
上述條件能夠任意組合(雖然有些組合相比其餘更加廣泛,有些則不那麼受歡迎,如單集羣中的多網格場景)。shell
在一個涉及多集羣的生產環境中,能夠混合使用部署模型。例如,可使用多個控制面來作到HA。在一個3集羣環境中,能夠將兩個集羣共享一個控制面,而後給第三個集羣在不一樣的網絡中添加另一個控制面。而後配置三個集羣共享各自的控制面,這樣全部的集羣就可使用2個控制面來作到HA。json
實際使用中,須要根據隔離性,性能,以及HA要求來選擇合適的部署模型。本章將描述部署Istio時的各類選擇和考量。緩存
該模式下,應用的負載會運行在多個集羣中。爲了隔離,性能或高可用,能夠限定集羣的可用zone和region。安全
取決於具體要求,生產系統能夠跨多個zone或region的多個集羣運行,利用雲負載均衡器來處理諸如本地性,zonal 或regional故障轉移之類的事情。網絡
大多數場景下,集羣表示配置和終端發現的邊界。例如,每一個kubernetes集羣都有一個API Server來管理集羣的配置,以及提供服務終端的信息,如pod的啓停等。因爲kubernetes的這種配置行爲是基於單個集羣的,所以會將潛在的錯誤(如配置錯誤)限制在其所在的集羣中。app
使用Istio能夠在任意個集羣上配置一個服務網格。負載均衡
在最簡單的場景中,能夠在單個集羣中部署單Istio網格。一個集羣一般會運行在一個獨立的網絡中,但具體取決於基礎設施提供商。包含一個網絡的單集羣模型會包含一個控制面,這就是istio最簡單的部署模型:dom
單集羣的部署比較簡單,但同時也缺乏一些特性,如故障隔離和轉移。若是須要高可用,則應該使用多集羣模式。
一個網格能夠包含多個集羣。使用多集羣部署能夠在一個網格中提供以下功能。
cluster-1
宕機後,使用cluster-2
多集羣部署提供了更大的隔離性和可靠性,但同時也增長了複雜性。若是系統須要高可用,則集羣可能會跨多個zone和region。
能夠經過金絲雀配置來在單個集羣中修改或使用新的二進制版本,這樣配置變動僅會影響一小部分的用戶流量。若是一個集羣出現問題,能夠臨時把流量路由到臨近的集羣(直到問題解決)。
此外,能夠根據網絡和雲提供商支持的選項配置集羣間的通訊。例如,若是兩個集羣使用了相同的底層網絡,那麼就能夠經過簡單的防火牆規則實現集羣間的通訊。
不少生產系統須要多個網絡或子網來實現隔離和高可用。Istio支持將一個服務網格部署到多種類型的網絡拓撲中。經過這種方式選擇符合現有網絡拓撲的網絡模型。
在最簡單場景下,服務網格會運行在一個徹底鏈接的網絡上,在單網絡模型下,全部的負載示例可以在沒有Istio網格的狀況下實現互聯。
單個網絡使Istio可以在網格中以統一的方式配置服務使用者,並具備直接處理工做負載實例的能力。
多網絡提供了以下新功能:
這種模式下,不一樣網絡中的負載實例只能經過一個或多個Istio網關進行互聯。Istio使用分區服務發現來爲使用者提供service endpoints的不一樣視圖。視圖取決於使用者的網絡。
Istio網格使用控制面來配置網格內負載實例之間的通訊。經過複製控制面,工做負載能夠鏈接到任何控制面來獲取配置。
最簡單的場景下,可在單集羣中運行網格的控制面:
像這樣具備本身的本地控制平面的集羣被稱爲主集羣。
多集羣部署能夠共享相同的控制面實例。這種狀況下,控制面實例能夠位於一個或多個主集羣中。沒有本身的控制面的集羣稱爲遠端集羣。
一個徹底由遠程集羣組成的服務網格能夠經過外部控制面進行控制,而不須要經過運行在主集羣中的控制面進行控制。經過這種方式將istio在管理上進行了隔離,即將控制面和數據面服務進行了徹底分割。
雲提供商的
Managed Control Plane
實際上就是一個外部控制面。
爲了高可用,控制面可能須要跨多集羣,zone和region來部署。下圖中的服務網格在每一個region中都使用了一個控制面。
使用上述模型具備以下優點:
能夠經過故障轉移來提高控制面的可靠性。當一個控制面實例變爲不可用時,負載實例能夠鏈接到其餘可用的控制面實例上。集羣,zone和region中均可能發生故障遷移。下圖能夠看到,當左側的控制面出問題後,由右側的控制面託管了Envoy代理(虛線)。
如下列表按可用性對控制平面的部署進行了排序:
當在一個服務網格中建立負載實例時,istio會賦予該負載一個身份。
CA( certificate authority)會爲網格中使用的身份建立和頒發證書,後續就可使用CA爲該身份建立和頒發證書時使用的公鑰對消息發送端進行校驗。trust bundle是Istio網格使用的全部CA公鑰的集合。任何人均可以使用網格的trust bundle校驗來自網格的服務。
在單istio網格中,istio保證每一個負載實例都有一個標識其身份的證書,使用trust bundle來識別網格和聯邦網格中的全部身份。CA僅負責爲這些身份建立和簽發證書。該模型容許網格中的負載實例互聯。下圖展現了一個具備 certificate authority的服務網格。
若是一個網格中的服務須要調用另一個網格中的服務,此時須要在兩個網格之間使用聯邦身份。爲了實現聯邦身份的信任,須要交換網格的trust buncles(能夠經過手動或自動方式,如SPIFFE Trust Domain Federation來交換trust bundles)
Istio支持在一個網格或聯邦網格(也被稱爲多網格)中部署全部的應用。
單網格是部署Istio的最簡單的方式。在一個網格中,服務名是惟一的。例如,一個foo
命名空間中,只能存在一個名爲mysvc
的服務。此外,負載實例共享同一個身份service account,由於該資源在命名空間內是惟一的。
單網格能夠部署在一個或多個集羣中,以及一個或多個網絡上。在一個網格中,命名空間用於tenancy(見下)。
多網格是網格聯邦的結果。
多網格提供了以下功能:
default
命名空間能夠用於多種用途可使用中間網格來鏈接網格聯邦。當使用聯邦時,每一個網格均可以暴露一組全部參與的網格都能識別的服務和身份。
爲了不服務名衝突,能夠給每一個網格分配一個全局惟一的網格ID,來保證每一個服務的fully qualified domain name (FQDN)是有效的。
當聯邦中兩個網格沒有使用相同的信任域時,必須對這兩個網格的身份和trust bundles進行聯邦。查看Multiple Trust Domains。
在Istio中,租戶是一個共享用戶組,共享一組已部署的工做負載的訪問權限和特權。一般須要從網絡配置和策略層面來爲不一樣的租戶隔離負載實例。
能夠配置租戶模式來知足組織的隔離需求:
Istio支持兩種類型的租戶:
在一個網格中,Istio使用命名空間做爲租戶的單位。Istio也能夠運行在沒有實現命名空間租戶的環境中。在實現命名空間租戶的環境中,能夠保證僅容許一個團隊將負載部署在一個給定的命名空間或一組命名空間中。默認狀況下,多個租戶命名空間中的服務均可以互聯。
爲了提高隔離性,能夠選擇暴露到其餘命名空間中的服務。經過受權策略來暴露服務或限制訪問。
當使用多集羣時,每一個集羣中的相同名稱的命名空間被看做是相同的命名空間。例如,cluster-1
中的foo
命名空間中的Service B
,以及cluster-2
中的foo
命名空間中的Service B
被認爲是相同的服務,且Istio會在服務發現時合併endpoints,並在這些endpoints間執行負載均衡。下圖展現了具備相同命名空間的兩個集羣
Istio支持以集羣做爲租戶的單位。這種狀況下,能夠給每一個團隊指定特定的集羣或一組集羣來部署負載,並受權團隊成員。能夠給成員分配不一樣的角色,如:
爲了在Istio中使用集羣租戶,須要將每一個集羣做爲獨立的網格。此外,可使用Istio將一組集羣做爲單租戶。這樣每一個團隊就能夠擁有一個或多個集羣,而不是將全部的集羣配置爲單網格。爲了鏈接不一樣團隊的網格,能夠將這些將這些網格聯邦爲多網格。下圖展現了使用兩個集羣和命名空間來隔離服務網格。
因爲網格由不一樣的團隊或組織進行操做,所以服務命名不多會不一樣。例如,cluster-1
的foo
命名空間中的mysvc
和cluster-2
的foo
命名空間中的mysvc
服務並非相同的服務。最多見的示例是Kubernetes中的場景,許多團隊將工做負載部署到default
命名空間。
當每一個團隊都有各自的網格後,就可使用多網格模型跨網格進行通訊。
Istio使用豐富的路由,負載均衡,服務到服務的認證,監控等簡化了部署服務的網絡,且不須要修改應用代碼。Istio力爭使用最少的資源開銷來提供這些便利,以及在增長最小的延遲下支撐更大規模的網格和更高的請求率。
Istio數據面組件,Envoy代理會處理流經系統的數據。Istio的控制面組件,Pilot,Galley和Citadel來配置數據面。數據面和控制面都有明顯的性能問題。
Istio負載測試網格包含1000個服務和2000個sidecar,每秒70000個網格範圍的請求。在對Istio1.7測試以後,得出以下結果:
istio-telemetry
服務會使用0.6 vCPUPilot會根據用戶的配置文件和系統的當前狀態配置sidecar代理。在Kubernetes環境中,CRD和deployment構成了配置和系統狀態。Istio配置對象,如gateway和virtual service等提供了用戶可編輯的配置。爲了生成代理的配置,Pilot處理來自Kubernetes環境和用戶配置的組合配置以及系統狀態。
控制平面支持成千上萬的服務,這些服務分佈在成千上萬個Pod中,並使用相似數量的由用戶編寫的virtual services和其餘配置對象。Pilot的CPU和內存會隨着配置數據的變化和系統狀態而變化。CPU的使用包含以下因素:
但這部分是支持水平擴展的。
當啓用命名空間租戶時,使用1vCPU和1.5GB內存的單個Pilot能夠支持1000個服務,2000個sidecar。能夠經過增長Pilot的數量來下降配置全部代理的時間。
數據面性能依賴不少因素,如:
延遲,吞吐量以及代理的CPU和內存消耗均根據上述因素進行衡量。
因爲sidecar代理會在數據路徑上作一些額外的工做,所以會消耗CPU和內存。如Istio 1.1中,在每秒1000個請求的狀況下,一個代理會消耗0.6 vCPU。
代理的內存消耗取決於代理保存的總配置狀態。大量listeners,clusters和routes可能會增長內存消耗。Istio 1.1引入了命名空間隔離來限制發送到一個代理的配置。在一個大的命名空間中,一個代理大概會消耗50 MB的內存。
因爲代理一般不會緩存經過的數據,所以請求率不會影響內存消耗。
命名空間的隔離是經過sidecar資源實現的。如何使用能夠參見istio-namespace-isolation-tricks。
因爲Istio在數據路徑上注入了sidecar代理,所以延遲是一個須要重點考慮的因素。Istio會將身份驗證和Mixer過濾器添加到代理,每一個額外的過濾器都會增長代理內部的路徑長度,並影響到延遲。
Envoy代理會收在客戶端接收到響應以後採集原始的遙測數據。對採集請求的遙測數據的時間不會計算在總的完成請求所須要的時間內。但因爲worker忙於處理請求,所以worker可能不會當即處理下一個請求。這種處理會增長請求在隊列中等待的時間,並影響到平均值和尾部延遲。實際的尾部延遲取決於流量情況。
在網格中,請求會經過客戶端的代理,而後到達服務端。1.7的默認配置中(即,telemetry V2),這兩個代理在基準數據平面延遲的90百分位和99百分位延遲上分別增長了大約3.12ms 和3.13ms。經過Istio benchmarks的http/1.1
協議得出如上結論,使用兩個代理worker,並啓用mutual TLS,經過16個客戶端鏈接來發送每秒1000個請求,每一個請求1KB。
在即將發佈的Istio版本中,將把Istio策略和Istio遙測功能做爲TelemetryV2添加到代理中。經過這種方式來減小流經系統的數據量,從而減小CPU使用量和延遲。
P90 latency vs client connections without jitter
P99 latency vs client connections without jitter
P90 latency vs client connections with jitter
P99 latency vs client connections with jitter
baseline
客戶端Pod直接調用服務端Pod,不通過sidecarnone_both
使用Istio代理,但不配置Istio過濾器v2-stats-wasm_both
客戶端和服務端的sidecar都配置彷佛用telemetry v2 v8
v2-stats-nullvm_both
客戶端和服務端的sidecar默認都配置彷佛用telemetry v2 nullvm
v2-sd-full-nullvm_both
使用配置的 telemetry v2 nullvm
暴露Stackdriver metrics,訪問日誌v2-sd-nologging-nullvm_both
與上面系統,但不暴露訪問日誌Istio使用以下工具來進行benchmarking:
fortio.org
- 恆定吞吐量的負載測試工具blueperf
- 真實的雲原生應用程序isotope
- 具備可配置拓撲的合成應用程序做爲網格的一部分,kubernetes的pod和service必須知足以下要求:
NET_ADMIN
和NET_RAW
capabilities:若是集羣強制使用pod安全策略,則必須給pod添加 NET_ADMIN
和NET_RAW
capabilities。若是使用了Istio CNI 插件,則能夠不遵照該要求。app
和version
labels。app
和version
labels會給istio採集的metrics和遙測數據添加上下文信息
app
label:每一個deployment應該包含不一樣的app
label。app
label用於在分佈式跟蹤中添加上下文信息。version
label:指定特定deployment對應的應用版本。若是集羣使用了pod安全策略,除非使用了Istio CNI插件,不然pod必須容許NET_ADMIN
和NET_RAW
capabilities。Envoy代理的initialization容器會使用這些capabilities。
爲了校驗pod是否容許NET_ADMIN
和NET_RAW
capabilities,須要校驗pod對應的service account是否可使用pod安全策略來容許NET_ADMIN
和NET_RAW
capabilities。若是沒有在pod的deployment中指定service account,那麼pod會使用其所在命名空間的default
service account。
使用以下命令能夠列出一個service accout的capabilities,替換<your namespace>
和<your service account>
# for psp in $(kubectl get psp -o jsonpath="{range .items[*]}{@.metadata.name}{'\n'}{end}"); do if [ $(kubectl auth can-i use psp/$psp --as=system:serviceaccount:<your namespace>:<your service account>) = yes ]; then kubectl get psp/$psp --no-headers -o=custom-columns=NAME:.metadata.name,CAPS:.spec.allowedCapabilities; fi; done
例如可使用以下命令來校驗default
命名空間中的default
service account。
# for psp in $(kubectl get psp -o jsonpath="{range .items[*]}{@.metadata.name}{'\n'}{end}"); do if [ $(kubectl auth can-i use psp/$psp --as=system:serviceaccount:default:default) = yes ]; then kubectl get psp/$psp --no-headers -o=custom-columns=NAME:.metadata.name,CAPS:.spec.allowedCapabilities; fi; done
若是在capabilities列表中看到 NET_ADMIN
和 NET_ADMIN
或*
,則說明該pod容許運行Isti init容器,不然須要配置權限。