Istioアンビエントメッシュを始める

Istioアンビエントメッシュを始めるためのステップバイステップガイド。

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

アンビエントメッシュは本日発表されたIstioの新しいデータプレーンモードです。この入門ガイドに従うことで、アンビエントメッシュがアプリケーションのオンボーディングをどのように簡素化し、継続的な運用を支援し、サービスメッシュのインフラリソースの使用量を削減できるかを体験できます。

アンビエントモードでIstioをインストール

  1. アンビエントメッシュをサポートするIstioのプレビュー版をダウンロードします。
  2. サポートされている環境を確認してください。2つ以上のノードがあるバージョン1.21以降のKubernetesクラスターを使用することをお勧めします。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

上記のコマンドを実行すると、次の4つのコンポーネントが正常にインストールされたことを示す出力が得られます。

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

デフォルトでは、ambientプロファイルでは、Istioコア、Istiod、イングレスゲートウェイ、ゼロトラストトンネルエージェント(ztunnel)、およびCNIプラグインが有効になっています。Istio CNIプラグインは、アンビエントメッシュの一部であるアプリケーションポッドを検出し、ztunnel間のトラフィックリダイレクトを構成する役割を担います。デフォルトのアンビエントプロファイルで、次のポッドが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ポッドは、同じノードに併置されたすべてのポッドをチェックして、これらのポッドがアンビエントメッシュの一部であるかどうかを確認します。これらのポッドの場合、CNIプラグインはトラフィックリダイレクトを構成し、ポッドへのすべての着信および発信トラフィックが最初に併置されたztunnelにリダイレクトされるようにします。ノードで新しいポッドがデプロイまたは削除されると、CNIプラグインは引き続き監視し、それに応じてリダイレクトロジックを更新します。

アプリケーションをデプロイ

前のステップでIstioダウンロードの一部であるサンプルbookinfoアプリケーションを使用します。アンビエントモードでは、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クライアントとして機能できる2つの単純なアプリケーションです。

クラスターの外部からbookinfoアプリにアクセスできるように、productpageをIstioイングレスゲートウェイに接続します

$ 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

アプリケーションをアンビエントメッシュに追加

名前空間にラベルを付けるだけで、指定された名前空間内のすべてのポッドをアンビエントメッシュの一部にすることができます

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

おめでとうございます!デフォルトの名前空間内のすべてのポッドをアンビエントメッシュに正常に追加しました。最も良い点は、何も再起動または再デプロイする必要がないことです!

テストトラフィックを送信

$ 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へのインバウンドリクエスト

各IDの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

たとえば、出力には、ローカルKubernetesクラスターによって発行され、24時間有効なsleepプリンシパルの証明書が表示されます。

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ポッド(例:istioctl pc secret ztunnel-tcn4m -n istio-system)を指定できます。

セキュアなアプリケーションアクセス

アプリケーションをアンビエントメッシュに追加した後、L4認証ポリシーを使用してアプリケーションアクセスを保護できます。これにより、クライアントワークロードIDに基づいてサービスへのアクセスを制御できますが、GETPOSTなどのHTTPメソッドのようなL7レベルでは制御できません。

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

注:ウェイポイントプロキシの場合、gatewayClassNameistio-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

sleepサービスアカウントとistio-ingressgatewayサービスアカウントがproductpageサービスをGETすることを明示的に許可するようにAuthorizationPolicyを更新しますが、他の操作は実行しません

$ 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
セキュアオーバーレイおよびL7処理レイヤーを使用した、sleepから`productpage`へ、および`productpage`からreviewsへのインバウンドリクエスト

productpageウェイポイントプロキシがデプロイされると、productpageサービスへのすべてのリクエストに対してL7メトリクスも自動的に取得されます

$ kubectl exec deploy/bookinfo-productpage-waypoint-proxy -- curl -s http://localhost: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)が宛先ワークロード(productpage-v1)を相互TLS接続を介してソースプリンシパルと宛先プリンシパルと共に呼び出すときに、2つの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仮想サービスを適用して、レビューv1へのトラフィックの90%とレビューv2へのトラフィックの10%を制御します。

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

100のリクエストからのトラフィックの約10%が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リソースは引き続き機能します。

短いビデオを見て、LinがIstioアンビエントメッシュデモを5分で実行する様子をご覧ください

次は何ですか

シンプルな「アンビエント」アーキテクチャを備えた新しいIstioアンビエントデータプレーンに非常に興奮しています。アンビエントモードでのサービスメッシュへのアプリケーションのオンボーディングは、名前空間にラベルを付けるのと同じくらい簡単になりました。アプリケーションは、メッシュトラフィックの暗号化IDを備えたmTLSやL4の可観測性などの即時のメリットが得られます。アンビエントメッシュ内のアプリケーション間でアクセスやルートを制御したり、回復力を高めたり、L7メトリクスを取得したりする必要がある場合は、必要に応じてウェイポイントプロキシをアプリケーションに適用できます。リソースを節約するだけでなく、多くのプロキシを常に更新する運用コストも節約できるため、必要なものだけを支払うことを強く推奨します。新しいIstioアンビエントデータプレーンアーキテクチャを試して、そのシンプルさを体験してください。Istioコミュニティでフィードバックをお待ちしています!

この投稿を共有