摘要:{ "version_info": "2020-05-14T03:15:47Z/18", "cluster": { "@type": "type.googleapis.com/envoy.api.v2.Cluster", "name": "outbound|9080||reviews.default.svc.cluster.local", "type": "EDS", "eds_cluster_config": { "eds_config": { "ads": {} }, "service_name": "outbound|9080||reviews.default.svc.cluster.local" }, "service_name": "outbound|9080||reviews.default.svc.cluster.local" }, "circuit_breakers": {...}, "filters": [...], "transport_socket_matches": [ { "name": "tlsMode-istio", "match": { "tlsMode": "istio" }, "transport_socket": { "name": "envoy.transport_sockets.tls", "typed_config": { "@type": "type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext", "common_tls_context": { "alpn_protocols": [ "istio-peer-exchange", "istio" ], "tls_certificate_sds_secret_configs": [ { "name": "default", // 配置用於訪問 reviews 服務的客戶端證書 "sds_config": { "api_config_source": { "api_type": "GRPC", "grpc_services": [ { "envoy_grpc": { "cluster_name": "sds-grpc" // 配置用於獲取客戶端證書的 SDS 服務器 } } ] } } } ], "combined_validation_context": { "default_validation_context": { "verify_subject_alt_name": [ "spiffe://cluster.local/ns/default/sa/bookinfo-reviews" // 驗證服務器證書時需要驗證 SAN 中的 service account 名稱 ] }, "validation_context_sds_secret_config": { "name": "ROOTCA", // 配置驗證 reviews 服務器證書的 CA 根證書 "sds_config": { "api_config_source": { "api_type": "GRPC", "grpc_services": [ { "envoy_grpc": { "cluster_name": "sds-grpc" // 配置用於獲取 CA 根證書的 SDS 服務器 } } ] } } } } }, "sni": "outbound_.9080_._.reviews.default.svc.cluster.local" } } }, ] }, "last_updated": "2020-05-14T03:16:33.061Z" }。除了 Ingress Gateway 對外提供服務的服務器證書和 Egress Gateway 訪問第三方服務的客戶端證書之外,其他證書都是 Envoy 通過 SDS 服務從 Istio CA 獲取的,因此都使用 Istio Root CA 證書進行驗證。

在上一篇文章 一文帶你徹底釐清 Kubernetes 中的證書工作機制 中,我們介紹了 Kubernetes 中證書的工作機制。在這篇文章中,我們繼續探討 Istio 是如何使用證書來實現網格中服務的身份認證和安全通信的。

本文是對 Istio 認證工作機制的深度分析,因此假設讀者已經瞭解 Service Mesh 以及 Istio 的相關基礎概念,在本文對此類基礎概念不再解釋,如果讀者閱讀時有疑問,建議先閱讀 Istio 官方網站上的的這篇基礎介紹 What is Istio?

Istio 安全架構

Istio 以一種對應用無侵入的,可插拔的方式實現了網格中服務之間的雙向 TLS 認證。應用不需要修改代碼,就可以實現服務之間以及服務和外部系統/用戶之間的安全通信。Istio 安全的高層架構如下圖所示:

圖1. Istio Security Architecture,圖片來源 istio.io

圖中展示了 Istio 中的服務認證和授權兩部分內容。讓我們暫時忽略掉授權部分,先關注認證部分。服務認證是通過控制面和數據面一起實現的:

  • 控制面:Istiod 中實現了一個 CA (Certificate Authority,證書機構) 服務器。該 CA 服務器負責爲網格中的各個服務簽發證書,併發送給數據面的邊車代理。
  • 數據面:在網格中的服務相互之間發起 plain HTTP/TCP 通信時,和服務同一個 pod 中的邊車代理會攔截服務請求,採用證書和對端服務的邊車代理進行雙向 TLS 認證並建立一個 TLS 連接,使用該 TLS 連接來在網絡中傳輸數據。

控制面證書籤發流程

圖1是對 Istio 安全架構的一個高度概括的描述,讓我們把圖1中控制面的交互展開,看一下其中的細節。

圖2. Istio 證書籤發流程

Istio 控制面向 Envoy 簽發證書的流程如下:

  1. Envoy 向 pilot-agent 發起一個 SDS (Secret Discovery Service) 請求,要求獲取自己的證書和私鑰。
  2. Pilot-agent 生成私鑰和 CSR (Certificates Signing Request,證書籤名請求),向 Istiod 發送 CSR 請求。
  3. Istiod 根據請求中客戶端的 Service Account 爲其簽發證書,將證書返回給 Pilot-agent。
  4. Pilot-agent 將證書和私鑰返回給 Envoy。

爲什麼要通過 Pilot-agent 中轉?

從圖2可以看到,Istio 證書籤發的過程中涉及到了三個組件: Istiod (Istio CA) —> Pilot-agent —> Enovy。爲什麼其他 xDS 接口都是由 Istiod 直接向 Envoy 提供,但 SDS 卻要通過 Pilot-agent 進行一次中轉,而不是直接由 Envoy 通過 SDS 接口從 Istiod 獲取證書呢?這樣做主要有兩個原因。

首先,在 Istio 的證書籤發流程中,由 Pilot-agent 生成私鑰和 CSR,再通過 CSR 向 Istiod 中的 CA 申請證書。在整個過程中,私鑰只存在於本地的 Istio-proxy 容器中。如果去掉中間 Pilot-agent 這一步,直接由 Envoy 向 Isitod 申請證書,則需要由 Istio的 生成私鑰,並將私鑰和證書一起通過網絡返回給 Envoy,這將大大增加私鑰泄露的風險。

另一方面,通過 Pilot-agent 來提供 SDS 服務,由 Pilot-agent 生成標準的 CSR 證書籤名請求,可以很容易地對接不同的 CA 服務器,方便 Istio 和其他證書機構進行集成。

控制面身份認證

要通過服務證書來實現網格中服務的身份認證,必須首先確保服務從控制面獲取自身證書的流程是安全的。Istio 通過 Istiod 和 Pilog-agent 之間的 gRPC 通道傳遞 CSR 和證書,因此在這兩個組件進行通信時,雙方需要先驗證對方的身份,以避免惡意第三方僞造 CSR 請求或者假冒 Istiod CA 服務器。在目前的版本中(Istio1.6),Pilot-agent 和 Istiod 分佈採用了不同的認證方式。

  • Istiod 身份認證
    • Istiod 採用其內置的 CA 服務器爲自身簽發一個服務器證書(圖2中的 Istiod certificate),並採用該服務器證書對外提供基於 TLS 的 gPRC 服務。
    • Istiod 調用 Kube-apiserver 生成一個 ConfigMap, 在該 ConfigMap 中放入了 Istiod 的 CA 根證書(圖2中的 istio-ca-root-cert)。
    • 該 ConfigMap 被 Mount 到 Istio-proxy 容器中,被 Pilot-agent 用於驗證 Istiod 的服務器證書。
    • 在 Pilot-agent 和 Istiod 建立 gRPC 連接時,Pilot-agent 採用標準的 TLS 服務器認證流程對 Istiod 的服務器證書進行認證。
  • Pilot-agent 身份認證
    • 在 Kubernetes 中可以爲每一個 pod 關聯一個 Service Account ,以表明該 pod 中運行的服務的身份信息。例如 bookinfo 中 reviews 服務的 service accout 是 “bookinfo-reviews” 。
    • Kubernetes 會爲該 service account 生成一個 jwt token,並將該 token 通過 secret 加載到 pod 中的一個文件。
    • Pilot-agent 在向 Istiod 發送 CSR 時,將其所在 pod 的 service account token 也隨請求發送給 Istiod。
    • Istiod 調用 Kube-apiserver 接口驗證請求中附帶的 service account token,以確認請求證書的服務身份是否合法。

備註:除了 Kubernetes 之外, Istio 也支持虛機部署,在虛機部署的場景下,由於沒有 service account,Pilot-agent 和 Pilotd 之間的身份認證方式有所不同。由於 Istio 的主要使用場景還是 Kubernetes,本文只分析 Kubernetes 部署場景。

SDS 工作原理

和其他 xDS 接口一樣,SDS 也是 Envoy 支持的一種動態配置服務接口。Envoy 可以通過 SDS(secret discovery service) 接口從 SDS 服務器自動獲取證書。和之前的方式相比,SDS 最大的好處就是簡化了證書管理。在沒有使用 SDS 前,Istio 中的服務證書被創建爲 Kubernetes secret,並掛載到代理容器中。如果證書過期了,則需要更新 secret 並重啓 Envoy 容器,以啓用新的證書。使用SDS後,SDS 服務器(Pilot-agent充當了 SDS 服務器的角色)將向 Envoy 實例主動推送證書。如果證書過期,SDS 服務器只需將新的證書推送到 Envoy 例中,Envoy 會使用新的證書來創建鏈接,無需重新啓動。

圖3. Envoy SDS 服務

可以看到,Istio 採用 SDS 後,避免了在證書更新後重啓 Envoy,大大減少了證書更新對業務的影響。同時,由於 Pilot-agent 和 Envoy 處於同一容器中,私鑰只存在於本地容器,避免了在網絡中傳遞私鑰,也降低了私鑰泄露的安全風險。

SDS 服務向 Envoy 下發的數據結構爲 extensions.transport_sockets.tls.v3.Secret ,其結構如下:

{
  "name": "...",                            // Secret 名稱
  "tls_certificate": "{...}",               // 數字證書
  "session_ticket_keys": "{...}",
  "validation_context": "{...}",            // 證書驗證信息
  "generic_secret": "{...}"
}

其中在 Istio 中用到的主要是 tls_certificatevalidation_context 。 分別用於傳遞數字證書和驗證對方證書使用到的根證書。下面是這兩個字段的結構,結構中標註了我們主要需要關注的內容。

tls_certificate

{
  "certificate_chain": "{...}",           // 證書內容
  "private_key": "{...}",                 // 證書的私鑰
  "private_key_provider": "{...}",
  "password": "{...}"
}

validation_context

{
  "trusted_ca": "{...}",                 // CA 根證書
  "verify_certificate_spki": [],
  "verify_certificate_hash": [],
  "match_subject_alt_names": [],         // 需要驗證的 subject alt name
  "crl": "{...}",
  "allow_expired_certificate": "...",
  "trust_chain_verification": "..."
}

網格邊車證書配置

在 Istio 的 Enovy 邊車配置中,有兩處需要通過 SDS 來配置證書:

  • Inbound Listener:由於Enovy 通過 Listener 對外提供服務,需要通過 SDS 配置服務器證書,服務器證書私鑰,以及驗證下游客戶端證書的 CA 根證書。
  • Outbound Cluster:對於上游的 Cluster 而言,Envoy 是客戶端的角色,因此需要在 Cluster 中通過 SDS 配置客戶端證書,客戶端證書私鑰,以及驗證上游服務器的 CA 根證書。

下面我們來看一下 bookinfo 示例中 Envoy 邊車代理上 reviews 微服務相關的證書配置,以對 Istio 中 SDS 的運作機制有一個更清晰的認識。爲了簡略起見,本文只顯示了部分關鍵的配置。你也可以查看 Github 上的 完整配置

通過 Envoy 的管理端口,可以導出 Envoy 中的當前配置,導出命令如下:

kubectl exec reviews-v1-6d8bc58dd7-ts8kw -c istio-proxy curl http://127.0.0.1:15000/config_dump > config_dump

配置文件中 SDS 服務器的定義如下,Pilot-agent 在 /etc/istio/proxy/SDS 這路徑上通過 unix domain socket 提供了一個 SDS 服務器。

{
  "name": "sds-grpc",
  "type": "STATIC",
  "connect_timeout": "10s",
  "hidden_envoy_deprecated_hosts": [
   {
    "pipe": {
     "path": "/etc/istio/proxy/SDS"
    }
   }
  ],
  "http2_protocol_options": {}
}

Details Pod 在 9080 端口對外提供服務,因此需要通過 SDS 配置 9080 端口上的服務端證書和驗證客戶端證書的 CA 根證書。

{
  "name": "virtualInbound",                                // 15006端口上的虛擬入向監聽器
  "active_state": {
  "version_info": "2020-05-14T03:59:54Z/25",
  "listener": {
   "@type": "type.googleapis.com/envoy.api.v2.Listener",
   "name": "virtualInbound",
   "address": {
    "socket_address": {
     "address": "0.0.0.0",
     "port_value": 15006
    }
   },
   "filter_chains": [
   {
     "filter_chain_match": {
      "prefix_ranges": [
       {
        "address_prefix": "10.44.0.8",
        "prefix_len": 32
       }
      ],
      "destination_port": 9080                            // 用於處理發向reviews服務9080端口的業務請求的filter chain
     },
     "filters": [...],
     "transport_socket": {
      "name": "envoy.transport_sockets.tls",
      "typed_config": {
       "@type": "type.googleapis.com/envoy.api.v2.auth.DownstreamTlsContext",
       "common_tls_context": {
        "alpn_protocols": [
         "h2",
         "http/1.1"
        ],
        "tls_certificate_sds_secret_configs": [          // 配置服務器端證書
         {
          "name": "default",                             // 服務器證書 Secret 名稱
          "sds_config": {
           "api_config_source": {
            "api_type": "GRPC",
            "grpc_services": [
             {
              "envoy_grpc": {
               "cluster_name": "sds-grpc"               // 配置用於獲取服務器端證書的 SDS 服務器
              }
             }
            ]
           }
          }
         }
        ],
        "combined_validation_context": {
         "default_validation_context": {},
         "validation_context_sds_secret_config": {     // 配置驗證客戶端證書的 CA 根證書
          "name": "ROOTCA",                            // CA 根證書 Secret 名稱
          "sds_config": {
           "api_config_source": {
            "api_type": "GRPC",
            "grpc_services": [
             {
              "envoy_grpc": {
               "cluster_name": "sds-grpc"             // 配置用於獲取 CA 根證書的 SDS 服務器
              }
             }
            ]
           }
          }
         }
        }
       },
       "require_client_certificate": true
      }
     }
    }
   ],
 }
}

客戶端 Pod 上的 Enovy 通過 reviews outbound cluster 訪問上游 reviews 服務,因此需要在該 cluster 上配置客戶端證書以及驗證服務器端證書的 CA 根證書。在這裏我們需要注意的是,Envoy 在驗證服務器端證書時會同時驗證證書中的 subject alternative name 字段。該字段中設置的是 reviews 服務 Pod 關聯的 Service Account 名稱。 由於 Service Account 是 Istio 中認可的一種用戶賬戶,因此通過爲 Service Account 設置不同的資源訪問權限,可以進一步實現細粒度的權限控制,例如按照 URL 進行授權。

{
  "version_info": "2020-05-14T03:15:47Z/18",
  "cluster": {
   "@type": "type.googleapis.com/envoy.api.v2.Cluster",
   "name": "outbound|9080||reviews.default.svc.cluster.local",
   "type": "EDS",
   "eds_cluster_config": {
    "eds_config": {
     "ads": {}
    },
    "service_name": "outbound|9080||reviews.default.svc.cluster.local"
   },
   "service_name": "outbound|9080||reviews.default.svc.cluster.local"
  },
  "circuit_breakers": {...},
  "filters": [...],
  "transport_socket_matches": [
   {
    "name": "tlsMode-istio",
    "match": {
     "tlsMode": "istio"
    },
    "transport_socket": {
     "name": "envoy.transport_sockets.tls",
     "typed_config": {
      "@type": "type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext",
      "common_tls_context": {
       "alpn_protocols": [
        "istio-peer-exchange",
        "istio"
       ],
       "tls_certificate_sds_secret_configs": [
        {
         "name": "default",                                     // 配置用於訪問 reviews 服務的客戶端證書
         "sds_config": {
          "api_config_source": {
           "api_type": "GRPC",
           "grpc_services": [
            {
             "envoy_grpc": {
              "cluster_name": "sds-grpc"                        // 配置用於獲取客戶端證書的 SDS 服務器
             }
            }
           ]
          }
         }
        }
       ],
       "combined_validation_context": {
        "default_validation_context": {
         "verify_subject_alt_name": [
          "spiffe://cluster.local/ns/default/sa/bookinfo-reviews"  // 驗證服務器證書時需要驗證 SAN 中的 service account 名稱
         ]
        },
        "validation_context_sds_secret_config": {
         "name": "ROOTCA",                                     // 配置驗證 reviews 服務器證書的 CA 根證書
         "sds_config": {
          "api_config_source": {
           "api_type": "GRPC",
           "grpc_services": [
            {
             "envoy_grpc": {
              "cluster_name": "sds-grpc"                       // 配置用於獲取 CA 根證書的 SDS 服務器
             }
            }
           ]
          }
         }
        }
       }
      },
      "sni": "outbound_.9080_._.reviews.default.svc.cluster.local"
     }
    }
   },
  ]
 },
 "last_updated": "2020-05-14T03:16:33.061Z"
}

上面配置中 SAN 中的 service account 名稱來自於 reviews pod 中的 service account 配置。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: reviews-v1
  labels:
    app: reviews
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: reviews
      version: v1
  template:
    metadata:
      labels:
        app: reviews
        version: v1
    spec:
      serviceAccountName: bookinfo-reviews                             // 設置 reviews pod 的 service account
      containers:
      - name: reviews
        image: docker.io/istio/examples-bookinfo-reviews-v1:1.15.0
        imagePullPolicy: IfNotPresent
        env:
        - name: LOG_DIR
          value: "/tmp/logs"
        ports:
        - containerPort: 9080
...

在導出的配置中可以看到 Envoy 通過 SDS 服務器獲取到的證書內容。

{
   "@type": "type.googleapis.com/envoy.admin.v3.SecretsConfigDump",
   "dynamic_active_secrets": [
    {
     "name": "default",
     "version_info": "05-14 03:16:30.900",
     "last_updated": "2020-05-14T03:16:31.125Z",
     "secret": {
      "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret",
      "name": "default",
      "tls_certificate": {
       "certificate_chain": {
        "inline_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FUXXXXXXXXXXXXXXUZJQ0FURS0tLS0tCg=="           // details 服務的證書,該證書被同時用作了服務器證書和客戶端證書
       },
       "private_key": {
        "inline_bytes": "W3JlZGFjdGVkXQ=="                                                        // detatils 服務證書對應的私鑰
       }
      }
     }
    },
    {
     "name": "ROOTCA",
     "version_info": "2020-05-14 03:16:31.300416193 +0000 UTC m=+1.537483882",
     "last_updated": "2020-05-14T03:16:31.343Z",
     "secret": {
      "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret",
      "name": "ROOTCA",
      "validation_context": {
       "trusted_ca": {
        "inline_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0XXXXXXXXXXXXXXXXXXXXJQ0FURS0tLS0tCg=="       // 用於驗證通信對方證書的 CA 根證書
       }
      }
     }
    }
   ]
  }

通過上面的配置,我們可以看到,雖然需要在 Enovy 邊車配置文件中不同的位置爲 Envoy 配置服務器、客戶端證書以及驗證對方的 CA 根證書,但 Istio 中實際上只採用了一個服務證書和 CA 根證書。Isito 將名稱爲 default 的證書被同時用於 Inbound Listener 的服務器證書和 Outbound Cluster 的客戶端證書,並將名稱爲 ROOTCA 的證書被用於驗證下游客戶端證書和上游服務器證書的根證書。

Gateway 證書配置

除了需要和網格內部的服務進行通信之外,Ingress Gateway 和 Egress Gateway 還需要連接到網格外部的系統。如果這些外部連接也需要採用 TLS,則 Gateway 中也要配置這些外部系統的相關證書。

Ingress Gateway 中需要如下證書相關的配置:

  • 作爲客戶端和網格內部其他服務進行通信的客戶端證書和私鑰,和其他服務使用的證書類似,該證書也是由 Istio CA 頒發的。
  • 驗證網格內其他服務證書的 CA 根證書,該根證書是 Istio CA 的根證書。
  • 作爲網關向網格外部提供服務使用的服務器端證書和私鑰,該證書一般是由一個權威 CA 或者第三方 CA 簽發的。如果有多個 host,需要爲每一個 host 分別配置配置不同的證書。
  • 如果對外提供的服務需要雙向 TLS 認證,還需要配置用於驗證客戶端證書的 CA 根證書。

Egress Gateway 中需要如下證書相關的配置:

  • 作爲服務器接受網格內部其他服務訪問的服務器證書和私鑰,和其他服務使用的證書類似,該證書也是由 Istio CA 頒發的。
  • 驗證網格內其他服務證書的 CA 根證書,該根證書是 Istio CA 的根證書。
  • 作爲出口網關訪問外部服務時,如果該外部服務採用了 TLS,則需要配置一個驗證該服務器證書的 CA 根證書來驗證該服務器。該根證書一般是一個權威 CA 或者第三方 CA。
  • 如果訪問的外部服務要求雙向 TLS 認證,則還需要網關配置一個該外部服務認可的客戶端證書。該證書一般是由一個權威 CA 或者第三方 CA 簽發的。

由於 Gateway 中配置的和外部系統相關的證書不是通過 SDS 從 Istio CA 獲取的,而是採用第三方 CA 頒發的,因此到期後並不能自動更新,而需要手動進行更新。因此需要注意這些證書的有效期,在證書過期前及時重新申請證書並更新到 Gateway 配置中,以避免影響業務。

在 Gateway 上配置第三方證書的方法是採用 Kubernetes Secret 和 Istio Gateway CRD。例如我們可以採用下面的步驟在 Ingress Gateway 上配置對外提供服務使用的服務器證書。

首先創建一個 secret,該 secret 中包含了服務器證書和私鑰:

kubectl create -n istio-system secret tls bookinfo-credential --key=bookinfo.example.com.key --cert=bookinfo.example.com.crt

然後通過 Gateway CRD 定義一個對外提供服務的虛擬主機,並指定使用剛纔定義的 secret。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: mygateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: httpbin-credential # 在此處設置包含了服務器證書和私鑰的 secret

    hosts:
    - bookinfo.example.com

Istio 將此配置通過 xDS 接口下發到 Ingress Gateway Pod 中的 Envoy 上,可以在該 Envoy 的配置導出中看到 Ingress 網關對外提供的 443 端口上的證書配置(配置文件中的端口是8443,這是因爲 Pod 內使用了8443端口,但對外暴露的 LoadBalancer 上的端口是443)。

{
  "name": "0.0.0.0_8443",
  "active_state": {
   "version_info": "2020-05-27T07:43:51Z/21",
   "listener": {
    "@type": "type.googleapis.com/envoy.api.v2.Listener",
    "name": "0.0.0.0_8443",
    "address": {
     "socket_address": {
      "address": "0.0.0.0",
      "port_value": 8443
     }
    },
    "filter_chains": [
     {
      "filter_chain_match": {
       "server_names": [
        "bookinfo.example.com"
       ]
      },
      "filters": [...],
      "transport_socket": {
       "name": "envoy.transport_sockets.tls",
       "typed_config": {
        "@type": "type.googleapis.com/envoy.api.v2.auth.DownstreamTlsContext",
        "common_tls_context": {
         "alpn_protocols": [
          "h2",
          "http/1.1"
         ],
         "tls_certificate_sds_secret_configs": [
          {
           "name": "bookinfo-credential",                            // Ingress Gateway 中配置的 Kubernetes secret
           "sds_config": {
            "api_config_source": {
             "api_type": "GRPC",
             "grpc_services": [
              {
               "google_grpc": {
                "target_uri": "unix:/var/run/ingress_gateway/sds",   // 從本地 unix domain socket 上的 SDS 服務器獲取服務器證書
                "stat_prefix": "sdsstat"
               }
              }
             ]
            }
           }
          }
         ]
        },
        "require_client_certificate": false
       }
      }
     }
    ],
   },
  }
 }

從配置中可以看出,Ingress Gateway 使用的服務器證書也是通過 SDS 服務獲取的。Pilot-agent 在路徑 unix:/var/run/ingress_gateway/sds 上爲 Ingress Gateway 提供了一個基於 unix domain socket 的 SDS 服務。Ingress Gateway 中的 Envoy 向該 SDS 服務器請求上述配置文件中的 secret,Pilot-agent 從 Kubernetes 中查到該 同名 secret,然後轉換爲 SDS 消息返回給 Envoy。

備註:Ingress Gateway 用於和網格內其他服務通信的服務身份證書還是由 Istio CA 頒發的,其證書籤發的流程同圖2。

圖4. Envoy SDS 服務

數據面使用的所有證書

下圖中以 bookinfo 來舉例說明 Istio 在數據面使用到的所有證書。爲了方便說明 Gateway 的證書配置,我們假設在 Ingress Gateway 上以 bookinfo.example.com 的主機名對外提供服務,並且 ratings 服務通過 Egress Gateway 訪問了一個網格外部的第三方 TLS 服務。

圖中不同顏色邊框的圖標代表了不同的證書。該示例中一共使用了七個不同的證書,分別爲3個服務的證書(同時用作服務器和客戶端證書),Ingress Gateway 自身的客戶端證書,Ingress Gateway 對外部提供服務的服務器證書,Egress Gateway 自身的服務器證書,Egress Gateway 訪問外部服務使用的客戶端證書。

除了 Ingress Gateway 對外提供服務的服務器證書和 Egress Gateway 訪問第三方服務的客戶端證書之外,其他證書都是 Envoy 通過 SDS 服務從 Istio CA 獲取的,因此都使用 Istio Root CA 證書進行驗證。這兩個第三方證書則需要採用第三方 CA 根證書進行驗證。

圖5. Istio 數據面使用到的所有證書

小結

微服務應用本質上是一個分佈式的網絡程序,在微服務應用內存在大量的服務間網絡通信。在雲化部署環境中,服務間的身份認證和安全通信是微服務面臨的一大挑戰。Istio 建立了一套以數字證書爲基礎的服務認證安全框架,在不修改應用的前提下提供了服務之間的身份認證和安全通信,並以身份認證爲基礎提供了強大的授權機制。

相關文章