ちょっと話題の記事

後悔先に立たずなマルチクラスタ運用の知見がてんこ盛り「最高のKubernetes on AWSを実現するために」 #AWSSummit

最初に考えておかないとずーっと後悔するであろう、Kubenetesのマルチクラスタ運用の話です。後悔する前に!読むのだ!
2020.09.08

「Kubernetes、考えることがいっぱいあって楽しいですね。今日はそんなKubernetesのお話です」

こんな謎の問いかけから始まった、Kubernetesセッション、皆さんご覧になりましたか? Kubernetesで実現するアプリケーションの未来まで見据えたとき、最初に検討しないと一生後悔する忘れがちだけど考えないといけない知見がてんこ盛りのセッションでした。このブログでは、そのセッション内容を余すことなく解説。

  • EKS/Kubernetesの運用に自信がない
  • Kubernetesクラスタの長期運用を真剣に考えたい
  • クラスターのアップデートができず不安

そんなあなたの未来を明るく照らす知見が、このセッションには詰まっています。ぜひ、Kubernetesクラスタ運用に迷いがあるかたはこのブログご覧になって、未来の負債をこの場で削ぎ落としましょう。

もう、アレコレ悩まなくても良いの…!?

  ( ゚д゚) ガタッ
  /   ヾ
__L| / ̄ ̄ ̄/_
  \/   /

ええんやで。

セッション内容

セッションスピーカー

Tori Hara / ポジティブな Toriさん (@toricls) / Twitter

Sr. Product Developer Advocate
Containers Product, Amazon WebServices

セッション概要

Kubernetes を AWS 上で動かしていると、それが Self-hosted であれ Amazon EKS を利用したものであれ、一定の「難しさ」のようなものを感じることがあるかと思います。特に AWS と Kubernetes 双方に熟知したエンジニアであればあるほど、トレードオフと行うべき意思決定の数の多さに悩んでいるかもしれません。Kubernetes を AWS 上で構築・運用する際によく遭遇する課題とその解決策。本セッションでは、それらの考察を通して、みなさまの Kubernetes on AWS を成功に導くヒントを紹介していきます。

想定聴講者

・Amazon Elastic Kubernetes Service(Amazon EKS)/Kubernetesを使っているが自信を持って使えていない
・Kubernetesクラスタを作ってみたが長期運用を考えた構成になっていない気がしている
・アップグレードできずに放置しているKubernetesクラスタがあり、先行きに不安がある

このセッションのゴール

クラスタ管理者の観点から、状況変化に対応しやすいKubernetesクラスタについて学び、AWS上でサステナブルなKubernetesクラスタを構築する上で抑えておくべきポイントを理解する

アジェンダ

  • 思考停止のマルチテナントを見直そう
  • Beyond single Kubernetes cluster
    • AWSリソースを共有しないクラスタ群
    • AWSリソースを共有するクラスタ群
  • まとめ

セッション動画とスライド

AWS-34_AWS_Summit_Online_2020_720p

思考停止のマルチテナントを見直そう

こちら、代表的なマルチテナントのKubernetesクラスタの運用イメージです。

1つのクラスターが複数のNameSpaceに分かれていて、それぞれが各サービスチームに対応している。クラスター管理者は、サービス横断的にクラスターを管理し、各チームはRBACを利用して、それぞれが任意のタイミングでデプロイをしていきます。

マルチテナント単一クラスタの利点

非常に代表的な利用パターンなので、こういう形に落ち着くことが多いです。なぜなら複数メリットがあるからですね。

  • 運用クラスタ数が最小限ですむ
  • ワーカーノード群のリソース使用効率が高い
  • サービスディスカバリーなど、Kubernetesクラスタに閉じた世界での設計が可能
  • OSSを素直に使える。多くのOSSは、クラスター内で動作することを考慮して機能性が構成されている場合が多い
  • オンプレミスでもよく見られる事例が多い。インターネットで検索したときに事例がひっかかりやすい

マルチテナント単一クラスタの課題

対して、この構成にはデメリットも多くあります。

  • クラスタ責務が肥大化する
  • クラスタの障害が、全てに影響する
  • ステークホルダが多くなることで、運用負荷が高くなる(特にクラスター管理者)

上記に加えて、一番のデメリットとして、上記を特に考慮しなくても、マルチテナントクラスタが構築できてしまうというのが非常に大きいです。ここで提言しておきたいのは、思考停止でマルチテナントにしてしまうことのリスクです。将来的な足かせになってしまう場合が多い。いろんな現場で見てきました。

  • クラスタを増やすことへの心理的障壁がある
    • IaCで始めたが、その後の運用が手作業
    • 新チームのオンボード時、クラスタ管理チームへの連絡〜作業など依存関係が発生
  • サービスや組織の拡大によるクラスタの肥大化
    • 新サービスチームは待てない。仕方ないので、既存クラスタに同居
  • 秘伝のタレ継ぎ足しによるクラスタ構築・運用
    • どこかでなんとなくやったkubectl applyが再現不能

これを続けていくと、悲しいことに昔を思い出しますね。Kubernetesクラスタのペット化が発生してしまいます。

目指したいゴールは、クラスタを増やせば、サービスや組織のスケールに対応できる構成。そんな構成を目指したい。

Kubernetesクラスタのペット化を避けるためには?

基本に立ち返りましょう。例えば、こういうメソドロジーがありますねよね。

Infrastructure as Code / Immutable Infrastructure

  • クラスタ上のアプリケーションはKubernetesクラスタ自体の責務
  • 更新作業を含めた将来のクラスタ運用の考慮
  • 手動オペレーションの排除

上記を元に、いつでも削除できいつでも再作成できるKubernetesクラスタが実現できれば、それは理想の姿になります。また、クラスタ以降や分割といった新規クラスタの追加可能性を考慮して構築方法を検討することも重要。

Beyond single Kubernetes cluster

ここからは、複数クラスタの代表的構成パターンについてお話していきます。

1. AWSリソースを共有しないクラスタ群

  • Pros
    • クラスタ障害が互いに影響を与えない → クラスタごとに異なるライフサイクルを保有可能
  • Cons
    • クラスタ運用コストが増大

これらProsConsがあるため、どのようなシチュエーションでそれぞれの方式を分類するか、あらかじめ想定・意思決定しておくことが重要となります。その判断基準を例示していきます。

独立したクラスタを持つべきシチュエーション

こういった場合は、クラスタを分割するべきでしょう。

  • 環境別(dev, staging, prod)でクラスタを管理
  • 異なる事業ラインでサービスを運用
  • 複数サービスから利用される共通サービス(e.g. 独自ID基盤)
  • 固有のSLAがあるサービス
  • R&D用のクラスタ

クラスタ分割を検討すべきシチュエーション

対して、分割するか検討したほうがよいシチュエーションがこちらです。

  • SLOの有無、もしくはSLOが大きく違うサービス
  • マイクロサービスの各サービスで自律性をもたせたい
  • クラスターのバージョンアップ調整作業に数週間かかる

AWSアカウントはどうする?

これらがクラスタ分割における考慮事項の一例となりますが、AWS上でKubernetesを運用するにあたり、そもそもAWSアカウントをどのように分割するかという点も考慮が必要です。

AWSリソースを共有しない場合、IaCが前提となっていればクラスタを作ること自体は難しくありません。なので、AWSアカウントを分けておいたほうが、セキュリティの観点や運用権限、アカウント単位でのサービス上限値でメリットが大きいです。

もちろん、AWSアカウントを増やすと運用コストが嵩んでしまうので、AWS OrganizationsやAWS SSOの併用により運用コストを軽減する方法もあります。

また、クラスタコントロールプレーンのAuditログをCloudWatch Logsからクラスタ間利用AWSアカウントに集約し、クラスタ群全体のAPIコールを監査する方法もあります。

2. AWSリソースを共有するクラスタ群

AWSリソースを共有するクラスタ群というパターンもあります。よくあるのは、クラスタとAWSリソースを疎結合にしたいであったりとか、クラスタ単位でのB/Gデプロイなど。

真ん中が共有リソースとなります。

  • Pros
    • クラスタとAWSリソースを疎結合にできる → クラスタの責務範囲を狭くできる
  • Cons
    • 構築時に考えることが増えてしまう(ビルディングブロック的な難しさがでてくる)

よくある課題「Application Load Balancer(ALB)の場合」

Kubernetesにおいて代表的なAWSリソースにALBがありますが、運用上の課題も多くあります。

例えば、ALB Ingress Controllerを利用する場合、ALBの作成、リスナ、ターゲットグループ、その登録を全てALB Ingress Controllerが行います。そのため、他のクラスタで、同じALBを利用することができません。

でも、運用上は、1つのALBを複数のKubernetesアプリケーションで共有し、EC2にもルーティングした場合も多くあります。また、Kubernetesクラスタを削除すると、それに紐づくALBも一緒に削除されてしまいます。

これに対するワークアラウンドを考えてみます。

ALB関連リソースの作成には、CloudFormationやTerraformを使い、Kubernetes Serviceをtype:NodePortでポート番号固定で用意しておきます。EC2 Auto ScalingグループをALBターゲットグループと関連付けて作成し、EC2のスケールアウトに応じて自動的にEC2がALBターゲットに登録されるようにしておきます。

この場合、ポート番号を固定しているのとAuto Scalingグループとターゲットグループの紐付けを設定しているため、複数のアプリケーションをALB経由でトラフィックを受けることができません。ので、ALBに加えてNginx Ingress Controllerを利用することで、ALBからのトラフィックをクラスタ内に通した上で、Nginx Ingressを利用して複数のKubernetesアプリケーションにルーティングすることが可能になります。

また、正式リリース前ですが、ALB Ingress Controllerの"IngressGroup"を利用することで1つのALBから複数のKubernetesアプリケーションにルーティングすることが可能です。

また、ALB Ingress Controllerではリソース自体を作成せず、既存のターゲットグループへの登録だけができるようにする機能も追加される予定です。また、同様の機能を持ったサードパーティのOSSツールも存在している。

さらに、ALB Ingress Controllerはそのまま利用し、Route 53やGlobal Acceleratorのレイヤーでクラスタにまたがる荷重ルーティングを実施することも選択肢としてあります。

よくある課題「Virtual Private Cloud(VPC)の場合」

クラスタを横に作成し、RDBMSを新旧クラスタから同じものを参照する構成にしたが、なんと、サブネットのIPアドレスが不足し、新クラスタへのアプリケーションデプロイができなくなるパターンです。VPCにはRDBMSがいるので、VPCやサブネットの再作成は避けたい。

そんなときは、CNIカスタムネットワーキングを利用することで、PodのIPアドレスをノードとは異なるCIDRレンジから割り当てることができます。

ただ、本質的には、そもそも最初のクラスタ作成時点で、少なくとも2つのクラスタをデプロイできるようにVPCやサブネットのCIDRをサイジングしておくことが重要です。ロードバランサーなどもIPアドレスを消費するので、注意です。

まとめ

本日のセッションのまとめです。

  • Kubernetesは単一クラスタだけで利用すると使いやすい
    • →そのため、思考停止のマルチテナント単一クラスタには注意が必要
    • なし崩し的なクラスタ肥大化、複雑化、メンテナンス性悪化につながる
    • チーム間の依存関係から「動きにくい」Kubernetesクラスタになりやすい
  • クラスタのペット化をさける
    • IaC, Immutable Infrastructureを利用する
    • 肥大化してから分割を検討するのではなく、事前に必ず検討しておく
  • クラスタ管理者の視点で、どのような分割が必要になるか事前に把握しておく
  • AWSリソースをKubernetesクラスタから疎結合に作成する方法は手間がかかるが、Kubernetesクラスタそのものの運用容易性が高い

Appendix

以降、本編からもれたおまけです。

複数クラスターを並べて、クラスタレベルでB/Gデプロイをしたくなる理由が、サポートバージョンの短さ。あると思います。

運用コストの削減には、Amazon EKS on AWS Fargateもデータプレーンの運用コストを下げる上で有用な選択肢になります。

アーキテクチャがこちら。EKS Fargate profileがある状態でpodが作成されると、Webhookで判定され、Fargateが起動します。

ワーカーノードのアーキテクチャがこちら。運用コストがFargateにすることで下がる部分は、おもに、Fargate taskとAmazon EC2 instanceの間の部分。ここが、AWS管理になるため、その運用が不要になります。

素敵です。

マルチクラスター運用を一番最初から考えることの重要性を学べる貴重なセッション

以上、セッションレポートでした。冒頭、マルチクラスターの必要性は重要度を問いただしてからの分割や検討ポイントの提示、そしてAWS上でKubernetesを運用するにあたり、非常に重要な検討ポイントであるALBについて、非常に具体的なノウハウが満載の貴重なレポートでした。

また、クラスターアップデートをする際に、典型的パターンとしてクラスターを一つのVPCで複数構築するのもよくある手法だとは思いますが、その際のネットワーク設計も先にやっておかないと、後から超痛い目をみるというのも至極納得です。VPCのネットワーク、あとからいじるの大変ですからね…

一度運用を始めると根本的な設計変更は難しいKubernetesの世界。忘れられがちなマルチクラスターの必要性と検討ポイントがめっちゃ具体的にまとまっているセッションだったので、これからKubernetesクラスターを構築する方は、必ずこのセッションの内容を検討ポイントとして抑えておくことを強くオススメします。

それでは、今日はこのへんで。濱田(@hamako9999)でした。