スタンドアロン・プログラムとしてのIstioの作業
Kubernetes Engine (OKE)で作成したクラスタにスタンドアロン・プログラムとしてIstioをインストールする方法をご紹介します。
このトピックでは、Kubernetes Engine (OKE)で作成したクラスタにスタンドアロン・プログラムとしてIstioをインストールする方法の例を示します。また、OKEとIstioの主な特徴を示した。
次のトピックが含まれています。
サービス・メッシュ製品(Oracle Cloud Infrastructure Service Mesh、Istio、Linkerdなど)は、ポッド・ネットワーキングにOCI VCNネイティブ・ポッド・ネットワーキングCNIプラグインを使用するときにサポートされます。Istioアドオンを除き、現在サポートはOracle Linux 7に制限されています(Oracle Linux 8のサポートが計画されています)。Istioアドオンは、Oracle Linux 7とOracle Linux 8の両方でサポートされています。ワーカー・ノードは、Kubernetes 1.26 (以降)を実行している必要があります。
Istioは、管理対象ノード・プールで使用できますが、仮想ノード・プールでは使用できません。
スタンドアロン・プログラムとしてのIstioのインストール
Istioの使用を開始するには、OKEクラスタを作成するか、既存のOKEクラスタを使用してから、Istioをインストールします。次の項では、Istio設定をインストールおよびテストするステップについて説明します。インストール・オプションの詳細は、ここを参照してください。
OKEクラスタの作成
OKEクラスタを作成します。
- まだ作成していない場合は、OCIテナンシ内にOKEクラスタを作成します。OKEクラスタの作成には、複数のオプションを使用できます。最も簡単なオプションは、Webコンソールの「クイック作成」ウィザードです。
- ローカル・マシン上のOKEクラスタにアクセスするには、kubectlおよびoci-cliをインストールします。
kubectl
を使用してコマンドラインからOKEクラスタにアクセスするには、kubeconfig
ファイルを設定し、kubectl
がクラスタにアクセスできることを確認します。
コマンドラインからのIstioのダウンロード
コマンドラインからIstioをダウンロードするには、次のステップに従います。
- 次のコマンドを実行してIstioをダウンロードします。
curl -L https://istio.io/downloadIstio | sh -
- Istioパッケージのディレクトリに移動します。たとえば、パッケージがistio-1.1.11.2の場合:
cd istio-1.11.2
istioctl
クライアント・ツールをワークステーションのPATH
に追加します。export PATH=$PWD/bin:$PATH
- 事前チェックを実行して、クラスタがIstioインストール要件を満たしているかどうかを検証します。
istioctl x precheck
istioctlによるIstioのインストール
istioctl
を使用してIstioをインストールします。
istioctl install
Bookinfoアプリケーションの実行
Istioプロジェクトは、Istioの機能を実証する方法としてBookinfoアプリケーションを提供します。オンライン・ブック・ストアの単一のカタログ・エントリと同様に、ブックに関する情報が表示されます。各ブック・ページには、ブックの説明、ブックの詳細(ISBN、ページ数)、およびいくつかのブック・レビューが含まれます。Bookinfoアプリケーションの詳細は、Bookinfoのドキュメントを参照してください。
図に示すように、Bookinfoアプリケーションは4つのマイクロサービスで構成されています。
- 製品ページ・サービス: 「詳細」および「レビュー」サービスをコールして、製品ページを作成します。
- 詳細サービス:ブック情報を返します。
- レビュー・サービス:ブック・レビューを返し、評価サービスをコールします。
- 評価サービス:ブックレビューのランキング情報を返します。
Bookinfoアプリケーションをインストールして実行するには、次のステップに従います。
- アプリケーションをホストするネームスペースに
istio-injection=enabled
でラベルを付けます。kubectl label namespace default istio-injection=enabled
- サンプルBookinfoアプリケーションをデプロイします。
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
- すべてのサービスおよびポッドが実行されていることを確認します。
kubectl get services kubectl get pods
- ポッドからcurlコマンドを送信して、アプリケーションが実行中であることを確認します。
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
- クラスタの外部からアプリケーションにアクセスできるようにします。
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
- アプリケーションがゲートウェイを使用していることを確認します。これらの手順を使用して、
INGRESS_HOST
およびINGRESS_PORT
を決定します。curl -s "http://${INGRESS_HOST}:${INGRESS_PORT}/productpage" | grep -o "<title>.*</title>"
また、ブラウザでURL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage
を開いて、Bookinfo Webページを表示します。ページを何度かリフレッシュすると、製品ページに表示される様々なバージョンのレビューが表示されます。
Istio統合アプリケーションの追加
Istioは、一般的なKubernetes関連アプリケーションとよく統合されています。
プロメテウス
Istioは、Prometheusを迅速に起動して実行するための基本的なサンプル・インストールを提供します。
kubectl apply -f samples/addons/prometheus.yaml
または、prometheusをインストールし、Istioメトリックをスクレイプするように構成します。
Prometheusを使用した本番規模のモニタリングについては、「本番規模のモニタリングでのPrometheusの使用」を参照してください。
Grafana
Istioは、Grafanaを迅速に起動して実行するための基本的なサンプル・インストールを提供します。すべてのIstioダッシュボードがインストールに含まれています。
kubectl apply -f samples/addons/grafana.yaml
または、Grafanaを別途インストールします。さらに、Istioの事前構成済ダッシュボードをインポートできます。
Jaeger
Istioは、Jaegerをすばやく起動して実行するための基本的なサンプル・インストールを提供します。
kubectl apply -f samples/addons/jaeger.yaml
または、Jaegerを個別にインストールし、Jaegerデプロイメントにトレースを送信するためにIstioを構成します。
ジプキン
Istioは、zipkinをすばやく起動して実行するための基本的なサンプル・インストールを提供します。
kubectl apply -f samples/addons/extras/zipkin.yaml
または、zipkinを個別にインストールし、Istioを構成してトレースをzipkinデプロイメントに送信します。
キアリ
Istioは、Kialiを迅速に起動して実行するための基本的なサンプルインストールを提供します。
kubectl apply -f samples/addons/kiali.yaml
または、Kialiを別途インストールおよび構成します。
Istio監視の確認
この項では、Istio統合アプリケーションによって提供されるパフォーマンス・メトリックおよびトレース機能を確認します。
PrometheusからのBookinfoアプリケーションのメトリックの問合せ
PrometheusとIstioでは、Bookinfoのパフォーマンス・データをいくつかの方法で分析します。
まず、Prometheusがインストールされていることを確認します。
kubectl -n istio-system get svc prometheus
次のコマンドを使用してPrometheus UIを起動します。
istioctl dashboard prometheus
ヘッダーのPrometheusの右側にある「Graph(グラフ)」をクリックします。一部のデータを表示するには、ブラウザまたはcurl
を使用して製品ページのトラフィックを生成します。トラフィックはPrometheusダッシュボードに反映されます。
- 結果を表示するには、ここでの手順に従ってください。
- Prometheusの問合せの詳細は、Istioのドキュメントの問合せを参照してください。
Grafanaを使用したBookinfoアプリケーションのメトリックのビジュアル化
PrometheusとGrafanaを組み合せると、アプリケーションに適したパフォーマンス・ダッシュボードが提供されます。ダッシュボードを使用するには、まずPrometheusとGrafanaの両方がインストールされていることを確認します。
kubectl -n istio-system get svc prometheus
kubectl -n istio-system get svc grafana
Istio Grafanaダッシュボードを起動します。
istioctl dashboard grafana
Grafanaダッシュボードの管理
Istioサービス・メッシュは、6つのGrafanaダッシュボードを提供します。Istioサービス・メッシュGrafanaダッシュボードのスナップショットがここで取得されます。
ブラウザまたは
curl
を使用して製品ページへのトラフィックを生成し、Grafanaダッシュボードに反映されるようにします。Istioメッシュダッシュボード
Istioサービス・ダッシュボード
Istioワークロード・ダッシュボード
Istioパフォーマンス・ダッシュボード
Istioコントロール・ペイン・ダッシュボード
ダッシュボードの作成、構成および編集方法の詳細は、Grafanaのドキュメントを参照してください。
Jaegerを使用した分散トレースの実行
Jaegerオープン・ソース・フレームワークを使用して、Istioでアプリケーション・トレースを実行します。
istioctl
を使用してトレースを有効化および構成します。istioctl install --set meshConfig.enableTracing=true
- Bookinfoアプリケーションがデプロイされた状態で、
istioctl
を使用してJaeger UIを開きます。istioctl dashboard jaeger
- トレースを生成するには、プロダクト・ページにリクエストを送信します。
for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done
トレースがJaegerダッシュボードに反映されていることがわかります。
Jaegerダッシュボード
Jaegerアプリケーション・トレース
zipkinを使用した分散トレースの実行
zipkinオープン・ソース・フレームワークを使用して、Istioでアプリケーション・トレースを実行します。
istioctl
を使用してトレースを有効化および構成します。istioctl install --set meshConfig.enableTracing=true
- Bookinfoアプリケーションがデプロイされた状態で、
istioctl
を使用してzipkin UIを開きます。istioctl dashboard zipkin
- トレースを生成するには、プロダクト・ページにリクエストを送信します。
for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done
トレースがzipkinダッシュボードに反映されていることがわかります。
サンプルzipkinダッシュボード
OCI Application Performance Monitoringを使用した分散トレースの実行
OCI Application Performance Monitoring (APM)は、Jaegerやzipkinなどのオープン・ソース・トレース・システム・ツールと統合されます。APMでは、OCIでトレース・データをアップロードできます。OCI APMと統合するには、ここに記載されている手順に従ってAPMドメインを作成します。APMドメインは、APMによってモニターされるシステムを含むOCIリソースです。
ドメインの作成後、ドメインの詳細を表示し、データ・アップロード・エンドポイントの取得、秘密キーおよび公開キーを使用してAPMコレクタURLを構成します。APMコレクタURLは、APMサービスと通信するようにオープン・ソース・トレーサを構成するときに必要です。コレクタURL形式では、データ・アップロード・エンドポイントをベースURLとして使用して構築されたURLが必要であり、秘密キーまたは公開キーの値を含む選択肢に基づいてパスが生成されます。形式はここに記載されています。URLパスを構成して、そのURLをIstio構成に接続します。
APMにトレースを送信するためのIstioの構成
istioctl
を使用してトレースを有効にします。istioctl install --set meshConfig.defaultConfig.tracing.zipkin.address=aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com:443
ノート
aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com
のエンドポイント・アドレスは例であり、実際のエンドポイントではありません。- Envoyを構成して、APMにzipkinトレースを送信します。
samples/custom-bootstrap/custom-bootstrap.yaml
のコードを次のコード・ブロックに置き換えます。apiVersion: v1 kind: ConfigMap metadata: name: istio-custom-bootstrap-config namespace: default data: custom_bootstrap.json: | { "tracing": { "http": { "name": "envoy.tracers.zipkin", "typed_config": { "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig", "collector_cluster": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain] "collector_endpoint": "/20200101/observations/private-span?dataFormat=zipkin&dataFormatVersion=2&dataKey=2C6YOLQSUZ5Q7IGN", // [Replace with the private datakey of your apm domain. You can also use public datakey but change the observation type to public-span] "collectorEndpointVersion": "HTTP_JSON", "trace_id_128bit": true, "shared_span_context": false } } }, "static_resources": { "clusters": [{ "name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain:443] "type": "STRICT_DNS", "lb_policy": "ROUND_ROBIN", "load_assignment": { "cluster_name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain] "endpoints": [{ "lb_endpoints": [{ "endpoint": { "address": { "socket_address": { "address": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain] "port_value": 443 } } } }] }] }, "transport_socket": { "name": "envoy.transport_sockets.tls", "typed_config": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "sni": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com" // [Replace this with data upload endpoint of your apm domain] } } }] } } EOF
- カスタム構成を適用します。
kubectl apply -f samples/custom-bootstrap/custom-bootstrap.yaml
- Bookinfoのすべてのサービスでこのカスタム・ブートストラップ構成を使用するには、値としてカスタムConfigMapの名前を持つ注釈
sidecar.istio.io/bootstrapOverride
を追加します。次の例では、製品ページの注釈がsamples/bookinfo/platform/kube/bookinfo.yaml
の下に追加されます。同様の注釈を他のサービスに追加します。apiVersion: apps/v1 kind: Deployment metadata: name: productpage-v1 labels: app: productpage version: v1 spec: replicas: 1 selector: matchLabels: app: productpage version: v1 template: metadata: labels: app: productpage version: v1 annotations: sidecar.istio.io/bootstrapOverride: "istio-custom-bootstrap-config" #[Name of custom configmap] spec: serviceAccountName: bookinfo-productpage containers: - name: productpage image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2 imagePullPolicy: IfNotPresent ports: - containerPort: 9080 volumeMounts: - name: tmp mountPath: /tmp securityContext: runAsUser: 1000 volumes: - name: tmp emptyDir: {} ---
- yamlを適用すると、再起動されたすべてのポッドがAPMへのトレースの送信を開始します。
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
- イングレス・ゲートウェイがトレースを送信できるようにするには、istio-systemネームスペースに
custom-bootstrap.yaml
という名前のconfigmap
を作成します:apiVersion: v1 kind: ConfigMap metadata: name: istio-custom-bootstrap-config namespace: istio-system data: custom_bootstrap.json: | { "tracing": { "http": { "name": "envoy.tracers.zipkin", "typed_config": { "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig", "collector_cluster": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain] "collector_endpoint": "/20200101/observations/private-span?dataFormat=zipkin&dataFormatVersion=2&dataKey=2C6YOLQSUZ5Q7IGN", // [Replace with the private datakey of your apm domain. You can also use public datakey but change the observation type to public-span] "collectorEndpointVersion": "HTTP_JSON", "trace_id_128bit": true, "shared_span_context": false } } }, "static_resources": { "clusters": [{ "name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain:443] "type": "STRICT_DNS", "lb_policy": "ROUND_ROBIN", "load_assignment": { "cluster_name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain] "endpoints": [{ "lb_endpoints": [{ "endpoint": { "address": { "socket_address": { "address": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain] "port_value": 443 } } } }] }] }, "transport_socket": { "name": "envoy.transport_sockets.tls", "typed_config": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "sni": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com" // [Replace this with data upload endpoint of your apm domain] } } }] } } EOF
- カスタム・ブートストラップ構成の使用を開始するイングレス・ゲートウェイ用の
gateway-patch.yaml
という名前のパッチを作成します:spec: template: spec: containers: - name: istio-proxy env: - name: ISTIO_BOOTSTRAP_OVERRIDE value: /etc/istio/custom-bootstrap/custom_bootstrap.json volumeMounts: - mountPath: /etc/istio/custom-bootstrap name: custom-bootstrap-volume readOnly: true volumes: - configMap: name: istio-custom-bootstrap-config defaultMode: 420 optional: false name: custom-bootstrap-volume
- イングレス・ゲートウェイに以前のパッチを適用します:
kubectl --namespace istio-system patch deployment istio-ingressgateway --patch "$(cat gateway-patch.yaml)"
- トレースを生成するには、プロダクト・ページにリクエストを送信します。
for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done
トレースは、ここのステップに従ってAPMダッシュボードに反映されます。
Zipkinトレース・エクスプローラ
ジプキントレース
ジプキンスパン
スパンを表示するには、APMリストの「ホーム」をクリックします。
Zipkinアプリ・ダッシュボード
APMには、ダッシュボードを作成し、時間の経過とともに生成されたスパンを調べる機能があります。ダッシュボードは、ここのステップに従って作成できます。
Zipkinメトリック・エクスプローラ
APMでは、メトリック、アラームおよび通知を使用して、アプリケーションのヘルス、容量およびパフォーマンスをモニターできます。メトリックを構成するには、ここのステップに従います。
OCIロギングを使用したログの監視
OCI Loggingは、OCIのテナンシのログ・ファイル・エントリを分析および検索するための中央コンポーネントです。OKEワーカー・ノードからのKubernetesコンテナ・ログは、カスタム・ログとしてOCIロギングに公開できます。コンテナ・ログを取り込むには、ここで説明するステップに従ってOCIロギングを構成します。
istioctl
を使用して、Istioでのenvoyアクセス・ロギングを有効にします。istioctl install --set meshConfig.accessLogFile=/dev/stdout
- ブラウザまたはcurlを使用して、Bookinfo製品ページにアクセスします。生成されたアクセス・ログは、
kubectl
コマンドを使用して表示できます。kubectl logs -l app=productpage -c istio-proxy
クラスタにOCIロギングが構成されている場合は、OCIコンソールのログ検索ページを使用して、これらのログを問い合せて分析できます。
OCIロギング検索
OCIロギング検索の拡張
Kialiを使用したメッシュの視覚化
Kialiがインストールされていることを確認します。
kubectl -n istio-system get svc kiali
ブラウザでKiali UIを開きます。
istioctl dashboard kiali
製品ページにトラフィックを送信します。
for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done
ここからステップ5に従って、Kialiでメッシュを視覚化します。
トラフィックの管理
Istioのトラフィック・ルーティング・ルールにより、サービス間のトラフィックのフローを制御し、サーキット・ブレーカ、タイムアウト、再試行などのサービス・レベルのプロパティの構成を簡素化できます。Istioを使用すると、A/Bテスト、カナリア・ロールアウト、ステージ・ロールアウトなどの重要なタスクを、パーセンテージ・ベースのトラフィック分割で簡単に設定できます。
Istioのトラフィック管理APIリソース:
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
シフト・トラフィック
Istioでは、Istioの重み付けされたルーティング機能を使用して、トラフィックをあるバージョンのマイクロサービスから別のバージョンに段階的に移行できます。次の例は、トラフィックの50%をreviews:v1
に送信し、50%をreviews:v3
に送信するように構成する方法を示しています。その後、トラフィックの100%をreviews:v3
に送信して移行を完了します。
- すべてのトラフィックを各マイクロサービスのv1バージョンにルーティングします。
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
Bookinfo Webページを表示するには、ブラウザでURL
http://${INGRESS_HOST}:${INGRESS_PORT}/productpage
を開きます。リフレッシュの回数に関係なく、ページのレビュー部分は星の評価なしで表示されます。Istioは、レビュー・サービスのすべてのトラフィックをreviews:v1
にルーティングするように構成されており、このバージョンのサービスはスター評価サービスにアクセスしません。 - 次のコマンドを使用して、トラフィックの50%を
reviews:v1
からreviews:v3
に転送し、新しいルールが伝播されるまで待機します。kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml
ブラウザの
/productpage
URLをリフレッシュし、約50%の赤色の星評価を確認します。reviews:v3
は星評価サービスにアクセスしますが、reviews:v1
バージョンはアクセスしません。 - トラフィックの100%を
reviews:v3
にルーティングします。kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml
- ブラウザの
/productpage
URLをリフレッシュし、レビューごとに赤色の星評価を常に表示します。
リクエスト・ルーティングの管理
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
Bookinfo Webページを表示するには、ブラウザでURL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage
を開きます。リフレッシュの回数に関係なく、ページのレビュー部分は星の評価なしで表示されます。Istioは、レビュー・サービスのすべてのトラフィックをバージョンreviews:v1
にルーティングするように構成されているためです。このバージョンのサービスは、星評価サービスにアクセスしません。
ユーザー・アイデンティティに基づくルーティング
ユーザー・アイデンティティに基づいてルーティングするには:
jason
という名前の特定のユーザーからのすべてのトラフィックがreviews:v2
にルーティングされるように、ルート構成を変更します。Istioには、ユーザー・アイデンティティに関する特別な組込みの理解はありません。この例では、productpage
サービスは、レビュー・サービスへのすべてのアウトバウンドHTTPリクエストにカスタム・エンドユーザー・ヘッダーを追加します。kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
Bookinfo Webページを表示し、ユーザー
jason
としてログインするには、ブラウザでURLhttp://${INGRESS_HOST}:${INGRESS_PORT}/productpage
を開きます。ブラウザをリフレッシュして、各レビューの横に星評価が表示されます。ブラウザでURL
http://${INGRESS_HOST}:${INGRESS_PORT}/productpage
を開き、Bookinfo Webページを表示し、jason
以外のユーザーとしてログインします。ブラウザをリフレッシュして、レビューごとに星を表示しません。
URLリライトに基づくルーティング
この例では、/products
または/bookinfoproductpage
で始まるパスを持つHTTPリクエストは、/productpage
にリライトされます。HTTPリクエストは、ポート9080で実行されているproductpage
を使用してポッドに送信されます。Istio URLのリライトの詳細は、ここを参照。
- 次のyamlを適用します。
kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: bookinfo spec: hosts: - "*" gateways: - bookinfo-gateway http: - match: - uri: prefix: /products - uri: prefix: /bookinfoproductpage rewrite: uri: /productpage route: - destination: host: productpage port: number: 9080 EOF
Bookinfo Webページを表示するには、ブラウザでURL
http://${INGRESS_HOST}:${INGRESS_PORT}/products
およびhttp://${INGRESS_HOST}:${INGRESS_PORT}/bookinfoproductpage
を開きます。どちらの場合も、リクエストを転送する前にリライトが実行されます。リライト/ブック製品ページ
リライト/製品
- yamlファイルをIstioが提供する元のバージョンにクリーンアップし、適用します。
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
URL
http://${INGRESS_HOST}:${INGRESS_PORT}/bookinfoproductpage
またはhttp://${INGRESS_HOST}:${INGRESS_PORT}/products
を開いて、yamlがリクエストをリライトしないため、製品ページを表示しません。404エラー/製品
404エラー/booksproductpage
ネットワークの自己回復性のテスト
Istioでは、リクエスト・タイムアウト、フォルト・インジェクションおよび回路遮断器用にインストールを構成できます。これらの設定により、デプロイされたアプリケーションのフォルト・トレランスを管理およびテストできます。
リクエスト・タイムアウトの設定
タイムアウトは、Envoyプロキシが特定のサービスからの応答を待機する時間です。タイムアウトにより、サービスは応答を無期限に待機せず、予測可能な時間枠内にコールが成功または失敗することを保証します。タイムアウトの詳細は、こちらを参照してください。
HTTPリクエストのタイムアウトは、ルート・ルールのタイムアウト・フィールドを使用して指定できます。デフォルトでは、リクエスト・タイムアウトは無効です。
- 次のコマンドを実行して、アプリケーション・バージョン・ルーティングを初期化します。
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
reviews:v2
サービスにリクエストをルーティングします。実際には、評価サービスをコールするバージョンです。kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v2 EOF
- 評価サービスへのコールに2秒間の遅延を追加します。
kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: ratings spec: hosts: - ratings http: - fault: delay: percent: 100 fixedDelay: 2s route: - destination: host: ratings subset: v1 EOF
- 評価の星が表示されたBookinfo Webページを表示するには、ブラウザでURL
http://${INGRESS_HOST}:${INGRESS_PORT}/productpage
を開きます。ページをリフレッシュすると、2秒間の遅延が発生します。 - レビュー・サービスへのコールの半秒リクエスト・タイムアウトを追加します:
kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v2 timeout: 0.5s EOF
- Bookinfo Webページを表示するには、ブラウザでURL
http://${INGRESS_HOST}:${INGRESS_PORT}/productpage
を開きます。ページが2ではなく約1秒で戻ってきて、レビューが使用できないことに注意してください。
タイムアウトが半秒で構成されていても、レスポンスに1秒かかる理由は、productpage
サービスでハードコードされた再試行が原因です。サービスは、タイムアウトしたレビュー・サービスを2回コールしてから戻ります。
ルート・ルールでオーバーライドする以外に、アプリケーションがアウトバウンド・リクエストにx-envoy-upstream-rq-timeout-ms
ヘッダーを追加する場合、リクエストごとにタイムアウトをオーバーライドすることもできます。
フォルト・インジェクションの管理
障害注入は、システムにエラーを導入して、システムがエラー状態に耐え、エラー状態から回復するようにするテスト方法です。Istioでは、HTTPエラー・コードなどのアプリケーション・レイヤーでのフォルト・インジェクションが可能です。Istioは、2つのタイプのフォルトを注入します。どちらも仮想サービスを使用して構成されます。障害インジェクションの詳細は、ここを参照してください。
- 遅延:遅延とは、ネットワーク・レイテンシの増加またはオーバーロードされたアップストリーム・サービスを模倣するタイミングの失敗です。
- 中断:中断は、アップストリーム・サービスの障害を模倣するクラッシュ障害です。HTTPエラーコードまたはTCP接続の失敗の形式でマニフェストを中止します。
障害インジェクションをテストするには、次のコマンドを実行してアプリケーション・バージョン・ルーティングを初期化します。
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
HTTP遅延フォルトの注入
遅延障害を注入するには、次の手順に従います。
- ユーザー
jason
からのトラフィックを遅延させるフォルト・インジェクション・ルールを作成します。次のコマンドは、reviews:v2
とユーザーjason
の評価マイクロサービスの間に7秒の遅延を注入します。kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
ノート
reviews:v2
サービスには、評価サービスへのコールに対する10秒のハードコードされた接続タイムアウトがあります。7秒の遅延では、エンドツーエンドのフローがエラーなしで続行されることを想定します。 - Bookinfo Webページを表示するには、ブラウザでURL
http://${INGRESS_HOST}:${INGRESS_PORT}/productpage
を開きます。Bookinfoホーム・ページは、約7秒でエラーなしでロードされます。ただし、レビュー・セクションにエラー・メッセージが表示されます: 「申し訳ありません。このマニュアルでは、製品レビューは現在使用できません」。アプリケーション・コードにバグが存在します。
productpage
とreviews
サービス間のハードコードされたタイムアウトにより、6秒の遅延、3秒に1回の再試行が発生します。その結果、reviews
へのproductpage
コールは途中でタイムアウトし、6秒後にエラーがスローされます。バグを修正するには、
productpage
をreviews
サービス・タイムアウトに増やすか、reviews
をratings
タイムアウトに減らして3秒未満にします。 - ユーザー
jason
のratings
サービスに2秒の遅延を追加して、バグを修正します。kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: ratings spec: hosts: - ratings http: - match: - headers: end-user: exact: jason fault: delay: percentage: value: 100.0 fixedDelay: 2s route: - destination: host: ratings subset: v1 - route: - destination: host: ratings subset: v1 EOF
- バグが修正されたら、ブラウザでURL
http://${INGRESS_HOST}:${INGRESS_PORT}/productpage
を開き、Bookinfo Webページを表示します。評価星が表示された状態でjason
としてサインインします。
HTTP中断フォルトの注入
中断フォルトを注入するには、次のステップを実行します。
- ユーザー
jason
のHTTP中断レスポンスを送信するフォルト・インジェクション・ルールを作成します:kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
- Bookinfo Webページを表示するには、ブラウザでURL
http://${INGRESS_HOST}:${INGRESS_PORT}/productpage
を開きます。ユーザーjason
としてログインします。ratings
サービスが使用できないことを示すメッセージが表示されます。ユーザー
jason
からログアウトするか、他のユーザーでログインしてエラー・メッセージを表示しません。
回路遮断器の作成
回路遮断により、障害の影響、遅延スパイク、およびネットワークの特殊性によるその他の望ましくない影響を制限するアプリケーションを記述できます。回路遮断器の詳細は、こちらを参照してください。
- 宛先ルールを作成して、製品サービスを呼び出すときに回路遮断設定を適用します。次のルールは、最大接続数を1つ以下に設定し、最大1つのHTTP保留リクエストを持ちます。また、ルールはホストを1秒ごとにスキャンするように構成します。5XXエラーコードで1回失敗するホストは、3分間イジェクトされます。また、アップストリーム・サービスのロード・バランシング・プール内のホストの100%がイジェクトされます。
kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: productpage spec: host: productpage trafficPolicy: connectionPool: tcp: maxConnections: 1 http: http1MaxPendingRequests: 1 maxRequestsPerConnection: 1 outlierDetection: consecutive5xxErrors: 1 interval: 1s baseEjectionTime: 3m maxEjectionPercent: 100 subsets: - name: v1 labels: version: v1 EOF
- すべてのトラフィックを各マイクロサービスのv1バージョンにルーティングします。
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
- 製品サービスにトラフィックを送信するクライアントを作成します。Fortioでは、送信HTTPコールの接続数、同時実行性および遅延を制御できます。自動サイドカー・インジェクションを有効にした場合は、
fortio
サービスをデプロイします。kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml
または、fortio
アプリケーションをデプロイする前に、サイドカーを手動で注入します。kubectl apply -f <(istioctl kube-inject -f samples/httpbin/sample-client/fortio-deploy.yaml)
- クライアント・ポッドにログインし、
fortio
ツールを使用してproductpage
をコールし、次のコマンドを使用してレスポンス・ステータス・コードが200であることを確認します。export FORTIO_POD=$(kubectl get pods -l app=fortio -o 'jsonpath={.items[0].metadata.name}') kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio curl http://productpage:9080
次の出力が生成されます。HTTP/1.1 200 OK content-type: text/html; charset=utf-8 content-length: 1683 server: envoy date: Tue, 07 Sep 2021 11:01:02 GMT x-envoy-upstream-service-time: 5
- 2つの同時接続(-c 2)でサービスをコールし、20リクエスト(-n 20)を送信します。興味深いことに、16のリクエストパススルーと4が失敗します。
kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://productpage:9080
このコマンドを実行すると、次のような出力が生成されます。11:03:43 I logger.go:127> Log level is now 3 Warning (was 2 Info) Fortio 1.11.3 running at 0 queries per second, 128->128 procs, for 20 calls: http://productpage:9080 Starting at max qps with 2 thread(s) [gomax 128] for exactly 20 calls (10 per thread + 0) 11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) Ended after 51.340006ms : 20 calls. qps=389.56 Aggregated Function Time : count 20 avg 0.0045031997 +/- 0.002036 min 0.000387421 max 0.007704444 sum 0.090063995 # range, mid point, percentile, count >= 0.000387421 <= 0.001 , 0.000693711 , 15.00, 3 > 0.003 <= 0.004 , 0.0035 , 20.00, 1 > 0.004 <= 0.005 , 0.0045 , 65.00, 9 > 0.005 <= 0.006 , 0.0055 , 75.00, 2 > 0.006 <= 0.007 , 0.0065 , 95.00, 4 > 0.007 <= 0.00770444 , 0.00735222 , 100.00, 1 # target 50% 0.00466667 # target 75% 0.006 # target 90% 0.00675 # target 99% 0.00756356 # target 99.9% 0.00769036 Sockets used: 5 (for perfect keepalive, would be 2) Jitter: false Code 200 : 16 (80.0 %) Code 503 : 4 (20.0 %) Response Header Sizes : count 20 avg 133.6 +/- 66.8 min 0 max 167 sum 2672 Response Body/Total Sizes : count 20 avg 1528.2 +/- 643.6 min 241 max 1850 sum 30564 All done 20 calls (plus 0 warmup) 4.503 ms avg, 389.6 qps
- 同時接続数を3に増やします。
kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 3 -qps 0 -n 30 -loglevel Warning http://productpage:9080
リクエストの26.7%のみが成功し、回路が切断されて残りがトラップされます。11:10:19 I logger.go:127> Log level is now 3 Warning (was 2 Info) Fortio 1.11.3 running at 0 queries per second, 128->128 procs, for 30 calls: http://productpage:9080 Starting at max qps with 3 thread(s) [gomax 128] for exactly 30 calls (10 per thread + 0) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) 11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503) Ended after 28.105508ms : 30 calls. qps=1067.4 Aggregated Function Time : count 30 avg 0.0024256753 +/- 0.003264 min 0.000261072 max 0.010510116 sum 0.07277026 # range, mid point, percentile, count >= 0.000261072 <= 0.001 , 0.000630536 , 66.67, 20 > 0.001 <= 0.002 , 0.0015 , 73.33, 2 > 0.005 <= 0.006 , 0.0055 , 76.67, 1 > 0.006 <= 0.007 , 0.0065 , 83.33, 2 > 0.007 <= 0.008 , 0.0075 , 93.33, 3 > 0.009 <= 0.01 , 0.0095 , 96.67, 1 > 0.01 <= 0.0105101 , 0.0102551 , 100.00, 1 # target 50% 0.000805545 # target 75% 0.0055 # target 90% 0.00766667 # target 99% 0.0103571 # target 99.9% 0.0104948 Sockets used: 25 (for perfect keepalive, would be 3) Jitter: false Code 200 : 8 (26.7 %) Code 503 : 22 (73.3 %) Response Header Sizes : count 30 avg 44.533333 +/- 73.85 min 0 max 167 sum 1336 Response Body/Total Sizes : count 30 avg 670.06667 +/- 711.5 min 241 max 1850 sum 20102 All done 30 calls (plus 0 warmup) 2.426 ms avg, 1067.4 qps
istio-proxy
統計を問い合せて、詳細情報を取得します。kubectl exec "$FORTIO_POD" -c istio-proxy -- pilot-agent request GET stats | grep productpage | grep pending
回路遮断は、メトリックupstream_rq_pending_overflow
を参照して32コールにフラグを付けます。cluster.outbound|9080|v1|productpage.default.svc.cluster.local.circuit_breakers.default.remaining_pending: 1 cluster.outbound|9080|v1|productpage.default.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0 cluster.outbound|9080|v1|productpage.default.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0 cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_active: 0 cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_failure_eject: 0 cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_overflow: 32 cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_total: 39
- クライアントをクリーンアップします。
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml kubectl delete deploy fortio-deploy kubectl delete svc fortio
ミラー化
トラフィック・ミラーリング(シャドウイングとも呼ばれる)により、チームはできるだけ少ないリスクで本番環境に変更を加えることができます。ミラー化では、ライブ・トラフィックのコピーがミラー化サービスに送信されます。ミラー化されたトラフィックは、プライマリ・サービスのクリティカル・リクエスト・パスの外部で発生します。
- すべてのトラフィックを各マイクロサービスのv1バージョンにルーティングします。
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
- トラフィックをミラー化するようにルート・ルールを
reviews:v2
に変更します。kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v1 weight: 100 mirror: host: reviews subset: v2 mirrorPercentage: value: 100.0 EOF
前のルート・ルールは、トラフィックの100%を
reviews:v1
に送信し、同じトラフィックの100%をreviews:v2
サービスにミラー化します。トラフィックがミラー化されると、リクエストは、ホスト/認可ヘッダーに
-shadow
が付加されたミラー化サービスに送信されます。たとえば、レビューはreviews-shadow.Mirrored
リクエストになり、「fire and forget」とみなされます。ミラー化されたレスポンスは破棄されます。すべてのリクエストをミラー化するかわりに、
mirrorPercentage
フィールドの値フィールドを変更してトラフィックの割合をミラー化します。このフィールドがない場合、すべてのトラフィックがミラー化されます。 - ブラウザでURL
http://${INGRESS_HOST}:${INGRESS_PORT}/productpage
をリフレッシュして、一部のトラフィックを送信します。 reviews:v1
サービスのログ。v1サービスは評価サービスをコールしません。reviews:v2
ミラー化サービスのログ。v2サービスでは、ヘッダーに-shadow
が付加されます。
ゲートウェイの管理
Gatewayは、受信または送信HTTP/TCP接続を受信するメッシュの端で動作するロード・バランサを表します。ゲートウェイ構成は、サービス・ワークロードとともに実行されているサイドカーのEnvoyプロキシではなく、メッシュの端で実行されているスタンドアロンのEnvoyプロキシに適用されます。Istioには、事前構成されたゲートウェイ・プロキシ・デプロイメントistio-ingressgateway
およびistio-egressgateway
がいくつか用意されています。
istioctl install
このコマンドは、ゲートウェイを含むデフォルト設定を使用してIstioをデプロイします。詳細は、ここを参照してください。
Istio Gatewayを使用したイングレスの構成
イングレス・ゲートウェイは、公開されているポートおよびプロトコルを構成しますが、Kubernetesイングレス・リソースとは異なり、トラフィック・ルーティング構成は含まれません。イングレス・トラフィックのトラフィック・ルーティングは、かわりにIstioルーティング・ルールを使用して構成されます。Istioイングレスの詳細は、こちらを参照してください。
Bookinfoアプリケーションをすでにデプロイしている場合は、次のステップは必要ありません。
- HTTPトラフィックのポート80に構成するIstioゲートウェイを作成します。
kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: bookinfo-gateway spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" EOF
- ゲートウェイ経由で入力するトラフィックのルートを構成します。
kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: bookinfo spec: hosts: - "*" gateways: - bookinfo-gateway http: - match: - uri: exact: /productpage - uri: prefix: /static - uri: exact: /login - uri: exact: /logout - uri: prefix: /api/v1/products route: - destination: host: productpage port: number: 9080 EOF
- Bookinfoアプリケーションをデプロイするには、「IstioおよびOKEのインストール」ページのBookinfoアプリケーションの実行に関する項を参照してください。
- curlを使用して
productpage
サービスにアクセスします。curl -s -I http://$INGRESS_HOST:$INGRESS_PORT/productpage
このコマンドにより、次の出力が生成されます。
HTTP/1.1 200 OK content-type: text/html; charset=utf-8 content-length: 4183 server: istio-envoy date: Tue, 07 Sep 2021 13:48:39 GMT x-envoy-upstream-service-time: 36
- 明示的に公開されていないその他のURLにアクセスします。HTTP 404エラーが表示されます。
curl -s -I http://$INGRESS_HOST:$INGRESS_PORT/any
このコマンドにより、次の出力が生成されます。
HTTP/1.1 404 Not Found date: Tue, 07 Sep 2021 13:49:45 GMT server: istio-envoy transfer-encoding: chunked
- ゲートウェイ内の明示的なホストの場合は、-Hフラグを使用してホストHTTPヘッダーを設定します。このフラグは、イングレス・ゲートウェイおよび仮想サービスがホストを処理するように構成されているため必要です。たとえば、ホストはexample.comで、名前はゲートウェイと仮想サービスの両方で指定されます。
curl -s -I -HHost:example.com http://$INGRESS_HOST:$INGRESS_PORT/productpage
- また、ブラウザでURL
http://${INGRESS_HOST}:${INGRESS_PORT}/productpage
を開いて、Bookinfo Webページを表示します。
Kubernetesイングレス・リソースを使用したイングレスの構成
リーダーは、Bookinfoアプリケーションがクラスタにデプロイされていることを前提としています。Bookinfoアプリケーションをデプロイするには、「IstioおよびOKEのインストール」ページのBookinfoアプリケーションの実行に関する項を参照してください。
- 構成がすでに適用されている場合は、Istioゲートウェイを削除します。
kubectl delete -f samples/bookinfo/networking/bookinfo-gateway.yaml
- HTTPトラフィックのポート80にイングレス・リソースを作成します。
kubectl apply -f - <<EOF apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: istio name: ingress spec: rules: - http: paths: - path: /productpage pathType: Prefix backend: service: name: productpage port: number: 9080 EOF
この
Ingress
を処理するようにIstioゲートウェイ・コントローラに指示するには、kubernetes.io/ingress.class
注釈が必要です。 - 前の項の手順に従って、Bookinfoアプリケーションにアクセスしていることを確認します。
- リソースを削除し、さらにタスクを行うためにIstioゲートウェイを有効にします。
kubectl delete ingress ingress kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
エグレスを使用した外部サービスへのアクセス
デフォルトでは、Istio対応ポッドからのすべてのアウトバウンド・トラフィックはサイドカー・プロキシにリダイレクトされ、Istioは不明なサービスに対するリクエストを通過するようにEnvoyプロキシを構成します。Istioは、構成フィールドmeshConfig.outboundTrafficPolicy.mode
を介して外部サービスのサイドカー処理を構成します。このオプションを次のように設定した場合:
ALLOW_ANY
(デフォルト): Istioプロキシでは、不明なサービスへのコールがパス・スルーされます。REGISTRY_ONLY
: Istioプロキシは、メッシュ内でHTTPサービスまたはサービス・エントリが定義されていないホストをブロックします。
リーダーは、Bookinfoアプリケーションがクラスタにデプロイされていることを前提としています。そうでない場合は、ステップに従ってBookinfoアプリケーションをデプロイします。
外部サービスへのEnvoyパススルーの管理
外部サービスへのパススルーを有効にするには、次のステップを実行します。
-
istioctl
を使用して、meshConfig.outboundTrafficPolicy.mode
オプションをALLOW_ANY
に変更します。istioctl install --set meshConfig.outboundTrafficPolicy.mode=ALLOW_ANY
ノート
このステップは、インストール中にオプションを明示的にREGISTRY_ONLY
に設定した場合にのみ必要です。 - 成功した200レスポンスを確認するには、
SOURCE_POD
から外部サービスにリクエストします。export SOURCE_POD=$(kubectl get pod -l app=ratings -o jsonpath='{.items..metadata.name}') kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"
このコマンドにより、次の出力が生成されます。HTTP/1.1 200 OK
しかし、このアプローチの欠点は、外部サービスへのトラフィックのIstioの監視と制御が失われることです。
外部サービスへのアクセスの制御[推奨]
外部サービスへの制御アクセスを設定するには、次のステップに従います。
meshConfig.outboundTrafficPolicy.mode
オプションをREGISTRY_ONLY
に変更します。このステップは、インストール中にオプションを明示的にREGISTRY_ONLY
に設定していない場合にのみ必要です。- 「Envoy Passthrough to External Services」セクションの手順1のみに従ってください。ここで変更するのは、
ALLOW_ANY
をREGISTRY_ONLY
に置き換えることのみです。 - 外部サービスがブロックされていることを確認するには、
SOURCE_POD
から外部HTTPSサービスへのリクエストをいくつか行います。構成の変更は伝播に数秒かかるため、正常な接続が可能です。数秒待ってから、最後のコマンドを再試行してください。export SOURCE_POD=$(kubectl get pod -l app=ratings -o jsonpath='{.items..metadata.name}') kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"
このコマンドにより、次の出力が生成されます。
HTTP/1.1 502 Bad Gateway
- 外部HTTPサービスへのアクセスを許可する
ServiceEntry
を作成します。kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1beta1 kind: ServiceEntry metadata: name: httpbin-ext spec: hosts: - httpbin.org ports: - number: 80 name: http protocol: HTTP resolution: DNS location: MESH_EXTERNAL EOF
SOURCE_POD
から外部HTTPサービスにリクエストします。Istioサイドカー・プロキシによって追加されたヘッダー(X-Envoy-Decorator-Operation
)を確認します。kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"
このコマンドにより、次の出力が生成されます。HTTP/1.1 200 OK
grep
コマンドを削除して、すべてのヘッダーを表示します。kubectl exec $SOURCE_POD -c ratings -- curl -sS http://httpbin.org/headers
このコマンドにより、次の出力が生成されます。
{ "headers": { "Accept": "*/*", "Host": "httpbin.org", "User-Agent": "curl/7.52.1", "X-Amzn-Trace-Id": "Root=1-61384b41-2d3cf8b5571ba7504ab9a834", "X-B3-Sampled": "0", "X-B3-Spanid": "6983ef0cec914f83", "X-B3-Traceid": "d510c4d190cb099d6983ef0cec914f83", "X-Envoy-Attempt-Count": "1", "X-Envoy-Decorator-Operation": "httpbin.org:80/*", "X-Envoy-Peer-Metadata": "ChsKDkFQUF9DT05UQUlORVJTEgkaB3JhdGluZ3MKGgoKQ0xVU1RFUl9JRBIMGgpLdWJlcm5ldGVzChkKDUlTVElPX1ZFUlNJT04SCBoGMS4xMS4xCtQBCgZMQUJFTFMSyQEqxgEKEAoDYXBwEgkaB3JhdGluZ3MKIAoRcG9kLXRlbXBsYXRlLWhhc2gSCxoJYzk5NDdiOTlmCiQKGXNlY3VyaXR5LmlzdGlvLmlvL3Rsc01vZGUSBxoFaXN0aW8KLAofc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtbmFtZRIJGgdyYXRpbmdzCisKI3NlcnZpY2UuaXN0aW8uaW8vY2Fub25pY2FsLXJldmlzaW9uEgQaAnYxCg8KB3ZlcnNpb24SBBoCdjEKGgoHTUVTSF9JRBIPGg1jbHVzdGVyLmxvY2FsCiQKBE5BTUUSHBoacmF0aW5ncy12MS1jOTk0N2I5OWYtbGN4bHQKFgoJTkFNRVNQQUNFEgkaB2RlZmF1bHQKTgoFT1dORVISRRpDa3ViZXJuZXRlczovL2FwaXMvYXBwcy92MS9uYW1lc3BhY2VzL2RlZmF1bHQvZGVwbG95bWVudHMvcmF0aW5ncy12MQoXChFQTEFURk9STV9NRVRBREFUQRICKgAKHQoNV09SS0xPQURfTkFNRRIMGgpyYXRpbmdzLXYx", "X-Envoy-Peer-Metadata-Id": "sidecar~10.244.0.11~ratings-v1-c9947b99f-lcxlt.default~default.svc.cluster.local" } }
- HTTPS呼び出しにアクセスするには、サービスエントリの作成時にポートとプロトコルを置き換えます。
- このアプローチでは、タイムアウトやフォルト・インジェクションなどの外部サービス・トラフィック管理機能が追加されます。次のリクエストは、約5秒で200 (OK)を返します。
kubectl exec $SOURCE_POD -c ratings -- curl http://httpbin.org/delay/5
kubectl
を使用して、httpbin.org外部サービスへのコールで3秒間のタイムアウトを設定します。kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: httpbin-ext spec: hosts: - httpbin.org http: - timeout: 3s route: - destination: host: httpbin.org weight: 100 EOF
今回は、3秒後にタイムアウトが表示されます。httpbin.orgは5秒待機していましたが、Istioはリクエストを3秒で停止しました。kubectl exec $SOURCE_POD -c ratings -- curl http://httpbin.org/delay/5
- 将来のタスクのためにリソースをクリーンアップします。
kubectl delete serviceentry httpbin-ext kubectl delete virtualservice httpbin-ext --ignore-not-found=true
外部サービスへのアクセスの指示
このアプローチでは、Istioサイドカー・プロキシがバイパスされ、サービスは外部サーバーに直接アクセスできます。ただし、この方法でプロキシを構成する場合は、クラスタ・プロバイダ固有の知識および構成が必要です。最初のアプローチと同様に、外部サービスへのアクセスの監視を失い、外部サービスへのトラフィックにIstio機能を適用できません。これらのステップに従って、外部サービスへの直接アクセスを提供します。
Istioの保護
Istioのセキュリティ機能は、強固なアイデンティティ、強力なポリシー、透過的なTLS暗号化、認証、認可、監査(AAA)ツールを提供し、サービスとデータを保護します。
認証の構成
Istioは、トランスポート認証のフルスタック・ソリューションとして相互TLSを提供します。これは、サービス・コードの変更を必要とせずに有効化されます。
sleep
およびhttpbin
サービスをデフォルト・ネームスペースにデプロイします。
kubectl apply -f samples/sleep/sleep.yaml
kubectl apply -f samples/httpbin/httpbin.yaml
デフォルトでは、Istioは複数のタスクを実行します。Istioは、Istioプロキシに移行されたサーバー・ワークロードを追跡します。Istioは、相互TLSトラフィックをこれらのワークロードに自動的に送信するようにクライアント・プロキシを構成します。Istioは、サイドカーなしでワークロードにプレーン・テキスト・トラフィックを送信します。
sleep
ポッドからhttpbin
ポッドにリクエストを送信し、X-Forwarded-Client-Certヘッダーを探します。
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl -s http://httpbin.default:8000/headers -s | grep X-Forwarded-Client-Cert | sed 's/Hash=[a-z0-9]*;/Hash=<redacted>;/'
sleep
およびhttpbin
サービスの別のインスタンスをデプロイします。 kubectl create ns legacy
kubectl apply -f samples/sleep/sleep.yaml -n legacy
kubectl apply -f samples/httpbin/httpbin.yaml -n legacy
sleep
ポッドからレガシー・ネームスペースのhttpbin
ポッドへのリクエストは、宛先がサイドカー対応ではないためプレーン・テキストです。次のコマンドを実行して、プレーン・テキストが送信されていることを確認します。
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl http://httpbin.legacy:8000/headers -s | grep X-Forwarded-Client-Cert
sleep
ポッドからデフォルト・ネームスペースのhttpbin
へのリクエストも、プレーン・テキスト接続で成功します。次のコマンドを使用して検証できます。kubectl exec "$(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name})" -n legacy -c sleep -- curl http://httpbin.default:8000/headers
STRICT
に設定して、メッシュ全体のピア認証ポリシーを設定します。
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: "default"
namespace: "istio-system"
spec:
mtls:
mode: STRICT
EOF
STRICT
に設定されている場合、レガシー・ネームスペースのsleep
ポッドからデフォルト・ネームスペースのhttpbin
への接続は機能しなくなりました。 kubectl exec "$(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name})" -n legacy -c sleep -- curl http://httpbin.default:8000/headers
STRICT
ピア認証設定を元に戻します。 kubectl delete peerauthentication -n istio-system default
グローバル相互TLS設定に加えて、ネームスペースまたはワークロード・レベルで設定することもできます。認証構成の詳細は、Istioのドキュメントを参照してください。
認可の構成
Istioでは、アプリケーションの認可ポリシーを構成できます。
allow-nothing
ポリシーを構成し、ワークロードへのより多くのアクセスを段階的かつ段階的に付与します。
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: default
spec:
{}
EOF
ブラウザでBookinfo製品ページを開きます。deny-all
ポリシーが意図したとおりに機能していることを確認するRBAC: access denied
エラーが表示されます。
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:
- to:
- operation:
methods: ["GET"]
EOF
「Bookinfoサンプル」ページが表示されますが、productpage
サービスは詳細およびレビュー・ページにアクセスできません。
次のポリシーを追加して、productpage
ワークロードに詳細へのアクセス権を付与し、ワークロードをレビューし、ratings
ワークロードへのワークロード・アクセスをレビューします。
詳細ビューアの設定
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: "details-viewer"
namespace: default
spec:
selector:
matchLabels:
app: details
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
to:
- operation:
methods: ["GET"]
EOF
レビュービューアを設定
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: "reviews-viewer"
namespace: default
spec:
selector:
matchLabels:
app: reviews
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
to:
- operation:
methods: ["GET"]
EOF
評価ビューアの設定
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: "ratings-viewer"
namespace: default
spec:
selector:
matchLabels:
app: ratings
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/bookinfo-reviews"]
to:
- operation:
methods: ["GET"]
EOF
エラーなくブラウザから製品ページを表示します。
適用されたポリシーを元に戻すには、次のコマンドを入力します。
kubectl delete authorizationpolicy.security.istio.io/allow-nothing
kubectl delete authorizationpolicy.security.istio.io/productpage-viewer
kubectl delete authorizationpolicy.security.istio.io/details-viewer
kubectl delete authorizationpolicy.security.istio.io/reviews-viewer
kubectl delete authorizationpolicy.security.istio.io/ratings-viewer
TLSを使用したゲートウェイの保護
シンプルまたは相互TLSを使用して、BookinfoアプリケーションをセキュアなHTTPSサービスとして公開できます。サービスの証明書に署名するには、ルート証明書と秘密鍵を作成します。
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt
productpage.bookinfo.com
の証明書および秘密キーを作成します。
openssl req -out bookinfo.example.com.csr -newkey rsa:2048 -nodes -keyout bookinfo.example.com.key -subj "/CN=bookinfo.example.com/O=bookinfo organization"
openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in bookinfo.example.com.csr -out bookinfo.example.com.crt
Bookinfoアプリケーションをデプロイしたことを確認します。イングレス・ゲートウェイ証明書のシークレットを作成します。
kubectl create -n istio-system secret tls bookinfo-credential --key=bookinfo.example.com.key --cert=bookinfo.example.com.crt
セキュアなポートを含めるようにBookinfoゲートウェイを更新します。
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: bookinfo-gateway-https
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: bookinfo-credential
hosts:
- bookinfo.example.com
EOF
Bookinfo宛先ルールを作成します(まだ作成されていない場合)。
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
ゲートウェイにバインドされた仮想サービスを作成します。
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: bookinfo-https
spec:
hosts:
- "bookinfo.example.com"
gateways:
- bookinfo-gateway-https
http:
- route:
- destination:
host: productpage
subset: v1
EOF
次のcurl
コマンドを使用して、ゲートウェイへのTLS接続を確認できます。
curl -v -HHost:bookinfo.example.com --resolve "bookinfo.example.com:443:$INGRESS_HOST" --cacert example.com.crt "https://bookinfo.example.com/productpage"