インフラ レッスン4
Kubernetes入門
コンテナオーケストレーションの基本を学ぼう
コンテナオーケストレーションとは?
Dockerで作ったコンテナが増えてくると、「どのサーバーでどのコンテナを動かすか」「コンテナが 落ちたら自動で再起動したい」「負荷に応じてスケールしたい」といった課題が出てきます。Kubernetes(K8s)はこれらを自動化する コンテナオーケストレーションプラットフォームです。
Kubernetes クラスターの構成:
┌─────────────────────────────────────────────────┐
│ Control Plane │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ API Server│ │ Scheduler│ │ Controller Manager│ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
│ ┌──────────┐ │
│ │ etcd │ ← クラスターの状態を保存 │
│ └──────────┘ │
└─────────────────────────────────────────────────┘
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Worker Node │ │ Worker Node │ │ Worker Node │
│ ┌───┐ ┌───┐ │ │ ┌───┐ ┌───┐ │ │ ┌───┐ │
│ │Pod│ │Pod│ │ │ │Pod│ │Pod│ │ │ │Pod│ │
│ └───┘ └───┘ │ │ └───┘ └───┘ │ │ └───┘ │
│ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │
│ │ kubelet │ │ │ │ kubelet │ │ │ │ kubelet │ │
│ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │
└───────────────┘ └───────────────┘ └───────────────┘Pod
PodはKubernetesの最小デプロイ単位です。 1つ以上のコンテナをまとめたもので、同じPod内のコンテナはネットワークとストレージを共有します。 通常は1つのPodに1つのコンテナを配置します。
# pod.yaml - 基本的なPod定義
apiVersion: v1
kind: Pod
metadata:
name: my-app
labels:
app: my-app
spec:
containers:
- name: app
image: node:20-alpine
ports:
- containerPort: 3000
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
env:
- name: NODE_ENV
value: "production"
- name: PORT
value: "3000"
# Podの作成
$ kubectl apply -f pod.yaml
# Podの確認
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-app 1/1 Running 0 30s
# Podの詳細
$ kubectl describe pod my-app
# Podのログ
$ kubectl logs my-app
# Pod内でコマンドを実行
$ kubectl exec -it my-app -- /bin/shDeployment
DeploymentはPodの宣言的な管理を行うリソースです。 レプリカ数の維持、ローリングアップデート、ロールバックなどを自動で処理します。 実運用ではPodを直接作らず、Deploymentを使います。
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3 # 常に3つのPodを維持
selector:
matchLabels:
app: my-app
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 更新時に最大1つ追加
maxUnavailable: 0 # 更新時にダウンするPodは0
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: myregistry/my-app:v1.0.0
ports:
- containerPort: 3000
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
periodSeconds: 20
# デプロイ
$ kubectl apply -f deployment.yaml
# Deploymentの確認
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
my-app 3/3 3 3 2m
# イメージの更新(ローリングアップデート)
$ kubectl set image deployment/my-app app=myregistry/my-app:v1.1.0
# ロールバック
$ kubectl rollout undo deployment/my-app
# 更新履歴の確認
$ kubectl rollout history deployment/my-appService
ServiceはPodへの安定したアクセスポイントを提供します。 Podは動的にIPが変わりますが、Serviceは固定のアドレスでアクセスできます。
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app # label が app=my-app のPodに振り分け
type: ClusterIP # クラスター内部からのみアクセス
ports:
- protocol: TCP
port: 80 # Serviceのポート
targetPort: 3000 # Podのポート
---
# 外部公開する場合(LoadBalancer)
apiVersion: v1
kind: Service
metadata:
name: my-app-public
spec:
selector:
app: my-app
type: LoadBalancer # 外部ロードバランサーを作成
ports:
- protocol: TCP
port: 80
targetPort: 3000
---
# NodePort(開発・テスト用)
apiVersion: v1
kind: Service
metadata:
name: my-app-nodeport
spec:
selector:
app: my-app
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 3000
nodePort: 30080 # ノードのIPでアクセス可能
# Serviceの確認
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
my-app-service ClusterIP 10.96.0.100 <none> 80/TCP
my-app-public LoadBalancer 10.96.0.101 203.0.113.1 80:31234/TCPConfigMap と Secret
ConfigMapは設定データを、Secretは機密データを Podから分離して管理するリソースです。
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
NODE_ENV: "production"
LOG_LEVEL: "info"
API_BASE_URL: "https://api.example.com"
---
# secret.yaml(値はbase64エンコード)
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
DATABASE_URL: cG9zdGdyZXM6Ly91c2VyOnBhc3NAZGIvbXlhcHA=
API_KEY: c2VjcmV0LWFwaS1rZXktMTIzNDU=
# base64エンコード
$ echo -n 'postgres://user:pass@db/myapp' | base64
---
# Deploymentで使う
spec:
containers:
- name: app
image: myregistry/my-app:v1.0.0
envFrom:
- configMapRef:
name: app-config # ConfigMapの全キーを環境変数に
- secretRef:
name: app-secrets # Secretの全キーを環境変数にkubectlの基本操作とスケーリング
kubectlはKubernetesクラスターを操作するCLIツールです。 リソースの作成、確認、更新、削除を行います。
# リソースの確認
$ kubectl get pods # Pod一覧
$ kubectl get pods -o wide # 詳細情報(IPやノード)
$ kubectl get all # 全リソース
$ kubectl get pods -n my-namespace # 名前空間を指定
# リソースの作成・更新
$ kubectl apply -f deployment.yaml # YAMLから作成/更新
$ kubectl delete -f deployment.yaml # YAMLのリソースを削除
# デバッグ
$ kubectl describe pod my-app-xxx # 詳細情報とイベント
$ kubectl logs my-app-xxx # ログを表示
$ kubectl logs -f my-app-xxx # ログをリアルタイム表示
$ kubectl exec -it my-app-xxx -- sh # コンテナ内にシェル接続# 手動スケーリング
$ kubectl scale deployment/my-app --replicas=5
# 自動スケーリング(HPA: Horizontal Pod Autoscaler)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # CPU使用率70%を超えたらスケールアウト
# HPAの確認
$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
my-app-hpa Deployment/my-app 45%/70% 2 10 3まとめ
- Kubernetesはコンテナのデプロイ・スケーリング・管理を自動化するプラットフォーム
- Podはコンテナの最小デプロイ単位、Deploymentでレプリカ管理とローリングアップデートを行う
- ServiceはPodへの安定したアクセスポイント(ClusterIP、LoadBalancer、NodePort)
- ConfigMapとSecretで設定と機密情報をPodから分離して管理する
- kubectlでクラスターのリソースを操作・監視する
- HPAで負荷に応じた自動スケーリングが可能