はじめに
前回の記事では、Herokuへの簡単なデプロイ方法と 負荷対策(データベース最適化、キャッシュ、非同期処理、ページネーション)を解説しました。
今回は、より高度な運用手法としてKubernetes(K8s)を活用したデプロイ方法とより具体的な負荷テストの実施方法について解説します。
対象読者
- Goで開発したWebアプリをKubernetes上にデプロイしたい方
- 負荷テストを実施し、パフォーマンスを計測 & 最適化したい方
目次
- Kubernetesを活用したデプロイ
- Kubernetesの基本概念
- Kubernetesクラスターの構築(Minikubeを使用)
- KubernetesへのGoアプリのデプロイ
- 負荷テストの実施
- 負荷テストの目的
- k6を使った負荷テスト
- 負荷テストの結果分析と最適化
1. Kubernetesを活用したデプロイ
1.1 Kubernetesの基本概念
Kubernetes(K8s) は、コンテナ化されたアプリケーションを管理・運用するためのオーケストレーションツールです。
- 自動スケーリング:負荷に応じてコンテナを増減
- サービスディスカバリ & ロードバランシング:複数のコンテナにトラフィックを分散
- 自己回復機能:クラッシュしたコンテナを自動で再起動
1.2 Kubernetesクラスターの構築(Minikubeを使用)
まずは、ローカル環境でKubernetesクラスターを構築するためにMinikubeを使用します。
Minikubeのインストール
# Minikubeをインストール
brew install minikube
# Minikubeを起動
minikube start
1.3 KubernetesへのGoアプリのデプロイ
Dockerイメージの作成 & Minikubeにプッシュ
docker build -t my-go-app .
minikube image load my-go-app
Kubernetesのデプロイメント定義
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-app
spec:
replicas: 3
selector:
matchLabels:
app: go-app
template:
metadata:
labels:
app: go-app
spec:
containers:
- name: go-app
image: my-go-app
ports:
- containerPort: 8080
サービスの定義(Service.yaml)
apiVersion: v1
kind: Service
metadata:
name: go-app-service
spec:
type: NodePort
selector:
app: go-app
ports:
- protocol: TCP
port: 8080
targetPort: 8080
Kubernetesにデプロイ
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
サービスの確認 & アクセス
minikube service go-app-service --url
2. 負荷テストの実施
2.1 負荷テストの目的
負荷テストを行うことで、アプリケーションの限界性能を確認し、適切なスケーリングのための指標を得ることができます。
負荷テストの目的:
- 最大リクエスト数の測定
- レスポンス時間の分析
- スケールアップの必要性の判断
2.2 k6を使った負荷テスト
k6のインストール
brew install k6
負荷テストのスクリプト作成(load-test.js)
import http from 'k6/http';
import { check, sleep } from 'k6';
export let options = {
vus: 50, // 仮想ユーザー数
duration: '30s', // テスト時間
};
export default function () {
let res = http.get('http://localhost:8080/api/todos');
check(res, {
'status was 200': (r) => r.status == 200,
'response time < 200ms': (r) => r.timings.duration < 200,
});
sleep(1);
}
負荷テストの実行
k6 run load-test.js
2.3 負荷テストの結果分析と最適化
k6の出力例
checks..................: 100.00% ✓ 1500 ✗ 0
http_req_duration......: avg=120.56ms min=90ms max=250ms
http_reqs..............: 50 requests per second
このデータを元に、以下の最適化を検討します。
課題 | 改善策 |
---|---|
レスポンスが遅い | キャッシュ(Redis)を導入 |
CPU 負荷が高い | Kubernetesのオートスケールを設定 |
リクエストが増えすぎる | レートリミットを適用 |
Kubernetesのオートスケール設定
kubectl autoscale deployment go-app --cpu-percent=50 --min=2 --max=5
レートリミットの設定(Gin Middleware)
import "golang.org/x/time/rate"
var limiter = rate.NewLimiter(1, 5)
func rateLimitMiddleware(c *gin.Context) {
if !limiter.Allow() {
c.JSON(http.StatusTooManyRequests, gin.H{"error": "Too many requests"})
c.Abort()
return
}
c.Next()
}
まとめ
項目 | 説明 |
---|---|
Kubernetes | アプリケーションをスケーラブルにデプロイするためのオーケストレーションツール |
Minikube | ローカル環境でKubernetesをテストするためのツール |
負荷テスト(k6) | Webアプリケーションのパフォーマンスを測定するためのツール |
スケーリング & 最適化 | キャッシュ、オートスケール、レートリミットを活用して負荷を軽減 |
本記事では、Kubernetes を活用したデプロイ方法と負荷テストの具体的な実施方法について解説しました。
もう少しクラウド環境(AWS, GCP, Azure)でのデプロイとかKubernetesのCI/CDパイプライン構築もやっていこうかな