1. Serviceタイプ
| タイプ | アクセス | 使用場面 |
|---|---|---|
| ClusterIP | クラスター内部のみ(クラスターDNS) | Service間通信(デフォルト) |
| NodePort | NodeIP:30000-32767 | 開発/テスト環境の外部アクセス |
| LoadBalancer | クラウドLBの外部IP | 本番環境の外部アクセス(クラウド) |
| ExternalName | CNAME 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に一致 |
| ImplementationSpecific | IngressClassに依存 | コントローラーに依存 |
試験のポイント: 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付きIngress | tls: 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を持つクラウドロードバランサーを提供し、本番環境向けです。