Day 10: 本番環境への準備とベストプラクティス
今日学ぶこと
- Namespaceによるリソース分離
- RBACによるアクセス制御
- ResourceQuotaとLimitRange
- モニタリングとロギング
- 本番運用のベストプラクティス
Namespace によるリソース分離
Day 2でNamespaceの基本を学びました。本番環境では、Namespaceを使って環境やチームごとにリソースを分離します。
flowchart TB
subgraph Cluster["Kubernetes Cluster"]
subgraph Dev["dev namespace"]
D1["App Pod"]
D2["DB Pod"]
end
subgraph Staging["staging namespace"]
S1["App Pod"]
S2["DB Pod"]
end
subgraph Prod["production namespace"]
P1["App Pod x3"]
P2["DB Pod"]
end
end
style Dev fill:#22c55e,color:#fff
style Staging fill:#f59e0b,color:#fff
style Prod fill:#3b82f6,color:#fff
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
environment: production
# Namespace作成
kubectl create namespace production
kubectl create namespace staging
# Namespace内にリソース作成
kubectl apply -f deployment.yaml -n production
# デフォルトNamespaceの設定
kubectl config set-context --current --namespace=production
RBAC(Role-Based Access Control)
RBACは誰が何をできるかを制御する仕組みです。
flowchart LR
USER["User / ServiceAccount"] --> RB["RoleBinding"]
RB --> ROLE["Role"]
ROLE --> RES["Resources\n(Pods, Services...)"]
style ROLE fill:#3b82f6,color:#fff
style RB fill:#8b5cf6,color:#fff
Role と ClusterRole
| リソース | スコープ | 用途 |
|---|---|---|
| Role | Namespace内 | 特定Namespaceのリソースへのアクセス |
| ClusterRole | クラスタ全体 | 全Namespaceまたはクラスタリソースへのアクセス |
# developer-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer
namespace: production
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"] # Secretは閲覧のみ
RoleBinding
# developer-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-binding
namespace: production
subjects:
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
ServiceAccount
PodがKubernetes APIにアクセスするための認証情報です。
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-service-account
namespace: production
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: production
spec:
template:
spec:
serviceAccountName: app-service-account
containers:
- name: web
image: nginx:1.27
ResourceQuota と LimitRange
ResourceQuota
Namespaceごとのリソース使用量の上限を設定します。
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
pods: "50"
services: "20"
persistentvolumeclaims: "10"
LimitRange
個々のPodやコンテナのリソースのデフォルト値と上限を設定します。
apiVersion: v1
kind: LimitRange
metadata:
name: production-limits
namespace: production
spec:
limits:
- type: Container
default:
cpu: "250m"
memory: "256Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
max:
cpu: "2"
memory: "4Gi"
min:
cpu: "50m"
memory: "64Mi"
# 確認
kubectl describe resourcequota production-quota -n production
kubectl describe limitrange production-limits -n production
NetworkPolicy
Pod間のネットワーク通信を制御します。Docker書籍のネットワーク分離の発展版です。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-network-policy
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
flowchart LR
FE["frontend"] -->|"許可: 8080"| API["api"]
API -->|"許可: 5432"| DB["postgres"]
OTHER["other pods"] -->|"拒否"| API
style API fill:#3b82f6,color:#fff
style OTHER fill:#ef4444,color:#fff
モニタリングとロギング
Metrics Server
# ノードのリソース使用量
kubectl top nodes
# Podのリソース使用量
kubectl top pods -n production
kubectl top pods --sort-by=cpu
kubectl top pods --sort-by=memory
ログの管理
# Podのログ
kubectl logs deployment/web-app -n production
kubectl logs deployment/web-app -n production -f --tail=100
# 全コンテナのログ
kubectl logs deployment/web-app -n production --all-containers
# ラベルセレクターでログ取得
kubectl logs -l app=web -n production
Prometheus + Grafana(概要)
本格的なモニタリングにはPrometheusとGrafanaを使います。
flowchart LR
PODS["Pods\n(/metrics)"] --> PROM["Prometheus\n(メトリクス収集)"]
PROM --> GRAF["Grafana\n(可視化)"]
PROM --> ALERT["AlertManager\n(アラート)"]
style PROM fill:#ef4444,color:#fff
style GRAF fill:#f59e0b,color:#fff
style ALERT fill:#8b5cf6,color:#fff
# Helm でインストール
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring --create-namespace
本番環境チェックリスト
セキュリティ
| 項目 | 説明 |
|---|---|
| RBAC設定 | 最小権限の原則でアクセス制御 |
| NetworkPolicy | Pod間の不要な通信を制限 |
| Pod Security | 非rootユーザーでコンテナを実行 |
| Secret管理 | 外部シークレット管理ツールの利用 |
| イメージスキャン | 脆弱性スキャンを実施 |
Pod Security の設定
spec:
template:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: app
image: myapp:1.0
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
信頼性
| 項目 | 設定 |
|---|---|
| レプリカ数 | 最低2以上 |
| PodDisruptionBudget | 最小稼働Pod数を保証 |
| Probe設定 | liveness、readiness、startupProbeを設定 |
| リソース制限 | requests/limitsを必ず設定 |
| Affinity/Anti-Affinity | Podを異なるノードに分散 |
PodDisruptionBudget
ノードメンテナンス時などに最低限のPod数を維持します。
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: web
Pod Anti-Affinity
Podを異なるノードに分散させます。
spec:
template:
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostname
本番環境の完全な構成例
apiVersion: v1
kind: Namespace
metadata:
name: production
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: quota
namespace: production
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
pods: "50"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: web
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: web
spec:
serviceAccountName: web-sa
securityContext:
runAsNonRoot: true
runAsUser: 1000
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostname
containers:
- name: web
image: myapp:1.0
ports:
- containerPort: 3000
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secret
---
apiVersion: v1
kind: Service
metadata:
name: web-service
namespace: production
spec:
selector:
app: web
ports:
- port: 80
targetPort: 3000
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
namespace: production
spec:
minAvailable: 2
selector:
matchLabels:
app: web
kubectlコマンドリファレンス
この書籍で学んだ主要コマンドの一覧です。
| カテゴリ | コマンド | 説明 |
|---|---|---|
| 情報取得 | kubectl get <resource> |
リソース一覧 |
kubectl describe <resource> <name> |
リソース詳細 | |
kubectl logs <pod> |
ログ表示 | |
kubectl top <nodes/pods> |
リソース使用量 | |
| 作成・更新 | kubectl apply -f <file> |
宣言的に作成/更新 |
kubectl create <resource> |
リソース作成 | |
kubectl scale deployment <name> --replicas=N |
スケーリング | |
kubectl set image deployment/<name> |
イメージ更新 | |
| 削除 | kubectl delete -f <file> |
ファイルのリソース削除 |
kubectl delete <resource> <name> |
指定リソース削除 | |
| デバッグ | kubectl exec -it <pod> -- /bin/sh |
コンテナ内でコマンド実行 |
kubectl port-forward <pod> <local>:<remote> |
ポートフォワード | |
kubectl cp <pod>:<path> <local-path> |
ファイルコピー | |
| ロールアウト | kubectl rollout status deployment/<name> |
更新状況確認 |
kubectl rollout undo deployment/<name> |
ロールバック | |
kubectl rollout history deployment/<name> |
履歴確認 |
Docker から Kubernetes への対応表
| Docker コマンド | Kubernetes コマンド |
|---|---|
docker run |
kubectl run / kubectl apply |
docker ps |
kubectl get pods |
docker logs |
kubectl logs |
docker exec |
kubectl exec |
docker stop |
kubectl delete pod |
docker-compose up |
kubectl apply -f |
docker-compose down |
kubectl delete -f |
docker volume |
kubectl get pv/pvc |
docker network |
kubectl get svc/ingress |
まとめ
| 概念 | 説明 |
|---|---|
| Namespace | リソースの論理的分離 |
| RBAC | ロールベースのアクセス制御 |
| ResourceQuota | Namespaceごとのリソース上限 |
| NetworkPolicy | Pod間のネットワークアクセス制御 |
| PodDisruptionBudget | メンテナンス時の最小Pod数保証 |
| Pod Security | 非rootユーザー、読み取り専用ファイルシステム等 |
重要ポイント
- 本番環境ではNamespace、RBAC、ResourceQuotaで適切にリソースを管理・分離する
- セキュリティは多層防御。Pod Security、NetworkPolicy、RBACを組み合わせる
- 信頼性のためにProbe、PDB、Anti-Affinity、HPAを設定する
練習問題
問題1: Namespace設計
開発(dev)、ステージング(staging)、本番(production)の3つのNamespaceを作成し、それぞれにResourceQuotaを設定してください。
問題2: RBAC
developmentチームが開発Namespaceの全リソースにアクセスでき、本番NamespaceではPodの参照のみ可能なRBAC設定を作成してください。
チャレンジ問題
本番環境の完全な構成例を参考に、Webアプリ + API + データベースの3層アーキテクチャを構築してください。Namespace、RBAC、NetworkPolicy、HPA、PDBを全て設定しましょう。
参考リンク
おわりに
10日間を通じて、Docker書籍で学んだコンテナ技術をKubernetesで本格的に運用するための知識を習得しました。
| Day | 学んだこと |
|---|---|
| 1 | Kubernetesの概要とアーキテクチャ |
| 2 | クラスタ構築とkubectl |
| 3 | Podの詳細とヘルスチェック |
| 4 | ReplicaSetとDeployment |
| 5 | Serviceによるネットワーキング |
| 6 | ストレージとデータ永続化 |
| 7 | ConfigMapとSecret |
| 8 | Ingressと外部公開 |
| 9 | スケーリングとアップデート戦略 |
| 10 | 本番環境への準備 |
Dockerでコンテナの基礎を学び、Kubernetesでオーケストレーションを学んだことで、現代のクラウドネイティブアプリケーションを構築・運用するための基盤が整いました。次のステップとして、Helm、GitOps(ArgoCD)、サービスメッシュ(Istio)などの発展的なトピックにも挑戦してみてください。