前書き

サービスメッシュは、アプリケーションのマイクロサービス間の通信を管理できるインフラストラクチャレイヤーです。 より多くの開発者がマイクロサービスを使用するにつれて、サービスメッシュが進化し、分散セットアップで一般的な管理タスクと管理タスクを統合することにより、その作業がより簡単かつ効果的になりました。

アプリケーションアーキテクチャにマイクロサービスアプローチを採用するには、アプリケーションを疎結合サービスのコレクションに分割する必要があります。 このアプローチには特定の利点があります。チームは、より広範なツールと言語を使用して、設計を反復し、迅速に拡張できます。 一方、マイクロサービスは、運用の複雑さ、データの一貫性、およびセキュリティに関して新たな課題をもたらします。

サービスメッシュは、サービスが相互に通信する方法をきめ細かく制御することにより、これらの課題のいくつかに対処するように設計されています。 具体的には、開発者に以下を管理する方法を提供します。

  • サービス発見

  • ルーティングとトラフィックの構成

  • 暗号化と認証/承認

  • メトリックと監視

Kubernetesのようなコンテナオーケストレーターを使用してこれらのタスクをネイティブに実行することは可能ですが、このアプローチでは、httpsなどのサービスメッシュソリューションと比較して、より多くの事前の意思決定と管理が必要になります。 //istio.io/[Istio]およびhttps://linkerd.io/[Linkerd]はすぐに使用できます。 この意味で、サービスメッシュは、マイクロサービスアーキテクチャの一般的なコンポーネントを使用するプロセスを合理化および簡素化できます。 場合によっては、これらのコンポーネントの機能を拡張することもできます。

サービスメッシュが必要な理由

サービスメッシュは、分散アプリケーションアーキテクチャに固有のいくつかの課題に対処するように設計されています。

これらのアーキテクチャは、アプリケーションをWeb層、アプリケーション層、およびデータベース層に分割する3層アプリケーションモデルから発展しました。 大規模に、このモデルは急速な成長を経験している組織にとって挑戦的であることが証明されています。 モノリシックアプリケーションのコードベースは扱いにくいものになり、http://www.laputan.org/mud/ [「泥の大きな玉」]となり、開発と展開に課題が生じます。

この問題に対応して、Google、Netflix、Twitterなどの組織は、サービス全体のランタイム操作を標準化するための内部「脂肪クライアント」ライブラリを開発しました。 これらのライブラリは、サービスメッシュ機能の前兆であるロードバランシング、サーキットブレイク、ルーティング、およびテレメトリを提供しました。 ただし、開発者が使用できる言語に制限を課し、サービス自体が更新または変更された場合、サービス全体で変更を必要としました。

マイクロサービス設計により、これらの問題の一部が回避されます。 大規模な一元化されたアプリケーションコードベースを使用する代わりに、アプリケーションの機能を表す個別に管理されたサービスのコレクションがあります。 マイクロサービスアプローチの利点は次のとおりです。

  • チームがさまざまなアプリケーション機能に個別に取り組んで展開できるため、開発と展開の俊敏性が向上します。

  • 個々のマイクロサービスを個別にテストおよび再展開できるため、CI / CDのより良いオプション。

  • 言語とツールのその他のオプション。 開発者は、特定の言語またはツールセットに制限されるのではなく、手元のタスクに最適なツールを使用できます。

  • スケーリングが容易。

  • 稼働時間、ユーザーエクスペリエンス、および安定性の向上。

同時に、マイクロサービスには課題もあります。

  • 分散システムでは、待ち時間、ルーティング、非同期ワークフロー、および障害についてさまざまな考え方が必要です。

  • マイクロサービスのセットアップは、モノリシックのセットアップと同じデータ整合性の要件を必ずしも満たすことができません。

  • より高いレベルの配信では、特にサービス間の通信に関して、より複雑な運用設計が必要になります。

  • サービスの配布により、セキュリティの脆弱性の表面積が増加します。

サービスメッシュは、サービスの通信方法を調整してきめ細かく制御することにより、これらの問題に対処するように設計されています。 以下のセクションでは、サービスメッシュが、サービスの検出、ルーティングと内部負荷分散、トラフィックの構成、暗号化、認証と承認、およびメトリックと監視を通じてサービス間の通信を促進する方法を見ていきます。 Istioのhttps://istio.io/docs/examples/bookinfo/[Bookinfoサンプルアプリケーション]-特定の書籍に関する情報を一緒に表示する4つのマイクロサービス-サービスメッシュがどのように機能するかを示す具体例として使用します。

サービス発見

分散フレームワークでは、サービスに接続する方法と、サービスが利用可能かどうかを知る必要があります。 サービスインスタンスの場所はネットワーク上で動的に割り当てられ、コンテナに関する情報は絶えず変化します。コンテナは自動スケーリング、アップグレード、および障害によって作成および破棄されます。

歴史的に、マイクロサービスフレームワークでサービスを検出するためのツールがいくつかありました。 etcdなどのKey-Valueストアは、https://github.com/gliderlabs/registrator [Registrator]などの他のツールと組み合わせて、サービス検出ソリューションを提供しました。 Consulなどのツールは、ユーザーがDNSサーバーまたはノードを直接操作できるようにするキーと値のストアをDNSインターフェイスと組み合わせることでこれを繰り返しました。

同様のアプローチを採用して、KubernetesはデフォルトでDNSベースのサービス検出を提供します。 これを使用して、サービスとサービスポートを検索し、一般的なDNS命名規則を使用して逆IPルックアップを実行できます。 一般に、KubernetesサービスのAレコードはこのパターンに一致します: + .. svc.cluster.local。 Bookinfoアプリケーションのコンテキストでこれがどのように機能するかを見てみましょう。 たとえば、Bookinfoアプリの `+ details +`サービスに関する情報が必要な場合は、Kubernetesダッシュボードの関連エントリを確認できます。

image:https://assets.digitalocean.com/articles/service_mesh_intro/details_svc_k8.png [Kubernetes Dashの詳細サービス]

これにより、サービス名、名前空間、および「+ ClusterIP +」に関する関連情報が得られます。これらの情報を使用して、個々のコンテナが破棄および再作成されても、サービスに接続できます。

Istioのようなサービスメッシュは、サービス検出機能も提供します。 サービスの検出を行うために、Istioは、トラフィック管理コンポーネントhttps://istio.io/docs/concepts/what-is-istio/#pilot[Pilot]によって管理されるIstio独自のコントロールプレーンであるKubernetes API間の通信に依存しています。 Envoyサイドカープロキシによって管理されるデータプレーン。 パイロットはKubernetes APIサーバーからのデータを解釈して、ポッドの場所の変更を登録します。 次に、そのデータを標準的なIstio表現に変換し、サイドカープロキシに転送します。

これは、Istioでのサービス検出がプラットフォームに依存しないことを意味します。これは、Istioのhttps://istio.io/docs/tasks/telemetry/using-istio-dashboard/[Grafanaアドオン]を使用して `+ Istioのサービスダッシュボードのdetails + `サービス:

画像:https://assets.digitalocean.com/articles/service_mesh_intro/details_svc_istio.png [詳細サービスIstioダッシュ]

アプリケーションはKubernetesクラスター上で実行されているため、他のパフォーマンスデータとともに、「+ details +」サービスに関連するDNS情報を確認できます。

分散アーキテクチャでは、サービスに関する最新の、正確で、見つけやすい情報を保持することが重要です。 KubernetesとIstioのようなサービスメッシュの両方は、DNS規則を使用してこの情報を取得する方法を提供します。

ルーティングとトラフィックの構成

分散フレームワークでトラフィックを管理することは、クラスターへのトラフィックの到達方法とサービスへの転送方法を制御することを意味します。 外部および内部トラフィックを構成する際の制御と特異性が高いほど、セットアップでより多くのことができるようになります。 たとえば、カナリアデプロイメントで作業している場合、アプリケーションを新しいバージョンに移行する場合、またはフォールトインジェクションを使用して特定のサービスのストレステストを行う場合、サービスが取得するトラフィックの量と送信元を決定することが重要ですあなたの目的の成功。

Kubernetesは、開発者がクラスターへの外部トラフィックを制御できるさまざまなツール、オブジェクト、およびサービスを提供しています:https://kubernetes.io/docs/tasks/access-kubernetes-api/http-proxy-access-api/[+kubectl proxy + `]、https://kubernetes.io/docs/concepts/services-networking/service/nodeport [ + NodePort + ]、https://kubernetes.io/docs/concepts/services-networking/service/ loadbalancer [Load Balancers]、およびhttps://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-controllers[Ingress Controllers and Resources]。 `+ kubectl proxy +`と `+ NodePort +`の両方を使用すると、サービスを外部トラフィックにすばやく公開できます。+ kubectl proxy + はHTTPパスで静的コンテンツへのアクセスを許可するプロキシサーバーを作成し、 + NodePort + `はランダムに公開します各ノードに割り当てられたポート。 これは迅速なアクセスを提供しますが、欠点は、 `+ kubectl proxy `の場合は認証ユーザーとして ` kubectl `を実行する必要があり、 ` NodePort +`の場合はポートとノードIPに柔軟性がないことです。 また、ロードバランサーは特定のサービスにアタッチすることで柔軟性を最適化しますが、各サービスには独自のロードバランサーが必要であり、コストがかかる可能性があります。

IngressリソースとIngress Controllerを組み合わせることで、これらの他のオプションよりも高い柔軟性と設定可能性が得られます。 入力リソースで入力コントローラーを使用すると、外部トラフィックをサービスにルーティングし、内部ルーティングと負荷分散を構成できます。 イングレスリソースを使用するには、サービス、イングレスコントローラーと + LoadBalancer +、およびイングレスリソース自体を設定する必要があります。これらは、サービスへの目的のルートを指定します。 現在、Kubernetesは独自のhttps://github.com/kubernetes/ingress-nginx/blob/master/README.md[Nginx Controller]をサポートしていますが、https://で管理される他のオプションも選択できます。 www.nginx.com/products/nginx/kubernetes-ingress-controller[Nginx]、https://konghq.com/blog/kubernetes-ingress-controller-for-kong/[Kong]など。

Istioはhttps://istio.io/docs/reference/config/istio.networking.v1alpha3/#Gateway[Istio Gateways]およびhttps://istio.io/docs/reference/configを使用してKubernetes Controller / Resourceパターンを反復処理します/istio.networking.v1alpha3/#VirtualService[VirtualServices]。 入口コントローラーと同様に、ゲートウェイは、使用する公開ポートとプロトコルを指定して、着信トラフィックの処理方法を定義します。 これは、メッシュ内のサービスへのルートを定義するVirtualServiceと連携して機能します。 これらのリソースは両方とも情報をPilotに伝達し、Pilotはその情報をEnvoyプロキシに転送します。 ゲートウェイとVirtualServicesは、イングレスコントローラーとリソースに似ていますが、トラフィックに対する異なるレベルの制御を提供します。https://en.wikipedia.org/wiki/OSI_model [Open Systems Interconnection(OSI)layer and protocols]を組み合わせる代わりに、ゲートウェイとVirtualServiceを使用すると、設定でOSIレイヤーを区別できます。 たとえば、VirtualServicesを使用することで、アプリケーション層の仕様を扱うチームは、さまざまな層の仕様を扱うセキュリティ運用チームから懸念事項を分離できます。 VirtualServicesは、個別のアプリケーション機能または異なる信頼ドメイン内で作業を分離することを可能にし、カナリアテスト、段階的なロールアウト、A / Bテストなどの用途に使用できます。

サービス間の関係を視覚化するには、Istioのhttps://istio.io/docs/tasks/telemetry/servicegraph/[Servicegraphアドオン]を使用できます。これにより、リアルタイムのトラフィックデータを使用してサービス間の関係の動的な表現が生成されます。 Bookinfoアプリケーションは、カスタムルーティングが適用されていない場合、次のようになります。

image:https://assets.digitalocean.com/articles/service_mesh_intro/istio_mini_graph.png [Bookinfoサービスグラフ]

同様に、https://www.weave.works/docs/scope/latest/introducing/ [Weave Scope]などの視覚化ツールを使用して、特定の時間におけるサービス間の関係を確認できます。 高度なルーティングのないBookinfoアプリケーションは次のようになります。

image:https://assets.digitalocean.com/articles/service_mesh_intro/weave_scope_service_dash.png [Weave Scope Service Map]

分散フレームワークでアプリケーショントラフィックを構成する場合、KubernetesネイティブオプションからIstioなどのサービスメッシュまで、外部トラフィックがアプリケーションリソースに到達する方法とこれらのリソースがどのように通信するかを決定するさまざまなオプションを提供する多くの異なるソリューションがあります別の。

暗号化と認証/承認

分散フレームワークは、セキュリティの脆弱性の機会を提供します。 モノリシックセットアップの場合のように、ローカル内部コールを介して通信する代わりに、マイクロサービスアーキテクチャのサービスは、特権情報を含む情報をネットワーク経由で通信します。 全体として、これは攻撃のためのより大きな表面積を作成します。

Kubernetesクラスターを保護するには、さまざまな手順が必要です。認証、承認、暗号化に焦点を当てます。 Kubernetesは、これらのそれぞれに対してネイティブアプローチを提供します。

  • Authentication:KubernetesのAPIリクエストは、認証が必要なユーザーアカウントまたはサービスアカウントに関連付けられています。 必要な資格情報を管理する方法はいくつかあります。静的トークン、ブートストラップトークン、X509クライアント証明書、https://openid.net/connect/ [OpenID Connect]などの外部ツールです。

  • Authorization:Kubernetesには、ロール、属性、その他の特殊な機能などに基づいてアクセスを決定できるさまざまな承認モジュールがあります。 APIサーバーへのすべてのリクエストはデフォルトで拒否されるため、APIリクエストの各部分は認可ポリシーで定義する必要があります。

  • 暗号化:これは、エンドユーザーとサービス間の接続、秘密データ、Kubernetesコントロールプレーンのエンドポイント、ワーカークラスターコンポーネントとマスターコンポーネント間の通信のいずれかを指します。 Kubernetesには、これらのそれぞれに対して異なるソリューションがあります。

  • Ingress Controllers and Resources。https://github.com/jetstack/cert-managerなどのアドオンと組み合わせて使用​​できます[ cert-manager] TLS証明書を管理します。

  • `+ etcd +`のシークレットリソースを暗号化するためのhttps://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/ [保存中のシークレットデータの暗号化]。

  • TLS bootstrappingを使用してkubeletsのクライアント証明書をブートストラップし、ワーカーノードと `+ kube-apisever +`間の通信を保護します。 Weave Netのようなオーバーレイネットワークをhttps://www.weave.works/docs/net/latestに使用することもできます。 / concepts / encryption-implementation / [これを行う]。

Kubernetesで個別のセキュリティポリシーとプロトコルを構成するには、管理投資が必要です。 Istioのようなサービスメッシュは、これらのアクティビティの一部を統合できます。

Istioは、サービスを保護する作業の一部を自動化するように設計されています。 そのコントロールプレーンには、セキュリティを処理するいくつかのコンポーネントが含まれています。

  • * Citadel *:キーと証明書を管理します。

  • パイロット:認証および命名ポリシーを監督し、この情報をEnvoyプロキシと共有します。

  • ミキサー:認証と監査を管理します。

たとえば、サービスを作成すると、Citadelは `+ kube-apiserver +`からその情報を受け取り、このサービスのhttps://spiffe.io/[SPIFFE]証明書とキーを作成します。 次に、この情報をPodsおよびEnvoyサイドカーに転送して、サービス間の通信を促進します。

Istioのインストール中にhttps://istio.io/docs/concepts/security/#mutual-tls-authentication [相互TLSを有効化]することにより、いくつかのセキュリティ機能を実装することもできます。 これには、クラスター間およびクラスター間の通信、サービス間およびユーザー間の安全な通信のための強力なサービスID、およびキーと証明書の作成、配布、ローテーションを自動化できるキー管理システムが含まれます。

Kubernetesが認証、承認、暗号化を処理する方法を繰り返すことで、Istioのようなサービスメッシュは、安全なKubernetesクラスターを実行するための推奨ベストプラクティスの一部を統合および拡張できます。

メトリックと監視

分散環境により、メトリックと監視の要件が変更されました。 監視ツールは、サービスとネットワークアドレスへの頻繁な変更に対応し、包括的で、サービス間でやり取りされる情報の量と種類を考慮して、適応性が必要です。

Kubernetesには、デフォルトでいくつかの内部監視ツールが含まれています。 これらのリソースはhttps://kubernetes.io/docs/tasks/debug-application-cluster/resource-usage-monitoring/#resource-metrics-pipeline [リソースメトリックパイプライン]に属しているため、クラスターが期待どおりに実行されます。 cAdvisorコンポーネントは、個々のコンテナおよびノー​​ドからネットワーク使用量、メモリ、およびCPU統計を収集し、その情報をkubelet; kubeletは、REST APIを介してその情報を公開します。 Metrics Serverはこの情報をAPIから取得し、https:// githubに渡します.com / kubernetes / kube-aggregator [+ kube-aggregator +]でフォーマットします。

これらの内部ツールと監視機能を完全なメトリックソリューションで拡張できます。 Prometheusなどのサービスをメトリックアグリゲーターとして使用すると、Kubernetesリソースメトリックパイプラインの上に直接構築できます。 Prometheusは、ノード上にある独自のエージェントを介してcAdvisorと直接統合します。 メインの集約サービスは、ノードからデータを収集して保存し、ダッシュボードとAPIを通じて公開します。 メインの集約サービスをhttps://www.influxdata.com/time-series-platform/influxdb/[InfluxDB]などのバックエンドストレージ、ロギング、および視覚化ツールと統合することを選択した場合、追加のストレージおよび視覚化オプションも利用できます。 ://grafana.com/ [Grafana]、https://www.elastic.co/ [ElasticSearch]、https://www.elastic.co/products/logstash [Logstash]、https://www.elastic。 co / products / kibana [Kibana]など。

Istioのようなサービスメッシュでは、完全なメトリックパイプラインの構造はメッシュの設計の一部です。 ポッドレベルで動作するEnvoyサイドカーは、ポリシーとテレメトリを管理するhttps://istio.io/docs/concepts/policies-and-telemetry/[Mixer]にメトリックを伝達します。 さらに、PrometheusおよびGrafanaサービスはデフォルトで有効になっています(ただし、https://helm.sh/ [Helm]でIstioをインストールする場合は、https://github.com/istio/istio/tree/master/installが必要です。 / kubernetes / helm / istio#configuration [インストール中に `+ granafa.enabled = true +`を指定])。 完全なメトリックパイプラインの場合と同様に、ロギングオプションと表示オプションについてhttps://istio.io/docs/tasks/telemetry/fluentd/ [他のサービスとデプロイを構成]することもできます。

これらのメトリックツールと視覚化ツールを使用すると、サービスとワークロードに関する現在の情報に一元的にアクセスできます。 たとえば、BookInfoアプリケーションのグローバルビューは、Istio Grafanaダッシュボードでは次のようになります。

画像:https://assets.digitalocean.com/articles/service_mesh_intro/grafana_bookinfo_istio_mesh_dash.png [Grafana dashのBookinfoサービス]

Kubernetesの完全なメトリックパイプラインの構造を複製し、その一般的なコンポーネントへのアクセスを簡素化することにより、Istioのようなサービスメッシュは、クラスターで作業する際のデータ収集と視覚化のプロセスを合理化します。

結論

マイクロサービスアーキテクチャは、アプリケーションの開発と展開を高速で信頼性のあるものにするように設計されています。 しかし、サービス間通信の増加により、特定の管理タスクのベストプラクティスが変わりました。 この記事では、これらのタスクの一部、Kubernetesネイティブコンテキストでの処理方法、サービスメッシュ(この場合はIstio)を使用した管理方法について説明します。

ここで取り上げるKubernetesのトピックの詳細については、次のリソースを参照してください。

さらに、https://kubernetes.io/docs/home/ [Kubernetes]およびhttps://istio.io/docs/[Istio]ドキュメントハブは、ここで説明しているトピックに関する詳細情報を見つけるのに最適な場所です。