コンテンツにスキップ

リソース定義@Istio

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. 全部入りセットアップ

インストール

▼ チャートとして

チャートリポジトリからチャートをインストールし、Kubernetesリソースを作成する。

チャートは、istioctlコマンドインストール時にmanifestsディレクトリ以下に同梱される。

# IstioOperatorのdemoをインストールし、リソースを作成する
$ istioctl install --set profile=demo revision=1-10-0

# 外部のチャートを使用する場合
$ istioctl install --manifests=foo-chart

執筆時点 (2023/01/16) でIstioOperatorは非推奨になっている。

▼ Operatorとして (ユーザー定義)

プロファイルを使用する代わりに、IstioOperatorを自前で定義しても良い。

# istio-operator.yamlファイル
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  namespace: istio-system
  name: istio-operator
spec:
  # Istioのdemoチャートをインストールし、リソースを作成する。
  profile: demo
$ kubectl apply -f istio-operator.yaml


ローカルマシンのセットアップ

▼ Minikube

Istioによる種々のコンテナが稼働するために、MinikubeのNodeのCPUとメモリを最低サイズを以下の通りにする必要がある。

$ minikube start --cpus=4 --memory=16384


01-02. コンポーネント別セットアップ

インストール

▼ Google-APIsから

Google-APIsから、Istioのコンポーネント別にチャートをインストールし、リソースを作成する。

$ helm repo add <チャートリポジトリ名> https://istio-release.storage.googleapis.com/charts

$ helm repo update

$ kubectl create namespace istio-system

# baseチャート
$ helm install <Helmリリース名> <チャートリポジトリ名>/base -n istio-system --version <バージョンタグ>

# Istiodコントロールプレーンのみ
# istiodチャート
$ helm install <Helmリリース名> <チャートリポジトリ名>/istiod -n istio-system --version <バージョンタグ>

IngressGatewayのインストールは必須ではない。

# IngressGatewayのみ
# gatewayチャート
$ helm install <Helmリリース名> <チャートリポジトリ名>/gateway -n istio-system --version <バージョンタグ>


02. AuthorizationPolicy

.spec.action

▼ actionとは

認可スコープで、認証済みの送信元を許可するか否かを設定する。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: bar-authorization-policy
  namespace: istio-system
spec:
  action: ALLOW


.spec.provider

▼ providerとは

認可フェーズの委譲先のIDプロバイダーを設定する。

事前に、ConfigMapの.mesh.extensionProviderキーにIDプロバイダーを登録しておく必要がある。

*実装例*

ここでは、oauth2-proxyをIDプロバイダーとして使用する。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: oauth2-proxy-authorization-policy
  namespace: istio-system
spec:
  action: CUSTOM
  provider:
    name: oauth2-proxy
  rules:
    - to:
        - operation:
            paths: ["/login"]

oauth2-proxyのPodに紐づくServiceを識別できるようにする。

apiVersion: v1
kind: ConfigMap
metadata:
  name: istio-mesh-cm
  namespace: istio-system
data:
  mesh: |
    extensionProviders:
      - name: oauth2-proxy
        envoyExtAuthzHttp:
          service: oauth2-proxy.auth.svc.cluster.local
          port: 80
        includeHeadersInCheck:
          - cookie
          - authorization


.spec.rules

▼ rulesとは

認可スコープで、実施条件 (例:いずれのKubernetesリソース、HTTPリクエストのメソッド、JWTの発行元の識別子) を設定する。

その条件に合致した場合に、認証済みの送信元を許可するか否かを実施する。

▼ 認証が『相互TLS認証』の場合

相互TLS認証の場合、送信元のPod紐づくServiceAccountが適切な場合に、認可を実施するように設定する。

*実装例*

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: bar-authorization-policy
  namespace: istio-system
spec:
  rules:
    - from:
        - source:
            principals: ["cluster.local/ns/default/sa/inventory-sa"]
      to:
        - operation:
            methods: ["GET"]

▼ 認証が『JWTによるBearer認証』の場合

JWTによるBearer認証の場合、リクエストヘッダーにあるJWTの発行元が適切な場合に、認可を実施するように設定する。

*実装例*

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: bar-authorization-policy
  namespace: istio-system
spec:
  rules:
    - from:
        - source:
            namespaces: ["foo"]
      to:
        - operation:
            methods: ["GET"]
      when:
        - key: request.auth.claims[iss]
          values: ["<JWTの発行元の識別子 (issuer)>"]


.spec.selector

▼ selectorとは

AuthorizationPolicyの設定を適用するKubernetesリソースを設定する。

設定したKubernetesリソースに対して認証済みの送信元が通信した場合に、AuthorizationPolicyを適用する。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: bar-authorization-policy
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: foo-pod


03. DestinationRule

.spec.exportTo

▼ exportToとは

そのDestinationRuleにリクエストできるNamespaceを設定する。

* (アスタリスク)

全てのNamespaceからリクエストできるようにする。

デフォルト値である。

もし他のNamespace (例:istio-ingress) 内のIstio IngressGatewayからリクエストを受信する場合、*とする必要がある。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  exportTo:
    - "*"
  gateways:
    - foo-igressgateway

. (ドット)

同じNamespaceからのみリクエストできるようにする。

Pod間通信の場合、他のNamespaceからリクエストを受信しなてもよければ、.とする。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  exportTo:
    - "."
  gateways:
    - mesh


.spec.host

インバウンド通信のルーティング元とするServiceの名前を設定する。

これにより、Envoyは特定のServiceからのルーティングのみ受信するようになる。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  host: foo-service.default.svc.cluster.local # Service名でも良いが完全修飾ドメイン名の方が良い。


.spec.subsets

▼ subsetsとは

VirtualServiceを起点としたPodのカナリアリリースで使用する。

ルーティング先のPodの.metadata.labelsキーを設定する。

.spec.subsets[*].nameキーの値は、VirtualServiceで設定した.spec.http[*].route[*].destination.subsetキーに合わせる必要がある。

istio_virtual-service_destination-rule_subset

*実装例*

サブセットv1に対するインバウンド通信では、versionキーの値がv1であるPodにルーティングする。

v2も同様である。

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  subsets:
    - name: v1
      labels:
        version: v1 # 旧Pod
    - name: v2
      labels:
        version: v2 # 新Pod


.spec.trafficPolicy

▼ connectionPool.http.maxRequestsPerConnection

EnvoyがHTTPプロトコルを処理する場合に、接続当たりのリクエストの上限値を設定する。

デフォルトでは上限がない。

1とする場合、Envoyによるkeep-aliveを無効化する。

また、サーキットブレイカーの閾値になる。

上限を超過した場合、Podへのルーティングが停止し、直近の成功時の処理結果を返信する (サーキットブレイカー) 。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  trafficPolicy:
    connectionPool:
      http:
        maxRequestsPerConnection: 1

▼ connectionPool.http.http1MaxPendingRequests

記入中...

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  trafficPolicy:
    connectionPool:
      http:
        http1MaxPendingRequests: 1

▼ connectionPool.tcp.maxConnections

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100

▼ outlierDetection

サーキットブレイカーを設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  trafficPolicy:
    outlierDetection:
      # エラー検知の間隔
      interval: 10s
      # サーキットブレイカーを実施するエラーの閾値数
      consecutiveGatewayErrors: 3
      # Podをルーティング先から切り離す秒数
      baseEjectionTime: 30s
      maxEjectionPercent: 99

▼ loadBalancer

Podへのルーティング時に使用する負荷分散方式を設定する。

*実装例*

複数のゾーンのPodに対して、ラウンドロビンでルーティングする。

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  trafficPolicy:
    loadBalancer:
      # ラウンドロビン
      simple: ROUND_ROBIN

*実装例*

指定したゾーンのPodに対して、指定した重みづけでルーティングする。

リージョン名やゾーン名は、PodのtopologyKeyキー(topology.kubernetes.io/regionキー、topology.kubernetes.io/zoneキー、など) の値を設定する。

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  trafficPolicy:
    loadBalancer:
      localityLbSetting:
        enabled: "true"
        distribute:
          - from: <リージョン名>/<ゾーン名>/*
            to:
              "<リージョン名>/<ゾーン名>/*": 70
              "<リージョン名>/<ゾーン名>/*": 30

▼ portLevelSettings.loadBalancer

Podのポート番号別のルーティングの負荷分散方式を設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  trafficPolicy:
    portLevelSettings:
      - loadBalancer:
          simple: ROUND_ROBIN

▼ portLevelSettings.port

Podのポート番号別ルーティングで使用するポート番号を設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  trafficPolicy:
    portLevelSettings:
      - port:
          number: 80

▼ tls.mode

Podへのルーティング時に使用するHTTPSプロトコルのタイプを設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  trafficPolicy:
    tls:
      mode: DISABLE # HTTPプロトコル
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL # 相互TLS認証

▼ tls.certificate系

相互TLSの場合に、使用するSSL証明書を設定する。

設定しない場合、Istiodコントロールプレーンは作成したSSL署名書を自動的に割り当てる。

Namespace全体に同じ設定を適用する場合、PeerAuthenticationを使用する。

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  namespace: istio-system
  name: foo-destination-rule
spec:
  trafficPolicy:
    tls:
      mode: MUTUAL
      clientCertificate: /etc/certs/myclientcert.pem
      privateKey: /etc/certs/client_private_key.pem
      caCertificates: /etc/certs/rootcacerts.pem


04. EnvoyFilter

.spec.configPatches.applyTo

適用したいフィルター名を設定する。

*実装例*

ネットワークフィルターの設定値を変更する。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - applyTo: NETWORK_FILTER

*実装例*

ネットワークフィルターであるnetwork.http_connection_managerの設定値を変更する。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - applyTo: HTTP_FILTER

*実装例*

リスナーフィルターの設定値を変更する。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - applyTo: LISTENER_FILTER


.spec.configPatches.match

▼ matchとは

フィルターの設定値を変更する場合に、その実行条件を設定する。

条件に合致する設定値があった場合、.spec.configPatches.patchキーで設定した内容の変更処理を実施する。

▼ cluster

指定したクラスターが存在する場合に、フィルターの設定値を変更する。

*実装例*

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - match:
        cluster:
          name: foo-cluster

▼ listener

指定したリスナーが存在する場合に、フィルターの設定値を変更する。

*実装例*

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - match:
        listener:
          filterChain:
            filter:
              name: envoy.filters.network.http_connection_manager

▼ context

指定したワークロードタイプ (例:istio-ingressgateway内のistio-proxyコンテナ、サイドカーのistio-proxyコンテナ) の場合に、フィルターの設定値を変更する。

*実装例*

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - match:
        # istio-ingressgatewayとサイドカーの両方に適用する
        - context: ANY
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - match:
        # サイドカーのistio-proxyコンテナのIngressリスナー後のフィルターに適用する
        - context: SIDECAR_INBOUND
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - match:
        # istio-ingressgateway内のistio-proxyコンテナに適用する
        - context: GATEWAY
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - match:
        # サイドカーのistio-proxyコンテナのアウトバウンド通信 (Egressリスナー後のフィルター)
        - context: SIDECAR_OUTBOUND


.spec.configPatches.patch

▼ patchとは

.spec.configPatches.matchキーに設定した設定値があった場合、フィルターの設定値の変更内容を設定する。

▼ operation

フィルターの設定値の変更方法を設定する。

*実装例*

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - patch:
        operation: MERGE

*実装例*

.spec.configPatches.matchキーに合致したフィルターの直前に挿入する。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - patch:
        operation: INSERT_BEFORE

*実装例*

フィルターの一番最初に挿入する。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - patch:
        operation: INSERT_FIRST

*実装例*

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - patch:
        operation: MERGE

▼ value

既存のフィルターに適用したいフィルターを設定する。

*実装例*

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  configPatches:
    - patch:
        operation: MERGE
        value:
          name: envoy.filters.network.http_connection_manager
          typed_config:
            # ネットワークフィルター (http_connection_manager) を指定する
            "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager


.spec.configPatches.priority

フィルターの適用タイミングを設定する。

マイナス値の場合、デフォルトのフィルターよりも先に適用する。

*実装例*

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  namespace: istio-system
  name: foo-envoy-filter
spec:
  priority: -1


04-02. EnvoyFilter例

KeepAliveの設定

istio-ingressgateway内のistio-proxyコンテナで、KeepAliveを実行できるようにする。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: istio-ingressgateway
  namespace: foo-namespace
spec:
  configPatches:
    - applyTo: LISTENER
      match:
        # istio-ingressgatewayのフィルターの設定値を変更する
        context: GATEWAY
        listener:
          name: 0.0.0.0_8443
          portNumber: 8443
      patch:
        operation: MERGE
        value:
          socket_options:
            - level: 1
              name: 9
              # KeepAliveを有効にする
              int_value: 1
              state: STATE_PREBIND
            - level: 6
              name: 4
              # 15秒間の無通信が発生したら、KeepAliveを実行する
              int_value: 15
              state: STATE_PREBIND
            - level: 6
              name: 5
              # 15秒間隔で、KeepAliveを実行する
              int_value: 15
              state: STATE_PREBIND
            - level: 6
              name: 6
              # 3回応答がなければ終了する
              int_value: 3
              state: STATE_PREBIND


04-03. EnvoyFilter以外のカスタマイズ方法

VirtualService、DestinationRuleの定義

VirtualServiceとDestinationRuleの設定値は、istio-proxyコンテナに適用される。


annotationsの定義

DeploymentやPodの.metadata.anontationsキーにて、istio-proxyコンテナごとのオプション値を設定する。


istio-proxyコンテナの定義

DeploymentやPodでistio-proxyコンテナを定義することにより設定を変更できる。

*実装例*

apiVersion: apps/v1
kind: Deployment
metadata:
  name: foo-deployment
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: foo-pod
  template:
    spec:
      containers:
        - name: app
          image: app
        # istio-proxyコンテナの設定を変更する。
        - name: istio-proxy
          lifecycle:
            # istio-proxyコンテナ終了直前の処理
            preStop:
              exec:
                # istio-proxyコンテナが、必ずアプリコンテナよりも後に終了する。
                # envoyプロセスとpilot-agentプロセスの終了を待機する。
                command:
                  - "/bin/bash"
                  - "-c"
                  - |
                    sleep 5
                    while [ $(netstat -plnt | grep tcp | egrep -v 'envoy|pilot-agent' | wc -l) -ne 0 ]; do sleep 1; done"
            # istio-proxyコンテナ開始直後の処理
            postStart:
              exec:
                # istio-proxyコンテナが、必ずアプリコンテナよりも先に起動する。
                # pilot-agentの起動完了を待機する。
                command:
                  - |
                    pilot-agent wait


05. Gateway

.spec.selector

▼ selectorとは

Istio IngressGateway/EgressGatewayに付与された.metadata.labelsキーを設定する。

デフォルトでは、Istio IngressGatewayにはistioラベルがあり、値はingressgatewayである。

また、Istio EgressGatewayにはistioラベルがあり、値はegressgatewayである。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  namespace: istio-system
  name: gateway
spec:
  selector:
    istio: istio-ingressgateway
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: istio-ingressgateway
    istio: ingressgateway


.spec.servers

▼ port.name

Istio IngressGateway/EgressGatewayのPodで待ち受けるポート名を設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  namespace: istio-system
  name: gateway
spec:
  servers:
    - port:
        name: http

▼ port.number

Istio IngressGateway/EgressGatewayのPodで待ち受けるポート番号を設定する。

IngressGatewayの内部的なServiceのタイプに関して、NodePort Serviceを選んだ場合、Nodeの宛先ポート番号に合わせる。

一方で、LoadBalancer Serviceを選んだ場合、LoadBalancerがルーティングできる宛先ポート番号とする。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  namespace: istio-system
  name: gateway
spec:
  servers:
    - port:
        number: 30000

▼ port.protocol

Istio IngressGateway/EgressGatewayのPodで受信するプロトコルを設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  namespace: istio-system
  name: gateway
spec:
  servers:
    - port:
        protocol: HTTP

▼ port.targetPort

Istio IngressGateway/EgressGatewayのPodの宛先ポート番号を設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  namespace: istio-system
  name: gateway
spec:
  servers:
    - port:
        targetPort: 80

▼ hosts

Gatewayでフィルタリングするインバウンド通信のHostヘッダー名を設定する。

ドメインレジストラのドメインのみを許可しても良いが、 ワイルドカード (*) を使用して全てのドメインを許可しても良い。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  namespace: istio-system
  name: gateway
spec:
  servers:
    - hosts:
        - "*"

▼ tls.caCertificates

.spec.servers.tls.modeキーで相互TLSを設定している場合、クライアント証明書に対応するCA証明書である必要がある。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  namespace: istio-system
  name: gateway
spec:
  servers:
    - tls:
        privateKey: /etc/certs/privatekey.pem

▼ tls.credentialName

CAを含むSSL証明書を保持するSecretを設定する。

SSL証明書のファイルを指定する場合は、.spec.servers[*].tls.serverCertificateキーを設定する。

Secretを更新した場合、Podを再起動せずに、PodにSecretを再マウントできる。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  namespace: istio-system
  name: gateway
spec:
  servers:
    - tls:
        credentialName: istio-gateway-certificate-secret

▼ tls.mode

Gatewayの宛先との通信の暗号化方式を設定する。

*実装例*

クライアントとGatewayの通信間で相互TLSを実施する。

クライアント証明書が必要になる。

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  namespace: istio-system
  name: gateway
spec:
  servers:
    - tls:
        mode: MUTUAL

*実装例*

クライアントとGatewayの通信間で通常のHTTPSを実施する。

クライアント証明書は不要にである。

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  namespace: istio-system
  name: gateway
spec:
  servers:
    - tls:
        mode: SIMPLE

▼ tls.privateKey

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  namespace: istio-system
  name: gateway
spec:
  servers:
    - tls:
        privateKey: /etc/certs/privatekey.pem

▼ tls.serverCertificate

SSL証明書のファイルを設定する。

.spec.servers.tls.modeキーで相互TLSを設定している場合、クライアント証明書に対応するSSL証明書である必要がある。

SSL証明書を保持するSecretを指定する場合は、.spec.servers[*].tls.credentialNameキーを設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  namespace: istio-system
  name: gateway
spec:
  servers:
    - tls:
        serverCertificate: /etc/certs/server.pem


06. PeerAuthentication

.spec.mtls

▼ mtls

特定のNamespace内のすべてのistio-proxyコンテナ間通信で、相互TLS認証を有効化するか否かを設定する。

特定のPod間でのみ相互TLSを使用したい場合、DestinationRuleでSSL証明書を設定する。

▼ mode

相互TLS認証のタイプを設定する。

項目 説明
UNSET 記入中...
DISABLE 相互TLS認証を使用しない。
PERMISSIVE 相互TLS認証の時、プロトコルはHTTPSとHTTPの両方を許可する。
STRICT 相互TLS認証の時、プロトコルはHTTPSのみを許可し、HTTPを許可しない。

*実装例*

apiVersion: install.istio.io/v1alpha1
kind: PeerAuthentication
metadata:
  # foo内の全てのサイドカーにPeerAuthenticationを適用する
  namespace: foo
  name: peer-authentication
spec:
  mtls:
    mode: STRICT # 相互TLS認証を使用する。

相互TLS認証を使用する場合はSSL証明書が必要になり、SSL証明書が無いと以下のようなエラーになってしまう。

transport failure reason: TLS error: *****:SSL routines:OPENSSL_internal:SSLV3_ALERT_CERTIFICATE_EXPIRED


07. RequestAuthentication

.spec.jwtRules

Bearer認証で使用するJWTの発行元を設定する。

apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: foo-request-authentication-jwt"
  namespace: istio-system
spec:
  jwtRules:
    - issuer: foo-issuer
      jwksUri: https://example.com/.well-known/jwks.json


.spec.selector

JWTによるBearer認証を適用するKubernetesリソース名を設定する。

apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: foo-request-authentication-jwt"
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: istio-ingressgateway


08. ServiceEntry

.spec.hosts

▼ hostsとは

コンフィグストレージに登録する宛先のドメイン名を設定する。

宛先のドメインレジストラのドメインのみを許可しても良いが、ワイルドカード (*) を使用して全てのドメインを許可しても良い。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: foo-service-entry
spec:
  hosts:
    - "*"


.spec.location

▼ locationとは

登録したシステムがサービスメッシュ内か否かを設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: foo-service-entry
spec:
  location: EXTERNAL_MESH


.spec.ports

▼ portsとは

コンフィグストレージに登録する宛先のポート番号を設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: foo-service-entry
spec:
  ports:
    - name: http
      number: 80
      protocol: HTTP
    - name: https
      number: 443
      protocol: HTTPS


.spec.resolution

▼ resolutionとは

コンフィグストレージに登録する宛先のIPアドレスの設定する。

なお、Istio EgressGatewayは値に注意が必要である。

ServiceEntryに対するリクエストの宛先IPアドレスはIstio EgressGatewayに書き換えられている。

そのため、DNS解決をNONEにすると、Istio EgressGatewayはServiceEntryを見つけられず、自分自身でループしてしまう。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: foo-service-entry
spec:
  # DNSサーバーから返信されたIPアドレスを許可する
  resolution: DNS


09. Telemetry

accessLogging

▼ accessLoggingとは

同じNamespace内のistio-proxyコンテナを対象として、アクセスログの作成方法を設定する。

apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: access-log-provider
  # サイドカーをインジェクションしている各Namespaceで作成する
  namespace: foo
spec:
  selector:
    matchLabels:
      name: app
  # Envoyをアクセスログプロバイダーとして設定する
  # なお、デフォルトのため設定不要である
  accessLogging:
    - providers:
        - name: envoy


metrics

▼ metricsとは

同じNamespace内のistio-proxyコンテナを対象として、メトリクスの作成方法を設定する。

apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: access-log-provider
  # サイドカーをインジェクションしている各Namespaceで作成する
  namespace: foo
spec:
  selector:
    matchLabels:
      name: app
  metrics:
    - providers:
        - name: prometheus


tracing

▼ tracingとは

同じNamespace内のistio-proxyコンテナを対象として、スパンの作成方法を設定する。

apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: access-log-provider
  # サイドカーをインジェクションしている各Namespaceで作成する
  namespace: foo
spec:
  selector:
    matchLabels:
      name: app
  tracing:
    - providers:
        - name: opentelemetry
      randomSamplingPercentage: 100


10. VirtualService

.spec.exportTo

▼ exportToとは

そのVirtualServiceにリクエストできるNamespaceを設定する。

* (アスタリスク)

全てのNamespaceのみからリクエストできるようにする。

デフォルト値である。

もし他のNamespace (例:istio-ingress) 内のIstio IngressGatewayからリクエストを受信する場合、*とする必要がある。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  exportTo:
    - "*"
  gateways:
    - foo-igressgateway

. (ドット)

同じNamespaceからのみリクエストできるようにする。

Pod間通信の場合、他のNamespaceからリクエストを受信しなてもよければ、.とする。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  exportTo:
    - "."
  gateways:
    - mesh


.spec.hosts

▼ hostsとは

VirtualServiceの設定値を適用するHostヘッダー値を設定する。

ドメインレジストラのドメインのみを許可しても良いが、 ワイルドカード (*) を使用して全てのドメインを許可しても良い。

なお、.spec.gatewaysキーでmeshを使用する場合、ワイルドカード以外を設定しないといけない。 (例:.spec.hostsキーを設定しない、特定のホストヘッダー値を設定する、など)

*実装例*

全てのホストヘッダー値でVirtualServiceを適用する。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  hosts:
    - "*"


.spec.gateways

▼ gatewaysとは

インバウンド通信をいずれのGatewayから受信するかを設定する。

<Namespace名>/<Gateway名>

Gateway名とこれのNamespaceを設定する。

VirtualServiceとGatewayが同じNamespaceに所属する場合は、Namespaceを省略できる。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  gateways:
    - foo-namespace/foo-gateway

<Gateway名>

VirtualServiceを、Istio IngressGateway/EgressGatewayに紐づける場合 (サービスメッシュ内外の通信) は<Gateway名>とする。

VirtualServiceとGatewayが同じNamespaceに所属する場合は、Namespaceを省略できる。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-ingress-virtual-service
spec:
  gateways:
    - foo-ingressgateway
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-egress-virtual-service
spec:
  hosts:
    #  ホストヘッダー値がexternal.comの時にVirtualServiceを適用する。
    - external.com
  gateways:
    # PodからIstio EgressGatewayのPodへの通信で使用する
    - mesh
    # Istio EgressGatewayからエントリ済みシステムへの通信で使用する
    - foo-egressgateway
  http:
    # external.comに対するリクエストは、Istio EgressGatewayにルーティング (リダイレクト) する
    - match:
        - gateways:
            # PodからIstio EgressGatewayのPodへの通信で使用する
            - mesh
          port: 80
      route:
        - destination:
            host: istio-egressgateway.istio-egress.svc.cluster.local
            port:
              number: 80
    # Istio EgressGatewayに対するリクエストは、エントリ済システムにルーティングする
    - match:
        - gateways:
            # Istio EgressGatewayからエントリ済みシステムへの通信で使用する
            - foo-egressgateway
          port: 80
      route:
        - destination:
            host: external.com
            port:
              number: 80
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-egress-virtual-service
spec:
  hosts:
    #  ホストヘッダー値がexternal.comの時にVirtualServiceを適用する。
    - external.com
  gateways:
    # PodからIstio EgressGatewayのPodへの通信で使用する
    - mesh
    # Istio EgressGatewayからエントリ済みシステムへの通信で使用する
    - foo-egressgateway
  tls:
    # external.comに対するリクエストは、Istio EgressGatewayにルーティング (リダイレクト) する
    - match:
        - gateways:
            # PodからIstio EgressGatewayのPodへの通信で使用する
            - mesh
          port: 443
          sniHosts:
            - external.com
      route:
        - destination:
            host: istio-egressgateway.istio-egress.svc.cluster.local
            port:
              number: 443
  http:
    # Istio EgressGatewayに対するリクエストは、エントリ済システムにルーティングする
    - match:
        - gateways:
            # Istio EgressGatewayからエントリ済みシステムへの通信で使用する
            - foo-egressgateway
          port: 443
      route:
        - destination:
            host: external.com
            port:
              number: 443

▼ mesh

VirtualServiceを、Pod間通信で使用する場合はmeshとする。

ホストヘッダーに* (ワイルドカード) を使用できず、特定のホストヘッダーのみを許可する必要がある。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  gateways:
    - mesh
  hosts:
    # ワイルドカードを指定できず、特定のホストヘッダーを許可する必要がある
    - account-app


.spec.http

▼ httpとは

HTTP/1.1、HTTP/2.0 (例:gRPCなど) 、のプロトコルによるインバウンド通信をDestinationRuleに紐づくPodにルーティングする。

▼ fault

発生させるフォールトインジェクションを設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  http:
    - fault:
        - abort:
            # 発生させるエラー
            httpStatus: 503
            # エラーを発生させる確率
            percentage:
              value: 100

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  http:
    - fault:
        - delay:
            # レスポンスの遅延時間
            fixedDelay: 22s
            # 遅延レスポンスを発生させる割合
            percentage:
              value: 100

▼ retries.attempt

istio-proxyコンテナのリバースプロキシに失敗した場合の再試行回数を設定する。

Serviceへのルーティングの失敗ではないことに注意する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  http:
    - retries:
        attempts: 3

▼ retries.retryOn

再試行する失敗理由を設定する。

istio-proxyコンテナは、レスポンスのx-envoy-retry-onヘッダーに割り当てるため、これの値を設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  http:
    - retries:
        retryOn: "connect-failure,refused-stream,unavailable,503"

▼ timeout

istio-proxyコンテナの宛先にリクエストを送信する時のタイムアウト時間を設定する。

0秒の場合、タイムアウトは無制限になる。

これは、Envoyのルートのgrpc_timeout_header_maxtimeoutの両方に適用される。

指定した時間以内に、istio-proxyコンテナの宛先からレスポンスがなければ、istio-proxyコンテナはタイムアウトとして処理する。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  http:
    # destinationにリクエストを送信する時のタイムアウト時間
    - timeout: 40s
      route:
        - destination:
            # Service名でも良い
            host: foo-service.foo-namespace.svc.cluster.local
            port:
              number: 80
            subset: v1 # 旧Pod
          weight: 70
        - destination:
            # Service名でも良い
            host: foo-service.foo-namespace.svc.cluster.local
            port:
              number: 80
            subset: v2 # 新Pod
          weight: 30


.spec.http.match

▼ http.match

受信した通信のうち、ルールを適用するもののメッセージ構造を設定する。

▼ <ヘッダー名>

ヘッダー名で合致条件を設定する。

*実装例*

受信した通信のうち、x-fooヘッダーにbarが割り当てられたものだけにルールを適用する。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  http:
    - match:
        - headers:
            x-foo:
              exact: bar

▼ gateways

.spec.gatewaysキーで設定した<Gateway名>meshのうちで、その合致条件に使用する方を設定する。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  exportTo:
    - "*"
  hosts:
    - httpbin.org
  gateways:
    - foo-igressgateway
    - mesh
  http:
    - match:
        - gateways:
            # PodからIstio EgressGatewayのPodへの通信で使用する
            - mesh
          port: 443
      route:
        - destination:
            host: istio-egressgateway.istio-egress.svc.cluster.local
            port:
              number: 443
    - match:
        - gateways:
            # Istio EgressGatewayからエントリ済みシステムへの通信で使用する
            - foo-igressgateway
          port: 443
      route:
        - destination:
            host: httpbin.org
            port:
              number: 443

▼ uri

ヘッダー名で合致条件を設定する。

*実装例*

受信した通信のうち、URLの接頭辞が/fooのものだけにルールを適用する。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  http:
    - match:
        - headers:
            uri:
              prefix: /foo


.spec.http.route

▼ destination.host

受信した通信で宛先のServiceのドメイン名 (あるいはService名) を設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
spec:
  hosts:
    - foo-service.foo-namespace.svc.cluster.local
  http:
    - route:
        - destination:
            # Service名でも良い。
            host: foo-service.foo-namespace.svc.cluster.local

▼ destination.port

受信する通信でルーティング先のポート番号を設定する。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  hosts:
    - foo-service.foo-namespace.svc.cluster.local
  http:
    - route:
        - destination:
            host: foo-service.foo-namespace.svc.cluster.local
            port:
              number: 80

▼ destination.subset

istio_virtual-service_destination-rule_subset

VirtualServiceを起点としたPodのカナリアリリースで使用する。

紐付けたいDestinationRuleのサブセット名と同じ名前を設定する。

DestinationRuleで受信した通信を、DestinationRuleのサブセットに紐づくPodにルーティングする。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  hosts:
    - foo-service.foo-namespace.svc.cluster.local
  http:
    - route:
        - destination:
            # Service名でも良い
            host: foo-service.foo-namespace.svc.cluster.local
            port:
              number: 80
            subset: v1 # 旧Pod
          weight: 70
        - destination:
            # Service名でも良い
            host: foo-service.foo-namespace.svc.cluster.local
            port:
              number: 80
            subset: v2 # 新Pod
          weight: 30

▼ weight

Serviceの重み付けルーティングの割合を設定する。

.spec.http[*].route[*].destination.subsetキーの値は、DestinationRuleで設定した.spec.subsets[*].nameキーに合わせる必要がある。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  hosts:
    - foo-service.foo-namespace.svc.cluster.local
  http:
    - route:
        - destination:
            # Service名でも良い
            host: foo-service.foo-namespace.svc.cluster.local
            port:
              number: 80
            subset: v1 # 旧Pod
          weight: 70
        - destination:
            # Service名でも良い
            host: foo-service.foo-namespace.svc.cluster.local
            port:
              number: 80
            subset: v2 # 新Pod
          weight: 30


.spec.tcp

▼ tcpとは

TCPスリーウェイハンドシェイクの通信を、DestinationRuleに紐づくPodにルーティングする。

▼ match

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  tcp:
    - match:
        - port: 9000

▼ route.destination.host

.spec.httpキーと同じ機能である。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  hosts:
    - foo-service.foo-namespace.svc.cluster.local
  tcp:
    - route:
        - destination:
            # Service名でも良い
            # foo-service
            host: foo-service.foo-namespace.svc.cluster.local

▼ route.destination.port

.spec.httpキーと同じ機能である。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  hosts:
    - foo-service.foo-namespace.svc.cluster.local
  tcp:
    - route:
        - destination:
            # Service名でも良い
            # foo-service
            host: foo-service.foo-namespace.svc.cluster.local
            port:
              number: 9000

▼ route.destination.subset

.spec.httpキーと同じ機能である。

*実装例*

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  namespace: istio-system
  name: foo-virtual-service
spec:
  tcp:
    - route:
        - destination:
            # Service名でも良い
            # foo-service
            host: foo-service.foo-namespace.svc.cluster.local
            port:
              number: 9000
            subset: v1 # 旧Pod
          weight: 70
        - destination:
            # Service名でも良い
            # foo-service
            host: foo-service.foo-namespace.svc.cluster.local
            port:
              number: 9000
            subset: v2 # 新Pod
          weight: 30


宛先のServiceのポート番号について

Istioは、宛先のServiceに送信しようとするプロトコルを厳格に認識する。

宛先のServiceの.spec.ports[*].nameキー (<プロトコル名>-<任意の文字列>) または.spec.ports[*].appProtocolキーを認識し、そのServiceには指定されたプロトコルでしか通信を送れなくなる。

*例*

appProtocolを使用しない場合は以下の通りとなる。

apiVersion: v1
kind: Service
metadata:
  name: foo-service
spec:
  ports:
    # HTTPのみ
    - name: http-foo
      port: 80
apiVersion: v1
kind: Service
metadata:
  name: foo-service
spec:
  ports:
    # TCPのみ
    - name: tcp-foo
      port: 9000

*例*

appProtocolを使用する場合は以下の通りとなる。

apiVersion: v1
kind: Service
metadata:
  name: foo-service
spec:
  ports:
    # HTTPのみをVirtualServiceから送信できる
    - appProtocol: http
      port: 80
apiVersion: v1
kind: Service
metadata:
  name: foo-service
spec:
  ports:
    # TCPのみをVirtualServiceから送信できる
    - appProtocol: tcp
      port: 9000