エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

AWS ECSユーザーからみたGKE再入門

こんにちは、エンジニアリンググループ AI・機械学習チームの安田です。

これは エムスリー Advent Calendar 2020 の22日目の記事です。

今回は、普段AWS ECSを主に使っている私が、GKEをECSとの比較から眺め直します。

先日、GKEを業務で触る機会を得た時に苦しみ続けたので、再入門したいと思い立ち今回このネタを調べました。

普段はterraformを用いてAWS ECSとGCP GKEを利用しています。その中でECSは利用歴が長く仕組みがある程度自信を持ってわかると言えるのですが、GKEについてはそれほど理解していないため、ECSとの比較をして理解を深めようというのが記事の趣旨になります。

EKSとGKEとの比較記事ではないのでご注意ください。そちらをお求めの方は、先人が素敵な記事をたくさん書いてくれていると思うので、ネットの海から探していただけると幸いです。

特に、terraformでコード管理しているとGKEはECSに対して暗黙的に生成される部分が多いように感じるため、その部分を明らかにすることが大きな目的です。

他のECS利用者の方への参考になると幸いです。

読者想定/前提

読者想定

  • ECSについてよく知っているけどGKEについてはしらない
  • GKEを業務でつかっているけどなんとなく運用している
  • GKEのterraformを読んで絶望した

前提

  • ECS/GKEともterraform + json/yaml構成で扱っている
    • terraformでは、AWSはAWS Provider, GCPはGCP Providerのみを利用している
  • ECSはFargateは取り扱わずEC2をベースとしたものを扱う

ECSの復習

ECSの主要コンポーネントと関係性をAPI/Batchごとに確認します。

今回前提としてterraformを利用していることを置いているので、terraformから見える目線で整理していきたいと思います。

API

APIは外部からのアクセスがあるためLBに付随するコンポーネントを含むのが特徴です。 それを取りまとめるのは ECS Service でこちらはk8sと同じような名前ですね。

f:id:sora_sakaki:20201221142008p:plain
ECS APIの図

この構成ではまず、ECS Cluster が該当クラスタの名前を持ったAgentの動いている EC2 を掴んで管理下に組み込みます。その上で動かすタスクは ECS TaskDefinition で定義されており、そのタスクを ECS Service がkickするという挙動をします。 この際、ALBからタスクへの接続も ECS Service が実施しますが、ALBは事前に作成したものを ECS Service へ渡します。

Batch

BatchはAPIと異なり外部からアクセスする口は存在しない代わりに、定期実行のスケジューラを含みます。 ただ、スケジューラはECSの外部にあるCloudWatch Eventを使用します。

f:id:sora_sakaki:20201221142145p:plain
ECS Batchの図

ECS Cluster がタスクを動かすためのEC2を管理下に置いている点はAPIと共通です。スケジュールでタスクを実行する際は前述の通り、CloudWatch Event を使用します。CloudWatch Event は決まった時間になんらかのアクションを実行できるサービスですが、そのアクションの中に ECS Task を実行する機能があるため、簡単に実行できます。

ECSのまとめ

ECSは上記のように、既存のリソースを紐づけて管理するような構成になっています。特にterraformではjsonになっているのはtask definitionのみで他は独立したリソースとして記述し、それぞれのrelationをパラメータで渡すような形になります。

GKEの確認

上記を踏まえて、次はGKEを確認していきます。 こちらも同じようにterraformから見える目線で整理していきます。

API

ECSと同様にAPIの構成を確認していきます。

f:id:sora_sakaki:20201222001854p:plain
GKE APIの図

????

と、ジョークはこの辺にしてここで気づいたことはGKEのterraformは全然要素がないことです。GKEに関してはクラスターの構築までしかできません。*1

GCPのterraformでGKEに関してできることは以下の通りです。

  • Resources
    • google_container_cluster
    • google_container_node_pool
  • Data Sources
    • google_container_cluster
    • google_container_engine_versions

つまり、terraformからみるとGKEはあまりできることがないということがわかります。多くの部分をkubernetesネイティブなyamlで構築する必要があります。

API(k8sのyamlあり)

さて、1つterraformだけ眺めていてもなんともならない理由が明らかになりましたが、気を取り直して暗黙的に生成されていそうなリソースを探して、k8sのyamlありの構成をみていきましょう。

f:id:sora_sakaki:20201221170211p:plain
GKE APIの図(yamlあり)

この図のnode pool, GKE Clusterの部分はterraformで作成、その他はk8sのyamlで作成しています。

yamlで作成した部分で、Service, Ingressの作成するLBの部分はどのようなものが作成されるのかわからなかったのでなんらかのモジュールが作成されるとして記述しました。

GKEでは、ECSと異なりGKEのnode poolというリソースで実体のVMを管理・生成します。この点AWSと異なりAgentに設定ファイルを食わせるなどしなくていい点は素直に見えました。この実体VMはGCEのページで確認できるのでGCEのVMを利用しているのがわかります。

また、大きな違いとして、ServiceとIngressでLB(的なもの)が2つ存在することがあります。

Batch

Batchも同様に確認していきましょう。

f:id:sora_sakaki:20201221171553p:plain
GKE Batchの図 

Batchの場合、DeploymentではなくCronJobでtemplateを記述します。この点どちらもTaskを利用するECSと異なります。

外部からの口がなくなったのは共通なのでそれに付随するLB等はなくなっています。他方不明点はJobをkickする実体です。

ECSとGKEの比較とGKEの疑問点

ECSとGKEの比較

簡単にECSとGKEを確認したところで、双方を比較してみます。*2

ECS GKE
バックエンド EC2 VM GCE VM
バックエンドとクラスタの接続方法 EC2上のAgent GKE nodepool*3
APIのコンテナ定義 ECS Task K8S Deployment
APIのコンテナ管理,起動 ECS Service K8S Service
APIのLB ALB ?(serviceで生成)
APIへ外部からアクセスする際のLB ALB ?(Ingressで生成)
Batchのコンテナ定義 ECS Task K8S CronJob
Batchのコンテナ管理,起動 CloudWatch Event ?(cronjobで生成)

結局、k8sのyamlで生成されている

  • LB(service)
  • LB(Ingress)
  • スケジューラ(cronjob)

の実体がわかれば概ね疑問点は解消できそうです。なのでこれらを確認していきます。

LB(service)

こちらは、GKEの公式ドキュメントに記載があります。

cloud.google.com

どのような実体が作成されるかはServiceのタイプに依存します。

  • 以下はk8sが提供するアプリケーションにてルーティングされる
    • ClusterIP
    • NodePort
  • 以下はGCPのLBを生成する
    • LoadBalancer

よってこちらは設定に依存しますが、k8sのアプリケーションで提供されるかGCPのLBを使うかになります。

LB(Ingress)

cloud.google.com

GKEのドキュメントによると、基本的にはGCPのLBが生成されます。

スケジューラ(cronjob)

cloud.google.com

GKEのドキュメントによると、こちらはk8sのネイティブ機能です。

まとめ

結論として、terraformを扱っている際に暗黙的な部分が多いように感じる原因は

  1. そもそもterraformで扱ってないリソースがほとんど
  2. 実際に暗黙的に生成されているリソースがあった

ECSを軸に整理したリソースの関係性は以下のような対応になるようです。

ECS GKE
バックエンド EC2 VM GCE VM
バックエンドとクラスタの接続方法 EC2上のAgent GKE nodepool
APIのコンテナ定義 ECS Task K8S Deployment
APIのコンテナ管理,起動 ECS Service K8S Service
APIのLB ALB K8Sネイティブ/GCPのLB
APIへ外部からアクセスする際のLB ALB GCPのLB
Batchのコンテナ定義 ECS Task K8S CronJob
Batchのコンテナ管理,起動 CloudWatch Event K8S CronJob

暗黙的に見えた部分は、IngressのLB以外はkubernetes標準の機能で提供されるようでした。これらはAWSやGCP提供のリソースのように細かい部分がGCPのコンパネから見えないため、GKEを使う場合はkubectl等のk8s用のツールを使わないと確認できないことがわかりました。

なんか調べてみたらわりとデータソース含めて当たり前な感じだったので、この記事を書いた意味....という気持ちもありますが、ふわっとわからなかった部分をちゃんと整理したということで同じような人の参考になることを祈って。

We are hiring!

エムスリーではクラウド基盤の技術が活躍できる場面はたくさんあるので、興味のある方はぜひ応募してみてください!

jobs.m3.com

*1:GKE以外の部分、たとえばGKEで使用するLBを事前に作成したり、global ipの確保することはterraformで可能です。

*2:AWS ECSの粒度で無理やりGKEを整理しているため、無理があるがECSユーザー向けなので妥協

*3:厳密にはnodepoolで生成されたVMをどう紐づけて、取り扱うのか調べる必要がある気がする