【ITニュース解説】Part-108: 🚀Kubernetes Ingress – Context Path Based Routing in Google Kubernetes Engine
2025年10月03日に「Dev.to」が公開したITニュース「Part-108: 🚀Kubernetes Ingress – Context Path Based Routing in Google Kubernetes Engine」について初心者にもわかりやすく解説しています。
ITニュース概要
Kubernetesで複数アプリを動かす際、Ingressは一つのロードバランサーでURLのパスに応じてアクセスを振り分ける。これによりコスト削減と管理が楽になる。GKEにNginxアプリを3つデプロイし、「/app1/」「/app2/」といったパスで各アプリへルーティングする具体的な設定手順を解説した。
ITニュース解説
Kubernetes(クーバネティス)は、コンテナ化されたアプリケーションを効率的にデプロイし、管理するための強力なプラットフォームである。しかし、アプリケーションを外部に公開する際には、いくつかの課題に直面することがある。特に、複数のアプリケーションを運用している場合、それぞれに個別のロードバランサー(外部からのアクセスを複数のサーバーに分散させる仕組み)を用意すると、コストがかさむだけでなく、管理も複雑になるという問題がある。このような課題を解決するために「Ingress(イングレス)」という機能がKubernetesには用意されている。
Ingressの主な役割は、単一のロードバランサーを介して、URLのパスに基づいて異なるアプリケーションにトラフィックを振り分ける「パスベースルーティング」を実現することである。例えば、http://example.com/app1へのアクセスはアプリケーション1へ、http://example.com/app2へのアクセスはアプリケーション2へ、といった具合に振り分けることができる。これにより、コストを削減し、運用管理をシンプルにすることが可能となる。
具体的な例として、Google Kubernetes Engine(GKE)上で3つの異なるNginxアプリケーションをデプロイし、Ingressを使ってパスベースルーティングを設定する手順を見ていこう。
まず、アプリケーションをKubernetes上にデプロイするには「Deployment(デプロイメント)」と「Service(サービス)」という2つの重要なリソースが必要となる。Deploymentは、アプリケーションのコンテナイメージや、何個のインスタンス(Podと呼ばれる実行単位)を起動するかといった、アプリケーションの実行方法を定義する。Serviceは、それらのPodに対して外部からアクセスするための安定したネットワークエンドポイントを提供する。PodのIPアドレスは変動する可能性があるため、固定のアクセスポイントとしてServiceが不可欠となるのだ。
この例では、「app1」「app2」「app3」という3つのNginxアプリケーションをそれぞれDeploymentとして定義する。各アプリケーションは、ghcr.io/stacksimplify/kube-nginxapp1:1.0.0のような異なるコンテナイメージを使用しており、それぞれ専用のウェブページを表示する想定である。そして、これらのアプリケーションに外部からアクセスできるようにするため、各Deploymentに対応するServiceを作成する。ここでは「NodePort(ノードポート)」タイプのServiceを使用している。NodePortサービスは、Kubernetesクラスター内の各ノード(サーバー)の特定のポートを開放し、そのポートを通してアプリケーションにアクセスできるようにする。これは、IngressがバックエンドサービスとしてPodにアクセスするために使われる一般的な方法だ。
それぞれのアプリケーションのDeploymentとServiceは、app1-deployment.yaml、app2-deployment.yaml、app3-deployment.yamlというファイルに定義されている。これらのファイルはそれぞれ、アプリケーション名、Podのラベル、使用するコンテナイメージ、公開するポート番号などを設定している。例えば、app1-deployment.yamlでは、app1-nginx-deploymentというDeploymentと、app1-nginx-nodeport-serviceというServiceが定義されている。
すべてのアプリケーションのDeploymentとServiceが準備できたら、いよいよIngressの設定を行う。Ingressリソースはingress-cpr.yamlというファイルに定義される。このIngressの設定ファイルの中で最も重要な部分は、rulesセクションとdefaultBackendセクションである。
rulesセクションには、URLのパスとそれに対応するバックエンドサービスのマッピングを記述する。この例では、path: /app1へのアクセスはapp1-nginx-nodeport-serviceのポート80へ、path: /app2へのアクセスはapp2-nginx-nodeport-serviceのポート80へルーティングされるように設定されている。pathType: Prefixは、指定されたパスで始まる全てのURLにマッチすることを意味する。例えば、/app1というパスが指定されていれば、/app1/index.htmlや/app1/images/logo.pngといったパスもapp1サービスにルーティングされる。
そして、どのパスルールにもマッチしなかった場合のデフォルトのルーティング先としてdefaultBackendが指定されており、ここではapp3-nginx-nodeport-serviceが設定されている。つまり、http://<INGRESS-ADDRESS>/のように、パスが指定されない(またはどのパスルールにもマッチしない)アクセスは、すべてapp3サービスに振り分けられることになる。
また、ingress-cpr.yamlの中にはannotationsとしてkubernetes.io/ingress.class: "gce"という行がある。これは、KubernetesがGKE上で動作している場合、Ingressコントローラー(Ingressリソースの設定を実際に処理するコンポーネント)に、Google Cloudのロードバランサーを利用して外部公開することを指示している。これにより、GKEは自動的にGoogle Cloudの高性能なロードバランサーをプロビジョニングし、Ingressのルーティングルールを適用してくれるのだ。
これらの設定が完了したら、kubectl apply -f ingress/コマンドを使ってKubernetesクラスターにすべてのリソース(Deployment、Service、Ingress)を適用する。リソースが正しくデプロイされたかを確認するために、kubectl get pods、kubectl get svc、kubectl get ingressといったコマンドを実行する。特にIngressに関しては、GKEがロードバランサーをプロビジョニングするのに数分かかる場合があるため、kubectl get ingressで表示されるADDRESSフィールドが埋まるまで待つ必要がある。
ロードバランサーのアドレスが確認できたら、そのIPアドレスを使ってアプリケーションにアクセスしてみる。例えば、Ingressのアドレスがhttp://XXX.XXX.XXX.XXXだった場合、http://XXX.XXX.XXX.XXX/app1/index.htmlにアクセスすればapp1のコンテンツが、http://XXX.XXX.XXX.XXX/app2/index.htmlにアクセスすればapp2のコンテンツが表示されるはずである。そして、http://XXX.XXX.XXX.XXX/のようにパスを指定せずにアクセスすると、app3のコンテンツが表示されることを確認できる。これにより、単一のロードバランサーを通じて、URLのパスによって異なるアプリケーションにトラフィックが適切にルーティングされていることがわかる。
GKE環境では、Google Cloud Consoleにアクセスして「ロードバランシング」のセクションを確認することで、実際にGKEがプロビジョニングしたロードバランサーの詳細設定を見ることができる。そこでは、フロントエンド(外部からの接続を受け付ける部分)、ホスト/パスルール(Ingressで設定したルーティングルール)、バックエンドサービス(トラフィックが送られる先のサービス)、ヘルスチェック(サービスの健全性を監視する設定)などが確認できる。
最後に、実験が終わったら、作成したリソースをクリーンアップすることが重要だ。kubectl delete -f ingress/コマンドを実行することで、デプロイしたアプリケーション、サービス、Ingress、そしてそれによって作成されたGoogle Cloudのロードバランサーもすべて削除される。これにより、不要なリソースが残り、課金されることを防げる。
このように、KubernetesのIngress機能とGKEの連携を使うことで、複数のマイクロサービスを効率的かつ経済的に外部に公開することが可能になる。これは、現代のクラウドネイティブなアプリケーション開発において非常に一般的な、そして重要なルーティングパターンの一つである。