Istio 環境網格入門

使用 Istio 環境網格的逐步入門指南。

2022 年 9 月 7 日 | 作者:Lin Sun - Solo.io、John Howard - Google

環境網格是 Istio 今天推出的新資料平面模式。按照本入門指南,您可以體驗環境網格如何簡化您的應用程式導入、協助持續運營,並減少服務網格基礎架構的資源使用。

安裝具有環境模式的 Istio

  1. 下載支援環境網格的 Istio 預覽版本
  2. 查看支援的環境。我們建議使用 Kubernetes 1.21 或更新版本,且至少有兩個節點的叢集。如果您沒有 Kubernetes 叢集,您可以本地設定(例如使用如下的 kind)或在 Google 或 AWS Cloud 中部署一個。
$ kind create cluster --config=- <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: ambient
nodes:
- role: control-plane
- role: worker
- role: worker
EOF

ambient 設定檔旨在幫助您開始使用環境網格。使用上面下載的 istioctl,在您的 Kubernetes 叢集上安裝具有 ambient 設定檔的 Istio。

$ istioctl install --set profile=ambient

執行上述命令後,您將獲得以下輸出,表明這四個組件已成功安裝!

✔ Istio core installed
✔ Istiod installed
✔ Ingress gateways installed
✔ CNI installed
✔ Installation complete

預設情況下,環境設定檔啟用了 Istio 核心、Istiod、ingress 閘道、零信任隧道代理(ztunnel)和 CNI 外掛程式。Istio CNI 外掛程式負責偵測哪些應用程式 Pod 是環境網格的一部分,並配置 ztunnel 之間的流量重新導向。您會注意到以下 Pod 安裝在具有預設環境設定檔的 istio-system 命名空間中

$ kubectl get pod -n istio-system
NAME                                    READY   STATUS    RESTARTS   AGE
istio-cni-node-97p9l                    1/1     Running   0          29s
istio-cni-node-rtnvr                    1/1     Running   0          29s
istio-cni-node-vkqzv                    1/1     Running   0          29s
istio-ingressgateway-5dc9759c74-xlp2j   1/1     Running   0          29s
istiod-64f6d7db7c-dq8lt                 1/1     Running   0          47s
ztunnel-bq6w2                           1/1     Running   0          47s
ztunnel-tcn4m                           1/1     Running   0          47s
ztunnel-tm9zl                           1/1     Running   0          47s

istio-cni 和 ztunnel 組件部署為 Kubernetes DaemonSets,它們在每個節點上執行。每個 Istio CNI Pod 都會檢查與其在同一個節點上的所有 Pod,以查看這些 Pod 是否為環境網格的一部分。對於這些 Pod,CNI 外掛程式會配置流量重新導向,以便所有進出 Pod 的流量首先重新導向到位於同一位置的 ztunnel。當新的 Pod 在節點上部署或移除時,CNI 外掛程式會繼續監控並相應地更新重新導向邏輯。

部署您的應用程式

您將使用範例bookinfo 應用程式,它是您先前步驟中 Istio 下載的一部分。在環境模式下,您可以像沒有 Istio 一樣將應用程式部署到 Kubernetes 叢集中。這表示您可以在啟用環境網格之前讓應用程式在 Kubernetes 中執行,並讓它們加入網格而無需重新啟動或重新配置您的應用程式。

$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
$ kubectl apply -f https://raw.githubusercontent.com/linsun/sample-apps/main/sleep/sleep.yaml
$ kubectl apply -f https://raw.githubusercontent.com/linsun/sample-apps/main/sleep/notsleep.yaml
Applications not in the ambient mesh with plain text traffic
未在環境網格中的應用程式,使用純文字流量

注意:sleepnotsleep 是兩個簡單的應用程式,可以作為 curl 用戶端。

productpage 連接到 Istio ingress 閘道,以便您可以從叢集外部存取 bookinfo 應用程式

$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

測試您的 bookinfo 應用程式,無論是否有閘道,它都應該可以正常運作。注意:您可以將下面的 istio-ingressgateway.istio-system 替換為其負載平衡器的 IP 位址(或主機名稱),如果有的話

$ kubectl exec deploy/sleep -- curl -s http://istio-ingressgateway.istio-system/productpage | head -n1
$ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | head -n1
$ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | head -n1

將您的應用程式新增至環境網格

您可以透過簡單地標記命名空間,來啟用給定命名空間中的所有 Pod 成為環境網格的一部分

$ kubectl label namespace default istio.io/dataplane-mode=ambient

恭喜!您已成功將預設命名空間中的所有 Pod 新增至環境網格。最棒的是,無需重新啟動或重新部署任何內容!

傳送一些測試流量

$ kubectl exec deploy/sleep -- curl -s http://istio-ingressgateway.istio-system/productpage | head -n1
$ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | head -n1
$ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | head -n1

您將立即在環境網格中的應用程式之間獲得 mTLS 通訊。

Inbound requests from sleep to `productpage` and from `productpage` to reviews with secure overlay layer
從 sleep 到 `productpage` 以及從 `productpage` 到 reviews 的入站請求,具有安全覆蓋層

如果您對每個身分識別的 X.509 憑證感到好奇,您可以透過逐步執行憑證來了解更多資訊

$ istioctl pc secret ds/ztunnel -n istio-system -o json | jq -r '.dynamicActiveSecrets[0].secret.tlsCertificate.certificateChain.inlineBytes' | base64 --decode | openssl x509 -noout -text -in /dev/stdin

例如,輸出會顯示 sleep 主體有效的憑證,有效時間為 24 小時,由本機 Kubernetes 叢集頒發。

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 307564724378612391645160879542592778778 (0xe762cfae32a3b8e3e50cb9abad32b21a)
    Signature Algorithm: SHA256-RSA
        Issuer: O=cluster.local
        Validity
            Not Before: Aug 29 21:00:14 2022 UTC
            Not After : Aug 30 21:02:14 2022 UTC
        Subject:
        Subject Public Key Info:
            Public Key Algorithm: RSA
                Public-Key: (2048 bit)
                Modulus:
                    ac:db:1a:77:72:8a:99:28:4a:0c:7e:43:fa:ff:35:
                    75:aa:88:4b:80:4f:86:ca:69:59:1c:b5:16:7b:71:
                    dd:74:57:e2:bc:cf:ed:29:7d:7b:fa:a2:c9:06:e6:
                    d6:41:43:2a:3c:2c:18:8e:e8:17:f6:82:7a:64:5f:
                    c4:8a:a4:cd:f1:4a:9c:3f:e0:cc:c5:d5:79:49:37:
                    30:10:1b:97:94:2c:b7:1b:ed:a2:62:d9:3b:cd:3b:
                    12:c9:b2:6c:3c:2c:ac:54:5b:a7:79:97:fb:55:89:
                    ca:08:0e:2e:2a:b8:d2:e0:3b:df:b2:21:99:06:1b:
                    60:0d:e8:9d:91:dc:93:2f:7c:27:af:3e:fc:42:99:
                    69:03:9c:05:0b:c2:11:25:1f:71:f0:8a:b1:da:4a:
                    da:11:7c:b4:14:df:6e:75:38:55:29:53:63:f5:56:
                    15:d9:6f:e6:eb:be:61:e4:ce:4b:2a:f9:cb:a6:7f:
                    84:b7:4c:e4:39:c1:4b:1b:d4:4c:70:ac:98:95:fe:
                    3e:ea:5a:2c:6c:12:7d:4e:24:ab:dc:0e:8f:bc:88:
                    02:f2:66:c9:12:f0:f7:9e:23:c9:e2:4d:87:75:b8:
                    17:97:3c:96:83:84:3f:d1:02:6d:1c:17:1a:43:ce:
                    68:e2:f3:d7:dd:9e:a6:7d:d3:12:aa:f5:62:91:d9:
                    8d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                Server Authentication, Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Authority Key Identifier:
                keyid:93:49:C1:B8:AB:BF:0F:7D:44:69:5A:C3:2A:7A:3C:79:19:BE:6A:B7
            X509v3 Subject Alternative Name: critical
                URI:spiffe://cluster.local/ns/default/sa/sleep

注意:如果您沒有任何輸出,可能表示 ds/ztunnel 已選擇一個不管理任何憑證的節點。您可以指定一個特定的 ztunnel Pod(例如 istioctl pc secret ztunnel-tcn4m -n istio-system),它管理其中一個範例應用程式 Pod。

保護應用程式存取

在您將應用程式新增至環境網格後,您可以使用 L4 授權原則來保護應用程式存取。這可讓您根據用戶端工作負載身分識別控制對服務的存取,但不能在 L7 層級(例如 HTTP 方法,如 GETPOST)。

L4 授權原則

明確允許 sleep 服務帳戶和 istio-ingressgateway 服務帳戶呼叫 productpage 服務

$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: productpage-viewer
 namespace: default
spec:
 selector:
   matchLabels:
     app: productpage
 action: ALLOW
 rules:
 - from:
   - source:
       principals: ["cluster.local/ns/default/sa/sleep", "cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"]
EOF

確認上述授權原則有效

$ # this should succeed
$ kubectl exec deploy/sleep -- curl -s http://istio-ingressgateway.istio-system/productpage | head -n1
$ # this should succeed
$ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | head -n1
$ # this should fail with an empty reply
$ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | head -n1

第 7 層授權原則

使用 Kubernetes Gateway API,您可以為使用 bookinfo-productpage 服務帳戶的 productpage 服務部署一個航點代理。任何前往 productpage 服務的流量都將由第 7 層 (L7) 代理仲介、強制執行和觀察。

$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
 name: productpage
 annotations:
   istio.io/service-account: bookinfo-productpage
spec:
 gatewayClassName: istio-mesh
EOF

請注意,航點代理的 gatewayClassName 必須為 istio-mesh

檢視 productpage 航點代理的狀態;您應該會看到閘道資源的詳細資訊,其狀態為 Ready

$ kubectl get gateway productpage -o yaml
...
status:
  conditions:
  - lastTransitionTime: "2022-09-06T20:24:41Z"
    message: Deployed waypoint proxy to "default" namespace for "bookinfo-productpage"
      service account
    observedGeneration: 1
    reason: Ready
    status: "True"
    type: Ready

更新我們的 AuthorizationPolicy,以明確允許 sleep 服務帳戶和 istio-ingressgateway 服務帳戶 GET productpage 服務,但不要執行其他任何操作

$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: productpage-viewer
 namespace: default
spec:
 selector:
   matchLabels:
     app: productpage
 action: ALLOW
 rules:
 - from:
   - source:
       principals: ["cluster.local/ns/default/sa/sleep", "cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"]
   to:
   - operation:
       methods: ["GET"]
EOF

確認上述授權原則有效

$ # this should fail with an RBAC error because it is not a GET operation
$ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ -X DELETE | head -n1
$ # this should fail with an RBAC error because the identity is not allowed
$ kubectl exec deploy/notsleep -- curl -s http://productpage:9080/  | head -n1
$ # this should continue to work
$ kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | head -n1
Inbound requests from sleep to `productpage` and from `productpage` to reviews with secure overlay and L7 processing layers
從 sleep 到 `productpage` 以及從 `productpage` 到 reviews 的入站請求,具有安全覆蓋和 L7 處理層

部署了 productpage 航點代理後,您還將自動獲得對 productpage 服務的所有請求的 L7 指標

$ kubectl exec deploy/bookinfo-productpage-waypoint-proxy -- curl -s https://#:15020/stats/prometheus | grep istio_requests_total

您會注意到指標包含 response_code=403 和一些 response_code=200 的指標,如下所示

istio_requests_total{
  response_code="403",
  source_workload="notsleep",
  source_workload_namespace="default",
  source_principal="spiffe://cluster.local/ns/default/sa/notsleep",
  destination_workload="productpage-v1",
  destination_principal="spiffe://cluster.local/ns/default/sa/bookinfo-productpage",
  connection_security_policy="mutual_tls",
  ...
}

指標顯示當來源工作負載 (notsleep) 透過相互 TLS 連線呼叫目標工作負載 (productpage-v1) 以及來源和目標主體時,會有兩個 403 回應。

控制流量

使用 bookinfo-review 服務帳戶為 review 服務部署航點代理,以便任何前往 review 服務的流量都將由航點代理仲介。

$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
 name: reviews
 annotations:
   istio.io/service-account: bookinfo-reviews
spec:
 gatewayClassName: istio-mesh
EOF

套用 reviews 虛擬服務以控制 90% 的流量至 reviews v1 和 10% 的流量至 reviews v2。

$ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-90-10.yaml
$ kubectl apply -f samples/bookinfo/networking/destination-rule-reviews.yaml

確認大約 10% 的流量(來自 100 個請求)前往 reviews-v2

$ kubectl exec -it deploy/sleep -- sh -c 'for i in $(seq 1 100); do curl -s http://istio-ingressgateway.istio-system/productpage | grep reviews-v.-; done'

總結

現有的 Istio 資源將繼續運作,無論您選擇使用 sidecar 或環境資料平面模式。

觀看短片,了解 Lin 如何在 5 分鐘內完成 Istio 環境網格示範

下一步

我們對新的 Istio 環境資料平面及其簡單的「環境」架構感到非常興奮。使用環境模式將您的應用程式導入服務網格現在就像標記命名空間一樣簡單。您的應用程式將立即獲得諸如 mTLS 和網格流量的加密身分識別以及 L4 可觀察性等好處。如果您需要控制環境網格中應用程式之間的存取或路由、提高復原能力或獲得 L7 指標,您可以根據需要將航點代理套用至您的應用程式。我們非常喜歡只為我們需要的東西付費,因為它不僅節省資源,還可以節省不斷更新許多代理的操作成本!我們邀請您試用新的 Istio 環境資料平面架構,以體驗它有多簡單。我們期待您在 Istio 社群中的回饋

分享這篇文章