istio部署

Istio的部署介紹

部署模型

當配置一個生產級別的Istio時,須要解決一些問題:如網格是單集羣使用,仍是跨集羣使用?全部的服務會放到一個徹底可達的網絡中,仍是須要網關來鏈接跨網絡的服務?使用一個控制面(可能會跨集羣共享一個控制面),仍是使用多個控制面來實現高可用(HA)?全部的集羣都鏈接到一個多集羣服務網格,仍是聯合成一個多網格形態。git

全部這些問題,以及他外因素,都表明了Istio部署的各個配置維度。github

  1. 單集羣或多集羣
  2. 單網絡或多網絡
  3. 單控制面或多控制面
  4. 單網格或多網格

上述條件能夠任意組合(雖然有些組合相比其餘更加廣泛,有些則不那麼受歡迎,如單集羣中的多網格場景)。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可以在網格中以統一的方式配置服務使用者,並具備直接處理工做負載實例的能力。

多網絡

多網絡提供了以下新功能:

  • service endpoints提供了可交叉的IP或VIP
  • 跨邊界
  • 容錯功能
  • 擴展網絡地址
  • 符合網絡分段的標準

這種模式下,不一樣網絡中的負載實例只能經過一個或多個Istio網關進行互聯。Istio使用分區服務發現來爲使用者提供service endpoints的不一樣視圖。視圖取決於使用者的網絡。

控制面模型

Istio網格使用控制面來配置網格內負載實例之間的通訊。經過複製控制面,工做負載能夠鏈接到任何控制面來獲取配置。

最簡單的場景下,可在單集羣中運行網格的控制面:

像這樣具備本身的本地控制平面的集羣被稱爲主集羣。

多集羣部署能夠共享相同的控制面實例。這種狀況下,控制面實例能夠位於一個或多個主集羣中。沒有本身的控制面的集羣稱爲遠端集羣。

一個徹底由遠程集羣組成的服務網格能夠經過外部控制面進行控制,而不須要經過運行在主集羣中的控制面進行控制。經過這種方式將istio在管理上進行了隔離,即將控制面和數據面服務進行了徹底分割。

雲提供商的Managed Control Plane實際上就是一個外部控制面。

爲了高可用,控制面可能須要跨多集羣,zone和region來部署。下圖中的服務網格在每一個region中都使用了一個控制面。

使用上述模型具備以下優點:

  • 提高可用性:若是一個控制面不可用,停機的範圍將僅限於該控制平面
  • 配置隔離:能夠修改一個集羣,zone或region中的配置,而不會影響另一個控制面的配置。

能夠經過故障轉移來提高控制面的可靠性。當一個控制面實例變爲不可用時,負載實例能夠鏈接到其餘可用的控制面實例上。集羣,zone和region中均可能發生故障遷移。下圖能夠看到,當左側的控制面出問題後,由右側的控制面託管了Envoy代理(虛線)。

如下列表按可用性對控制平面的部署進行了排序:

  • 每一個region一個集羣(低可用性)
  • 每一個region多集羣
  • 一個zone一個集羣
  • 一個zone多個集羣
  • 每一個集羣一個控制面(高可用性)

身份和信任模型

當在一個服務網格中建立負載實例時,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支持兩種類型的租戶:

Namespace tenancy

在一個網格中,Istio使用命名空間做爲租戶的單位。Istio也能夠運行在沒有實現命名空間租戶的環境中。在實現命名空間租戶的環境中,能夠保證僅容許一個團隊將負載部署在一個給定的命名空間或一組命名空間中。默認狀況下,多個租戶命名空間中的服務均可以互聯。

爲了提高隔離性,能夠選擇暴露到其餘命名空間中的服務。經過受權策略來暴露服務或限制訪問。

當使用多集羣時,每一個集羣中的相同名稱的命名空間被看做是相同的命名空間。例如,cluster-1中的foo命名空間中的Service B,以及cluster-2中的foo命名空間中的Service B被認爲是相同的服務,且Istio會在服務發現時合併endpoints,並在這些endpoints間執行負載均衡。下圖展現了具備相同命名空間的兩個集羣

Cluster tenancy

Istio支持以集羣做爲租戶的單位。這種狀況下,能夠給每一個團隊指定特定的集羣或一組集羣來部署負載,並受權團隊成員。能夠給成員分配不一樣的角色,如:

  • 集羣管理員
  • 開發人員

爲了在Istio中使用集羣租戶,須要將每一個集羣做爲獨立的網格。此外,可使用Istio將一組集羣做爲單租戶。這樣每一個團隊就能夠擁有一個或多個集羣,而不是將全部的集羣配置爲單網格。爲了鏈接不一樣團隊的網格,能夠將這些將這些網格聯邦爲多網格。下圖展現了使用兩個集羣和命名空間來隔離服務網格。

因爲網格由不一樣的團隊或組織進行操做,所以服務命名不多會不一樣。例如,cluster-1foo命名空間中的mysvccluster-2foo命名空間中的mysvc服務並非相同的服務。最多見的示例是Kubernetes中的場景,許多團隊將工做負載部署到default命名空間。

當每一個團隊都有各自的網格後,就可使用多網格模型跨網格進行通訊。

性能和可靠性

Istio使用豐富的路由,負載均衡,服務到服務的認證,監控等簡化了部署服務的網絡,且不須要修改應用代碼。Istio力爭使用最少的資源開銷來提供這些便利,以及在增長最小的延遲下支撐更大規模的網格和更高的請求率。

Istio數據面組件,Envoy代理會處理流經系統的數據。Istio的控制面組件,Pilot,Galley和Citadel來配置數據面。數據面和控制面都有明顯的性能問題。

1.7的性能摘要

Istio負載測試網格包含1000個服務和2000個sidecar,每秒70000個網格範圍的請求。在對Istio1.7測試以後,得出以下結果:

  • 在每秒有1000個請求通過代理時,Envoy代理會使用0.5 vCPU50 MB內存
  • 若是部署時使用了Mixer,在每秒有1000個網格範圍的請求時,istio-telemetry服務會使用0.6 vCPU
  • Pilot使用1 vCPU 和1.5 GB內存
  • Envoy代理對90%的延遲增長了3.12毫秒。

控制面性能

Pilot會根據用戶的配置文件和系統的當前狀態配置sidecar代理。在Kubernetes環境中,CRD和deployment構成了配置和系統狀態。Istio配置對象,如gateway和virtual service等提供了用戶可編輯的配置。爲了生成代理的配置,Pilot處理來自Kubernetes環境和用戶配置的組合配置以及系統狀態。

控制平面支持成千上萬的服務,這些服務分佈在成千上萬個Pod中,並使用相似數量的由用戶編寫的virtual services和其餘配置對象。Pilot的CPU和內存會隨着配置數據的變化和系統狀態而變化。CPU的使用包含以下因素:

  • deployment變化率
  • 配置變化率
  • 鏈接到Pilot的代理數目

但這部分是支持水平擴展的。

當啓用命名空間租戶時,使用1vCPU和1.5GB內存的單個Pilot能夠支持1000個服務,2000個sidecar。能夠經過增長Pilot的數量來下降配置全部代理的時間。

數據面性能

數據面性能依賴不少因素,如:

  • 客戶端鏈接數
  • 目標請求率
  • 請求大小和響應大小
  • 代理worker的線程數
  • 協議
  • CPU cores
  • 代理過濾器的數目和類型,特別是Mixer的過濾器

延遲,吞吐量以及代理的CPU和內存消耗均根據上述因素進行衡量。

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可能不會當即處理下一個請求。這種處理會增長請求在隊列中等待的時間,並影響到平均值和尾部延遲。實際的尾部延遲取決於流量情況。

Istio 1.7的延遲

在網格中,請求會經過客戶端的代理,而後到達服務端。1.7的默認配置中(即,telemetry V2),這兩個代理在基準數據平面延遲的90百分位和99百分位延遲上分別增長了大約3.12ms 和3.13ms。經過Istio benchmarkshttp/1.1協議得出如上結論,使用兩個代理worker,並啓用mutual TLS,經過16個客戶端鏈接來發送每秒1000個請求,每一個請求1KB。

在即將發佈的Istio版本中,將把Istio策略和Istio遙測功能做爲TelemetryV2添加到代理中。經過這種方式來減小流經系統的數據量,從而減小CPU使用量和延遲。

P90 latency vs client connections without jitter

image-20200905201003085

P99 latency vs client connections without jitter

P90 latency vs client connections with jitter

P99 latency vs client connections with jitter

  • baseline 客戶端Pod直接調用服務端Pod,不通過sidecar
  • none_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 與上面系統,但不暴露訪問日誌

Benchmarking 工具

Istio使用以下工具來進行benchmarking:

  • fortio.org - 恆定吞吐量的負載測試工具
  • blueperf - 真實的雲原生應用程序
  • isotope - 具備可配置拓撲的合成應用程序

Pods 和Services

做爲網格的一部分,kubernetes的pod和service必須知足以下要求:

  • 關聯的Service:一個pod必須對應至少一個kubernetes service,即便pod沒有暴露任何端口。若是一個pod對應多個kubernetes services,那麼這些services沒法爲不一樣的協議使用相同的端口號,如HTTP和TCP。
  • 應用的UID:確保pods不能以用戶ID (UID)值爲1337的身份運行應用程序
  • NET_ADMINNET_RAW capabilities:若是集羣強制使用pod安全策略,則必須給pod添加 NET_ADMINNET_RAW capabilities。若是使用了Istio CNI 插件,則能夠不遵照該要求。
  • Deployments 使用 appversion labels:建議Deployments 使用appversion labels。appversion labels會給istio採集的metrics和遙測數據添加上下文信息
    • app label:每一個deployment應該包含不一樣的app label。app label用於在分佈式跟蹤中添加上下文信息。
    • version label:指定特定deployment對應的應用版本。
  • 命名service端口:能夠選擇使用命名服務端口來指定協議。更多細節參見Protocol Selection

要求的pod capabilities

若是集羣使用了pod安全策略,除非使用了Istio CNI插件,不然pod必須容許NET_ADMINNET_RAW capabilities。Envoy代理的initialization容器會使用這些capabilities。

爲了校驗pod是否容許NET_ADMINNET_RAW capabilities,須要校驗pod對應的service account是否可使用pod安全策略來容許NET_ADMINNET_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_ADMINNET_ADMIN*,則說明該pod容許運行Isti init容器,不然須要配置權限

相關文章
相關標籤/搜索