このポストは Kubernetes Advent Calendar Day 25の記事です。
Google Compute Engine (GCE)ではPreemptible Instanceを作ることができます。Preemptible Instanceを使うと変動するようなワークロードにかなりコストを削減できます。
Google Kubernetes Engine (GKE)は標準にクラスターオートスケーラーがついています。 クラスターオートスケーラーを有効にするとクラスターの要求されているワークロードに 対してクラスターを自動的にスケールできます。GKEクラスターのノードはGCEのVMに なっているので preemptible instanceのノードプールの 作成にサポートしています。
この記事ではこの2つの機能を組み合わせて安くて自動的にスケールするリソースの作成をやってみたい。 一緒にやってみたい方はGCPの$300無料トライアルを使うといいと思います。
Preemptible Instances
Preemptible instanceはGCEの単価が 安く一時的なVMを作成できる機能です。GCEゾーンのデータセンターの余裕キャパを買うような感じですので、 かなり安く提供できるけど、VMのアベイラビリティが普段より低い。
例えば、普通のn1-standard-1のインスタンスは東京リージョンですと$0.0610ですが、 Preemptibleですと$0.01325で、1/4以下の値段。
Preemptible Instanceの欠点はいくつかある。その一つはVMがいつでも停止される可能性があることです。GCEのシステム状況によって ACPI G2 Soft OffメッセージをVMに送ってきます。そのあと、VMに動いているアプリケーションが安全に停止する時間があります。
もう一つの欠点は、Preemptible VMが最大24時間で停止される。そして、新しいインスタンスを作るには必要なリソースを確保できない 可能性は普通のインスタンスより低い。VMを作れないゔ可能性は低いけれど、たまに作れない時がある。
欠点がありますが、たくさんのユースケースをローコストで満たせます。Preemptible instanceを--preemptibleフラグで作れます:
gcloud compute instances create preemptible-instance --preemptible
GKE Cluster Autoscaler
GKEはクラスターノードを動的にスケールするcluster autoscaler機能があります。オートスケーラーはクラスターのノードプールを利用してソートスケーリングを有効にすることができます。
クラスターオートスケーラーはスケジュールされてなく、リソースの確保を待っているPodを監視し、スケールすれば、スケジュールできるようになったら、VMノードを追加して、クラスターをスケールアップします。
オートスケーラーを有効にするには--enable-autoscalingをクラスター作成時に指定します。最大と最低のPod数を指定できます。このコマンドはオートスケーラーを有効にしたノードプールが含まれるクラスターを作ります:
gcloud container clusters create autoscaled-cluster \
--enable-autoscaling \
--min-nodes=1 \
--max-nodes=5
オートスケーリングするノードプールをあとでも追加できます:
gcloud container node-pools create autoscaled-pool \
--cluster=autoscaled-cluster \
--enable-autoscaling \
--min-nodes=1 \
--max-nodes=5
Preemptibleノードプールのオートスケーリング
クラスターオートスケーラーとPreemptibleインスタンスを組み合わせることで、動的にスケールするクラスターをオーコストで実現できる。
メモ:Preemptibleノードプールは現在ベータなのでSLAやDeprecation policyがまだありません。
GKEベータAPIを使うために、以下のコマンドを実行する:
gcloud config set container/use_v1_api_client false
Preemptibleインスタンスを確保できない場合があるので、一般的なユースケースとして、普通のノードプールを固定したインスタンス数で作って、そして、別のPreemptibleノードプールでオートスケーリングをする。まずは普通のノードプールを作成:
gcloud container clusters create burstable-cluster --num-nodes 3
次ぐにオートスケーリングするPreemptibleノードプールを作成:
gcloud beta container node-pools create preemptible-pool \
--cluster burstable-cluster \
--preemptible \
--num-nodes 0 \
--enable-autoscaling \
--min-nodes 0 \
--max-nodes 5 \
--node-taints=pod=preemptible:PreferNoSchedule
このノードプールは必要なリソースに対して、スケールするけど、低コストのPreemptibleインスタンスを使ってくれます。Preemptibleリソースは取れない場合があるので、node taint を設定して、こういう変動するようなリソース状況を耐えるアプリケーションだけが実行を許可する。
どれで普通のノードプールとPreemptibleノードプール両方に動くようなDeploymentを作成できる:
cat <<EOF | kubectl apply -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
run: hello-web
name: hello-preempt
spec:
replicas: 10
selector:
matchLabels:
run: hello-web
template:
metadata:
labels:
run: hello-web
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
name: hello-web
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: "200m"
tolerations:
- key: pod
operator: Equal
value: preemptible
effect: PreferNoSchedule
EOF
クラスターは最初にリソースが足りないので、Pending
ステータスのPodをいくつか見れるはず。そのあとにノードが追加されることにつれて、Running
ステータスに変わる。
kubectl get pods -o wide
まとめ
上のコマンドを実行して、試してみた場合はいかのコマンドでリソースを削除できます。
gcloud compute instances delete preemptible-instance
gcloud container clusters delete autoscaled-cluster
gcloud container clusters delete burstable-cluster
GKEの高度な機能を組み合わせることで、低コストとアプリケーションアベイラビリティのバランスをとった構成が作れます。ベータ機能なのでクラスターを作れば、誰でもオートスケーラーとPreemtibleノードプールが利用できます。
もっとKubernetes知りたい方は、以下のアイテムをどうぞ:
- GKEの how-to guides を読む。
- Google Cloud Platform Slack (#kubernetes-engine チャンネルに参加してください。)
- GCPUG Slackに参加する (#gke_jaチャンネルに参加してください)
- Kubernetes Slackに参加すfる (#gkeチャンネルに注目)
ではまた!