Speee DEVELOPER BLOG

Speee開発陣による技術情報発信ブログです。 メディア開発・運用、スマートフォンアプリ開発、Webマーケティング、アドテクなどで培った技術ノウハウを発信していきます!

Kubernetesが実現した「インフラ設計不要のHA(High Availability)」というパラダイムシフト

お疲れさまです、DX事業本部開発基盤グループでSREをしています西田(@k.bigwheel)です。 3/31にDX事業本部はEC2ベースのサービスがなくなり全システムがKubernetes基盤へ移行しました。エンジニア向けのJenkinsやRedashといったシステムも廃止したりKubernetes上へ移行したためEKS管理ではないインスタンスは本当に0台になっています。

今回はそれを呼び水としてKubernetesの何がすごいのか、サービス開発の視点で一体何を実現したのかを僕の視点で書いていこうと思います。

f:id:den8:20210421081859p:plain:w256

tl;dr

  • Kubernetesは普通のサーバーのみで構成できるOSSのクラウドインフラだよ
  • Kubernetesマニフェスト(やchart)用に書かれたインフラ構成は過去最高に汎用性が高いよ、特にインフラ設計の一番難しいところだったHigh Availability (以下HA)構成が簡単にできるのがすごい
  • コモディティ化が進んだ結果、今までLinux OSが果たしていたようなプラットフォームの役割をKubernetesが果たすことになりそう

前提

この記事を読む前提としてECSやKubernetesの基本構造は理解しているものとします。話したいのは詳細の挙動ではなく本質的な設計思想の違いとそれが現実にどういった作用を及ぼしたかなので細かい挙動にも立ち入りません。 Kubernetesについては公式ドキュメントへ目を通すのが一番だと思いますが、サラッと動画で見るなら弊社の社内勉強会でも流した以下の動画が良いと思います。

基礎から学ぶ!アプリケーション開発者のためのKubernetes入門 | CloudNative Days Tokyo 2020

Kubernetesの特徴

Kubernetesは御存知の通りコンテナオーケストレーションシステムです。ECSなど同様のシステムと比較しての特徴といえば以下が挙げられます。

  • Hadoopなどと同じくGoogle社内で使用されていたシステムが元となったOSS
  • あらゆる命令がREST APIで可能
  • 高い可用性
  • Infrastructure as a Definitionを実現したreconcile loop*1

しかし、今回述べたいKubernetesの凄さというのは上記のどれかではありません。今回書きたいのはKubernetesによって配布アプリケーションがインフラ設計なしでも本番環境相当のHA構成を実現できるようになったことです。

「インフラ設計不要のHA」とは

具体例で話したほうがわかりやすいと思うのでRedashの例で話します。 冒頭で少し触れましたが、今回のDX事業本部の全面Kubernetes化の一環としてそれまでEC2内で動かしていたRedashをKuberentesベースへ移行しました。 その際に僕が行ったことは本質的に以下の2点だけです(GitHub - getredash/contrib-helm-chart: Community maintained Redash Helm Chartより)*2

helm repo add redash https://getredash.github.io/contrib-helm-chart/
helm upgrade --install -f my-values.yaml my-release redash/redash オプション設定省略

一見このコマンドは単にKubernetes用の簡単コマンドであり他の手法と大差ないように見えるかもしれません。 Redashの開発はAWS用のredash入りAMIも用意してくれているため、awscliを使ってコマンド1,2回で構築することも可能でしょう。 しかし、実はその2つには大きな違いがあります。 それは、Kubernetesの方は コマンドのみでHA構成になっている 点です。

もしAMIベースでredashサービスを構築する場合、AMIを起動するだけでは HA構成にはなりません。AWSのEC2障害によりインスタンスがダウンした場合、そのままredashサービスのダウンになります。 一方、kubernetesによってredashサービスを構築した場合はpod数を2以上にすることで冗長構成にすることができます。また仮にインスタンスがダウンしてそれまで動いていたpodがなくなった場合でもreconcile loopによって代わりのpodがすぐに立ち上がります。

そもそもHA構成とは

HA構成、つまりシステムの冗長化は現代の本番サービスでは事実上必須となっています。冗長化しないシステムでは1台のサーバーがダウンすると、直ちにユーザがサービスを利用できなくなるからです。

しかし、実はこのHA構成を実現することは従来とんでもなく大変なことでした。アプリケーション開発においてベンダーに頼むとそれだけで見積もりが大きく跳ね上がったり、AWS以後のクラウドインフラであってもヘルスチェック・オートスケーリング・ELBなどを使って安全で安定して動くHA構成を作ることは熟練したインフラエンジニアのみしかできませんでした。

OSSのHA構成可能なアプリケーションであるRedash, Elasticsearch, Hadoop, Rundeckなどにおいても、配布されているパッケージから実際に本番運用可能なHA構成で動かすまでにはとても多くの試行錯誤が必要でした。 そういったことを踏まえるとhelm chartのパラメータ一つでHA構成ですべて作ってくれることは驚異的です。

インフラ設計との戦い

Web企業のインフラエンジニアの責務というのは様々ありますが、その一つがアプリケーションを受け取ったのち、それが動くようサーバーをセットアップしてロードバランサーなどを設定することです。 このセットアップ作業は時代を経るにつれ以下のように自動化されてきました*3

  1. ソースコードのtarball
  2. パッケージ(rpm, pip, gem ...)
  3. puppet, chef
  4. コンテナ技術(Docker)
  5. cloudformation, terraform

またこれは環境間の差異との絶え間ない戦いでもありました。 ソースコードのconfigureコマンドに始まりrpmはパッケージの依存関係により多少のOS差異であればどこでも動くように努力した結果です。Dockerによる全依存関係のカプセル化はそれらの技術の集大成とも言えるでしょう。

しかし、クラウドインフラ(AWS, GCP...)については環境間の差異の吸収が進んでいませんでした。これはそもそもクラウドインフラ自体が新たなプラットフォームであり差異の吸収が未知の領域であったこと、業界リーダーのAWSにとってはベンダーロックインしてしまったほうが利益になるので進んでやる理由がなかったことなどが挙げられます。 それ故にDockerイメージがあったとしてもHA構成実現のためのインフラ設定は依然インフラエンジニアの手が必要でした。ECS, ELB, ECR, VPCなどを設計してヘルスチェックのエンドポイントを確認、設定を少しずつ変えながら適切に動くようにする、といった作業です。

helm chartがある今、コマンド一発でHA構成を作れるためもはやHA構成についての高度な知識を持ったインフラエンジニアはいりません。構築されたKubernetesクラスタとredash helm chartのような用意されたchartさえあれば誰でも本番環境レベルのサービスをデプロイできます。

パラダイムシフト

以上の理由などを背景に、helm chartの数は急速に増え利用も加速しています。

Jenkins, Hashicorp vaultなどは開発元公式のchartが存在しredis, elasticsearchなどのステートフルアプリケーションも実用可能な状態です。すでにキャズムを超えたと言ってもいいかもしれません。 アプリケーションの提供方法がソースコードからパッケージ、そしてDockerイメージへと遷移したようにそう遠くない日にhelm chart*4がアプリケーション配布の主流になるでしょう。そうなったとき、Kubernetesは今まで最も大きなアプリケーションプラットフォームであったLinux OSに変わる、新たなスタンダードプラットフォームになるのかもしれません。

*1:Kubernetesがいかに自動化の考え方を変えたか? | Taichi Nakashima

*2:実際にはDX事業本部のKuberentesはArgo CDで管理されているので、Helm - Argo CD - Declarative GitOps CD for Kubernetesのような下記コマンドと等価なyamlをgitリポジトリへcommit, pushする形になります

*3:余談ですがこの領域がアプリケーションに最も近いところから端を発して徐々にインフラストラクチャへ近づいていっているのは偶然ではないでしょう

*4:またはその代替となるKubernetes用のフォーマット