32
26

More than 5 years have passed since last update.

Istioは何ができるか

Last updated at Posted at 2019-08-22

マイクロサービスの課題

マイクロサービスの課題の中で以下のものがあります

  • 障害の連鎖
    • 1つのサービスが障害でレスポンスが悪くなった場合、他のサービスのレスポンスも悪くなり、さらにはシステム全体に影響が出てしまう場合がある
  • 障害が起きているもしくはレスポンスタイムが悪いサービスの特定
    • 1つのレスポンスの中で複数のマイクロサービスを呼び出すと、どのマイクロサービスが原因でエラーになっているのか、またはレスポンスタイムが悪くなっているのか、特定が容易ではなくなる
  • カナリーリリース
    • 複数のマイクロサービスが絡み合っている場合、カナリーリリースをしようとすると複雑になりがち。
    • サービスAとBとCがあって、リクエストの10%だけAとCの新バージョンにリクエストを流す場合とか
  • マイクロサービス間の通信の安全性
    • とあるマイクロサービスからのアクセスは本当に私達がデプロイした正規のマイクロサービスからのリクエストか?

これらの課題をサービスメッシュを使うことで解決できます。

サービスメッシュとは

サービスメッシュはサービス間通信を処理するソフトウェアレイヤーで、アプリケーションに代わってネットワーク要求を処理するヘルパーサービスです。

以下がサービスメッシュが提供する代表的な機能

  • トラフィック制御
  • 通信の回復性、耐障害性
  • 通信の可視化、分散トレーシング
  • 通信の認証、セキュリティ機能

Istioとは?

  • Google, IBM, Lyft社 共同開発によりOSS化されたサービスメッシュ
  • 環境非依存で複数のプラットフォームで利用可能
    • Kubernetes, Nomad & Consul, etc
  • Kubernetes Pod内にプロキシ(Envoy)をSidecarとしてデプロイするため コードを変更することなくサービスメッシュ機能の追加が可能
    • EnvoyはCNCFホストのプロジェクトで、ハイパフォーマンスなL4/L7プロキシーサーバ(ロードバランサー)
      • Envoyには以下のような機能がある
        • Dynamic service discovery
        • Load balancing
        • TLS termination
        • HTTP/2 and gRPC proxies
        • Circuit breakers
        • Health checks
        • Staged rollouts with %-based traffic split
        • Fault injection
        • Rich metrics

KubernetesにIstioを入れた場合の構成図

スクリーンショット 2019-08-10 17.03.19.png

リクエストはすべてプロキシサーバーであるEnvoyが担当します。これによりアプリケーションを修正することなく、ネットワークの制御が可能になっています。
またEnvoyはPodのサイドカーとしてデプロイされるためアプリケーションのコードを修正する必要がありません。
コントロールプレーンは、トラフィックルートのプロキシの管理や設定を行います。またポリシーの実施やテレメトリー(メトリックスやログ)の収集を行います。

Istioの機能

Load Balancing

サポートされているロードバランシングアルゴリズム
https://www.envoyproxy.io/docs/envoy/v1.5.0/intro/arch_overview/load_balancing#supported-load-balancers

  • Random
  • Round robin
  • Original destination
    • リクエスト情報をもとに、常に同じサーバーへリクエストを送る (sticky sessionのようなもの)
  • Weighted least request
    • 接続数が少ないサーバーへリクエストを送る
  • Ring hash
    • Consistent Hashingの一種

Traffic Management

Request Routing

  • URLやRequest Headerの中身をみてルーティングを設定することができる

例:

リクエストヘッダーにend-user: jasonが含まれていれば、reviewsサービスのv2にリクエストがいき、
その他はreviewsサービスのv1にリクエストがいく。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

Traffic Shifting

  • リクエストを流す割合を指定できる。例えば既存バージョンと新しいバージョンのアプリケーションに対して、新しいバージョンは1%しかリクエストを流さないということができる(カナリーリリース)

例:

90%のリクエストはreviewsサービスのv1にいき、残りの10%はv2にいく。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 90
    - destination:
        host: reviews
        subset: v2
      weight: 10

Request Timeouts

  • リクエストタイムアウト値を設定できる
    • これにより、レスポンスタイムが異常に悪いマイクロサービスが存在することによって他のマイクロサービスにまで影響がでることを防げる

例:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
    timeout: 9s

reviews v1へのリクエストは9秒でタイムアウトする

Retry

  • リトライ回数を設定することができる。これにより、とあるマイクロサービスへのリクエストがたまたまリクエスト処理に時間がかかっている場合に、リクエストをリトライさせることができる
  • n秒間以上リクエストに処理がかかった場合、n回リトライさせるといった設定ができる

例:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
    timeout: 9s          # 1
    retries:
      attempts: 3        # 2
      perTryTimeout: 3s  # 3
  • 1: 1つのリクエストのタイムアウトは9秒
  • 2: 3回リトライする
  • 3: 1回のリトライのタイムアウト値は3秒

つまり、1リクエストの中で最大3回リトライする

Circuit Breaking

  • 障害が発生したマイクロサービスによって、システム全体に影響が発生することがあります。これを防ぐための仕組みとしてサーキット・ブレーカーというものがあります。サーキット・ブレーカーは、とあるマイクロサービスに継続的に障害が発生している場合にはそのマイクロサービスからのリクエストタイムアウトを待たずにエラーを返します。
    • n秒間の間に500系エラーがn回返った場合、n秒間そのマイクロサービスからのリクエストタイムアウトを待たずにエラーを返す といった設定ができる

例:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: httpbin
spec:
  host: httpbin
  trafficPolicy:
    ...
    outlierDetection:
      consecutiveErrors: 7  # 継続した障害だと判定されるエラー(500系)数
      interval: 10s         # 解析を行う間隔
      baseEjectionTime: 30s # consecutiveErrorsの上限を越したときに、ホストが即時エラーを返す最小期間

とあるPodから10秒間の間に7回以上500エラーが返った返った場合、30秒間そのPodへリクエストは送られないようにする

Fault Injection

  • アプリケーションの信頼性をテストするために、ネットワーク層の障害を注入することができる(ネットワーク層のカオスエンジニアリング)
  • 例えばn%のリクエストをn秒間遅らせたり、n%のリクエストを特定のhttp status(例えば500エラー)を返すようにできたりする。
  • これによりアプリケーションの変更なしに簡単マイクロサービスの耐障害性をテストすることができる

delayを注入する例:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
  ...
spec:
  hosts:
  - ratings
  http:
  - fault:
      delay:
        fixedDelay: 7s
        percent: 90
    match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1

リクエストヘッダーにend-user: jasonが含まれている場合、そのリクエストの90%を7秒遅延させる

エラーを注入する例:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
  ...
spec:
  hosts:
  - ratings
  http:
  - fault:
      abort:
        httpStatus: 500
        percent: 90
    match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1

リクエストヘッダーにend-user: jasonが含まれている場合、そのリクエストの90%はHttpStatus: 500を返すようにさせる

Mirroring

  • 別のサービスにリクエストをコピーして送る
  • これにより、本番と同等のステージング環境が作れたり、新しい機能や新しいクラスタが問題なく動くかをユーザに影響なしにテストすることが可能になる。

例:

kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 100
    mirror:
      host: reviews
      subset: v2

reviews v1へのリクエストをv2にコピーして送る

Security

Istioのセキュリティゴール

  • Security by default
    • アプリケーションコードとインフラの変更を必要としない
  • Defense in depth
    • 複数の防御レイヤーを提供するために、既存のセキュリティシステムと連携
  • Zero-trust network
    • 信頼できないネットワーク上にセキュリティソリューションを構築

認証機能(Authentication)

  • 相互 TLS 認証
  • エンドユーザ認証
    • JWTトークンによるリクエストレベルの認証
    • Auth0、Firebase Auth、Google Auth、カスタム認証
  • 鍵管理
    • Istio の鍵管理システムは、鍵と証明書の生成、配布、ローテーション、失効を自動化します。
  • 役割ベースのアクセス制御(RBAC)

Policies

Rate Limits

ある一定時間のアクセス量を設定できる。
たとえば /timeline へのアクセスは1秒間100リクエストまで受け付け、100を超えたら429エラー(Too Many Requests)にできる。

Denials

特定の条件を満たすリクエストを遮断する

White/Black Listing

特定の条件を満たすリクエストのホワイトリスト/ブラックリストを定義できる

Observability

Logging

トラフィックに関するログ情報を標準出力したり、FluentdやStackdriverに送ることができる
https://istio.io/docs/reference/config/policy-and-telemetry/templates/

Metrics

トラフィックの各種統計情報
一般的には送信元/送信先、送信時刻といった情報が含まれる
Istioではこれ以外にも任意の情報をメトリックとして扱うことが可能
プラグイン機構によって以下のようなサービスにメトリックスを送信することができる

  • Amazon CloudWatch
  • Prometheus
  • Stackdriver
  • Datadog
  • Fluentd
  • etc

Grafana

Grafanaで可視化した様子
スクリーンショット 2019-08-12 13.12.00.png

Kiali

Istioはすべてのネットワークを把握しているので、どのコンポーネントにリクエストが送られていて、そのネットワークはどのくらい健康なのかを可視化できる。

以下はKialiを使ってネットワークグラフを表示したもの。グラフは自動で生成してくれる。

スクリーンショット 2019-08-12 13.19.32.png

アニメーションON

アニメーションONにするとリクエストの様子が見れてちょっと楽しい

Aug-12-2019 13-38-09.gif

Tracing

分散トレーシングとは

分散トレーシングとはマイクロサービスのような分散されたサービスで処理されるリクエストを追跡(トレーシング)するためのもの。
マイクロサービスのような分散アーキテクチャでは、1つのリクエストが複数のサービスで処理されることになり、リクエスト全体の処理の流れの把握やボトルネックの特定が難しくなります。
このような問題を、サービスの依存関係やサービス単位のレイテンシーの可視化をすることによって、解決の手助けするためのシステムが分散トレーシングシステムです。
具体的には1リクエストの中でどのサービスが呼ばれ、どのくらい時間がかかったのかを、ユニークなidをリクエストヘッダーに付与することでトレーシングできるようにします。またそれらを可視化もできる。

サポートしているトレーシングツール

Jaeger

どのコンポーネントが遅いか可視化してくれる
スクリーンショット 2019-08-12 13.14.01.png

Zipkin
LightStep

アプリケーション側で上記のような分散トレーシングツールを使う場合、Envoyが生成したトレースヘッダーを独自に伝播させる実装を行う必要がある。

参考

32
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
26