Chuyển đến nội dung chính

レッスン9: Services & Ingress

Serviceタイプ: ClusterIP、NodePort、LoadBalancer、ExternalName。kubectl expose。 Ingressリソース、IngressClass、TLS終端とパスベースルーティング。

ServiceタイプとIngressルーティング — ClusterIP、NodePort、LoadBalancer

1. Serviceタイプ

タイプアクセス使用場面
ClusterIPクラスター内部のみ(クラスターDNS)Service間通信(デフォルト)
NodePortNodeIP:30000-32767開発/テスト環境の外部アクセス
LoadBalancerクラウドLBの外部IP本番環境の外部アクセス(クラウド)
ExternalNameCNAME DNSエイリアス外部DNSの名前にルーティング
ClusterIP(デフォルト):
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
spec:
  type: ClusterIP     # 省略可能 — デフォルト
  selector:
    app: myapp
  ports:
  - port: 80          # Serviceポート(クライアントが接続するポート)
    targetPort: 8080  # コンテナポート(アプリがリッスンするポート)

NodePort:
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30080   # オプション: 30000-32767の範囲(省略時は自動割り当て)

2. kubectl expose

# DeploymentをClusterIPとして公開(デフォルト)
kubectl expose deployment myapp --port=80 --target-port=8080

# NodePortとして公開
kubectl expose deployment myapp --port=80 --target-port=8080 --type=NodePort

# Podを公開
kubectl expose pod mypod --port=80 --name=mypod-svc

# PodとServiceを素早く作成
kubectl run nginx --image=nginx --port=80 --expose
# PodとClusterIP Serviceの両方が作成される

試験のポイント: kubectl exposeにはPodラベルに一致するselectorが必要です。Deploymentがapp: myappを使用している場合、Serviceのselectorはapp: myappでなければなりません。kubectl runの--exposeフラグはPodとServiceの両方を同時に作成します — 試験では非常に高速です。

3. Ingress

IngressはL7 HTTP/HTTPSルーティングを提供します — ホスト/パスに基づいて複数のServiceにルーティングする単一のエントリポイントです。

                     ┌─────────────────────────────────┐
Internet ──────────►│   Ingress Controller (nginx)     │
                     │                                  │
                     │  /api  ──────────► api-service   │
                     │  /web  ──────────► web-service   │
                     │  blog.example.com → blog-service │
                     └─────────────────────────────────┘
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx       # 使用するIngressClass
  tls:
  - hosts:
    - myapp.example.com
    secretName: myapp-tls       # TLS証明書をSecretとして格納
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix        # PrefixまたはExact
        backend:
          service:
            name: api-service
            port:
              number: 80
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
pathType動作例
Exactパスを完全一致で照合/apiは/apiのみ一致
Prefixパスのプレフィックスで照合/apiは/api、/api/v1、/api/usersに一致
ImplementationSpecificIngressClassに依存コントローラーに依存

試験のポイント: Ingressが機能するにはIngress Controller(nginx、traefikなど)が必要です — Ingressリソースは設定にすぎません。IngressClassはどのコントローラーがリクエストを処理するかを指定します。試験では通常IngressClassは事前設定されています。kubectl get ingressclassで名前を確認しましょう。

4. Service接続のデバッグ

# Serviceの存在とEndpointsを確認
kubectl get services
kubectl get endpoints myapp-svc

# クラスター内部から接続をテスト(一時的なPodを作成)
kubectl run test --image=busybox --rm -it -- wget -qO- http://myapp-svc
kubectl run test --image=curlimages/curl --rm -it -- curl http://myapp-svc:80

# SelectorがPodに一致するか確認
kubectl get pods -l app=myapp  # Serviceのselectorと一致するか
kubectl describe service myapp-svc  # Endpointsセクションを確認

# Endpointsが空の場合: selectorの不一致!
# 確認: kubectl get pods --show-labels

5. チートシート

タスクコマンド
Deploymentを公開kubectl expose deploy/app --port=80 --type=NodePort
Pod + Serviceを作成kubectl run nginx --image=nginx --port=80 --expose
ServiceのEndpointsを確認kubectl get endpoints svc-name
クラスター内部からServiceをテストkubectl run tmp --image=busybox --rm -it -- wget -O- http://svc
TLS付きIngresstls: secretName + rulesのhosts

6. 練習問題

Q1: "webapp"というDeployment(selector: app=webapp、ポート8080)があります。クラスター内でポート80でアクセスできるServiceを作成するコマンドはどれですか?

  • A) kubectl expose deployment webapp --port=8080
  • B) kubectl expose deployment webapp --port=80 --target-port=8080 ✓
  • C) kubectl create service clusterip webapp --port=8080:80
  • D) kubectl expose deployment webapp --type=ClusterIP --port=80

解説: --port=80はServiceポート(クライアントが使用)、--target-port=8080はコンテナポート(アプリがリッスン)です。--target-portを指定しない場合、Kubernetesはtarget-portがportと同じと仮定します。選択肢Dは機能しますが、両方のポートが80になります。

Q2: Ingressリソースが存在しますが、トラフィックがバックエンドServiceに到達しません。kubectl get endpointsは正しいPod IPを表示しています。最も可能性の高い原因は何ですか?

  • A) ServiceタイプをClusterIPではなくLoadBalancerにすべき
  • B) Ingress Controllerがインストールされていないか、ingressClassNameが間違っている ✓
  • C) IngressにTLSの設定が必要
  • D) pathTypeをPrefixではなくExactにすべき

解説: Ingressリソースは単なる設定オブジェクトです。Ingress Controllerがなければ、ルールを処理するものがありません。ingressClassNameが実行中のコントローラーに接続されたIngressClassと一致しない場合、Ingressは事実上無視されます。kubectl get ingressclassとコントローラーPodの実行状態を確認しましょう。

Q3: 各クラスターノードの30000-32767の範囲のポートを使って外部アクセスを提供するServiceタイプはどれですか?

  • A) ClusterIP
  • B) ExternalName
  • C) NodePort ✓
  • D) LoadBalancer

解説: NodePortはクラスター内の全ノードで30000-32767の範囲のポートを開きます。外部トラフィックはNodeIP:NodePortでServiceに到達できます。通常は開発/テスト用です。LoadBalancerは安定した外部IPを持つクラウドロードバランサーを提供し、本番環境向けです。