Upgrade to Pro — share decks privately, control downloads, hide ads and more …

⛵️ Istioのサービス間通信を実現するサービスディスカバリーの仕組み

⛵️ Istioのサービス間通信を実現するサービスディスカバリーの仕組み

3-shake SRE Tech Talk』の登壇資料です

Istioのサービスディスカバリーの仕組みについて、Envoyを交えながら解説しました。

スライドでは仕組みの詳細を解説できませんでしたので、ぜひ元記事 (Istioのサービス間通信を実現するサービスディスカバリーの仕組み) も参照ください👍

長谷川広樹

December 15, 2022
Tweet

More Decks by 長谷川広樹

Other Decks in Programming

Transcript

  1. 1 2022/12/15 3-shake SRE Tech Talk 株式会社スリーシェイク 長谷川広樹 @Hiroki_IT github.com/hiroki-it

    hiroki-hasegawa.hatenablog.jp はてな Istio のサービス間通信を実現する サービスディスカバリーの 仕組み
  2. マイクロサービスアーキのインフラ領域が仕事 ・マイクロサービスアーキを支えるインフラ技術 ・ドメイン駆動設計 俺です 社内で色々ふざけ過ぎてるので、そろそろ怒られるかもー ・サービスメッシュ (Istio ←推し❤) ・IaC (Kubernetes,

    Helm, Terraform) ・CICD (GitLab CI, ArgoCD) ・監視 (Prometheus, Fluentd, Kiali, OpenTelemetry入門中) ・クラウドインフラ (AWS, ちょいGoogle Cloud) マイクロサービスアーキ関連の技術が好き 虫捕りついでに 虫食ってた話 する?
  3. SDの要素 要素 責務 送信元マイクロサービス リクエストを送信 宛先マイクロサービス リクエストを受信 サービスレジストリ 宛先マイクロサービスの宛先情報を保管 ロードバランサー

    宛先マイクロサービスのインスタンスにロードバランシング 名前解決 DNSベースのSDで使用するため、IstioのSDでは扱わない
  4. IstioによるSDの仕組み Podに自動注入される istio-proxyコンテナが軸 1. kube-apiserverがPod等の宛先情報を etcdなどに保管 (これはK8sの通常の仕組み) 2. discoveryはkube-apiserverから Pod等の宛先情報を取得して保管

    3. istio-proxyはdiscoveryから Pod等の宛先情報を取得 4. 送信元マイクロサービスが 宛先マイクロサービスにリクエストを送信し iptablesがistio-proxyにリダイレクト 5. istio-proxy内でロードバランシングされ 宛先Podにリクエストを送信
  5. IstioによるSDの仕組み istio-proxyを少し詳しく... 1. kube-apiserverがPod等の宛先情報を etcdなどに保管 (これはK8sの通常の仕組み) 2. discoveryはkube-apiserverから Pod等の宛先情報を取得してメモリ上に保管 3.

    istio-proxy内のEnvoyはpilot-agentを介して discoveryのADS-APIからPod等の宛先情報を取得 4. 送信元マイクロサービスが 宛先マイクロサービスにリクエストを送信し iptablesがistio-proxyにリダイレクト 5. istio-proxy内のEnvoyは 宛先Podにリクエストをロードバラシング
  6. EnvoyがADS-APIから取得した情報を見てみよう $ kubectl exec \ -it foo-pod \ -n foo-namespace

    \ -c istio-proxy \ -- bash -c "curl http://localhost:15000/config_dump" | yq -P 実際にEnvoyに登録されている宛先情報は istio-proxyの localhost:15000/config_dump からJSONで取得可能 JSONだと見にくいので、yqコマンドでYAMLに変換するとよい フォントサイズの制約上『中略』が多くなっています󰣹 お手元のIstioで、後ほどEnvoyをじっくり冒険していただけると
  7. リスナー値を確認する istio-proxyがADS-APIから取得したリスナー値は /config_dump?resource={dynamic_listeners} から確認できる $ kubectl exec \ -it foo-pod

    \ -n foo-namespace \ -c istio-proxy \ -- bash -c "curl http://localhost:15000/config_dump?resource={dynamic_listeners}" | yq -P ここでは foo-pod内でbar-podのリスナー値を 確認したとする
  8. configs: - "@type": type.googleapis.com/envoy.admin.v3.ListenersConfigDump.DynamicListener name: 0.0.0.0_50002 # リスナー名 active_state: listener:

    "@type": type.googleapis.com/envoy.config.listener.v3.Listener name: 0.0.0.0_50002 address: socket_address: address: 0.0.0.0 # 受信したパケットのうちで、宛先 IPアドレスでフィルタリング port_value: 50002 # 受信したパケットのうちで、宛先ポート番号でフィルタリング filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager rds: route_config_name: 50002 # 本リスナーに紐づくルート名 ... 中略 - "@type": type.googleapis.com/envoy.admin.v3.ListenersConfigDump.DynamicListener ... 中略
  9. ルート値を確認する $ kubectl exec \ -it foo-pod \ -n foo-namespace

    \ -c istio-proxy \ -- bash -c "curl http://localhost:15000/config_dump?resource={dynamic_route_configs}" | yq -P istio-proxyがADS-APIから取得したルート値は /config_dump?resource={dynamic_route_configs} から確認できる ここでは foo-pod内でbar-podのルート値を 確認したとする
  10. configs: - "@type": type.googleapis.com/envoy.admin.v3.RoutesConfigDump.DynamicRouteConfig route_config: "@type": type.googleapis.com/envoy.config.route.v3.RouteConfiguration name: 50002 #

    ルート名 virtual_hosts: - name: bar-service.bar-namespace.svc.cluster.local:50002 domains: - bar-service.bar-namespace.svc.cluster.local # ホストベースルーティング ... 中略 routes: - match: prefix: / # パスベースルーティング route: cluster: outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local # 本ルートに紐づくクラスター名 ... 中略 - '@type': type.googleapis.com/envoy.admin.v3.RoutesConfigDump.DynamicRouteConfig ... 中略
  11. クラスター値を確認する $ kubectl exec \ -it foo-pod \ -n foo-namespace

    \ -c istio-proxy \ -- bash -c "curl http://localhost:15000/config_dump?resource={dynamic_active_clusters}" | yq -P istio-proxyがADS-APIから取得したクラスター値は /config_dump?resource={dynamic_active_clusters} から確認できる ここでは foo-pod内でbar-podのクラスター値を 確認したとする
  12. configs: - "@type": type.googleapis.com/envoy.admin.v3.ClustersConfigDump.DynamicCluster cluster: "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster name: outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local #

    クラスター名 type: EDS eds_cluster_config: eds_config: ads: {} initial_fetch_timeout: 0s resource_api_version: V3 # クラスターに紐づくエンドポイントの親名 service_name: outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local ... 中略 - "@type": type.googleapis.com/envoy.admin.v3.ClustersConfigDump.DynamicCluster ... 中略
  13. エンドポイント値を確認する ここでは foo-pod内でbar-podのエンドポイント値を 確認したとする $ kubectl exec \ -it foo-pod

    \ -n foo-namespace \ -c istio-proxy \ -- bash -c "curl http://localhost:15000/config_dump?include_eds" | yq -P istio-proxyがADS-APIから取得したエンドポイント値は /config_dump?include_eds から確認できる
  14. configs: dynamic_endpoint_configs: - endpoint_config: "@type": type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment cluster_name: outbound|50002|v1|bar-service.bar-namespace.svc.cluster.local # エンドポイントの親名を指定している。

    endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 11.0.0.1 # 冗長化されたbar-podのIPアドレス port_value: 50002 # bar-pod内のコンテナが待ち受けているポート番号 ... 中略 - endpoint: address: socket_address: address: 11.0.0.2 # 冗長化されたbar-podのIPアドレス port_value: 50002 # bar-pod内のコンテナが待ち受けているポート番号 ... 中略 - endpoint_config: ... 中略