1. 導入:なぜServiceとIngressが必要なのか
Kubernetes(K8s)環境では、Podは動的に生成・削除され、そのたびにIPアドレスも変わります。この「不安定なPod」に対して、開発者がアプリケーションをデプロイする際、毎回IPを意識していては運用が破綻します。ServiceはPod群への「固定された接続点」を提供し、Ingressは外部ユーザーからのアクセスを「ドメインやパスに応じて適切なサービスへ振り分ける」役割を担います。これらを正しく理解することは、堅牢なマイクロサービスアーキテクチャを構築する上での最優先事項です。
2. 基礎知識:ServiceとIngressの役割分担
Serviceは、主にクラスター内部の通信を制御します。
・ClusterIP: デフォルト設定。クラスター内部からのみアクセス可能なIPを付与します。
・NodePort: 各ノードの特定のポートを開放し、外部からアクセス可能にします。
・LoadBalancer: クラウドベンダーのLBと連携し、グローバルIPを払い出します。
Ingressは、L7(アプリケーション層)のルーティングを担うリソースです。HTTP/HTTPSのホスト名(example.com)やパス(/api, /web)に基づいて、バックエンドのServiceへルーティングします。注意点として、Ingressリソース単体では動作せず、Nginx Ingress Controllerなどの「Ingress Controller」を別途デプロイする必要があります。
3. 実装:効率的なトラフィックルーティング
一般的な現場の実装パターンは、「内部向けにはClusterIPを使用し、外部公開用にはIngressを使用する」構成です。これにより、外部公開用の設定をIngress側に集約でき、セキュリティやSSL管理が容易になります。
4. サンプルプログラム:ServiceとIngressの定義
以下のマニフェストは、バックエンドのPodに対してServiceを定義し、Ingress経由で外部公開する例です。
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: my-app # このラベルを持つPodにトラフィックを流す
ports:
- protocol: TCP
port: 80 # サービスが受け付けるポート
targetPort: 8080 # Pod内のアプリケーションが待ち受けるポート
type: ClusterIP
—
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: main-ingress
annotations:
# Nginx Ingress Controllerを使用する場合の設定例
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-service # 上記で定義したServiceを指定
port:
number: 80
5. 応用・注意点:現場でハマりやすいポイント
・ラベルの不一致: ServiceのselectorとPodのラベルが一致していないと、トラフィックがどこにも飛ばず、Connection Refused等のエラーになります。kubectl get endpointsコマンドで、IPが正しく紐付いているか確認する癖をつけましょう。
・Ingress Controllerの選定: 現場ではNginx Ingress Controllerが一般的ですが、Cloud Load Balancerと直接統合されるALB Ingress Controller(AWS等)を使う場合、アノテーションの設定が大きく異なります。利用するコントローラーのドキュメントを必ず確認してください。
・SSL証明書の管理: IngressでSSL終端を行う場合、Cert-Manager等の自動化ツールを導入しないと、証明書の更新作業で障害が発生しやすくなります。本番環境では自動更新の仕組みをセットで導入することを強く推奨します。

コメント