Kubernetes基礎:初めてのクラスタ構築とアプリケーションデプロイ
Kubernetes(K8s)は、コンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化するためのオープンソースプラットフォームです。この記事では、Kubernetesの基本概念から始めて、実際にクラスタを構築し、アプリケーションをデプロイする方法を学びます。
マイクロサービスアーキテクチャやクラウドネイティブアプリケーションの運用に必要な知識を身につけましょう。
1. Kubernetesとは
Kubernetesは、Googleが開発したコンテナオーケストレーションシステムで、以下の機能を提供します。
- 自動デプロイ: アプリケーションの自動展開とロールバック
- スケーリング: 負荷に応じた自動スケーリング
- 自己修復: 障害のあるコンテナの自動再起動
- サービスディスカバリ: コンテナ間の自動サービス発見
- ロードバランシング: トラフィックの分散
1.1 Kubernetesのアーキテクチャ
- Master Node(コントロールプレーン): クラスタの管理
- Worker Node: アプリケーションコンテナを実行
- Pod: コンテナの最小デプロイ単位
- Service: Podへの安定したアクセスを提供
- Deployment: Podのレプリカ管理
1.2 環境の準備
# Minikubeのインストール(ローカル環境でのK8s)
# Mac
brew install minikube
# Linux
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# Minikubeの起動
minikube start
# kubectlのインストール(K8sコマンドラインツール)
# Mac
brew install kubectl
# kubectlの確認
kubectl version --client
2. 基本的なKubernetesオブジェクト
2.1 Pod
Podは、Kubernetesにおける最小デプロイ単位です。1つ以上のコンテナを含むことができます。
# pod-example.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx:latest
ports:
- containerPort: 80
# Podの作成
kubectl apply -f pod-example.yaml
# Podの一覧表示
kubectl get pods
# Podの詳細情報
kubectl describe pod nginx-pod
# Podのログ確認
kubectl logs nginx-pod
# Podの削除
kubectl delete pod nginx-pod
2.2 Deployment
Deploymentは、Podのレプリカを管理し、ロールアウトとロールバックを提供します。
# deployment-example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
# Deploymentの作成
kubectl apply -f deployment-example.yaml
# Deploymentの一覧
kubectl get deployments
# Deploymentの詳細
kubectl describe deployment nginx-deployment
# Podの状態確認
kubectl get pods -l app=nginx
# レプリカ数の変更
kubectl scale deployment nginx-deployment --replicas=5
# Deploymentの削除
kubectl delete deployment nginx-deployment
2.3 Service
Serviceは、Podの集合への安定したアクセスを提供します。
# service-example.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP # NodePort, LoadBalancer も指定可能
# Serviceの作成
kubectl apply -f service-example.yaml
# Serviceの一覧
kubectl get services
# Serviceの詳細
kubectl describe service nginx-service
# Serviceへのアクセス(ポートフォワード)
kubectl port-forward service/nginx-service 8080:80
# Serviceの削除
kubectl delete service nginx-service
3. 実践的なアプリケーションデプロイ
3.1 シンプルなWebアプリケーション
# web-app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: nginx:latest
ports:
- containerPort: 80
env:
- name: ENV
value: "production"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
3.2 データベースとの連携
# postgres-deployment.yaml
apiVersion: v1
kind: Secret
metadata:
name: postgres-secret
type: Opaque
data:
password: cG9zdGdyZXM= # base64エンコードされた値
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15
env:
- name: POSTGRES_USER
value: "postgres"
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: password
- name: POSTGRES_DB
value: "myapp"
ports:
- containerPort: 5432
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-pvc
---
apiVersion: v1
kind: Service
metadata:
name: postgres-service
spec:
selector:
app: postgres
ports:
- protocol: TCP
port: 5432
targetPort: 5432
4. ConfigMapとSecret
4.1 ConfigMap
ConfigMapは、設定データを格納するためのオブジェクトです。
# configmap-example.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database_url: "postgresql://localhost:5432/myapp"
log_level: "info"
api_key: "your-api-key"
# ConfigMapの作成
kubectl apply -f configmap-example.yaml
# ConfigMapの一覧
kubectl get configmaps
# ConfigMapの詳細
kubectl describe configmap app-config
# ConfigMapの使用(Deploymentで)
# envFromを使用して環境変数として読み込み
# deployment-with-configmap.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-with-config
spec:
template:
spec:
containers:
- name: app
image: my-app:latest
envFrom:
- configMapRef:
name: app-config
4.2 Secret
Secretは、機密情報(パスワード、トークンなど)を保存するためのオブジェクトです。
# Secretの作成(コマンドラインから)
kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password=secretpassword
# Secretの確認
kubectl get secrets
kubectl describe secret db-secret
# Secretの値の表示(デコード)
kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d
# secret-example.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
username: admin
password: secretpassword
5. スケーリング
5.1 手動スケーリング
# レプリカ数の変更
kubectl scale deployment web-app --replicas=5
# 現在のレプリカ数を確認
kubectl get deployment web-app
5.2 自動スケーリング(HPA)
Horizontal Pod Autoscaler(HPA)は、CPU使用率やカスタムメトリクスに基づいて自動的にスケーリングします。
# hpa-example.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
# HPAの作成
kubectl apply -f hpa-example.yaml
# HPAの状態確認
kubectl get hpa
# HPAの詳細
kubectl describe hpa web-app-hpa
6. ロールアウトとロールバック
6.1 ローリングアップデート
# イメージの更新
kubectl set image deployment/web-app web-app=nginx:1.22
# ロールアウトの状態確認
kubectl rollout status deployment/web-app
# ロールアウト履歴の確認
kubectl rollout history deployment/web-app
# 前のバージョンにロールバック
kubectl rollout undo deployment/web-app
# 特定のリビジョンにロールバック
kubectl rollout undo deployment/web-app --to-revision=2
6.2 デプロイメント戦略
# rolling-update-strategy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
replicas: 3
template:
# ...
7. 名前空間(Namespace)
名前空間は、クラスタ内でリソースを論理的に分離するために使用します。
# 名前空間の作成
kubectl create namespace development
kubectl create namespace production
# 名前空間の一覧
kubectl get namespaces
# 特定の名前空間での操作
kubectl get pods -n development
# 名前空間の切り替え(コンテキストの設定)
kubectl config set-context --current --namespace=development
# 名前空間の削除
kubectl delete namespace development
# namespace-example.yaml
apiVersion: v1
kind: Namespace
metadata:
name: staging
labels:
name: staging
8. ヘルスチェックとライブネスプローブ
# healthcheck-example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
template:
spec:
containers:
- name: web-app
image: nginx:latest
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
startupProbe:
httpGet:
path: /startup
port: 80
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 30
9. Ingress
Ingressは、クラスタ外部からサービスへのHTTP/HTTPSアクセスを管理します。
# ingress-example.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
tls:
- hosts:
- example.com
secretName: tls-secret
# Ingressコントローラーのインストール(nginx-ingress)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml
# Ingressの作成
kubectl apply -f ingress-example.yaml
# Ingressの確認
kubectl get ingress
10. ストレージ
10.1 PersistentVolumeとPersistentVolumeClaim
# pv-pvc-example.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /mnt/data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
10.2 StorageClass
# storageclass-example.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
replication-type: regional-pd
11. 実践的なデプロイメント例
11.1 完全なアプリケーションスタック
# full-stack-app.yaml
# Frontend Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: frontend:latest
ports:
- containerPort: 3000
env:
- name: API_URL
value: "http://backend-service:8000"
---
# Backend Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 2
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: backend:latest
ports:
- containerPort: 8000
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: url
- name: REDIS_URL
value: "redis://redis-service:6379"
---
# Database Deployment
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: postgres-storage
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 20Gi
---
# Redis Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
---
# Services
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
selector:
app: frontend
ports:
- port: 80
targetPort: 3000
type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend
ports:
- port: 8000
targetPort: 8000
---
apiVersion: v1
kind: Service
metadata:
name: postgres-service
spec:
selector:
app: postgres
ports:
- port: 5432
targetPort: 5432
---
apiVersion: v1
kind: Service
metadata:
name: redis-service
spec:
selector:
app: redis
ports:
- port: 6379
targetPort: 6379
12. 監視とロギング
12.1 kubectlコマンドでの監視
# リソース使用状況の確認
kubectl top nodes
kubectl top pods
# イベントの確認
kubectl get events --sort-by=.metadata.creationTimestamp
# リソースの詳細情報
kubectl describe pod <pod-name>
12.2 ログの確認
# Podのログ
kubectl logs <pod-name>
# 複数コンテナがある場合
kubectl logs <pod-name> -c <container-name>
# リアルタイムでログを表示
kubectl logs -f <pod-name>
# 過去のログ(以前のコンテナ)
kubectl logs --previous <pod-name>
13. まとめと次のステップ
このガイドを通じて、Kubernetesの基礎から実践的なデプロイメントまで学びました。
学んだこと
- 基本オブジェクト: Pod、Deployment、Service
- 設定管理: ConfigMap、Secret
- スケーリング: 手動スケーリング、HPA
- ロールアウト: ローリングアップデート、ロールバック
- ネットワーキング: Service、Ingress
- ストレージ: PV、PVC、StorageClass
- 実践デプロイ: 完全なアプリケーションスタック
次のステップ
- Helm: パッケージマネージャー
- Operator: カスタムリソースの管理
- Service Mesh: Istio、Linkerd
- クラウドKubernetes: GKE、EKS、AKS
- CI/CD統合: ArgoCD、Flux
Kubernetesは、現代のコンテナオーケストレーションの標準です。継続的な学習と実践を通じて、スケーラブルで堅牢なアプリケーションを構築できるようになりましょう!
Happy K8s!
コメント
コメントを読み込み中...
