【実務・中級編】Kubernetesのサービス公開とルーティング:ClusterIP, NodePort, LoadBalancerの違いとIngress徹底活用 – インフラ構成管理(IaC)活用バイブル

Kubernetesのルーティング地獄からの脱却:ClusterIPからIngressまでの完全解剖と実務ベストプラクティス

こんにちは。テックリードの私だ。

開発チームから「新しく作ったマイクロサービスを外部公開したいんだけど、なぜかアクセスできない」「ALBとIngressのパスルーティングの挙動が噛み合わない」といった悲鳴めいた相談を受けることはないだろうか。

Kubernetes(K8s)におけるトラフィックルーティングは、概念自体はシンプルに見えて、実務で触るとL4とL7の抽象化レイヤーの壁に阻まれ、多くのエンジニアが迷子になりやすい領域だ。

今回は、ClusterIPからNodePort、LoadBalancer、そしてIngressへと至るルーティングの全貌をレイヤーごとに解体し、「明日から即座にチームの生産性を爆上げする実践的設定とプロの知見」を叩き込む。

—

1. Kubernetes内部ネットワークの深淵:kube-proxyとパケットの行方

まず、K8sのネットワークモデルの根本を理解しよう。K8sクラスタ内では、すべてのPodにユニークなIPアドレスが割り振られ、NATなしで直接通信できる(IP-per-Podモデル)。しかし、Podはエフェメラル(儚い)であり、オートスケーリングやデプロイによってIPアドレスは常に変動する。

この「変わり続けるPodの集合」に対して安定した単一のアクセスポイントを提供するのが Service であり、その裏側でルーティングを支えているのが kube-proxy だ。

kube-proxyのモード:iptables vs IPVS

本番環境を構築する際、kube-proxyのモード選定はパフォーマンスを左右するクリティカルな選択だ。

  • iptablesモード(デフォルト):

ルール数が増えると(サービスやPod数が増大すると)、パケット処理の線形探索によりCPU負荷が跳ね上がり、レイテンシが悪化する。小規模なら問題ないが、数百サービスを超える本番環境では地雷となる。

  • IPVSモード(推奨):

LinuxカーネルのIPVS(IP Virtual Server)を利用する。ハッシュテーブルを使用するため、数千のサービスが存在してもO(1)の計算量でルーティングが行われ、圧倒的なスケーラビリティを誇る。本番環境では必ずIPVSモードを選択せよ。

—

2. サービスタイプの違いと「使い所」の境界線

サービスタイプ(`ClusterIP`, `NodePort`, `LoadBalancer`)の本質は、「トラフィックをどこからどこへ引き受けるか」のスコープの違いに他ならない。

[Client]
│
├─ (社内/VPC内) ──> ClusterIP (クラスタ内のみ)
│
├─ (NodeのIP:Port) ─> NodePort (全ノードのポートを専有)
│
└─ (クラウドLB) ──> LoadBalancer (外部からの直接受付 / コスト高)

比較と実務的アンチパターン

| タイプ | スコープ | メリット | デメリット・実務でのリスク |
| :— | :— | :— | :— |
| ClusterIP | クラスタ内部のみ | 最もセキュア。余計なポートを開けない。 | 外部から直接アクセス不可(プロキシ必須)。 |
| NodePort | クラスタの全ノードの特定ポート | 外部LBなしで手軽に外部公開できる。 | ポート枯渇問題、セキュリティグループの管理が煩雑。本番での直接利用は厳禁。 |
| LoadBalancer | クラウドプロバイダのLB | プロバイダのマネージドLBが即座に連動。 | サービスごとにLBが作られ、クラウド費用が爆発する。SSL終端や高度なパスルーティングが面倒。 |

> プロの知見:
> 本番環境において、サービスタイプとして `LoadBalancer` や `NodePort` を直接アプリケーションごとに乱立させるのはアンチパターンだ。クラウドのコストが破綻するし、セキュリティホールの温床になる。
> 「基本はすべて ClusterIP で統一し、外部からの入り口は Ingress(またはGateway API)に集約する」。これがモダンなK8sインフラの黄金律である。

—

3. Ingressコントローラーの導入と実践的ルーティング設定

L4(トランスポート層)のサービス群の限界を突破し、HTTP/HTTPSのL7(アプリケーション層)でドメイン名やURLパスに基づいた高度なルーティングを提供するのが Ingress だ。

Ingress単体はただの「定義書(リソース)」にすぎず、実体としてトラフィックを裁くのは Ingress Controller(Nginx, Traefik, AWS ALB Ingress Controllerなど)である。ここではデファクトスタンダードである Ingress-NGINX Controller をベースに解説する。

実用的な設定ファイル(YAML)ベストプラクティス

マルチテナントや複数チームが同居する開発クラスタを想定し、TLS終端とパスベースのルーティングを美しく記述したマニフェストの模範解答を提示する。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-gateway-ingress
namespace: production
annotations:
# NGINXコントローラーを指定
kubernetes.io/ingress.class: “nginx”

# クライアントのリアルIPをバックエンドPodに伝えるための設定
nginx.ingress.kubernetes.io/use-forwarded-headers: “true”

# バックエンドへの接続タイムアウトを調整(マイクロサービスの遅延対策)
nginx.ingress.kubernetes.io/proxy-connect-timeout: “60”
nginx.ingress.kubernetes.io/proxy-read-timeout: “600”

# レートリミット(DDoS対策・API保護): 1秒間に10リクエストまで
nginx.ingress.kubernetes.io/limit-rps: “10”

spec:
# TLS/SSL設定(次章で詳解)
tls:

  • hosts:
  • api.example.com

secretName: api-tls-cert

rules:

  • host: api.example.com

http:
paths:
# ユーザー認証サービスへのルーティング

  • path: /api/v1/auth

pathType: Prefix
backend:
service:
name: auth-service
port:
number: 8080

# コアビジネスロジック(注文サービス)へのルーティング

  • path: /api/v1/orders

pathType: Prefix
backend:
service:
name: order-service
port:
number: 3000

—

4. TLS/SSL証明書の導入手順:cert-managerによる完全自動化

手動でSSL証明書を発行し、Secretに手動でぶち込むような運用は、証明書切れによる障害を引き起こす「現代の技術的負債」だ。
Let’s Encryptと `cert-manager` を組み合わせ、証明書のライフサイクルを完全に自動化せよ。

1. cert-managerの導入(Helmを使用)

helm repo add jetstack https://charts.jetstack.io
helm repo update

helm install cert-manager jetstack/cert-manager \
–namespace cert-manager \
–create-namespace \
–set installCRDs=true

2. ClusterIssuerの定義(Let’s Encrypt連携)

ACMEプロトコルを用いて証明書を自動発行・自動更新するグローバル設定(`ClusterIssuer`)を投入する。

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# Let’s Encryptの本番サーバーURL
server: https://acme-v02.api.letsencrypt.org/directory
# 期限切れやトラブル時の通知用メールアドレス
email: admin@example.com
# KubernetesのSecretにACMEアカウントの秘密鍵を保存
privateKeySecretRef:
name: letsencrypt-prod-account-key
# HTTP-01チャレンジを用いたドメイン所有権の検証を指定
solvers:

  • http01:

ingress:
class: nginx

3. Ingressとcert-managerの統合

前章のIngressマニフェストに以下のたった1行のアノテーションを追加するだけで、`cert-manager` が裏側で自動的に証明書を要求し、上記の `tls.secretName` に格納してくれる。

metadata:
annotations:
cert-manager.io/cluster-issuer: “letsencrypt-prod”

—

🚀 現場の生産性を爆上げする!プロの実践テクニック

ここからは、日々のK8s運用のストレスを消し去り、開発スピードを加速させるための「秘伝の技」を伝授する。

1. 開発スピードを高めるキーボードショートカット & エイリアス

毎回 `kubectl describe ingress` や `kubectl get pods -n production` を手打ちしているエンジニアは今日で卒業しよう。`.zshrc` や `.bashrc` に以下のエイリアスを即座に仕込め。

エイリアスの設定
alias k=”kubectl”
alias kgp=”kubectl get pods”
alias kgs=”kubectl get svc”
alias kgi=”kubectl get ingress”
alias klogs=”kubectl logs -f”

【神コマンド】クラスタ内のすべてのIngressと紐づくバックエンドを俯瞰する
alias k-routes=”kubectl get ingress -A -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name,HOST:.spec.rules[].host,PATH:.spec.rules[].http.paths[].path,SERVICE:.spec.rules[].http.paths[].backend.service.name”

さらに、IDE(VS Code)を使っているなら、「Kubernetes (ms-kubernetes-tools)」 拡張機能に加え、「YAML (redhat.vscode-yaml)」 拡張機能を入れ、カスタムリソース定義(CRD)のスキーマ補完を有効化すること。これにより、YAMLのインデント地獄やタイポによるデプロイ失敗がゼロになる。

2. チーム開発で役立つ設定の共有化ルール

  • マニフェストは純粋なYAMLで管理するな(Kustomize or Helm)

環境(dev/staging/production)ごとに異なるドメイン名やレプリカ数をベタ書きしたYAMLをコピペするのは絶対悪だ。Kustomize を用いて、ベースとなるマニフェストに対し、環境差分(patches)のみをオーバレイする構造を強制せよ。

  • GitOps(Argo CD / Flux)の導入

`kubectl apply` を人間の手で叩く文化を今すぐ捨てろ。Gitリポジトリ(Config repository)の変更が自動的にクラスタに同期されるGitOpsフローを構築することこそが、インフラ変更の監査性と安全性を担保する唯一の道だ。

—

結びにかえて

Kubernetesのルーティングは、背後の仕組み(kube-proxy, L4/L7の分離)を正しく理解し、適切なレイヤー(Ingress + cert-manager + Kustomize)で設計さえすれば、これほど強力で拡張性の高いインフラストラクチャはない。

「なんとなく動く」から脱却し、予測可能で堅牢なネットワーク基盤を構築すること。それがチーム全体の開発スピードを真の意味で加速させる鍵となる。

さあ、今すぐあなたのクラスタのIngress設定を見直し、無駄なLoadBalancerを掃除しに行こう。

タイトルとURLをコピーしました