開発者のためのKubernetes入門 — Pod/Service/Deploymentの基本
Kubernetesは、コンテナオーケストレーションのデファクトスタンダードです。この記事では、開発者が知っておくべきKubernetesの基本を実践的に解説します。
Kubernetesとは
Kubernetesは、Dockerコンテナを大規模に管理するためのオープンソースプラットフォームです。略して「k8s」と呼ばれます(kとsの間に8文字あるため)。
Kubernetesが解決する課題
- スケーリング: トラフィックに応じて自動的にコンテナを増減
- 自己修復: 障害が発生したコンテナを自動的に再起動
- ロードバランシング: 複数のコンテナに負荷を分散
- デプロイ管理: ゼロダウンタイムでのアプリケーション更新
- 設定管理: 環境変数やシークレットの一元管理
ローカル開発環境のセットアップ
まずは、ローカルマシンでKubernetesクラスタを動かしましょう。
kind (Kubernetes in Docker)
# kindのインストール (macOS)
brew install kind
# クラスタの作成
kind create cluster --name dev-cluster
# クラスタの確認
kubectl cluster-info --context kind-dev-cluster
# クラスタの削除(不要になったら)
kind delete cluster --name dev-cluster
minikube
# minikubeのインストール (macOS)
brew install minikube
# クラスタの起動
minikube start
# ダッシュボードの起動
minikube dashboard
# クラスタの停止
minikube stop
kubectlの基本コマンド
kubectlは、Kubernetesクラスタを操作するためのCLIツールです。
# クラスタ情報の確認
kubectl cluster-info
# ノード一覧
kubectl get nodes
# すべてのリソースを表示
kubectl get all
# 特定のNamespaceのリソース
kubectl get all -n kube-system
# Pod一覧
kubectl get pods
# Pod詳細
kubectl describe pod <pod-name>
# Podのログ確認
kubectl logs <pod-name>
# Podに接続
kubectl exec -it <pod-name> -- /bin/sh
# リソースの削除
kubectl delete pod <pod-name>
# YAMLからリソースを作成
kubectl apply -f deployment.yaml
# リソースの削除
kubectl delete -f deployment.yaml
Podの基本
Podは、Kubernetesにおける最小のデプロイ単位です。1つ以上のコンテナを含みます。
シンプルなPod定義
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
env:
- name: ENVIRONMENT
value: "development"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
# Podの作成
kubectl apply -f pod.yaml
# Podの確認
kubectl get pods
# Podの詳細
kubectl describe pod nginx-pod
# Podのログ
kubectl logs nginx-pod
# Podに接続
kubectl exec -it nginx-pod -- /bin/bash
マルチコンテナPod
# multi-container-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-with-sidecar
spec:
containers:
# メインアプリケーション
- name: app
image: myapp:1.0
ports:
- containerPort: 8080
volumeMounts:
- name: shared-logs
mountPath: /var/log
# ログ収集用サイドカー
- name: log-collector
image: fluent/fluent-bit:2.0
volumeMounts:
- name: shared-logs
mountPath: /var/log
readOnly: true
volumes:
- name: shared-logs
emptyDir: {}
Deploymentによる管理
Podを直接作成するのではなく、Deploymentを使用することで、レプリケーションやローリングアップデートが可能になります。
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web
spec:
replicas: 3 # 3つのPodを起動
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 3
# Deploymentの作成
kubectl apply -f deployment.yaml
# Deploymentの確認
kubectl get deployments
# Podの確認(3つ起動されているはず)
kubectl get pods -l app=web
# スケーリング
kubectl scale deployment web-app --replicas=5
# ローリングアップデート
kubectl set image deployment/web-app nginx=nginx:1.26
# アップデートの確認
kubectl rollout status deployment/web-app
# ロールバック
kubectl rollout undo deployment/web-app
Serviceによるネットワーク管理
Serviceは、Podへのネットワークアクセスを提供します。
ClusterIP Service(クラスタ内部アクセス)
# service-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: ClusterIP # デフォルト
selector:
app: web
ports:
- protocol: TCP
port: 80 # Serviceのポート
targetPort: 80 # Podのポート
NodePort Service(外部アクセス)
# service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: web-service-external
spec:
type: NodePort
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080 # 30000-32767の範囲
LoadBalancer Service(クラウド環境)
# service-loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
name: web-service-lb
spec:
type: LoadBalancer
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 80
# Serviceの作成
kubectl apply -f service-clusterip.yaml
# Serviceの確認
kubectl get services
# Service詳細
kubectl describe service web-service
# Serviceへの接続確認(クラスタ内から)
kubectl run test-pod --image=busybox -it --rm -- wget -qO- http://web-service
ConfigMapとSecret
アプリケーションの設定と機密情報を管理します。
ConfigMap
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DATABASE_HOST: "postgres.default.svc.cluster.local"
DATABASE_PORT: "5432"
LOG_LEVEL: "info"
app.properties: |
server.port=8080
server.timeout=30s
Secret
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
stringData:
DATABASE_PASSWORD: "supersecret"
API_KEY: "your-api-key-here"
Deployment with ConfigMap & Secret
# deployment-with-config.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: myapp:1.0
env:
# ConfigMapから環境変数
- name: DATABASE_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: DATABASE_HOST
# Secretから環境変数
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: DATABASE_PASSWORD
volumeMounts:
# ConfigMapをファイルとしてマウント
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
Helmによるパッケージ管理
Helmは、Kubernetesのパッケージマネージャーです。複数のリソースをまとめて管理できます。
# Helmのインストール (macOS)
brew install helm
# リポジトリの追加
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# チャートの検索
helm search repo nginx
# チャートのインストール
helm install my-nginx bitnami/nginx
# インストール済みのリリース確認
helm list
# リリースのアップグレード
helm upgrade my-nginx bitnami/nginx --set replicaCount=3
# リリースの削除
helm uninstall my-nginx
カスタムHelmチャート
# 新しいチャートの作成
helm create myapp
# ディレクトリ構造
myapp/
├── Chart.yaml # チャートのメタデータ
├── values.yaml # デフォルト値
├── templates/ # Kubernetesマニフェストのテンプレート
│ ├── deployment.yaml
│ ├── service.yaml
│ └── ingress.yaml
└── charts/ # 依存チャート
# values.yaml
replicaCount: 3
image:
repository: myapp
tag: "1.0.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
# チャートのインストール
helm install myapp ./myapp
# カスタム値でインストール
helm install myapp ./myapp --set replicaCount=5
実践的なワークフロー
# 1. ローカル開発環境の起動
kind create cluster --name dev
# 2. イメージのビルド(Dockerfileから)
docker build -t myapp:dev .
# 3. kindにイメージをロード
kind load docker-image myapp:dev --name dev
# 4. マニフェストの適用
kubectl apply -f k8s/
# 5. 動作確認
kubectl get all
kubectl logs deployment/myapp
# 6. ポートフォワードで動作確認
kubectl port-forward service/myapp 8080:80
# ブラウザで http://localhost:8080 にアクセス
まとめ
Kubernetesの基本を理解することで、モダンなクラウドネイティブアプリケーションの開発・運用が可能になります。
学習のポイント:
- Podは最小単位だが、本番ではDeploymentを使う
- Serviceによってネットワークを抽象化
- ConfigMapとSecretで設定を外部化
- Helmで複雑な構成を管理
- ローカル環境(kind/minikube)で実験を繰り返す
まずはローカル環境で手を動かし、基本的なリソースの作成・更新・削除を体験することが重要です。Kubernetesは学習曲線が急ですが、一度習得すればあらゆるクラウド環境で活用できる強力なスキルとなります。