服務網格與Istio


一、服務網格

在微服務環境中,可將單一應用程序分解為獨立的多個組件,並作為分布式服務進行部署。這些服務通常是無狀態的、短暫的、可動態擴展的,運行在容器編排系統(如Kubernetes)中。
 
服務網格(Service Mesh)是一個專用的基礎設施層。服務實例根據需要進行啟動、停止、銷毀、重建或替換時,通過通信中間件來支持服務的動態發現和自我修復連接能力,從而使得這些服務之間能夠以安全、動態和可靠的方式相互通信。
 
服務網格是一種網絡模型,位於TCP/IP之上的抽象層。它假定底層的三四層網絡存在並且能夠從一點到另一點傳送數據,但網絡是不可靠的。
服務網格抽象了在服務之間可靠地傳遞請求的機制,但不關心傳送及編碼的方式,只負責完成從服務A發送到服務B,並且能夠保證故障不會影響服務間的通信的可靠性(通過熔斷、延遲感知的負載均衡、最終一致性的服務發現、重試與超時等機制等)。
此外,還提供了一個統一的應用程序控制點,從而將服務通信從不可見的基礎設施領域移出,轉變為可監控、管理和控制的系統。
 
服務網格一般由控制平面和數據平面組成:
    控制平面是一組運行在專用命名空間中的服務。這些服務負責管理數據平面的執行,包括聚合遙測數據、提供面向用戶的API、向數據平面代理提供控制數據等。
    數據平面是由一系列運行在每個服務實例旁的透明代理(相當於進程外網絡堆棧)構成。這些代理自動處理進出服務的所有流量、向控制平面發送遙測數據並從控制平面接收控制信號。
 
服務網格的主要功能:
1)通過應用動態路由規則來確定將請求路由到哪個服務。
2)通過服務發現檢索相應的實例池。如果結果與實踐中觀察到的信息不同,那么需要決定信任哪些信息來源。
3)根據各種因素(如觀察到的最近請求的延遲數據)選擇最有可能返回快速響應的實例。
4)嘗試將請求發送到選擇的實例,記錄響應結果的延遲和響應類型。
5)如果實例沒有響應或返回錯誤,則根據需要在另一個實例上重試該請求。
6)如果實例始終沒有響應或返回錯誤,則將其從負載均衡池中逐出,以便稍后定期重試。
7)如果請求的超時點已過,則會停止進一步重試,主動使請求失敗,以防雪崩發生。
8)以度量指標和分布式跟蹤的形式捕獲上述行為的各個方面,並將這些數據發送到集中式的度量系統或者鏈路跟蹤系統。
 

二、Istio

1、簡介

Istio是服務網格的一種開源實現,支持在Kubernetes上部署的服務、使用Consul注冊的服務、在虛擬機上運行的服務等。
主要包括以下組件:
Envoy:每個微服務的sidecar代理,用以處理集群內service間的流量、集群內service訪問集群外的流量等
istiod:istio的控制平面,提供了服務發現、配置、證書管理功能,包括:
    pilot:用於管理流量,可以控制服務之間的流量流動和API調用
    citadel:進行證書和密鑰的輪換
    Galley:進行配置信息的驗證、分發等
Operator:主要是安裝istio用的
 
目前提供了istioctl工具安裝、helm工具安裝、istio operator自動安裝等多種方式
為安裝提供了多種profile,不同profile本質上就是用的yaml文件不一樣
 
介紹
istio-egressgateway
istio-ingressgateway
istio-ingressgateway
default
官方推薦
 
demo
僅供試用
empty
什么都不裝
一般在其基礎上自定義配置
 
 
 
external
多集群時使用外部控制平面
 
 
 
minimal
最小化安裝
 
 
openshift
 
 
 
 
preview
試用istio新功能
 
remote
文檔沒有?
 
 
 
 

2、Istio的安全架構:

在workload與workload通信開始時,兩方必須交換身份信息(identity)的憑證以相互驗證身份。
    客戶端,根據安全命名(secure naming)檢查服務端的身份,以確定它是否是workload的授權運行者
    在服務端,根據授權策略確定客戶端可以訪問哪些信息,審計誰在什么時間訪問了什么。例如可實現按量計費並禁止欠費用戶訪問。
 
在不同的平台上,Istio對服務身份信息的標識方法不同
    Kubernetes:使用k8s service account
    GCE:使用GCE service account
    沒有服務身份的平台:使用可以對工作負載實例進行分組的其它身份,例如服務名稱
 
主要包括以下環節:
①根證書與集群證書管理
默認istio會自動簽發集群證書,但建議用統一的根證書為每個集群簽發證書
istio提供了簽發證書的工具tools/certs/Makefile.selfsigned.mk
1)簽發根證書
$ make -f Makefile.selfsigned.mk root-ca
會生成root-cert.pem、root-key.pem、root-ca.conf、root-cert.csr
2)簽發集群證書
$ make -f Makefile.selfsigned.mk cluster1-cacerts
會在cluster1目錄下生成ca-cert.pem、ca-key.pem、cert-chain.pem( 指定信任鏈,包含負載到根CA的所有中間CAs。此處由於僅包含了istio的CA簽名證書,因此與ca-cert.pem相同)、root-cert.pem
3)在istio-system下創建名為cacerts的secret
$ kubectl create namespace istio-system $ kubectl create secret generic cacerts -n istio-system \ --from-file=cluster1/ca-cert.pem \ --from-file=cluster1/ca-key.pem \ --from-file=cluster1/root-cert.pem \ --from-file=cluster1/cert-chain.pem
4)最終形成的證書鏈為:root-cert.pem-->cert-chain.pem(含ca-cert.pem)-->workload-cert.pem
在istio的samples/certs目錄下有一套證書作為示例
 
②身份與workload證書管理
istio agent需要定期為workload進行證書和密鑰輪換:
(1)istiod提供了一個gRPC服務來接受CSR。
(2)Istio agent啟動時會創建私鑰和CSR,然后將CSR及其憑據發送給istiod進行簽名。
(3)istiod中的CA驗證CSR中攜帶的憑據。 驗證成功后,它會簽署CSR以生成證書。
(4)當workload啟動時,Envoy通過Envoy SDS(secret discovery service)API從同一容器中的Istio agent請求證書和密鑰。
(5)Istio agent通過 Envoy SDS API將從istiod收到的證書和私鑰發送給Envoy。
(6)Istio agent監控工作負載證書的過期時間。 
 
現在,還支持基於k8s的CSR API,由自定義的CA為workload簽發證書,詳見: https://istio.io/latest/docs/tasks/security/cert-management/custom-ca-k8s/
 
③雙向TLS認證:
④鑒權:
 

3、遙測信息

Istio生成以下類型的telemetry(遙測信息),以提供整體服務網格可觀察性:
  • Metrics
Istio監控了所有進出服務網格以及服務網格內的服務流量,根據latency、traffic、errors 、saturation(飽和度)四個維度為服務生成service-level Metrics,提供了可提供網格內的服務的可觀察性。包括: https://istio.io/latest/docs/reference/config/metrics/
Istio根據sidecar代理Envoy自身豐富的metrics統計信息(可參考 https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/observability/statistics.html?highlight=statistics)生成了proxy-level Metrics,提供網格本身的可觀察性(例如出入sidecar的總流量、Envoy的配置與健康情況)。不過默認只收集了Envoy的一部分統計信息,同時需要為工作負載配置收集哪些Envoy的指標。可以使用proxy-status和proxy-config命令進行相應查看與調整。
默認在Istio代理過濾器中編譯telemetry V2。相同的Filter也將編譯為WebAssembly(WASM)模塊,並隨Istio代理一起提供。
Istio本身不再訪問k8s元數據,而是由代理服務器統一提供service-level Metrics和proxy-level Metrics。
主要通過Envoy WebAssembly插件豐富Envoy的統計子系統:
    元數據交互插件:從請求/響應中的自定義HTTP標頭獲取連接兩側的客戶端/服務器元數據
    統計信息插件:統計傳入和傳出的流量指標
  • Distributed Traces
Istio支持通過Envoy代理來進行服務的分布式追蹤,從而使運維人員能夠詳細了解網格內的服務調用鏈和服務之間的依賴性
支持的跟蹤后端包括Zipkin、Jaeger、Lightstep、Datadog
  • Access Logs
當流量進入網格內的服務時, Istio可以為每個請求生成完整的記錄,包含源和目標的metadata。
默認會由Envoy容器打印到標准輸出,該信息可以使運維人員審計在單個工作負載的級別上審計服務的行為。
 

4、k8s上的安裝CRD

以k8s上通過istioctl工具部署為例:
默認將控制平面安裝在istio-system namespace下
istio-ingressgateway這個svc是LoadBalancer類型的。如果k8s不支持自動分配external ip,仍然需要使用nodeport對外暴露http2和https的端口
除了通過istio ingress gateway,istio還實現了k8s官方的ingress api(IngressClass中controller指定為istio.io/ingress-controller)和sig-network的gateway api(GatewayClass中controller指定為istio.io/ingress-controller)
使用時,為namespace添加istio-injection=enabled的label,同時開啟webhook功能,才會為該ns下的Pod自動注入
部署完成后,在k8s上會創建以下CRD:
IstioOperator描述了Istio的期待狀態,istio operator會根據其進行istio的安裝、更新、卸載等
istioctl工具部署時,也會在istio-system namespace下創建名為installed-state的IstioOperator並維護其狀態 
VirtualService描述了一個或多個路由規則(用戶可尋址目標到網格內實際workload的映射)。Istio按順序評估它們,將每個給定的請求匹配到指定的實際目標地址。
要將服務網格內的請求路由到實際目標地址,Istio必須借助平台提供的服務發現能力。
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
    fault:
      delay:
        percentage:
          value: 0.1
        fixedDelay: 5s
hosts字段列出了虛擬服務的目標主機,即用戶指定的目標或路由規則設定的目標
    可以是ip地址或域名
    可以是可解析為FQDN(fully qualified domain name)的短域名
    可以加匹配
gateway字段可以將VirtualService與Gateway綁定,向網格外暴露這些hosts
    默認會綁定mesh,表示所有sidecar
    指定了綁定的Gateway后,就不再自動綁定mesh,需手動綁定
http字段列出了VirtualService的路由規則,規則越靠前優先級越高
    match表示匹配規則,可以根據http頭、uri等匹配
    fault:測試時用於注入錯誤,delay可以引發超時錯誤、aborts可以引發中止錯誤
    route中是http路由目的地,可以根據weight、head等決定destination(實際目標地址)
    timeout表示envoy代理等待服務的時間
    retries可以指定attempts(總嘗試次數)和perTryTimeout(每次嘗試的timeout)
    mirror和mirrorPercent可以控制將部分流量發送給一個鏡像服務
tcp字段列出了tcp流量的路由規則
    match表示匹配規則,可以根據port、destinationSubnets等匹配
    route中是L4路由目的地,可以根據weight決定destination
DestinationRule配置該目的地的流量發生的情況。
它定義了在路由發生后應用於服務的流量的策略。這些規則指定了負載平衡的配置、 sidecar的連接池大小和異常檢測設置,以檢測並驅逐負載平衡池中不健康的主機。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-destination-rule
spec:
  host: my-svc
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
  - name: v3
    labels:
      version: v3
trafficPolicy中指明了流量的規則:
    loadBalancer指明負載均衡規則:
        simple支持 ROUND_ROBIN、 LEAST_CONN、 RANDOM、 PASSTHROUGH等多種經典算
        consistentHash支持基於 httpHeaderName、httpCookie、 useSourceIp、 httpQueryParameterName、 minimumRingSize進行hash
        localityLbSetting支持基於流量的來去地點(region、zone、sub-zone)控制流量
            通過enabled啟用
            distribute指明分發規則,failover指明故障轉移規則,兩者不能共存(為啥)
    connectionPool為基於Envoy的circuit breaker提供了連接池配置:
        tcp可以配maxConnections、connectTimeout、tcpKeepalive
        http可以配http1MaxPendingRequests、http2MaxRequests等
    outlierDetection可以控制從負載均衡池驅逐不健康主機的策略
    tls是連接時的tls相關配置
    portLevelSettings可以用端口級別的流量策略覆蓋全局配置
subset是服務端點的集合
    可以基於label(例如k8s中Pod的label)對服務端點列表進行篩選
    其中聲明的trafficPolicy會覆蓋全局配置
exportTo指明了此DestinationRules暴露到哪些ns中
gateway描述了一個負載均衡器,該負載均衡器是網格邊緣獨立運行的Envoy代理,在網格的邊緣接收傳入或傳出的HTTP/TCP連接。
但gateway本身只能配置l4-L6的功能,例如暴露的端口、tls設置等。要為進出Gateway的流量配置相應的路由,必須為同一個host定義一個VirtualService,其配置中的gateways字段綁定該Gateway
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ext-host-gwy
spec:
  selector:
    app: my-gateway-controller
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - ext-host.example.com
    tls:
      mode: SIMPLE
      credentialName: ext-host-cert
selector基於標簽選擇服務作為gateway
入訪時,VirtualService中配置流量方向為external workload/用戶-> ingress gateway->sidecar
出訪時,VirtualService中配置流量方向為sidecar-> engress gateway->external service(通過ServiceEntry注冊)
可以通過ServiceEntry將平台外的服務添加到Istio內部維護的服務注冊表中。
添加后,Envoy代理可以將流量發送到該服務,就好像該服務條目是網格中的服務一樣
通過配置ServiceEntry,可以管理在網格外部運行的服務的流量。
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: details-svc
spec:
  hosts:
  - details.bookinfo.com
  location: MESH_INTERNAL
  ports:
  - number: 80
    name: http
    protocol: HTTP
    targetPort: 8080
  resolution: STATIC
  workloadSelector:
    labels:
      app: details-legacy
WorkloadEntry用於描述平台外(例如沒有部署在k8s上,而是直接部署在虛機或裸金屬服務器上)的workload,必須與ServiceEntry同步創建。
這個平台外的workload必須同樣具備服務身份、sidecar:
apiVersion: networking.istio.io/v1beta1
kind: WorkloadEntry
metadata:
  name: details-svc
spec:
  serviceAccount: details-legacy
  address: 2.2.2.2
  labels:
    app: details-legacy
    instance-id: vm1
對平台外的workload,通過WorkloadGroup模擬k8s中的sidecar注入規范和部署方式
apiVersion: networking.istio.io/v1alpha3
kind: WorkloadGroup
metadata:
  name: reviews
  namespace: bookinfo
spec:
  metadata:
    labels:
      app.kubernetes.io/name: reviews
      app.kubernetes.io/version: "1.3.4"
  template:
    ports:
      grpc: 3550
      http: 8080
    serviceAccount: default
  probe:
    initialDelaySeconds: 5
    timeoutSeconds: 3
    periodSeconds: 4
    successThreshold: 3
    failureThreshold: 3
    httpGet:
     path: /foo/bar
     host: 127.0.0.1
     port: 3100
     scheme: HTTPS
     httpHeaders:
     - name: Lit-Header
       value: Im-The-Best
metadata,尤其是其中的標簽,將會被應用於所有workload
template是用於生成對應WorkloadEntry的模板(address和label不可手動設置)
probe用於配置就緒探針,和k8s中的配置方法幾乎一樣
EnvoyFilter可以用來更新Envoy中的filter的配置,為服務網格控制面提供了更強大的擴展能力,使Envoy中filter chain具備自定義配置的能力。
  • telemetries.telemetry.istio.io
暫時不知道干嘛的
默認情況下,Istio將每個Envoy代理配置為接受其相關工作負載的所有端口上的流量,並在轉發流量時到達網格中的每個工作負載。 
可使用Sidecar執行以下操作:
    微調Envoy代理接受的端口和協議集。
    限制Envoy代理可以訪問的服務集。
例如,限制xxx命名空間下的服務僅能訪問同一命名空間和Istio-system中運行的服務:
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default
  namespace: xxx
spec:
  egress:
  - hosts:
    - "./*"
    - "istio-system/*"
即授權策略,可以實現workload/用戶→workload的訪問控制
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: httpbin
  namespace: foo
spec:
  action: DENY
  rules:
  - from:
    - source:
        namespaces: ["dev"]
    to:
    - operation:
        methods: ["POST"]
selector選擇了策略適用的workload,通過selector可以將策略分為mesh級、ns級、workload級
action包括DENY、ALLOW、AUDIT、CUSTOM(轉發給擴展程序處理用戶請求)
    多個策略共存時,CUSTOM>DENY>ALLOW
provider指定擴展程序的名字(action為CUSTOM時生效)
rules包括了:
    from中,source可以是(not)ns、ipblock、principals等
    to中,operation可以是(not)hosts、ports等
    when指定了key/(not)value的條件: https://istio.io/latest/docs/reference/config/security/conditions/
  • peerauthentications.security.istio.io
即peer認證(authentication)策略,配置的是workload-workload雙向通信的tls認證策略:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: "example-peer-policy"
  namespace: "foo"
spec:
  selector:
    matchLabels:
      app: reviews
  mtls:
    mode: STRICT
selector選擇了策略適用的workload,通過selector可以將策略分為mesh級、ns級、workload級
    范圍越小的優先級越高,范圍一樣時舊的優先級高
mels.mode指定了workload的雙向TLS模式
    PERMISSIVE:既支持雙向TLS,也運行明文通信
    STRICT:必須雙向TLS
    DISABLE:禁用雙向TLS
portLevelMtls.xx.mode則支持為某一個端口專門配置
即request認證(authentication)策略,基於對request中的JWT(JSON Web Token)進行校驗來實現認證
selector選擇了策略適用的workload,通過selector可以將策略分為mesh級、ns級、workload級
jwtRules中是一條條JWT檢查規則,可檢查的包括issuer、audiences、jwksUri、jwks(JSON Web Key Set)等
 

5、示例程序

samples/bookinfo/platform/kube/bookinfo.yaml下提供了一個示例程序
使用istio將其改造成如下架構:
 

三、其它服務網格產品

目前,很多傳統的反向代理也在向服務網格方向發展,例如Nginx構建的nginx Service Mesh、Traefix構建的Trafix Mesh
API網關產品kong也發展了kuma(也是基於Envoy)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM