STORES Tech Blog

こだわりを持ったお商売を支えるプラットフォーム「STORES」の開発チームによる技術ブログです。

こだわりを持ったお商売を支えるプラットフォーム「STORES」の開発チームによる技術ブログです。

GKE Autopilotをデータ基盤に導入してみた

データエンジニアの@komi_edtr_1230です。

今回データチームが管理しているデータ基盤にてGKE Autopilotを導入したのでその感想についてまとめていこうと思います。

TL; DR

GKE Autopilotを使い始めて、インフラ管理から解放され開発業務に専念できるようになりました。

データ基盤の利用という観点で本当に最高で便利です。

背景

heyではデータ分析に基づいた意思決定を促進するためにデータチームがあります。

データチームにはデータアナリストとデータエンジニアがいるのですが、それぞれの特徴として

人数 業務内容 備考
データアナリスト 4人 ビジネスサイドがメイン
A/Bテストによる施策の改善
各種データの抽出
などなど...
@jnishimuがいる
データエンジニア 3人 データ基盤の整備
データの利活用の促進
1人は業務委託

というようになっています。

heyは今や社員300人以上の規模の会社で現在扱っている事業としては

  • EC
  • 決済
  • 予約
  • レジ

と4つもあるのですが、それに対してデータエンジニアは3人しかいません。

同じ会社とはいえ各事業それぞれ別のプロダクトなのでバックエンド開発のメンバーは別々で、ゆえにデータ連携もそれぞれ対応しなければいけないのですが、データ連携以外にもセキュリティ対応やプライバシーポリシーなどリーガル的な確認、データチーム保有GCPAWSの運用なども行う必要があり、これらの業務量はとても3人では捌き切れません。

データエンジニアが運用するデータ基盤はGKE (Google Kubernetes Engine)とBigQuery、Metabaseで構成されるのですが、これらのメンテナンスコストもそれなりにかかっていました。

GKE Autopilotを導入

今年になってから新しく登場したGKE Autopilotですが、早速導入してみました。

GKE Autopilotの特徴として

  • ポッドの負荷に合わせてノードが自動的にプロビジョニング
  • デフォルトでセキュリティ機能が充実

などがあるのですが、こうした機能はまさにデータ基盤のようなバッチ処理などがメインとなる場合において本当にフィットします。

というのもバッチ処理のように一定時間だけかなりの高負荷がかかるもののインフラのチューニングは今までだと勘と経験に頼るみたいなところがあったのですが、GKE Autopilotはポッドの負荷に応じて最適なインスタンスタイプのノードでオートスケールしてくれるのです。

また、デフォルトでWorkload Identityなどといった高度なセキュリティ機能がついているので安心です。

かつてのGKEの設定はものすごい量のTerraformコードによってなんとか構成されていたのですが、今は基本的なネットワークの設定にenable_autopilot = trueの行を追加するだけで、初期設定自体もかなりミニマルになりました。

GKEについて今後はもうTerraformを叩く必要もなくなり、セキュリティ対応や死活管理なども手厚いクラウドサポートによって実現したため、インフラ管理から本当に解放されました!

実際にGKE Autopilotを眺めてみる

ここまでお気持ちを述べましたが、せっかくなのでGKE Autopilotの設定例をお見せしようと思います。

Terraform

まずTerraformのコードです。

resource "google_container_cluster" "data_platform" {
  name               = "data-platform-production"
  location           = "asia-northeast1"
  initial_node_count = 1
  network            = google_compute_network.data_platform.name
  subnetwork         = google_compute_subnetwork.data_platform.name

  enable_autopilot = true

  private_cluster_config {
    enable_private_nodes    = true
    enable_private_endpoint = false
    master_ipv4_cidr_block  = "{some_internal_ip}"
  }
}

AutopilotではないGKEではポッドの自動垂直スケーリングを有効化するために意図的にvertical_pod_autoscalingのブロックを書く必要がありましたが、Autopilotではこれがデフォルトで有効です。

データチームのGKEクラスタはプライベートクラスタとして立てているのでそのための設定ブロックはありますが、本当にこれだけです。

マニフェスト

次にKubernetesマニフェストを眺めてみます。

データチームのGKEクラスタではIAPやRoleBindingsなど色々マニフェストがあるのですが、簡単にDeploymentだけとりあげます。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    env: production
  name: digdag
  namespace: digdag
spec:
  replicas: 2
  selector:
    matchLabels:
      app: digdag
      env: production
  template:
    metadata:
      labels:
        app: digdag
        env: production
    spec:
      containers:
      - command:
        - java
        - -jar
        - /usr/local/bin/digdag
        - server
        - --task-log
        - /var/tmp
        - --max-task-threads
        - "4"
        - --log-level
        - error
        - --params-file
        - config/params.yaml
        - --config
        - config/digdag.properties
        env:
        - name: ENVIRONMENT
          valueFrom:
            configMapKeyRef:
              key: env
              name: env-var-config
        image: asia.gcr.io/[some_gcr_uri]/digdag:20210421-1
        name: digdag
        resources:
          requests:
            cpu: 3000m
            memory: 4Gi
      - command:
        - /cloud_sql_proxy
        - -instances=$(GCP-PROJECT):$(DIGDAG-DB-REGION):$(DIGDAG-DB)=tcp:5432
        env:
        - name: ENVIRONMENT
          valueFrom:
            configMapKeyRef:
              key: env
              name: env-var-config
        - name: GCP-PROJECT
          valueFrom:
            configMapKeyRef:
              key: gcp-project
              name: env-var-config
        - name: DIGDAG-DB
          valueFrom:
            configMapKeyRef:
              key: digdag-db
              name: env-var-config
        - name: DIGDAG-DB-REGION
          valueFrom:
            configMapKeyRef:
              key: digdag-db-region
              name: env-var-config
        image: gcr.io/cloudsql-docker/gce-proxy:1.17
        name: cloud-sql-proxy
        securityContext:
          runAsNonRoot: true
      serviceAccountName: digdag-sa

こちらはデータ基盤で動いているワークフロー管理エンジンのDigdagを立てるためのマニフェストで、同時にCloud SQLに接続するためのCloud SQL Proxyをサイドカーとして立てています。

ノードの様子

バッチが走っていないときのノードの状態は以下の通りで、最低限コンテナを立てていられる程度のノードしか存在しません。

f:id:komi1230:20210625211938p:plain
何もバッチが走っていないときのノード

さて、バッチを走らせました。

f:id:komi1230:20210629140450p:plain
Digdagのワークフローを起動した

ちゃんとワークフローが起動しておりバッチ処理が動いていますね。

そのときのノードがどうなってるか確認してみると....?

f:id:komi1230:20210625212115p:plain
バッチが走っているときのノード

ノードが増えています!

ポッドの負荷がかかっているのを見て適切にノードが増えているのがわかりました。

セキュリティの話

少しだけセキュリティの話を。

GKE Autopilotの素晴らしい点として、デフォルトで高度なセキュリティ機能が搭載されている点も挙げられます。

例えばセキュリティ設定としてWorkload Identityというものがあるのですが、これはポッドでサービスアカウントをデフォルトで認証してくれる機能です。

これによりサービスアカウントの認証のためにクレデンシャルのJSONファイルを持ち回る必要がないのでセキュリティ的に安心なのです。

前までデータチームでも普通のGKEでWorkload Identityを導入していたのですが、Terraformで書いたGKEの設定をする際にgoogle_container_clusterのリソースとは別でgoogle_container_node_poolでノードプールを作成しようとして(コスト対策のためにプリエンプティブルなノードプールを別で用意しようとしていた)、この別で作ったノードプールにはメタデータの設定をしていたもののデフォルトで作られるノードにメタデータを設定し忘れて確率的に認証落ちが発生するというバグに遭遇し、原因追求まで丸3日潰すという失敗談があり...

こうした悲しい話もあったのでWorkload Identityがデフォルトで有効化されているというのは嬉しいポイントでした。

まとめ

今回データ基盤でGKE Autopilotを導入し、それによって運用コストを低減させることができました。

heyのデータチームは本当に優秀なメンバーが集まっているので業務スピードもかなり早いのですが、それでもマンパワー不足はあるためこうしたフルマネージドのクラウドサービスの恩恵を授かれて本当に良かったと思います。

しかしここからが正念場で、今回はインフラ管理のコストを低減させましたがデータ基盤としてやるべきことはまだまだたくさんあるため、引き続きデータ利活用のカルチャーを強固にするべくデータにまつわる色々な開発に取り組んでいこうと思います。

heyではデータを活かして社会をアップデートしたい、そんなクールでアツい仲間を募集しています。

hello.hey.jp

参考記事