発展LESSON 08
この教材で学ぶこと クラスタ内外の通信経路とIngressを設計します。K8s ネットワークと Ingress
前提知識: Pod・Service・Deployment。本教材ではトラフィックフローとIngress設計を扱います。
1. K8s ネットワークの仕組み
K8s のネットワークモデル(基本原則):
1. すべての Pod は固有の IP を持つ
2. Pod 間通信は NAT なしで直接可能
3. Node から Pod へも NAT なしで通信可能
実装(クラスター構築時に選ぶ CNI プラグイン):
Calico → 高機能(NetworkPolicy が強力)、EKS で推奨
Flannel → シンプル・軽量
Cilium → eBPF ベース・高パフォーマンス・可視化機能付き(最近人気)
EKS のデフォルト: AWS VPC CNI
→ Pod に VPC の IP アドレスが直接割り当てられる
→ Pod から VPC 内のリソース(RDS 等)に直接通信可能
2. Service の種類
# ClusterIP(デフォルト)— クラスター内部のみ
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
type: ClusterIP # クラスター内の DNS で myapp-service.default.svc.cluster.local
---
# NodePort — 各ノードのポートを開放(開発・テスト向け)
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # 30000-32767 の範囲
---
# LoadBalancer — クラウドの LB を自動プロビジョニング
# EKS では AWS NLB/ALB が作られる
spec:
type: LoadBalancer
# EKS で ALB を使う場合は Ingress を使う方が推奨(後述)
3. Ingress — L7 ルーティングのベストプラクティス
Service type=LoadBalancer の問題:
サービスごとに AWS NLB が1台作られる → コスト増
Ingress の利点:
1台の ALB でパス・ホストベースの振り分けが可能
# EKS で AWS Load Balancer Controller を使った Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
# EKS: AWS Load Balancer Controller が ALB を自動作成
kubernetes.io/ingress.class: "alb"
alb.ingress.kubernetes.io/scheme: "internet-facing"
alb.ingress.kubernetes.io/target-type: "ip"
alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:ap-northeast-1:xxx:certificate/yyy"
alb.ingress.kubernetes.io/ssl-redirect: "443"
# WAF と連携
alb.ingress.kubernetes.io/wafv2-acl-arn: "arn:aws:wafv2:..."
spec:
rules:
- host: api.myapp.com
http:
paths:
- path: /api/v1
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /api/v2
pathType: Prefix
backend:
service:
name: api-v2-service
port:
number: 80
- host: admin.myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 80
4. NetworkPolicy — Pod 間の通信制限
# デフォルト: 全ての Pod 間通信が許可(セキュリティリスク)
# NetworkPolicy でホワイトリスト方式に変更
# まず全ての Ingress を拒否
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {} # 全 Pod に適用
policyTypes:
- Ingress
- Egress
---
# API Pod への接続を Front Pod からのみ許可
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
---
# DB への接続を API からのみ許可
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-to-db
namespace: production
spec:
podSelector:
matchLabels:
app: database
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- port: 5432
5. DNS と Service Discovery
# K8s 内の DNS 解決(CoreDNS)
# Service 名で別の Pod から接続できる
# 同じ Namespace
curl http://myapp-service/api/health
# 別の Namespace
curl http://myapp-service.production.svc.cluster.local/api/health
# 外部 DNS への解決
# Pod から RDS エンドポイントへ → VPC DNS で解決
# DNS の動作確認
kubectl run test-pod --image=nicolaka/netshoot -it --rm -- bash
# Pod 内から:
nslookup myapp-service.production.svc.cluster.local
curl http://myapp-service.production/health
6. トラブルシューティング
# Pod の通信テスト
kubectl exec -it mypod -- curl http://other-service/health
# NetworkPolicy が原因で繋がらない場合
# Cilium Hubble(可視化)やシンプルなデバッグ Pod で確認
kubectl run netshoot --image=nicolaka/netshoot --rm -it -- bash
# → tcpdump, curl, nslookup 等が使える
# Service のエンドポイントが正しいか確認
kubectl get endpoints myapp-service
# → Pods の IP が表示されなければ selector のラベルが合っていない
# Ingress の状態確認
kubectl describe ingress myapp-ingress
# → Events 欄にエラーがあれば ALB Controller の設定問題
kubectl logs -n kube-system deployment/aws-load-balancer-controller
🔗 次のステップ
- 01_K8s基礎.md — Deployment・Service・HPA の基礎
- ../../03_Cloud/AWS/02_コンテナサービス.md — EKS の AWS 設計
- ../../02_Infrastructure/Networking/02_ロードバランサーとプロキシ.md — ALB・Nginx の仕組み