6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【本気で学ぶKubernetes】IngressでHTTPルーティングを行ってみる

Last updated at Posted at 2025-12-10

はじめに

こんにちは!

本記事は「本気で学ぶKubernetes」シリーズの第11回です。このシリーズでは、Kubernetesの基礎から実践まで、段階的に学んでいきます。

このシリーズは、第1回から順に読むことで体系的に学べる構成にしています。
まだご覧になっていない方は、ぜひ最初からご覧ください!

Kubernetesとは?クラスタ構成の全体像をつかむ

今回は、Ingressについて学んでいきたいと思います。

以前の記事でServiceのタイプ(ClusterIP / NodePort / LoadBalancer)について触れましたが、今回はさらにその上のレイヤーであるIngressを使って、より高度にルーティングを行っていく方法を見ていこうと思います。

【本気で学ぶKubernetes】もう迷わない!Service タイプの正しい使い分け

この記事は人間がKubernetesの公式ドキュメントを読み漁りながら、人間の手で書いていますのでご安心ください!

ServiceとIngressの関係について

以前までの記事で利用していたServiceの機能はL4のトランスポート層でトラフィックがきた場合にルーティングを行うというものでしが。つまりはIPアドレスとポート番号を使ってPodにトラフィックを振り分けていました。

今回触れるIngressはより上位のレイヤーであるL7のアプリケーション層で動作するものとなっており、HTTPのパスやホスト名を参照して、それを異なるServiceに振り分けることができる機能となっています。

LoadBalancerの課題について

ServiceにはLoadBalancerのタイプがあります。

例えば、以下のような構成を考えて課題を整理してみます。

  • フロントエンドアプリ(frontend-service
  • APIサーバー(api-service
  • 管理画面(admin-service

ServiceごとにLoadBalancerを作成する

この場合、Service1つにつき1つのLoadBalancerが必要なため、例えばフロントエンドAPIサーバー管理画面等で分ける公開したい場合は、Kubernetesにおいて3つのLoadBalancerを作らなければならないということになります。

パスベースルーティングができない

同じドメインで動作させる場合にURLのパスによって異なるServiceに振り分けたい場合もあります。

  • example.com/ → フロントエンド
  • example.com/api → APIサーバー
  • example.com/admin → 管理画面

LoadBalancerだけだと、これを実現するのはなかなか難しいです。

ホストベースルーティングもできない

また同じドメインでなくとも、複数のサブドメインを使ってそれぞれ異なるServiceに振り分けたい場合も同様です。

  • app1.example.com → App1
  • app2.example.com → App2

Ingressとは

IngressはKubernetesのリソースの1つで、HTTP/HTTPSレベルでのルーティングを行うことができます。

冒頭でもお伝えした通り、ServiceのLoadBalancerはL4のトランスポート層でIPアドレスとポート番号で振り分けを行いますが、IngressはHTTPのパスやホスト名を見て振り分けることができるL7のアプリケーション層のロードバランサーです。

Ingressを使うことにより、1つのIPアドレス(または1つのLoadBalancer)で複数のServiceにルーティングできるようになります。

出典: Kubernetes公式ドキュメント - Ingress

Ingressを使っていく上で、2つの概念を押さえておく必要があります。

Ingress Controller

実際にHTTPリクエストを受け取り、ルーティングを行うロードバランサーの実態のようなものです。

主なIngress Controllerには以下のようなものがあり、自動的にインストールされるわけではないので選択して自分で有効化する必要があります。

  • nginx-ingress-controller: 最も広く使われている
  • Traefik: 動的な設定変更に強い
  • HAProxy: 高性能
  • GCE Ingress Controller: GKE専用
  • AWS Load Balancer Controller: EKS専用

Ingress Resource

ルーティングのルールを定義するマニフェストです。
YAML形式で「どのパスをどのServiceに振り分けるか」といったロードバランサーの設定を行います。

Ingress ControllerIngress Resourceの設定を読み込んで、実際のルーティングを行っていくというわけです。

出典: Kubernetes公式ドキュメント - Ingress Controllers

実際にIngressを使ってみる

今回の構成では2つのアプリケーションを用意します。
それぞれDeploymentとServiceを作成し、Ingressで振り分けるように構成していきます。

  • app1: /app1 にアクセスすると「Hello from App1」を返す
  • app2: /app2 にアクセすると「Hello from App2」を返す

Ingress Controllerの有効化

minikubeでは、nginx-ingress-controllerがaddonとして提供されていますので、以下のコマンドを実行してIngress Controllerを有効化します。

minikube addons enable ingress

# ...省略...
# 🌟  'ingress' アドオンが有効です

以下のコマンドで確認ができます。

kubectl get pods -n ingress-nginx

# NAME                                        READY   STATUS      RESTARTS   AGE
# ingress-nginx-admission-create-xxxxx        0/1     Completed   0          2m
# ingress-nginx-admission-patch-xxxxx         0/1     Completed   1          2m
# ingress-nginx-controller-xxxxx              1/1     Running     0          2m

ingress-nginx-controllerというPodがRunningになっていれば問題ありません。

ちなみにadmission-createadmission-patchは初期セットアップ用のJobのようで、役目が終わったためCompletedReady 0/1となっているようです。

app1のマニフェスト

ここからはnginxが動作する2つのアプリケーションのマニフェストを作成していきます。

app1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app1
  template:
    metadata:
      labels:
        app: app1
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: app1-service
spec:
  selector:
    app: app1
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

2つ目のアプリケーションのマニフェストです。

app2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app2
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app2
  template:
    metadata:
      labels:
        app: app2
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: app2-service
spec:
  selector:
    app: app2
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

nginxのデフォルトページを返すシンプルな構成としていて、DeploymentでPodを2つ起動されServiceでClusterIPを割り当て流ようになっています。

Ingressマニフェスト

次に、Ingressマニフェストを作成していきます。

ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /app1
        pathType: Prefix
        backend:
          service:
            name: app1-service
            port:
              number: 80
      - path: /app2
        pathType: Prefix
        backend:
          service:
            name: app2-service
            port:
              number: 80

簡単に解説すると

annotationsとは

nginx.ingress.kubernetes.io/rewrite-target: /という値を設定していますが、これは例えばブラウザでhttp://example.com/app1/index.htmlにアクセスしたとき、

Ingress Controllerはapp1-serviceに転送しまう都合/app1/index.htmlというパスになってしまうため /index.htmlというパスを書き換えてから転送しています。

rulesとは

ルーティングのルールです。

  • path: /app1app1-serviceに転送します
  • path: /app2app2-serviceに転送します

マニフェスト自体はここまで挙動確認しながら進めている方にとってはそこまで複雑なものではないと思います。

デプロイと動作確認

それでは、マニフェストをデプロイしてみます。

kubectl apply -f app1.yaml
kubectl apply -f app2.yaml
kubectl apply -f ingress.yaml

# deployment.apps/app1 created
# service/app1-service created
# deployment.apps/app2 created
# service/app2-service created
# ingress.networking.k8s.io/example-ingress created

Ingressの状態を確認してみます。

kubectl get ingress

# NAME              CLASS   HOSTS   ADDRESS        PORTS   AGE
# example-ingress   nginx   *       192.168.49.2   80      30s

minikube ip

# 192.168.49.2

ADDRESSにIPアドレスが表示されていれば正常にリソースが作成できています。
ちなみにこのIPアドレスは、minikubeのIPアドレスと同じになっているはずですので確認してみてください!

それぞれのPodにindex.htmlファイルを作成していきます。

# app1のPodに「Hello from App1」を書き込む
kubectl exec -it $(kubectl get pods -l app=app1 -o jsonpath='{.items[0].metadata.name}') -- bash -c "echo 'Hello from App1' > /usr/share/nginx/html/index.html"

# app2のPodに「Hello from App2」を書き込む
kubectl exec -it $(kubectl get pods -l app=app2 -o jsonpath='{.items[0].metadata.name}') -- bash -c "echo 'Hello from App2' > /usr/share/nginx/html/index.html"

curlでアクセスして確認してみます。

curl http://192.168.49.2/app1

# Hello from App1

curl http://192.168.49.2/app2

# Hello from App2

パスによって異なるServiceに振り分けられていることが確認できました!

環境によっては、上記のcurlコマンドで応答が返ってこない場合があります。
生成AIでトラブルシューティングをしたところ、minikubeでDockerドライバーを使用している場合はminikube IPには外部から直接アクセスできないことがあるようです。

その場合は、別のターミナルでminikube tunnelを実行してトンネルを作成すると、curl http://localhost/app1のようにlocalhostでアクセスできるようになるとのことです。

ホストベースルーティング

Ingressでは、パスだけでなくホスト名(ドメイン名)でも振り分けができます。

例えば、以下のようなルールを定義できます。

spec:
  rules:
  - host: app1.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app1-service
            port:
              number: 80
  - host: app2.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app2-service
            port:
              number: 80

この設定を適用するとapp1.example.comへのリクエストはapp1-serviceに、app2.example.comへのリクエストはapp2-serviceに振り分けられます。
そのため、ホスト名をベースにルーティングを行うことができます。

# http://app1.example.com
# http://app2.example.com

実際の本番環境では、DNSレコードを設定してホスト(ドメイン)ベースでルーティングを行っていくことがほとんどだと思います。
またHTTPSを使って外部公開していくケースが多いと思いますので、今後GKEなどにデプロイした後に実践編として試していければと思います。

Ingressは当然HTTPSにも対応しています。HTTPSを有効にするには、証明書と秘密鍵をSecretに格納してIngressに参照させてからSSL終端の設定を行います。

クリーンアップ

今回作成したリソースを削除しておきます。

kubectl delete -f ingress.yaml
kubectl delete -f app1.yaml
kubectl delete -f app2.yaml

# ingress.networking.k8s.io "example-ingress" deleted
# deployment.apps "app1" deleted
# service "app1-service" deleted
# deployment.apps "app2" deleted
# service "app2-service" deleted

Ingress Controllerは今後も使うかもしれないのでそのまま残しておきますが、もし無効化したい場合は以下のコマンドで無効化できます。

minikube addons disable ingress

まとめと次回予告

LoadBalancer TypeのServiceだけだと、Service1つにつき1つのロードバランサーが必要になりますが、Ingressでは1つのIPアドレスやLoadBalancerから複数のServiceにルーティングできることがわかりました。

Ingressは単体で使うものではなくServiceを組み合わせます。さらにHTTPS化することで本番環境でも利用可能なレベルでアクセスをより柔軟に管理できるようになります。

次回は、KubernetesのCPUやメモリのリソース指定が可能なResource Limits/Requestsについて触れていきたいと思います。

それでは、また次回!

6
0
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
6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?