kun432's blog

Alexaなどスマートスピーカーの話題中心に、Voiceflowの日本語情報を発信してます。たまにAWSやkubernetesなど。

〜スマートスピーカーやVoiceflowの記事は右メニューのカテゴリからどうぞ。〜

いまさらながらGKEを試す

f:id:kun432:20210920165841p:plain

Kubernetesについては、AWSではEKS、オンプレではkubeadmを使ってきましたが、そういえばGKEは一度も使ったことがない。ということで、少し触ってみました。

目次

クラスタの作成

GCPのコンソールから、"Kubernetes Engine" -> "クラスタ"をクリック。

f:id:kun432:20210920170144j:plain

初回の場合はAPIを有効化します。

f:id:kun432:20210920170243j:plain

"作成"をクリック。

f:id:kun432:20210920170554j:plain

クラスタの作成には2種類の方法があります。"GKE Autopilot"は、worker nodeをGCP側で管理してくれて勝手にスケーリングなどが行われるというようなものみたい。EKS Fargetみたいな感じですかね(Fargate触ったことないし、知らんけど)。とりあえず"GKE Standard"を選択します。

f:id:kun432:20210920170644j:plain

ここから作成するクラスタの設定を行っていきます。今回はあまり細かい設定は行わずにほぼデフォルトでクラスタ作って試してみるつもりなのですが、どのような設定項目があるのかは順に見ていきたいと思います。

クラスタの基本

まず、基本設定となる”クラスタの基本”。

f:id:kun432:20210920172308p:plain

”クラスタの基本”では、

  • クラスタ名
  • ロケーション(ゾーン、リージョン)
  • コントロールプレーンのバージョン

が指定できます。コントロールプレーンは、バージョン指定か、Googleのリリースチャンネルで指定できるみたい。

各リリースチャンネルごとのリリーススケジュールやサポートポリシーはこちら。

あと、右にあるクラスタセットアップガイドを使うと、それぞれの用途のおすすめの設定でクラスタ設定がカスタマイズされるみたい。今回は使わないけど。

f:id:kun432:20210920174922j:plain

f:id:kun432:20210920174932p:plain

ノードプール

次にノードプール。左のメニューから"default-pool"をクリックします。

f:id:kun432:20210920175108j:plain

f:id:kun432:20210920175240p:plain

ノードプールは、EKSでいうノードグループと同じもの。デフォルトで、クラスタに必ず1つ作成されます。"default-pool"はデフォルトの名前ってことですね。ここでは、

  • ワーカーノードのノード数
  • 自動スケーリング
  • 自動アップグレード・修復

などが設定できる。"自動アップグレード"、"自動修復"はグレーアウトしてるけど、コントロールプレーンのバージョン指定で"リリースチャンネル"を指定している場合は必須で、"静的バージョン"を指定している場合にOFFにもできるみたい。まあ"静的バージョン"を選択するぐらいなので、自動でアップグレードされたら困るということですね。"自動修復"は基本的にOFFにすることはないだろうけど。

ノード

ノードプールはさらにサブメニューがあります。まず"ノード"。

f:id:kun432:20210920180620j:plain

ここはワーカーノードとなるGoogle Compute Engineのインスタンスの指定ですね。

  • インスタンスイメージの種類
  • インスタンスのマシンタイプ(CPU/メモリ)
  • ディスクサイズ
  • プリエンプティブルノードの有効・無効
  • 1ノードあたりのPod数

あたりが設定できる。Kubernetesとして特に重要そうと思ったのは、"イメージの種類"、"1ノードあたりのPod数"あたりかな。

f:id:kun432:20210920181831p:plain

"イメージの種類"では、

  • cos
    • コンテナランタイムとしてDockerを使う、コンテナ最適化OS
  • cos_containerd
    • コンテナランタイムとして containerd を使う、コンテナ最適化OS。デフォルト。
  • ubuntu
    • コンテナランタイムとして Docker を使う。OSはUbuntu
  • ubuntu_containerd
    • コンテナランタイムとして containerd を使う。OSはUbuntu

あたりが選べるようです。書いてないけどWindowsコンテナも使えるみたい。

"1PodあたりのPod数"は"110"が最大みたいで、これ以上増やすことはできなかった。

f:id:kun432:20210920182917p:plain

オーバーライドできるとあるけど、多分減らすほうにってことかな。EKSだとEC2インスタンスタイプでこのあたりは決まるので、より大きいインスタンスタイプを選択すれば増やすことができるんだけど、マシンタイプ変えても変わらなかった。小さいマシンタイプでたくさんのPodを上げてもしょうがない気もするけど、小さなPodがたくさん必要になるようなケースで大きいマシンタイプを選ばざるを得なくてリソース無駄、ということを考えるとどっちもどっちかなという気がする。

セキュリティ

f:id:kun432:20210920183905p:plain

"セキュリティ"では、サービスアカウントの設定とノードの保護を行えるみたい。ただし、ここで言うサービスアカウントはKubernetesのサービスアカウントじゃなくて、GCPのサービスアカウントっぽい。なのでEKSだとノードとなるインスタンスに割り当てるIAMロールに近いと思う。IAM Roles for Service Accounts みたいなものはたぶんWorkload Identityというやつかな?

メタデータ

f:id:kun432:20210920183914p:plain

"メタデータ"は、その名の通り、メタデータの設定です。ラベルやtaintなどのメタデータを設定できます。

クラスタの詳細設定

ここからはクラスタのより詳細な設定です。この辺はサラッと。

自動化

f:id:kun432:20210920192920p:plain

"自動化"は、アップデートやメンテナンスやスケジュールウインドウを設定したりする感じですね。あとは、スケールアップ・スケールアウトあたり。

ネットワーキング

f:id:kun432:20210920192902p:plain

"ネットワーキング"は、VPC周りの設定など。Node Local DNSCacheの有効化とかもここで出来ちゃうみたい。

セキュリティ

f:id:kun432:20210920192850p:plain

Cloud KMSを使ったsecretの暗号化とか。Workload Identityもここで有効にできるみたいですね。

メタデータ

f:id:kun432:20210920192839p:plain

ここはGCPにおけるメタデータ、つまりAWSのタグと同じようなものだと思う。

特徴量

f:id:kun432:20210920192824p:plain

"特徴量"っていうこの名前、全然ピンとこないけど、主に他の機能と連携するような部分って感じがする。

  • Cloud Logging/Cloud Monitoringなどの有効有無
  • Copute Engine永続ディスクのCSIドライバの有効有無

あたりはデフォルトでオンになってるみたいですね。

クラスタを作成してみる

とりあえず、今回はお試しなので、"クラスタの基本”で、

  • クラスタ名を適当に。今回は"demo-cluster-01"にします。
  • ロケーション。東京リージョンのゾーンのうち一つを選択、今回は、"asia-northeast-1a"を選択。

だけを設定して一番下の「作成」をクリックします。

f:id:kun432:20210920194456j:plain

クラスタ作成中です。ちょっと時間がかかります。

f:id:kun432:20210920194632p:plain

できました。

f:id:kun432:20210920195402p:plain

クラスタへの操作

クラスタへの操作はCloud Shellを使います。

f:id:kun432:20210920212718j:plain

f:id:kun432:20210920195801j:plain

ためしにkubectlを叩いてみます。

$ which kubectl
/usr/bin/kubectl
$ kubectl get node
The connection to the server localhost:8080 was refused - did you specify the right host or port?

ということでCloud Shell側には何も設定されていませんね。クラスタにアクセスするための認証情報を取得します。

$ gcloud container clusters get-credentials demo-cluster-01 --zone asia-northeast1-a

実行すると以下のように承認が求められますので、承認します。

f:id:kun432:20210920212805j:plain

認証情報が取得されて、kubeconfigの設定が行われたようです。

Fetching cluster endpoint and auth data.
kubeconfig entry generated for demo-cluster-01.

ではkubectlを実行してみましょう。

$ kubectl config get-clusters
NAME
gke_sample-e2d18_asia-northeast1-a_demo-cluster-01

$ kubectl get node
NAME                                             STATUS   ROLES    AGE   VERSION
gke-demo-cluster-01-default-pool-aae0737e-cnfl   Ready    <none>   16m   v1.20.9-gke.701
gke-demo-cluster-01-default-pool-aae0737e-jgn2   Ready    <none>   16m   v1.20.9-gke.701
gke-demo-cluster-01-default-pool-aae0737e-qn5p   Ready    <none>   16m   v1.20.9-gke.701

$ kubectl get all --all-namespaces
NAMESPACE     NAME                                                            READY   STATUS    RESTARTS   AGE
kube-system   pod/event-exporter-gke-67986489c8-w2bv2                         2/2     Running   0          17m
kube-system   pod/fluentbit-gke-656xn                                         2/2     Running   0          17m
kube-system   pod/fluentbit-gke-8pvzp                                         2/2     Running   0          17m
kube-system   pod/fluentbit-gke-kxxhs                                         2/2     Running   0          17m
kube-system   pod/gke-metrics-agent-9fkqh                                     1/1     Running   0          17m
kube-system   pod/gke-metrics-agent-9pg8j                                     1/1     Running   0          17m
kube-system   pod/gke-metrics-agent-j5nb8                                     1/1     Running   0          17m
kube-system   pod/kube-dns-autoscaler-844c9d9448-7fl8m                        1/1     Running   0          17m
kube-system   pod/kube-dns-b4f5c58c7-9rkgx                                    4/4     Running   0          17m
kube-system   pod/kube-dns-b4f5c58c7-dk664                                    4/4     Running   0          17m
kube-system   pod/kube-proxy-gke-demo-cluster-01-default-pool-aae0737e-cnfl   1/1     Running   0          17m
kube-system   pod/kube-proxy-gke-demo-cluster-01-default-pool-aae0737e-jgn2   1/1     Running   0          16m
kube-system   pod/kube-proxy-gke-demo-cluster-01-default-pool-aae0737e-qn5p   1/1     Running   0          17m
kube-system   pod/l7-default-backend-56cb9644f6-9rwvr                         1/1     Running   0          17m
kube-system   pod/metrics-server-v0.3.6-9c5bbf784-ntxgs                       2/2     Running   0          16m
kube-system   pod/pdcsi-node-7rg44                                            2/2     Running   0          17m
kube-system   pod/pdcsi-node-8pb8b                                            2/2     Running   0          17m
kube-system   pod/pdcsi-node-qqwtr                                            2/2     Running   0          17m
kube-system   pod/stackdriver-metadata-agent-cluster-level-658b89df-7hzbb     2/2     Running   0          17m

NAMESPACE     NAME                           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)         AGE
default       service/kubernetes             ClusterIP   10.76.0.1      <none>        443/TCP         18m
kube-system   service/default-http-backend   NodePort    10.76.10.142   <none>        80:31187/TCP    17m
kube-system   service/kube-dns               ClusterIP   10.76.0.10     <none>        53/UDP,53/TCP   17m
kube-system   service/metrics-server         ClusterIP   10.76.10.52    <none>        443/TCP         17m

NAMESPACE     NAME                                       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR                                                        AGE
kube-system   daemonset.apps/fluentbit-gke               3         3         3       3            3           kubernetes.io/os=linux                                               17m
kube-system   daemonset.apps/gke-metrics-agent           3         3         3       3            3           kubernetes.io/os=linux                                               17m
kube-system   daemonset.apps/gke-metrics-agent-windows   0         0         0       0            0           kubernetes.io/os=windows                                             17m
kube-system   daemonset.apps/kube-proxy                  0         0         0       0            0           kubernetes.io/os=linux,node.kubernetes.io/kube-proxy-ds-ready=true   17m
kube-system   daemonset.apps/metadata-proxy-v0.1         0         0         0       0            0           cloud.google.com/metadata-proxy-ready=true,kubernetes.io/os=linux    17m
kube-system   daemonset.apps/nvidia-gpu-device-plugin    0         0         0       0            0           <none>                                                               17m
kube-system   daemonset.apps/pdcsi-node                  3         3         3       3            3           kubernetes.io/os=linux                                               17m
kube-system   daemonset.apps/pdcsi-node-windows          0         0         0       0            0           kubernetes.io/os=windows                                             17m

NAMESPACE     NAME                                                       READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/event-exporter-gke                         1/1     1            1           17m
kube-system   deployment.apps/kube-dns                                   2/2     2            2           17m
kube-system   deployment.apps/kube-dns-autoscaler                        1/1     1            1           17m
kube-system   deployment.apps/l7-default-backend                         1/1     1            1           17m
kube-system   deployment.apps/metrics-server-v0.3.6                      1/1     1            1           17m
kube-system   deployment.apps/stackdriver-metadata-agent-cluster-level   1/1     1            1           17m

NAMESPACE     NAME                                                                  DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/event-exporter-gke-67986489c8                         1         1         1       17m
kube-system   replicaset.apps/kube-dns-autoscaler-844c9d9448                        1         1         1       17m
kube-system   replicaset.apps/kube-dns-b4f5c58c7                                    2         2         2       17m
kube-system   replicaset.apps/l7-default-backend-56cb9644f6                         1         1         1       17m
kube-system   replicaset.apps/metrics-server-v0.3.6-57bc866888                      0         0         0       17m
kube-system   replicaset.apps/metrics-server-v0.3.6-886d66856                       0         0         0       17m
kube-system   replicaset.apps/metrics-server-v0.3.6-9c5bbf784                       1         1         1       16m
kube-system   replicaset.apps/stackdriver-metadata-agent-cluster-level-55bf669657   0         0         0       17m
kube-system   replicaset.apps/stackdriver-metadata-agent-cluster-level-658b89df     1         1         1       17m

クラスタでnodeが3台、その上でいろいろなpodが動いているのがわかりますね。

podを立ててみる。

ではpodを立ててみます。以下のマニフェストで。

gist.github.com

$ kubectl apply -f https://gist.githubusercontent.com/kun432/e29dd1c14f28806ed3acb1f6c66322c1/raw/e09fcd368634377485d2d9cd92ed14131ba793b3/sample-deployment.yaml
deployment.apps/bootcamp-deployment created

$ kubectl get pod -o wide
NAME                                  READY   STATUS    RESTARTS   AGE     IP          NODE                                             NOMINATED NODE   READINESS GATES
bootcamp-deployment-8d6697479-mpszh   1/1     Running   0          2m11s   10.72.0.6   gke-demo-cluster-01-default-pool-aae0737e-jgn2   <none>           <none>
bootcamp-deployment-8d6697479-n8755   1/1     Running   0          2m12s   10.72.0.5   gke-demo-cluster-01-default-pool-aae0737e-jgn2   <none>           <none>
bootcamp-deployment-8d6697479-rgkbr   1/1     Running   0          2m11s   10.72.1.4   gke-demo-cluster-01-default-pool-aae0737e-cnfl   <none>           <none>

$ kubectl get deployment -o wide
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                                         SELECTOR
bootcamp-deployment   3/3     3            3           2m41s   bootcamp     gcr.io/google-samples/kubernetes-bootcamp:v1   app=bootcamp

ローカルでアクセスできるか確認してみましょう。gcloudのプレビュー機能とkubectl port-forwardを使うとコンソールからWebアクセスをかんたんに試せます。Cloud Shellの以下のアイコンをクリックするとメニューが表示されます。

f:id:kun432:20210920211814p:plain

デフォルトだと8080で待ち受けてpodに流すようになっているようです。今回使っているkubernetes-bootcampのpodはport8080で待ち受けるようにハードコードされてるのでこうなります。

$ kubectl port-forward deployment/bootcamp-deployment 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080

この状態で、プレビュー機能から"ポート8080でプレビュー"をクリックします。

f:id:kun432:20210920212859j:plain

ブラウザの別タブが立ち上がって、podにアクセスできてるのがわかりますね。

f:id:kun432:20210920212605j:plain

serviceを立ててみる

クラウドにおけるKubernetesマネージドサービスの良さはクラウドの機能と連携できるところですが、特にLoadBalancer Serviceが使えることだと思っています。以下のマニフェストを適用してみます。

gist.github.com

適用してみます。

$ kubectl apply -f https://gist.githubusercontent.com/kun432/d94323661719fc06e13e1e75f7e91848/raw/2698bbdc94b1820efb4c0bc3fbfd8dc4e9a16acb/bootcamp-service.yaml
service/bootcamp-service created

$ kubectl get service
NAME               TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
bootcamp-service   LoadBalancer   10.76.3.220   <pending>     8888:30080/TCP   6s
kubernetes         ClusterIP      10.76.0.1     <none>        443/TCP          106m

作成したサービスのEXTERNAL-IPが"pending"になっていますが、しばらく待つとこうなります。

$ kubectl get serviceNAME               TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)          AGE
bootcamp-service   LoadBalancer   10.76.3.220   XXX.XXX.XXX.XXX   8888:30080/TCP   49s
kubernetes         ClusterIP      10.76.0.1     <none>           443/TCP          107m

XXX...にはグローバルなIPアドレスが付与されていると思います。これにさきほどのserviceのマニフェストにあるspec.ports[].portで指定しているポート8888を付与してブラウザでアクセスしてみましょう。

f:id:kun432:20210920214611j:plain

GCPのリソースはどうなっているかも確認してみましょう。メニューから、"ServicesとIngress"をクリックすると、LoadBalancerが起動してグローバルIPアドレスが割り振られているのがわかると思います。

f:id:kun432:20210920215541j:plain

service名をクリックするとより詳細な情報が見れます。serviceのCluster IPも見えますし、紐付いているdeploymentやpodも見えますね。

f:id:kun432:20210920215821j:plain

まとめ

一通り触ってみましたが、とてもわかりやすいですね。Kubernetesのマネージドサービスは以前はGKE一択と言われてたのも納得できますね。仕事で使うことはなさそうですが、これからKubernetesをはじめる、クラウドでやってみたい、という場合にはGKEのほうがわかりやすいのではないでしょうか。あくまでも個人の印象ですが。