GKEのRegional Clusters(Beta)を試してみた
この記事はGoogle Cloud Platform Advent Calendar 2017 20日目の記事です。
先日、GKEにRegional Clustersと呼ばれる機能がBetaで発表されていたようです。
この記事では、Regional Clustersを実際に立ててみて、既存のクラスタとどのような違いがあるのかを試してみようと思います。
※Beta版の機能のため内容に変更が入る可能性があります。この記事は12月16~19日に書いたので、その時点での情報になります。
TL;DR
- マスタノードをリージョン内のゾーンに分散させて可用性を向上させる仕組みです。
- クラスタのアップグレード中とかでもkubectlが操作できるのは嬉しい!
- クラスタに対する操作は通常のクラスタと比べて時間がかかるようです。
Regional Clusterとは
Regional Clustersは(1リージョン内の)各ゾーンにマスタノードを分散させることで可用性を高める仕組みのことです(すぐ上の方に書きましたが)。
具体的には、ゾーン障害やマスタのアップグレード等によるマスタのダウンタイムをゼロもしくは最小限に抑えることができるようです。
現行GKEでは、マスタノードは選択したゾーンに1つだけ動作させることができます。そのため、マスタノードが動作しているゾーンで障害が発生してしまった場合はマスタがダウンしてしまいます。
一方、Regional Clustersは1リージョン内の3ゾーンにマスタを分散させた状態で動作します。各マスタはLoad Balancer経由でのアクセスとなり、仮にゾーン障害等でどこかのマスタがダウンしてしまっても、別のマスタが応答するので問題ない、というところでしょうか。
引用元: Multi-Zone and Regional Clusters
構築
早速ですが比較のために、通常のGKEクラスタとRegional Clustersを構築します。
設定が異なるのは下記のみです。
現行GKEクラスタ | Regional Clusters | |
---|---|---|
ロケーション | ゾーン(asia-northeast1-b) | リージョン(asia-northeast1) |
ほかは極力同じような設定にしています。
Regional Clustersの構築
先にRegional Clustersを構築します。
通常のクラスタでは、構築するロケーションを --zone "asia-northeast1-b"
のように設定しますが、
Regional Clustersではゾーンではなくリージョンを設定するという点で違いがあり、--region "asia-northeast1"
のようなオプションで指定します。
構築するロケーション(ゾーンかリージョンか)によって、現行GKEクラスタとなるかRegional Clustersになるか違いが出てくるようです。
Cloud Consoleの場合はKubernetesのクラスタ作成時のこの部分の選択肢が先日から増えていて、「リージョン」を選択するとRegional Clustersになります。
※ここから出てくるコマンドは、Cloud Shellで実行しています。また、Regional ClustersはまだBeta版なのでgcloud beta
を用いる必要があります。
$ gcloud beta container clusters create "regional-cluster" \ --region "asia-northeast1" \ --cluster-version "1.7.11-gke.0" \ --machine-type "n1-standard-1" \ --image-type "COS" \ --num-nodes "1"
Regional Clustersでは、デフォルトでマルチゾーンクラスタのように各ゾーンに num-nodes
で指定した数だけノードが立ちます。
上記のコマンドを実行した場合、asia-northeast1-a、b、cにノードが1台ずつ(計3台)立ちます。
asia-northeast1の場合はゾーンが3つあるのですべてのゾーンに分散しますが、ゾーンが4つ存在するus-central1は、4ゾーンではなくGKEが選択した3ゾーンで分散するようです。
※Regional Clustersを構築するときに、このような警告が出て進めなくなることがあります。
Warning: you invoked `gcloud beta`, but with current configuration Kubernetes Engine v1 API will be used instead of v1beta1 API. If you intended to use v1beta1 API instead, please set container/use_v1_api_client property to false. Do you want to continue (Y/n)? ERROR: (gcloud.beta.container.clusters.create) ResponseError: code=400, message='asia-northeast1' is not a valid zone.
メッセージに記載されているとおり、container/use_v1_api_client
プロパティにfalseセットすると実行できるようになります。
Beta版APIを利用するときに必要な設定のようですね。
$ gcloud config set container/use_v1_api_client false Updated property [container/use_v1_api_client]. $ gcloud beta container ...
現行GKEクラスタの構築
同じように、現行GKEの通常のクラスタを構築してみましょう。
現行GKEクラスタの構築で利用したコマンド列です。
$ gcloud beta container clusters create "single-master-cluster" \ --zone "asia-northeast1-b" \ --cluster-version "1.7.11-gke.0" \ --machine-type "n1-standard-1" \ --image-type "COS" \ --num-nodes "1" \ --node-locations "asia-northeast1-b","asia-northeast1-a","asia-northeast1-c"
今回はマスタに対する検証なのでノードはあまり関係無いと思うのですが、なんとなく同じ台数のノードがないといけない気がしたので、--node-locations
を追加してマルチゾーンクラスタとして構築しています。
現行のGKEはマルチゾーンクラスタに設定したとしても、増えるのはワーカーノードだけで、asia-northeast1-bに1台のみマスタノードが構築されます。
これで、2つのクラスタを準備できました。
$ gcloud container clusters list NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS regional-cluster asia-northeast1 1.7.11-gke.0 xxxxxxxxxxxxx n1-standard-1 1.7.11-gke.0 3 RUNNING single-master-cluster asia-northeast1-b 1.7.11-gke.0 xxxxxxxxxxxxx n1-standard-1 1.7.11-gke.0 3 RUNNING
検証
クラスタが構築できたので、検証していきましょう。
※Regional Clustersがゾーン障害に強くなったとは言えゾーン障害を起こして検証することは Google側でタイミングよく何か大きく事故ってもらわないと 非常に難しいので、今回は構築した2つのクラスタに対して、
- デフォルトノードプールのオートスケールOFF -> ON
- マスタを1.7.11-gke.0 -> 1.8.4-gke.0へアップグレード
の操作を行っている最中に、GKE上で動いているサービス(Wordpress)がちゃんとレスポンスを返してくれるかと、
別セッションから接続したBashでkubectlが操作できるかどうかについて調べていきます。
準備
検証用のWordpress構築
今回はサクッと構築したいのでHelmを利用してWordpressを立てます。
資格情報の取得
$ gcloud container clusters get-credentials \ > single-master-cluster \ > --zone asia-northeast1-a \ > --project nfact-sandbox-2 Fetching cluster endpoint and auth data. kubeconfig entry generated for single-master-cluster.
Helmの初期化
$ helm init $HELM_HOME has been configured at /home/nokok_kz/.helm. Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster. Happy Helming!
これで構築したクラスタでHelmが使えるようになりました。
Wordpressのインストール
$ helm install stable/wordpress NAME: whimsical-dolphin LAST DEPLOYED: Sat Dec 16 15:23:40 2017 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/PersistentVolumeClaim NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE whimsical-dolphin-mariadb Pending standard 1s whimsical-dolphin-wordpress Pending standard 1s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE whimsical-dolphin-mariadb ClusterIP 10.23.249.67 <none> 3306/TCP 1s whimsical-dolphin-wordpress LoadBalancer 10.23.242.54 <pending> 80:32213/TCP,443:30728/TCP 1s ==> v1beta1/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE whimsical-dolphin-mariadb 1 1 1 0 1s whimsical-dolphin-wordpress 1 1 1 0 1s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE whimsical-dolphin-mariadb-1518259378-2sv6c 0/1 Pending 0 1s whimsical-dolphin-wordpress-3568978032-p7zs4 0/1 Pending 0 1s ==> v1/Secret NAME TYPE DATA AGE whimsical-dolphin-mariadb Opaque 2 1s whimsical-dolphin-wordpress Opaque 2 1s ==> v1/ConfigMap NAME DATA AGE whimsical-dolphin-mariadb 1 1s whimsical-dolphin-mariadb-tests 1 1s NOTES: 1. Get the WordPress URL: NOTE: It may take a few minutes for the LoadBalancer IP to be available. Watch the status with: 'kubectl get svc --namespace default -w whimsical-dolphin-wordpress' export SERVICE_IP=$(kubectl get svc --namespace default whimsical-dolphin-wordpress -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo http://$SERVICE_IP/admin 2. Login with the following credentials to see your blog echo Username: user echo Password: $(kubectl get secret --namespace default whimsical-dolphin-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)
しばらく待つと、Wordpressが立ち上がります。
すべてのPodがRunningとなるのを待ってから、
echo $(kubectl get svc --namespace default whimsical-dolphin-wordpress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
とすると立ち上がっているWordpressのIPアドレスが表示されます。
アクセスしてみると、
無事立ち上がっていることがわかりましたので、この状態で検証をしてみます。(regional-clustersの方も同様に設定してWordpressを立ち上げます)
簡易監視プログラムの作成
現行GKEクラスタとRegional Clusterで立ってるWordpressに対して、curlでアクセスし続ける簡易的なShell Scriptを準備しました。
現行GKEクラスタ用
$ cat connect_single.sh #!/bin/bash echo -n `(date "+%Y-%m-%d %H:%M:%S")`" : " >> SINGLE_HISTORY curl --connect-timeout 0.5 -s http://xxx.xxx.xxx.xxx/ -o /dev/null ; echo $? >> SINGLE_HISTORY &
Regional Clusters用
$ cat connect_regional.sh #!/bin/bash echo -n `(date "+%Y-%m-%d %H:%M:%S")`" : " >> REGIONAL_HISTORY curl --connect-timeout 0.5 -s http://xxx.xxx.xxx.xxx/ -o /dev/null ; echo $? >> REGIONAL_HISTORY &
リクエストを投げるIPアドレスと結果の出力先のみ異なります。(1ファイルでも良かったですが面倒だったのでコピペ)
このShell Scriptを実行すると、正常にアクセスが成功した場合は0、失敗したときはそれ以外の数字が表示されます。
2017-12-16 07:09:35 : 0 2017-12-16 07:09:36 : 0 2017-12-16 07:09:37 : 0 2017-12-16 07:09:38 : 7 2017-12-16 07:09:39 : 7 2017-12-16 07:09:40 : 28
簡単ではありますが、各操作中に0以外の数値が表示された場合は、ダウンタイムがあったとみなします。上の例の場合、7は接続失敗、28がタイムアウトです。
kubectlの検証についてはShellを別で起動させたうえでkubectl get pods
等を走らせたときにI/Oタイムアウトや接続の拒否が発生した場合、ダウンタイムがあったとみなします。
検証
1. デフォルトノードプールのオートスケールOFF -> ON
現行GKEクラスタ
$ gcloud container clusters \ > update single-master-cluster \ > --enable-autoscaling \ > --min-nodes=1 \ > --max-nodes=1 \ > --zone "asia-northeast1-b" \ > --node-pool default-pool
Regional Clusers
$ gcloud beta container clusters \ > update regional-cluster \ > --enable-autoscaling \ > --min-nodes=1 \ > --max-nodes=1 \ > --region "asia-northeast1" \ > --node-pool default-pool
minとmaxが両方とも1で、既に3ノード分生やしているので、この設定によりノードが増えたり減ったりすることはありません。
結果
現行GKEクラスタ
マスタへのアクセス
$ kubectl get pods Unable to connect to the server: dial tcp xxx.xxx.xxx.xxx:443: i/o timeout
gcloudコマンドを実行した直後からタイムアウトしてしまい、アクセスできませんでした。
サービスの稼働
ダウンタイムが発生せず、問題ありませんでした。(すべて0を返しました)
Regional Clusters
マスタへのアクセス
$ kubectl get pods NAME READY STATUS RESTARTS AGE ringed-hedgehog-mariadb-3682299131-5ql58 1/1 Running 0 22m ringed-hedgehog-wordpress-3049966572-8zx7z 1/1 Running 0 22m
問題なくアクセスできます!すごいですね。
サービスの稼働
こちらもダウンタイムが発生せず、問題ありませんでした。
2. マスタを 1.7.11-gke.0 -> 1.8.4-gke.0へアップグレード
どちらもCloud Console上の「アップグレード可能」というところからクリックしてアップグレードを実施しました。
結果
現行GKEクラスタ
マスタへのアクセス
$ kubectl get pods The connection to the server xx.xxx.xxx.xxx was refused - did you specify the right host or port?
先程とエラーは異なりますが、アクセスできなくなりました。
サービスの稼働
ダウンタイムが発生せず、問題ありませんでした。
Regional Clusters
マスタへのアクセス
$ kubectl get pods NAME READY STATUS RESTARTS AGE ringed-hedgehog-mariadb-3682299131-5ql58 1/1 Running 0 38m ringed-hedgehog-wordpress-3049966572-8zx7z 1/1 Running 0 38m
マスタのアップグレート中も問題ないですね!
サービスの稼働
しつこいようですが、問題ありませんでした。
3. 操作中の書き込み系操作
Regional Clustersでは、クラスタに対して何らかの操作をしている最中でも別のセッションからであれば kubectl
によって操作ができることがわかりました。
ここまでは読み取り系の操作しかしていなかったですが、書き込み系の操作をしてみましょう。
先程のRegional Clustersと同じクラスタを作成し、マスタのアップグレード中にWordpressを追加でいくつか立ててみたいと思います。
$ gcloud beta container clusters create "regional-cluster" \ --region "asia-northeast1" \ --cluster-version "1.7.11-gke.0" \ --machine-type "n1-standard-1" \ --image-type "COS" \ --num-nodes "1"
Cloud Console上で「アップグレード可能」をクリックしてから、アップグレード操作に入ったあとにWordpressを追加でインストールします。
$ helm install stable/wordpress NAME: whimsical-dolphin ...
ちょっとワンテンポ待ちましたが、問題なく操作出来ますね!
Cloud Consoleで見るとまだインジケータが回ったままでまさに「アップグレード中」の状態でしたが、それでもWordpressを追加で立ち上げることができました!
4. 操作時間
ここまでやってて気づいたのですが、Regional Clustersでは設定を反映させるために結構時間がかかってるように感じました。
試しにtimeコマンドにより時間を計測してみたところ、このような結果になりました。
現行GKEクラスタ | Regional Clusters | |
---|---|---|
クラスタの構築 | 約4分 | 約4分 |
オートスケーリング OFF -> ON | 約2分30秒 | 約10分 |
マスタのアップグレード | 約1分30秒 | 約10分 |
複数回試してみましたが、おおよそこのぐらいの時間で設定が反映できるようです。
クラスタの構築はほぼ変わらないのですが、それ以外の操作については体感で「待つなぁ~」と感じるぐらい時間がかかってしまいます。。。
Beta版だからということもありそうですが、そもそもマスタが物理的に3台あって切り替えながら作業をしていることを考えるとこの時間も納得です。むしろ早いほうかも?
まとめ
(あれ、GKEって元々サービス側に影響なしでマスタのアップグレードできたっけ?となってしまいサービス側の検証の不必要感が半端ないのと、そもそもから何かを間違えてるのでは?と途端に不安になっていますが、)
とりあえずマスタが落ちることなくマスタのアップグレード等ができることが分かりました。
今まではマスタのアップグレード中はkubectlからもCloud Console上からもPodの様子などを見ることはできなかったのですが、
今回試したRegional Clustersではアップグレード中でもマスタが応答してくれ、割りと色々なことができるようで安心感があります。
他には、1つのクラスタに対して複数人で作業しているような状況でも便利そうですね!積極的に使っていきたいと思います。
現在はBeta版なので無料で利用できますが、Betaだけあって随時調整が入っているようです。
リージョンで利用できるGKEのバージョンがコロコロ変わったり、同じコマンド列でコピペなのにAPIサーバーに400エラーを返されたりということがあったので、
試す上では注意が必要かもしれませんね。エラーで返されても何回か実行すると通ったり通らなかったりします。広い心で臨んでみましょう。
GAとなるのが待ち遠しいです!
以上「Regional Clusters(Beta)を試してみた」、でした!
GKEのマスタとノードで利用可能なバージョン一覧を取得する
--cluster-version
とかに渡せるバージョンを一覧で出すコマンドです。
gloud container get-server-config --zone {ZONE}
$ gcloud container get-server-config --zone asia-northeast1-b Fetching server config for asia-northeast1-b defaultClusterVersion: 1.7.8-gke.0 defaultImageType: COS validImageTypes: - COS - UBUNTU validMasterVersions: - 1.8.4-gke.0 - 1.8.3-gke.0 - 1.8.2-gke.0 - 1.8.1-gke.1 - 1.7.11-gke.0 - 1.7.10-gke.0 - 1.7.9-gke.0 - 1.7.8-gke.0 - 1.6.13-gke.0 - 1.6.11-gke.0 validNodeVersions: - 1.8.4-gke.0 - 1.8.3-gke.0 - 1.8.2-gke.0 - 1.8.1-gke.1 - 1.7.11-gke.0 - 1.7.10-gke.0 - 1.7.9-gke.0 - 1.7.8-gke.0 - 1.7.8 - 1.7.6 - 1.7.5 - 1.6.13-gke.0 - 1.6.11-gke.0 - 1.6.11 - 1.6.10 - 1.6.9 - 1.5.7
このように出てきます。
ERROR: (gcloud.beta.container.clusters.create) ResponseError: code=400, message=Version "1.7.11-gke.0" is invalid
のようなエラーになったときに利用します。
gcloud source repos cloneが失敗するのを回避する
GCPのGoogle Source Repositoriesからgitリポジトリをcloneできなくなったときの回避法です。
通常、下記のコマンドを用いることで、GCP上でホストされているプライベートリポジトリをGCPの認証情報を利用してcloneすることが出来ます。
gcloud source repos clone REPO_NAME --project=PROJECT_NAME
原因は分かっていませんが、cloneが行われるときに認証用のダイアログが表示されることがあります。
プライベートリポジトリなので入力しなければ、と考えてうっかりこのダイアログでIDとパスワードを入力してしまうと、そのIDが合っているかどうかにかかわらず、
gcloud init
をし直す等をしてもcloneができなくなってしまいます。
>gcloud source repos clone app app WARNING: If your system's credential.helper requests a password, choose cancel. Cloning into '(略)'... fatal: remote error: Invalid authentication credentials. Please generate a new identifier: https://source.developers.google.com/auth/start?scopes=https://www.googleapis.com/auth/cloud-platform ERROR: (gcloud.source.repos.clone) Command '['git', 'clone', '(略)', '(略)', '--config', 'credential.helper=!gcloud.cmd auth git-helper --account=アカウント名 --ignore-unknown $@']' returned non-zero exit status 128
最初に WARNING: If your system's credential.helper requests a password, choose cancel.
と警告が出ていますね。
このエラーをスルーして入力してしまうと、cloneできない問題が発生します。
一度失敗するとエラーで表示されている通り再認証を行っても、 gloud init
を行っても、cloneがずっと失敗する状況になってしまうのがこの問題の厄介な点です。
この問題の解決方法
Gitに登録されている credential.helper
の設定を削除し、再設定します。
※Windowsであれば管理者権限で実行します。
git config --system --unset "credential.helper" git config credential.helper gcloud.cmd
これでcloneができるようになりました。
なぜ?
この設定は、Source Repositoriesをリモートとして追加するときに実行する git config credential.helper gcloud.cmd
によって書き込まれる設定で、
先程表示されたダイアログにID、パスワードを入力してしまうとここの設定がおかしくなってしまうようです。(gcloud.cmdとなっているべきところが、managerなど別のものになってしまう)
なので、この設定を再設定することで、cloneすることができるようになります。