kakts-log

技術・エンジニアリング組織などについて調べたことをまとめます

【GKE】 NodePoolのマシンタイプをN1からN4に変える際のポイント

概要

GKEで稼働しているサービスで、コスト・パフォーマンス最適化のために昨年末に東京リージョンでGAとなったN4インスタンスへの利用を検討していて、 N4インスタンスに変更する際のハマリポイントを整理します。

cloud.google.com

マシンタイプの切り替え方法

マシンタイプを切り替える方法は、主に下記2つがあります。

  1. 既存のNodePoolのマシンタイプを変更する方法
  2. 新しく使うマシンタイプを設定したNodePoolを新規で作り、kubectl cordon, drainにより旧NodePoolのNodeから段階的にPodを追い出す方法

ここでは、切り替え次の可用性などを考慮して、2番の方法で検証を進めました。

N4に変える際のポイント

N4から、従来のstandardが使えなくなり、ストレージがhyperdiskのみにしか対応しておりません。 https://cloud.google.com/compute/docs/general-purpose-machines?hl=ja#supported_disk_types_for_n4

これに関係して、一部のStatefulSetリソースに関連したPodが起動せず、eventを確認すると下記のエラーが出ていました。

AttachVolume.Attach failed for volume "pvc-hoge" : rpc error: code = InvalidArgument desc = ControllerPublish not permitted on node "projects/dummy/zones/asia-northeast1-a/instances/gke-dummy-instance-abc" due to backoff condition FailedAttachVolume ...


AttachVolume.Attach failed for volume "pvc-hoge" : rpc error: code = InvalidArgument desc = Failed to Attach: failed when waiting for zonal op: rpc error: code = InvalidArgument desc = operation operation-xxx failed (UNSUPPORTED_OPERATION): [pd-standard, n4-standard-4] features are not compatible for creating instance.

設定内容は下記のyamlマニフェストに記載の通りです。
GKEクラスター内で稼働しているStatefulSetが、StatefulSetに紐づくPersistentVolumeClaimでstandardのストレージクラスを設定しており、N4インスタンスでサポートされなくなったことによりPodの起動時にVolumeを割り当てられなくなったことによりエラーが発生していました。

  volumeClaimTemplates:
    - metadata:
        name: dummy-app-data
        labels:
          app.kubernetes.io/name: dummy-app
          app.kubernetes.io/instance: test
          app.kubernetes.io/component: dummy-app
      spec:
        storageClassName: standard # ここでstandardを指定する
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 10Gi

StatefulSetリソースの仕組み上、リソースを登録すると、StatefulSetは作成されたPodに紐づくVolumeを作成するためのPersisitentVolumeClaim(PVC)リソースを作成します。
StatefulSetは直接ボリュームを作成するわけではなく、このPVCリソースの情報をもとに、各KubernetesクラスターでサポートされているPersisitentVolume(PV)が作成されます。

StatefulSetの仕組みについては公式ドキュメントをご確認ください。

同様のエラーに対するGoogleCloudのissue Compute VM Instance (n4-standard-16) with attached... - Google Cloud Community

kubernetes.io

このボリュームのタイプを指定したものがStorageClassというKubernetesのリソースで、各プロバイダーで固有のストレージタイプを定義して割り当てることができます。

kubernetes.io

GKEにおけるStorageClassの利用については下記のドキュメントを確認ください https://cloud.google.com/kubernetes-engine/docs/concepts/persistent-volumes?hl=ja

standardストレージからhyperdiskへのデータの移行

ここで、N4インスタンスを利用するにあたり、Hyperdiskストレージを使うように設定します。 主な手順は以下の通りです。

既存のStatefulSetで新しいPersistentVolumeを紐づけるには

StatefulSetの仕様により、稼働済みのStatefulSetに対して上述したvolumeClaimTemplatesを使うように変更することはできません。
そのため、新しいStatefulSetリソースを用意して、volumeClaimTemplatesの設定で新しいStorageClassを指定して作成する必要があります。

詳細は別途記事にまとめます。

まとめ

GKEにおいてN4マシンタイプを利用する際の注意点として下記の問題があります。

  • N4インスタンスでは従来のPersistentDiskやローカルSSDを利用できず、HyperdiskのHyperdisk Balanced というストレージブロックしか利用できない
    • これに伴い、StatefulSetなど、Volumeにstorageクラスなどを割り当てている場合はPod起動時にボリューム割り当てエラーがでてしまいPodが起動できない

上記の点に対処できれば、それ以外の問題は特になく、以前より新しい世代のcpuを使ったVMへの切り替えにより、クラスターのリソースのコストパフォーマンスを改善できるため、利点が上回るかと思います。

思わぬ問題もあるかもしれないため、当然のことですがマシンタイプ切り替えの際は開発環境などで十分にテストすることが重要です。