Kubernetesがサービスディスカバリを実装する方法について話す

Kubernetesがサービスディスカバリを実装する方法について話す

Kubernetes サービスの検出についてお話ししましょう。したがって、まず前提として、ホスト内通信とホスト間通信の両方が正常であること、つまり、同じ Kubernetes クラスター内のすべての Pod が相互運用可能であることが求められます。これは、docker0/CNI ブリッジ、Flannel vxlan/host-gw モードなどの低レベルのソリューションによって実現されますが、この記事では説明しません。

[[422281]]

すべての Pod が相互接続されているという前提の下では、podIP にアクセスすることで Pod 上のリソースを呼び出すことができますが、サービス検出までどのくらいかかるのでしょうか?まず、Pod IP は固定ではありません。一方、Pod インスタンスのグループにアクセスする場合は、負荷分散が必要になることがよくあります。このような問題を解決するために、Service オブジェクトが使用されます。

クラスター内通信

エンドポイント

サービスはまず、クラスター内の通信の必要性を解決します。まず、一般的なデプロイメントを記述します。

  1. APIバージョン: アプリ/v1
  2. 種類: デプロイメント
  3. メタデータ:
  4. 名前: ホスト名
  5. 仕様:
  6. セレクタ:
  7. 一致ラベル:
  8. アプリ:ホスト名
  9. レプリカ: 3
  10. テンプレート:
  11. メタデータ:
  12. ラベル:
  13. アプリ:ホスト名
  14. 仕様:
  15. コンテナ:
  16. - name : ホスト名
  17. イメージ: mirrorgooglecontainers/serve_hostname
  18. ポート:
  19. - コンテナポート: 9376
  20. プロトコル: TCP

このアプリケーションは、アクセス時に独自のホスト名を返すもので、各 Pod にはホスト名として APP というラベルが付けられます。

次に、これらのポッドに共通の Service を記述します。

  1. APIバージョン: v1
  2. 種類: サービス
  3. メタデータ:
  4. 名前: ホスト名
  5. 仕様:
  6. セレクタ:
  7. アプリ:ホスト名
  8. ポート:
  9. -名前:デフォルト 
  10. プロトコル: TCP
  11. ポート: 80
  12. ターゲットポート: 9376

サービスがセレクターを通じて対応するラベルを持つポッドを選択し、選択されたこれらのポッドがエンドポイントになることがわかります。試してみましょう:

  1. ~/cloud/k8s kubectl epホスト名を取得する
  2. 名前エンドポイント
  3. ホスト名 172.28.21.66:9376,172.28.29.52:9376,172.28.70.13:9376

Pod に問題がある場合、実行状態でない場合、または readinessProbe に失敗した場合、その Pod はエンドポイント リストから削除されます。

クラスターIP

上記にはサービスとエンドポイントがあり、作成されるサービスのデフォルト タイプは ClusterIP タイプです。先ほど作成したサービスを見てみましょう。

  1. ~ kubectl svc ホスト名を取得する
  2. 名前タイプ クラスター IP 外部 IP ポート 年齢
  3. ホスト名 ClusterIP 10.212.8.127 <なし> 80/TCP 8m2s

ClusterIP は 10.212.8.127 であることがわかります。これで、Kubernetes クラスターのこのアドレスを介してエンドポイント リスト内の任意の Pod にアクセスできるようになります。

  1. sh-4.2# カール 10.212.8.127
  2. ホスト名-8548b869d7-9qk6b
  3. sh-4.2# カール 10.212.8.127
  4. ホスト名-8548b869d7-wzksp
  5. sh-4.2# カール 10.212.8.127
  6. ホスト名-8548b869d7-bvlw8

ClusterIP アドレスに 3 回アクセスし、3 つの異なるホスト名を返した後、ClusterIP モード サービスが要求に対してラウンドロビン負荷分散を自動的に実行していることがわかりました。

現時点での ClusterIP モード サービスには、ClusterIP アドレスを指す service-name.namespace-name.svc.cluster.local の A レコードがあります。

  1. sh-4.2# nslookup ホスト名.coops- dev.svc.cluster.local  
  2. サーバー: 10.212.0.2
  3. アドレス: 10.212.0.2#53
  4.  
  5. 名前: hostnames.coops-dev.svc.cluster。地元 
  6. 住所: 10.212.8.127

もちろん、この A レコードを介してアクセスすることでも同じ効果が得られます。

  1. sh-4.2# curl ホスト名.coops- dev.svc.cluster.local  
  2. ホスト名-8548b869d7-wzksp

では、Pod の A レコードとは何でしょうか?見てみましょう:

  1. sh-4.2# nslookup 172.28.21.66  
  2. 66.21.28.172. -addr.arpa name = 172-28-21-66.hostnames.coops-dev.svc.cluster です地元

ヘッドレスサービス

デフォルトでは、サービスの CluserIP は Kubernetes によって自動的に割り当てられますが、自分で設定することもできます。 CluserIP を None に設定すると、ヘッドレス サービスになります。

ヘッドレス サービスは通常、StatefulSet とともに使用されます。 StatefulSet は、ステートフル アプリケーション向けのコンテナ オーケストレーション メソッドです。基本的な考え方は、Pod に特定の番号名を付けて、Pod が不変の一意のネットワーク識別コードを持つようにすることです。この場合、仮想 VIP ではなく特定の識別子を介して Pod 自体に直接アクセスする必要があるため、CluserIP ロード バランシングを使用して Pod にアクセスする方法は明らかに実行可能ではありません。

この時点で、実際に DNS を使用できます。各 Pod には、podIP を指す A レコード pod-name.service-name.namespace-name.svc.cluster.local が存在します。この A レコードを通じて Pod に直接アクセスできます。

対応する StatefulSet と Service を記述して確認してみましょう。

  1. ---  
  2. APIバージョン: アプリ/v1
  3. 種類: ステートフルセット
  4. メタデータ:
  5. 名前: ホスト名
  6. 仕様:
  7. サービス名: "ホスト名"  
  8. セレクタ:
  9. 一致ラベル:
  10. アプリ:ホスト名
  11. レプリカ: 3
  12. テンプレート:
  13. メタデータ:
  14. ラベル:
  15. アプリ:ホスト名
  16. 仕様:
  17. コンテナ:
  18. - name : ホスト名
  19. イメージ: mirrorgooglecontainers/serve_hostname
  20. ポート:
  21. - コンテナポート: 9376
  22. プロトコル: TCP
  23.  
  24. ---  
  25. APIバージョン: v1
  26. 種類: サービス
  27. メタデータ:
  28. 名前: ホスト名
  29. 仕様:
  30. セレクタ:
  31. アプリ:ホスト名
  32. クラスターIP: なし
  33. ポート:
  34. -名前:デフォルト 
  35. プロトコル: TCP
  36. ポート: 80
  37. ターゲットポート: 9376

上記のように、StatefulSet は、spec.serviceName という追加フィールドを除いて、デプロイメントと変わりません。このフィールドの機能は、StatefulSet コントローラーに、ロジック処理中にホスト名サービスを使用して Pod の一意の解決可能性を確保するように指示することです。

Apply を実行すると、しばらくすると対応する Pod が生成されることがわかります。

  1. ~ kubectl get pods -w -l app=ホスト名
  2. 名前準備完了 ステータス 再起動 年齢
  3. ホスト名-0 1/1 実行中 0 9分54秒
  4. ホスト名-1 1/1 実行中 0 9分28秒
  5. ホスト名-2 1/1 実行中 0 9分24秒

予想どおり、Pod 名は重複することなく増分番号が付けられ、これらの Pod の作成プロセスも番号に従って連続して実行されます。デプロイメントを使用してデプロイされた Pod の名前には、レプリカセット名と乱数が追加され、再起動後も変更され続けることがわかります。 StatefulSet を使用してデプロイされた Pod の場合、podIP は変更されますが、名前は変更されません。これに基づいて、固定の DNS A レコードを介して各ポッドにアクセスできます。

それでは、Pod の A レコードを見てみましょう。

  1. sh-4.2# nslookup ホスト名-0.ホスト名
  2. サーバー: 10.212.0.2
  3. アドレス: 10.212.0.2#53
  4.  
  5. 名前: hostnames-0.hostnames.coops- dev.svc.cluster.local  
  6. 住所: 172.28.3.57
  7.  
  8. sh-4.2# nslookup ホスト名-1.ホスト名
  9. サーバー: 10.212.0.2
  10. アドレス: 10.212.0.2#53
  11.  
  12. 名前: hostnames-1.hostnames.coops-dev.svc.cluster。地元 
  13. 住所: 172.28.29.31
  14.  
  15. sh-4.2# nslookup ホスト名-2.ホスト名
  16. サーバー: 10.212.0.2
  17. アドレス: 10.212.0.2#53
  18.  
  19. 名前: hostnames-2.hostnames.coops- dev.svc.cluster.local  
  20. 住所: 172.28.23.31

前の推論と一致して、pod-name.service-name.namespace-name.svc.cluster.local の A レコードを通じて podIP にアクセスできます。同じ名前空間では、pod-name.service-name に簡略化できます。

現時点でのサービスのAレコードとは何ですか?

  1. sh-4.2# nslookup ホスト名
  2. サーバー: 10.212.0.2
  3. アドレス: 10.212.0.2#53
  4.  
  5. 名前: hostnames.coops-dev.svc.cluster。地元 
  6. 住所: 172.28.29.31
  7. 名前: hostnames.coops-dev.svc.cluster。地元 
  8. 住所: 172.28.3.57
  9. 名前: hostnames.coops-dev.svc.cluster。地元 
  10. 住所: 172.28.23.31

これはエンドポイント リスト内の podIP のセットであることが判明しており、A レコード service-name.namespace-name.svc.cluster.local を介して負荷分散された方法でバックエンド Pod にアクセスできることを意味します。

iptables

Kubernetes のサービスが kube-proxy と iptables に基づいて動作することは、多かれ少なかれわかっています。サービスが作成されると、kube-proxy によって認識され、ホスト上に対応する iptables ルールが作成されます。

CluserIP モードのサービスを例にとると、最初にエントリとして KUBE-SERVICES ルールが作成されます。

  1. -A KUBE-SERVICES -d 10.212.8.127/32 -p tcp -m comment --comment "default/hostnames: クラスター IP" -m tcp --dport 80 -j KUBE-SVC-NWV5X2332I4OT4T3  

このレコードは、CluserIP 10.212.8.127 のすべての宛先アドレスが処理のために KUBE-SVC iptables チェーンにリダイレクトされることを意味します。

それでは、KUBE-SVC チェーンとは何かを見てみましょう。

  1. -A KUBE-SVC-NWV5X2332I4OT4T3 -m コメント--comment "default/hostnames:" -m 統計 --mode ランダム --確率 0.33332999982 -j KUBE-SEP-WNBA2IHDGP2BOBGZ  
  2. -A KUBE-SVC-NWV5X2332I4OT4T3 -m コメント--comment "default/hostnames:" -m 統計 --mode ランダム --確率 0.50000000000 -j KUBE-SEP-X3P2623AGDH6CDF3  
  3. -A KUBE-SVC-NWV5X2332I4OT4T3 -m コメント--comment "デフォルト/ホスト名:" -j KUBE-SEP-57KPRZ3JQVENLNBR  

このルールセットは、実際には負荷分散に使用されます。確率はそれぞれ 1/3、1/2、1 であることがわかります。 iptables ルールは上から下に照合されるため、これらの値を設定すると、各チェーンが同じ確率で一致するようになります。負荷分散ロジックを処理した後、リクエストは他の 3 つのルールに転送されます。見てみましょう:

  1. -A KUBE-SEP-57KPRZ3JQVENLNBR -s 172.28.21.66/32 -m コメント--comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000    
  2. -A KUBE-SEP-57KPRZ3JQVENLNBR -p tcp -m コメント--comment "default/hostnames:" -m tcp -j DNAT --to-destination 172.28.21.66:9376  
  3.  
  4. -A KUBE-SEP-WNBA2IHDGP2BOBGZ -s 172.28.29.52/32 -m コメント--comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000    
  5. -A KUBE-SEP-WNBA2IHDGP2BOBGZ -p tcp -m コメント--comment "default/hostnames:" -m tcp -j DNAT --to-destination 172.28.29.52:9376  
  6.  
  7. -A KUBE-SEP-X3P2623AGDH6CDF3 -s 172.28.70.13/32 -m コメント--comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000    
  8. -A KUBE-SEP-X3P2623AGDH6CDF3 -p tcp -m コメント--comment "default/hostnames:" -m tcp -j DNAT --to-destination 172.28.70.13:9376  

KUBE-SEP チェーンは 3 つの DNAT ルールで構成されており、DNAT の前に 0x00004000 のフラグが設定されていることがわかります。 DNAT ルールは、PREROUTING の前、つまりルーティングの前に、リクエストの宛先アドレスとポートを --to-destination で指定された podIP とポートに変更することです。このようにして、CluserIP 10.212.8.127 にアクセスするための最初のリクエストは、各 Pod に負荷分散されます。

では、Pod が再起動され、podIP が変更された場合はどうなるでしょうか?当然のことながら、kube-proxy は Pod の変更を監視し、iptables ルールを更新および維持する役割を担います。

ヘッドレス サービスの場合、固定の A レコードを介して Pod に直接アクセスするため、これらの iptables ルールは当然必要ありません。

iptables は比較的理解しやすいですが、パフォーマンスはあまり良くありません。ご想像のとおり、Pod が多数ある場合、何千もの iptables ルールが作成され、絶えず更新されるため、ホスト マシン上の CPU リソースが大量に占有されます。効果的な解決策は、IPVS モードに基づくサービスを使用することです。 IPVS では、各 Pod に iptables ルールを設定する必要はなく、これらのルールをカーネル状態に配置するため、これらのルールを維持するコストが大幅に削減されます。

クラスター間通信

サービスへの外部アクセス

上記では、主に kube-dns によって生成された DNS レコードと kube-proxy によって管理される iptables ルールに基づいて、Kubernetes クラスター内でリクエストがどのように通信されるかについて説明しました。この情報はすべてクラスター内で利用できるため、クラスターの外部から特定のサービスまたはポッドにアクセスすることはできません。

デフォルトの CluserIP モードに加えて、Service では、この問題を解決するために使用される nodePort モードなど、他の多くのモードも提供されます。

  1. APIバージョン: v1
  2. 種類: サービス
  3. メタデータ:
  4. 名前: ホスト名
  5. 仕様:
  6. セレクタ:
  7. アプリ:ホスト名
  8. タイプ: NodePort
  9. ポート:
  10. - ノードポート: 8477
  11. プロトコル: TCP
  12. ポート: 80
  13. ターゲットポート: 9376

NodePort モードで Service を作成し、NodePort を 8477 に設定しました。つまり、任意のホスト マシンのポート 8477 を介してホスト名 Service にアクセスできます。

  1. sh-4.2# カール 10.1.6.25:8477
  2. ホスト名-8548b869d7-j5lj9
  3. sh-4.2# カール 10.1.6.25:8477
  4. ホスト名-8548b869d7-66vnv
  5. sh-4.2# カール 10.1.6.25:8477
  6. ホスト名-8548b869d7-szz4f

アクセスするノード アドレスをランダムに見つけ、同じ戻り値を取得しました。

では、現時点で iptables ルールはどのように機能するのでしょうか。

  1. -A KUBE-NODEPORTS -p tcp -m コメント--comment "デフォルト/ホスト名: ノードポート" -m tcp --dport 8477 -j KUBE-SVC-67RL4FN6JRUPOJYM  

kube-proxy は各ホストで上記の iptables ルールを生成し、--dport を通じてポートを指定します。ポートへのアクセス要求は KUBE-SVC チェーンにジャンプします。 KUBE-SVC チェーンには、以前の CluserIP サービスと同じレシピがあります。残りは CluserIP サービスにアクセスする場合と変わりません。

ただし、リクエストが現在のホストから別のノードに送信されると、そのノードに対して SNAT 操作が実行されることに注意してください。

  1. -A KUBE-POSTROUTING -m comment --comment "SNAT を必要とする kubernetes サービス トラフィック" -m mark --mark 0x4000/0x4000 -j MASQUERADE  

このポストルーティング ルールは、ホストから送信されようとしている要求に対して SNAT を実行していることがわかります。判定条件は前回の DNAT でのフラグである 0x4000 フラグを持っていることです。通常のリクエストではなく、サービスから転送されたリクエストであると判断されます。

SNAT の理由は非常に単純です。まず、これは Kubernetes によって処理されない外部リクエストです。ノード 1 にアクセスすると、ノード 1 の負荷分散によってノード 2 の Pod に転送されます。これは大丈夫です。処理後、Pod はそれを外部クライアントに直接返します。この場合、外部クライアントは明らかに node1 にアクセスしているものの、返される応答は実際には node2 であるため、混乱します。このとき、エラーが報告されることが多いです。

SNAT の機能は DNAT の反対です。リクエストがノード 1 からノード 2 に送信されると、送信元アドレスはノード 1 のアドレスに変更されます。その後、node2 の Pod が戻ると、node1 に戻され、その後 node1 がクライアントに戻ります。

  1. クライアント
  2. | ^
  3. | |
  4. ヴ |
  5. ノード 2 < --- ノード 1  
  6. | ^ スナト
  7. | | --->  
  8. ヴ |
  9. エンドポイント

サービスには、外部からアクセスするための他の 2 つの方法があります。パブリック クラウドに適用可能な LoadBalancer モード サービスの場合、パブリック クラウド Kubernetes は CloudProvider を呼び出してパブリック クラウド上に負荷分散サービスを作成し、プロキシされた Pod の IP アドレスをバックエンドとして負荷分散サービスに構成します。もう 1 つは ExternalName モードで、spec.externalName で必要な外部アクセス ドメイン名 (hostnames.example.com など) を指定できます。その後、このドメイン名にアクセスすることは、service-name.namespace-name.svc.cluser.local にアクセスするのと同じになります。この時点で、kube-dns によって CNAME レコードが実際に追加されたことがわかります。

イングレス

LoadBalancer という種類のサービスがありますが、各サービスに負荷分散サービスを構成すると、コストがかかり、無駄が多くなります。一般的に言えば、異なる URL へのアクセスを異なるサービスに転送するグローバル ロード バランサーが必要になります。これは、Service of Service とも言える Ingress の機能です。

Ingress は、実際にはリバース プロキシの抽象化です。皆さんもすでに、これが Nginx と非常に似ていると感じていると思います。実際、Ingress は抽象レイヤーであり、その実装レイヤーの 1 つは Nginx をサポートしています。

nginx イングレス コントローラーをデプロイできます。

  1. $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml

Mandatory.yaml は、公式に管理されている Ingress コントローラーです。見てみましょう:

  1. 種類: ConfigMap
  2. APIバージョン: v1
  3. メタデータ:
  4. 名前: nginx-configuration
  5. 名前空間: ingress-nginx
  6. ラベル:
  7. app.kubernetes.io/名前: ingress-nginx
  8. app.kubernetes.io/一部: ingress-nginx
  9. ---  
  10. apiバージョン: extensions/v1beta1
  11. 種類: デプロイメント
  12. メタデータ:
  13. 名前: nginx-ingress-controller
  14. 名前空間: ingress-nginx
  15. ラベル:
  16. app.kubernetes.io/名前: ingress-nginx
  17. app.kubernetes.io/一部: ingress-nginx
  18. 仕様:
  19. レプリカ: 1
  20. セレクタ:
  21. 一致ラベル:
  22. app.kubernetes.io/名前: ingress-nginx
  23. app.kubernetes.io/一部: ingress-nginx
  24. テンプレート:
  25. メタデータ:
  26. ラベル:
  27. app.kubernetes.io/名前: ingress-nginx
  28. app.kubernetes.io/一部: ingress-nginx
  29. 注釈:
  30. ...
  31. 仕様:
  32. サービスアカウント名: nginx-ingress-serviceaccount
  33. コンテナ:
  34. -名前: nginx-ingress-controller
  35. イメージ: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.20.0
  36. 引数:
  37. - /nginx-イングレスコントローラー
  38. - --configmap=$(POD_NAMESPACE)/nginx-configuration  
  39. - --publish-service=$(POD_NAMESPACE)/ingress-nginx  
  40. - --annotations-prefix=nginx.ingress.kubernetes.io  
  41. セキュリティコンテキスト:
  42. 機能:
  43. 落とす
  44. -全て 
  45. 追加
  46. -NET_BIND_SERVICE
  47. # wwwデータ -> 33
  48. 実行ユーザー: 33
  49. 環境:
  50. -名前: POD_NAME
  51. 値:
  52. フィールド参照:
  53. フィールドパス: metadata.name  
  54. -名前: POD_NAMESPACE
  55. -名前: http
  56. 値:
  57. フィールド参照:
  58. フィールドパス: metadata.namespace
  59. ポート:
  60. -名前: http
  61. コンテナポート: 80
  62. -名前: https
  63. コンテナポート: 443

一般的に、nginx-ingress-controller イメージに基づいて Pod を定義しました。この Pod 自体は、Ingress オブジェクトとそのプロキシ バックエンド サービスの変更を監視するコントローラーです。

Ingress オブジェクトが作成されると、nginx-ingress-controller は Ingress オブジェクトの内容に基づいて Nginx 構成ファイル (nginx.conf) を生成し、それに応じて Nginx サービスを開始します。

Ingress オブジェクトが更新されると、nginx-ingress-controller はこの構成ファイルを更新します。 nginx-ingress-controller は、Nginx Lua ソリューションを通じて nginx アップストリームの動的な構成も実装します。

外部からこの Nginx にアクセスできるようにするには、Nginx を公開するサービスを作成する必要があります。

  1. $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml

ここでのコンテンツは、NodePort タイプのサービスについて説明します。

  1. APIバージョン: v1
  2. 種類: サービス
  3. メタデータ:
  4. 名前: ingress-nginx
  5. 名前空間: ingress-nginx
  6. ラベル:
  7. app.kubernetes.io/名前: ingress-nginx
  8. app.kubernetes.io/一部: ingress-nginx
  9. 仕様:
  10. タイプ: NodePort
  11. ポート:
  12. -名前: http
  13. ポート: 80
  14. ターゲットポート: 80
  15. プロトコル: TCP
  16. -名前: https
  17. ポート: 443
  18. ターゲットポート: 443
  19. プロトコル: TCP
  20. セレクタ:
  21. app.kubernetes.io/名前: ingress-nginx
  22. app.kubernetes.io/一部: ingress-nginx

このサービスは Nginx Pod の 80/443 ポートのみを公開していることがわかります。その後、ホスト IP と NodePort を介して Nginx にアクセスできるようになります。

次に、Ingress オブジェクトが一般的にどのように記述されるかを見てみましょう。例を挙げてみましょう。

  1. apiバージョン: extensions/v1beta1
  2. 種類: イングレス
  3. メタデータ:
  4. 名前: カフェイングレス
  5. 仕様:
  6. TLS: いいえ
  7. - ホスト:
  8. - カフェ
  9. secretName: カフェシークレット
  10. ルール:
  11. - ホスト: cafe.example.com
  12. http:
  13. パス:
  14. - パス: /tea
  15. バックエンド:
  16. サービス名: tea-svc
  17. サービスポート: 80
  18. - パス: /coffee
  19. バックエンド:
  20. サービス名: coffee-svc
  21. サービスポート: 80

この Ingress は、全体的なドメイン名が cafe.example.com であり、cafe.example.com/tea を介して tea-svc サービスにアクセスし、cafe.example.com/coffee を介して coffee-svc サービスにアクセスしたいことを示しています。ここでは、キー フィールド spec.rules を使用して転送ルールを記述します。

Ingress オブジェクトの詳細情報を表示できます。

  1. $ kubectl イングレスを取得
  2. 名前ホスト アドレス ポート 年齢
  3. カフェイングレス cafe.example.com 80, 443 2時間
  4.  
  5. $ kubectl イングレスカフェイングレスを記述します
  6. 名前: カフェイングレス
  7. 名前空間:デフォルト 
  8. 住所:
  9. デフォルトのバックエンド: default -http-backend:80 (<なし>)
  10. TLS:
  11. cafe-secret は cafe.example.com を終了します
  12. ルール:
  13. ホストパスバックエンド
  14. ---- ---- --------  
  15. カフェ
  16. /tea tea-svc:80 (<なし>)
  17. /コーヒー コーヒー-svc:80 (<なし>)
  18. 注釈:
  19. イベント:
  20. タイプ 理由 年齢送信元 メッセージ
  21. ---- ------ ---- ---- -------  
  22. 通常CREATE 4m nginx-ingress-controller Ingressデフォルト/cafe-ingress

先ほど、NodePort を介して nginx-ingress を公開したことを述べましたが、Ingress 構成では、cafe.example.com を介してバックエンド Pod にアクセスしたいと考えています。したがって、まず cafe.example.com ドメイン名が任意のホスト マシンの IP:nodePort を指す必要があり、リクエストが nginx-ingress に到達した後、各バックエンド サービスに転送されます。もちろん、NodePort 以外にも LoadBalancer、hostNetwork など、nginx-ingress を公開する方法はたくさんあります。

最後にもう一度リクエストを試してみましょう:

  1. $ curl cafe.example.com/coffee
  2. サーバー: coffee-7dbb5795f6-vglbv
  3. $ curl cafe.example.com/tea
  4. サーバー: tea-7d57856c44-lwbnp

Nginx Ingress コントローラーがリクエストを対応するバックエンド サービスに正常に転送したことがわかります。リクエストがどのイングレス ルールにも一致しない場合は、当然 404 が返されます。

これまで、Kubernetes のコンテナ ネットワークがサービス検出を実装する方法について説明しました。サービス検出は、マイクロサービス アーキテクチャにおける中心的な問題です。この問題が解決されれば、Kubernetes を使用してマイクロサービス アーキテクチャを実装することが半分達成されたことになります。

<<:  マイクロサービス CI/CD 実践 - GitOps の完全な設計と実装

>>:  PythonでSaga分散トランザクションを簡単に完了する

推薦する

概要: 検索エンジンでのウェブページのランキングに影響を与える 4 つの主な要因

最適化担当者が最も関心を持っているのは、検索エンジンのテクノロジーと動向であり、検索エンジンのランキ...

事例分析: Baidu Knows ページが特定のウェブサイトに大量に表示されています

なぜ一部のウェブサイトにはBaidu Knowsページを含むBaidu関連のドメインがあるのに、Ba...

セキュリティ保護されていない WiFi で安全にインターネットを閲覧する方法

2015年のCCTV 315 Galaで、CCTVは無料WiFiの危険性を暴露しました。ユーザーが携...

SEOトラフィック設計におけるXiong Zhanghaoの重要な役割とそれを活性化する方法は何ですか

月給5,000~50,000のこれらのプロジェクトはあなたの将来です熊張豪は、百度が2017年末に開...

SEO の専門家がウェブサイトの目標設定と測定について語る SEO の実践的なヒント

通常、SEO 最適化とは、ウェブサイトのランキングを上げ、ユーザーの検索を満足させることだと考えられ...

高品質のウェブサイトを構築するにはどうすればいいでしょうか?

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービス高品質なウェブサイトを構...

30日間で百度ウエイト3を突破したケーススタディシリーズ1: キーワードが王様

Baidu ウェイトは、Aizhan.com や Webmaster Tools などのサードパーテ...

ガートナー: インフラストラクチャ プラットフォーム エンジニアリングを活用してクラウド ネイティブ プラットフォームを管理する

クラウド ネイティブは、企業がクラウド テクノロジーを採用してデジタル変革を推進するための重要な原則...

サイトの縮小に伴う3つの主要な執行者を個人的に体験する

諺にあるように、世の中に生きていれば、必ず傷つくことになります。著者は 2 年間の最適化経験を持って...

ウェブサイトの最適化担当者にとって、Baiduの新しい状況最適化には、

ウェブサイトの最適化担当者にとって、Baidu の新しい状況最適化にはいくつかの犠牲が伴います。 2...

SEO業界の詳細な分業と責任。方向性は明確になっていますか?

インターネットの台頭とともに、SEO 業界が静かに誕生しました。多くの人は、SEO は比較的複雑な業...

arkecxクラウドサーバーはどうですか?簡単なレビュー: 英国ロンドンのデータセンター

arkecxはどうですか? arkecxクラウドサーバーはどうですか?今回は、英国ロンドンにあるar...

TmallのDouble Eleven公式サイトのロボットプロトコルを見る

毎年恒例の天猫ダブルイレブンがもうすぐやってきます。諺にあるように、素人にはその興奮はわかるかもしれ...

海外新興市場における人気オーディオ・動画アプリの広告出稿に関する調査・分析

過去6か月間、オーディオおよびショートビデオアプリケーションは熱い勢いを維持し、ツールアプリケーショ...

オリジナル記事を1位にすべきでしょうか?

Baidu が Spark プロジェクトを立ち上げ、オリジナル コンテンツを積極的にサポートして以来...