GKEでpreemptibleなマシンを使ってhello worldする

公開日:2019 M04 6最終更新日: 2019 M11 16

2019年4月14日追記: LoadBalancer について追記しました

GCP でプロジェクト作成、ローカルに gcloud skd 環境を構築したところからスタート。無料クレジット終了後、通常のアカウント状態で行なっています。低コストで運用する知見をすでに公開してくれている人がいるので真似します。

参考にしたサイト:

安価な GKE(k8s)クラスタを作って趣味開発に活用する

GKE document

プロジェクト設定とリージョンの設定

すでに GCP を使用して別のプロジェクトがある場合はローカルでプロジェクト設定を確認、今回使用するものに変更します。

gcloud config set project プロジェクト名

AlwaysFree

Compute Engine と Cloud Storage には無料枠がありますが適用されるのは特定のリージョンのみです。使い忘れないようにリージョンを設定しておきます。遊び用途でないならリージョンは日本の方が良いと思います。

gcloud config set compute/zone us-east1

machine-types

使用可能なマシンタイプの確認は以下のコマンドで可能。一番安いのは f1-micro でした、必要なコア数やメモリ数があるならそれに合わせます。

gcloud compute machine-types list

コストの試算

念のために日本と us-east1 でコスト比較。f1-micro だと kubernetes には compute engine が 3 台必要らしいので 3 台分で計算。

計算ツール

1 ヶ月: USD 7.67 (us-east1)

1 ヶ月: USD 10.95 (asia-northeast1, asia-northeast2)

東京、大阪のリージョンだと us-east1 と比較して 370 円くらい高いです。370 円くらいならと考えるか、同じ値段で米国なら 4 台使えると考えるか・・・です。ひとまずテスト作成なので今回は us-east1 で作成、問題があればリージョン変更を考えます。

VM マシン9台以上立ち上げるには割り当ての変更が必要

この後の手順で行うクラスタ作成時にこんなエラーが出ました。

Insufficient regional quota to satisfy request: resource "IN_USE_ADDRESSES": request requires '9.0' and is short '1.0'. project has a quota of '8.0' with '8.0' available.

最初意味がわからなかったのですが、現在の設定では compute_engine を一気に 9 台は立ち上げられないというエラーでした。3 台しか立ち上げる予定がないのに 9 台立ち上げのエラーが出ています。この時点でコマンド間違っているのに気付け!という話なのですが・・・気づけませんでした。

一応、対応策は下記です。

GCP 管理画面 -> I AM と管理 -> 割り当て 以下で絞り込み

サービス:Compute EngineAPI 指標:In-use IP addresses

対象のロケーションを選択してクォータの上限引き上げをサポートに送信(8 -> 9 に引き上げ要求)。GCP サポートの返事は驚くほど早く、すぐに 9 台立ち上げ可能になりました。ちなみに返答はメールでした。

Kubernetes Engine にアクセス

GCP 管理画面から KubernetesEngine にアクセスすると API の作成が自動で始まりました。この手順必要ないかもしれませんが一応記載。

cluster の作成

ローカルの terminal から作成します。管理画面からポチポチしないのは、他の人がコマンドでしているからそれに倣うくらいの気持ちです。preemptible を普通に選べるのかも謎でしたので。

disk-sizeは最低 10GB でデフォルトは 100GB。num-nodes の default は 3 ですが、3 を指定すると NUM NODES が 9 でクラスタが作成されて VM マシンも 9 台起動になりました。上記の 9 台以上の割り当て設定が必要になったのはここのせいです。num-nodes=1 を指定すると最終的に NUM_NODES 3 でクラスタが作成されて VM マシンも f1-micro が3台となっていました。

作成コマンド

gcloud beta container clusters create k8s-cluster --preemptible --machine-type=f1-micro --num-nodes=1 --disk-size=10

WARNING4 つほど出ましたが気にせずに続けます。num_nodes の設定が他の記事と違うのは gcloud beta を指定したから?1 指定ですが 3 台起動します。terminal でクラスタ作成したあと、VM マシンの確認は管理画面でも一応しておいた方が良いです。ちなみに 9 台立ち上げたり落としたりにかかった費用はすぐ落としたのもあって 6 円以下でした。

cluster の削除はお気軽に

GCP 管理画面から kubernetes で検索して GKE Engine にアクセス。上記手順で作成した、例えば k8s-cluster という名前のものが Kubernetes Engine にできています。これを削除すれば立ち上がった VM マシンも全て削除されます。マシン数の変更も可能です。まだ初期状態で特に設定もないので、失敗した!と思ったらとりあえず削除しておけば安全です。

先ほどの 8 台設定上限のように、無茶苦茶な失敗(壮大な数の VM マシンが立ち上がるような)はしないように GCP 側でブレーキかけてくれているみたいです。それでも従量課金なので念には念を入れた方が良く、良いマシンが走ればその分持って行かれます。予算アラートはこの辺りで入れておきましょう。

kubectl をインストール

ローカルの terminal で kubectl を有効にし、GCP の kubernetes に deploy できるようにします

gcloud components install kubectl

deployment.yaml の作成と登録

Hello World するだけの docker image を作成しました。いつもの kubernets コマンドを打ち、登録します。そのあと、get pods で作成を確認。

kubectl create -f deployment.yaml
kubectl get pods

使用できる docker image が手元にないが、すぐに hello world したい人は下記の delopyment.yaml をどうぞ。探せば GCP のサンプルもあると思います。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: helloworld
  template:
    metadata:
      labels:
        app: helloworld
        env: stage
    spec:
      containers:
        - image: hidekazoo/hello:latest
          name: helloworld
          ports:
            - containerPort: 80

使用しているイメージの容量は 6.6MB 程度。hello world と書いた index.html を golang の net/http で配信している image です。docker hub で public にしているので誰でも使えると思います。

LoadBalancer と NodePort

deploy した pod へ外部(ブラウザでみるなど)からアクセスするには Service が必要になります。Service の type に LoadBalancer か NodePort を指定。LoadBalancer を指定すると、複数 pod に負荷分散してアクセスを流してくれます。GKE では何も考えずに Service に LoadBalancer!と書いたら使えるのですが、これは上記で作成したマシンとは別料金がかかります。

なので、最安値を目指して構築するなら NodePort にしないとダメです(ちなみに VM マシン 3 台より 1 日の使用料高かったです)。また、LoadBalancer と関係ないかもしれませんが、上記の構成で type LoadBalancer で運用したらマシンスペック足りなくて途中で死んでました・・・。この辺りは後日また調べます。

Service を使用したアプリケーションの公開

service.yaml の登録(NodePort 編)

※Nodeport 用です。LoadBalancer 使う場合は飛ばしてください。

pod を作成すると GCP 管理画面の Kubernetes Engine -> ワークロードに表示されます。status ok なら次に Service を作成。status が失敗している時は、ローカルの kubernetes 環境でうまくいくかチェックをお勧めします。

上記で紹介した deployment.yaml を使用している場合は下記の service.yaml で動きます

apiVersion: v1
kind: Service
metadata:
  name: webserver

spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
      nodePort: 80
  selector:
    app: helloworld
kubectl create -f service.yaml
kubectl get svc

get svc コマンドで service の登録を確認します。紹介している service.yaml を使っているとwebserverという名前のものがあります。これの PORT(S)を確認すると、80:30092/TCP のようになっているはずで、30092 という数値を NODE_PORT の数値に使います。

公式の手順に従い、firewall の設定を変更してアクセスできるようにします。

gcloud compute firewall-rules create test-node-port --allow tcp:[NODE_PORT]

test-node-port は自由に変更、tcp:の部分は get svc で確認した値を入れます。今回だと tcp:30092 になります。作成に成功したらアクセスできます。

kubectl get nodes --output wide

cluster 作成時に指定した台数のマシンが並んでいるはずです。どれでも良いので EXTERNAL-IP をコピーします、全部数値です。その後ろに NODE_PORT 番号を:で繋ぐと deployment.yaml で登録した pod にアクセスできます

http:[EXTERNAL-IP]:[NODE_PORT]

上記をブラウザの URL に貼り付けるとアクセスできます。NodePort だと EXTERNAL-IP で 1 つの Pod にアクセスとなります。LoadBalancer だと、複数台のマシンに自動でアクセスを振り分けてくれます。

service.yaml の登録(LoadBalancer 編)

※NodePort だけの運用では必要ありません。LoadBalancer は別料金がかかりますので予算チェックしてから行ってください。以下は NodePort 手順を行なっていない前提です。

pod を作成すると GCP 管理画面の Kubernetes Engine -> ワークロードに表示されます。status ok なら次に Service を作成。status が失敗している時は、ローカルの kubernetes 環境でうまくいくかチェックをお勧めします。

kubectl create -f service.yaml
kubectl get svc

get svc コマンドで EXTERNAL-IP(全部数値)を確認。この IP にアクセスすると Hello World が表示されます。上記で紹介した deployment.yaml を使用している場合は下記の service.yaml で動きます

spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    app: helloworld

無事に EXTERNAL-IP で hello world が見れたら成功です。

感想

先人の記事があるとはいえ恐ろしく簡単に Kubernetes 環境の作成ができました。Azure と同じくらい簡単、サーバーレスはこの簡易さがスタンダードなんでしょうね。Azure と大きく違うのは、preemptibleo という色々制限はあるものの格安で使用できる VM マシンがあること。1 ヶ月使ってみてコストが想定通りかを確かめるのと、CI/CD の導入が次の目標です。

感想 2

元々は LoadBalancer で Service 使用していましたが今の段階で LoadBalancer 使うのは勿体無さすぎるのでやめました。

GCPのコスト画像、LoadBalancerがVMマシンよりも高い

こんな感じで LoadBalancer にかなりコスト取られていました。オレンジの方が LoadBalancer です。削除して NodePort に変更してからはコストは青のみで VM マシンだけ、1 日 27 円くらいとなっています。

立てただけで満足していまだに Hello World 状態。何かのせるアイデアを早く考えないと。今はどれくらい安定しているのかのチェック段階なので止めずに動かしていますが、後々は使わないときは cluster ごと削除してしまうのが良さそうですね。

db だけ他で動かせば API やアプリケーション部分は使うときだけ動いていれば良いので。

他の選択肢、調べたこと

今回、趣味用の Kubernetes 環境を作るに当たって VPS も候補に入れました。ただ、kubernetes 自体が結構リソースを使うようで、2GB くらいのメモリのマシンなると VPS でも値段は上がりがち。米国リージョンかつ機能制限つきとはいえ、月 1000 円を割りそうな GKE と互角に戦えるところを見つけるのは難しかったです

月 10 ドルで海外 VPS で Kubernetes を試してみる(kubernetes v1.9 版)

「Kubernetes」について - sakura internet

sakura internet の VPS には心惹かれてお試ししました。国内サービスでメモリ 2GB + SSD 50GB で月 1700 円くらい。スタートアップスクリプトに kubernetes があったので、導入する時間も短縮できて使用制限気にしなくて良いなら凄い!!・・・と思って使ってみたら、スタートアップスクリプトで kubernetes するには、VPS 契約 2 台必要でした(2GBx2 で月 3400 円くらい)。まあ Azure のスタンダードなマシンで 1 ヶ月 5000 円くらいだったので普通のマシンで動かすにはまだ安いか?というところ。

サーバーレスと違いアップデートや各種ツールも自身で用意する必要があるので、VPS でコストパフォーマンスの高い kubernetes 環境を作るには現状難しく感じました。そこを勉強するのも楽しそうではあるのですが、他に勉強したいこともたくさんあるので、今の自分の最善は GKE を使って低コストで kubernetes を運用し、アプリを展開する方を学んでいくという結論です。


hidekazoo
作者: hidekazooTwitter
JavaScriptやPHPなどプログラム関係やDockerといった開発環境など、ITエンジニアとして興味あることを紹介しているサイトです