1クール続けるブログ

とりあえず1クール続けるソフトウェアエンジニアの備忘録

【AWS Re:Inventレポート】CMP318-R1 - [REPEAT 1] Kubernetes on Spot Instances: Optimize for scale and cost

Kubernetes on Spot Instances: Optimize for scale and cost

今まで受けてきたKubernetes系のWorkshopはカテゴリがContainerでしたが、今回はComputeです。最終日はセッション1つだけなので、Workshopとしては最後になります。どうやらEKSでも使用しているWorkshopをベースにして作成されたようです。運営は主にcomputeのスタッフさんが多かったですが、コンテナのエキスパートさんもいらっしゃって自分はその方に質問しました。
資料はこちら

ec2spotworkshops.com

午前にあったWorkshopとかぶる部分がちょいちょいあってその部分は割愛しています。午前のWorkshopはこちらの記事から。

t.co

Workshopの流れ

今までで一番親切なWorkshopの進行でした。後半になると内容の説明をしなくなってしまうスピーカーの方が多いのですが、このセッションはめっちゃ詳しく説明してくれて、例えばtaintsとtolerationとかも午前に比べて優しい説明(+優しい語彙)ですごくわかりやすかったです。
最初にスピーカーの方が、本番でKubernetes使っている方をお聞きしていましたが、かなりの人数いらっしゃいました。Advancedのセッションだとやはり経験者が多いですね。スポットインスタンスを合わせて使っている人というものだと自分含めて数人くらいまで減ったので、スポットインスタンス使えているのは結構少ないのではとも感じました。

導入

EKS系のworkshopではお決まりのEKSクラスター構築から入りました。ちなみに作成するのは全てオンデマンドインスタンスです。

そしてクラスターが出来上がるまでの時間で、EKSのアーキテクチャについての説明が入りました。しっかりこういった図を見るのが初めてだったので、このタイミングで気づいたのですが、Control Planeの前段にはNLBがあるそうな。ENI AttachmentもControl Planeからやっているんだ…どうやって実装しているのなど疑問におもいました。

https://ec2spotworkshops.com/images/using_ec2_spot_instances_with_eks/introduction/eks-architecture.svg

kube-ops-viewの導入

自分は存じ上げていなかったのですが、kube-ops-viewというKubernetesクラスターのnode/podを可視化するツールがあります。こちらはHelmを使って導入していきます。実際に入れてみると、エンドポイントが出来ます。エンドポイントにアクセスしてみると下記のように見えます。なかなか良さげです。CPUとメモリも一緒に見れるのがいいですね。ドット絵っぽい感じもいいです。

f:id:jrywm121:20191209194244p:plain

スポットインスタンスの導入

スポットインスタンスの復習から入りました。なんとなく理解していたことではありますが、下記のページは知らなかったので驚きました。Terminationの頻度が出ているの便利ですね。

aws.amazon.com

eksctlを使ってスポットインスタンス(もしくはMixed-Instances)のNodeGroupを作成するには、eksctlのコマンドオプションだけでは難しいので、ClusterConfigを作成する必要がある。labelとtaintsを同時に作成しているけど、これは午前のWorkshopと同じなので言及は割愛。

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
    name: eksworkshop-eksctl
    region: $AWS_REGION
nodeGroups:
    - name: dev-4vcpu-16gb-spot
      minSize: 0
      maxSize: 5
      desiredCapacity: 1
      instancesDistribution:
        instanceTypes: ["m5.xlarge", "m5d.xlarge", "m4.xlarge","t3.xlarge","t3a.xlarge","m5a.xlarge","t2.xlarge"] 
        onDemandBaseCapacity: 0
        onDemandPercentageAboveBaseCapacity: 0
        spotInstancePools: 4
      labels:
        lifecycle: Ec2Spot
        intent: apps
      taints:
        spotInstance: "true:PreferNoSchedule"
      tags:
        k8s.io/cluster-autoscaler/node-template/label/lifecycle: Ec2Spot
        k8s.io/cluster-autoscaler/node-template/label/intent: apps
        k8s.io/cluster-autoscaler/node-template/taint/spotInstance: "true:PreferNoSchedule"
      iam:
        withAddonPolicies:
          autoScaler: true
          cloudWatch: true
          albIngress: true

ちなみにスポットとオンデマンドを混ぜるときには、結構工夫が必要。labelやtaintsをそれぞれで分けなくてはいけないから。CloudFormation側でコントロールする場合には、UserDataの中で下記のように スポットインスタンスかどうかを判断してあげて、Bootstrap.shにわたすコマンドオプションを分ける必要がある。

            ilc=`aws ec2 describe-instances --instance-ids  $iid  --query 'Reservations[0].Instances[0].InstanceLifecycle' --output text`
            if [ "$ilc" == "spot" ]; then
              /etc/eks/bootstrap.sh ${ClusterName} ${BootstrapArgumentsForSpotFleet}
            else
              /etc/eks/bootstrap.sh ${ClusterName} ${BootstrapArgumentsForOnDemand}
            fi

午前にあったのと同じくスポットインスタンス削除のhandlerを入れるのですが、午前中に提示されたOSSと違ったので、少し戸惑いました。せっかくなので、聞いてみたのですが、どうやら午前中に提示されたものを使用するべきみたいです。どうやらコードのベースは同じみたいなのですが…。

ちなみに今回提示されたものは自分が現在使っているものでこちら(今後は保守されない…?)

github.com

今後はこっち使ったほうがいいよと言われたのがこちら

t.co

その後

サンプルアプリケーションのデプロイとHPAとCAの導入を行いました。

感想

すごく丁寧なWorkshopでした。スタッフの方もかなり親切に声をかけてくれました。最後にスポットインスタンスのステッカーをいただけたのですが、非常に可愛いステッカーで気に入っています。

【AWS Re:Inventレポート】CON206-R2 - [REPEAT 2] Management and operations for Amazon EKS

Management and operations for Amazon EKS

朝はDr. Werner VogelsのKeynoteを開始から1時間位みてきました。Firecrackerはcontainerdをベアメタルサーバごとに共通化させていて、それもオープンソースとして開発しているなど、非常に面白かったです。FargateとEC2の比較なんかも動画だとかなりわかりやすくてよかったです(本当に?とも思いましたが…)。 ほんの少しだけ、Getting Started on Kubernetesをかぶる内容もありましたが、EKSでスポットインスタンスを使う方法やロギングでEFK構成を取る方法などをWorkshopで学んでいきました。
実はCON203/CON205/CON206は続けて取ると丁度よくEKSのWorkshop全てを網羅出来るみたいです。
ちなみにこのセッション、Walk-Upで行こうと思って並んで腰をおろしてPC開いたら予約できるようになっていました。予約して部屋戻って休憩できたので良かったです。

導入

他のWorkshopと同じようにチームハッシュの書かれたシールを貰って、https://dashboard.eventengine.run/にアクセスしてハッシュ打ち込むのかなと思っていたんですが、シールが用意されていませんでした。こういったケースもあるんですね。チームハッシュの書かれた紙をスタッフの方が持っていて、その方が「これだよー」と提示して頂いて確認します。自分は写真を撮りました。

Workshopの流れ

他のKubernetesのセッションは3回目になるので、セットアップはかなりすんなり行きました。ここで結構詰まってしまう方が多いのと、eksctlクラスターを作成するまでに時間がかかるので、CON203と同じく質問コーナーが設けられました。
EKS on Fargate発表後というのもあり、そのへんの質問が多かったように感じます。Twitterでも議論になっていましたが、「Daemonsetは使えなくなるので、FluentdコンテナとかはSideCarコンテナで」など、EKS on EC2でのマニフェストをそのまま適用できるかというとそうでは無いようです。
資料は下記

eksworkshop.com

Health Checks

正直に言いますとここはEKSの話というより、純粋なKubernetesでの話なのでMustではないのかなと感じました。内容としてもベーシックな内容でした。

Using Spot Instances with EKS

EKSでSpotInstanceを上手く使う方法ですね。この辺を知りたくて来ました。このセッションでは、スポットインスタンスのNodeGroupを別で作成しています。作成の際にlifecycle=Ec2SpotというlabelとspotInstance: true:PreferNoScheduleというtaintsをつけています。これを上手く利用します。
taintsはtolerationsという概念とともにKubernetesで扱われる機能の一つです。Node側からSchedulingされるpodを制限できるのが強みです。pod側のnodeSelectorだと何も指定しなければ、どこのNodeでもスケジューリングされてしまいます。今回のケースでは、pod側でspotInstance: trueというtolerationsを持っていないものは、スポットインスタンスのnodeGroupには、スケジューリング出来ないことになります。taintsについているPreferNoScheduleはeffectと呼ばれるもので、Taintsを許容できないpodはSchedulingするのをなるべく避けるというものなっています。

SpotInstanceはTerminateの2分前にEc2メタデータを通して通知を行います。それをキャッチしてハンドリングしないと、いきなりpodが死ぬことになります。そこで下記のものを使います。11月くらいからCommitが始まっているのでかなり最近のプロダクトになると思います。
Terminateの通知を受けとったら、ノードにTaintをつけて他のpodがSchedulingされないようにします。その後に、Drainを行うことでpod内の各コンテナにSIGTERMを発行し、Graceful Shutdownを促します。

t.co

このDaemonSetはデフォルトで全てのNodeにSchedulingされますが、lifecycle=Ec2SpotというlabelのついたものだけにSchedulingされるように変更したほうがいい。

そしてサンプルアプリケーションfrontendのマニフェストで、Spotinstanceのtaintsを受容するようなtolerationsを設定し、nodeAffinityでlifecycle=Ec2Spotのラベルが付いたノードに優先的にスケジュールするように変更する。frontendのアプリケーションのみスポットインスタンスで運用されるようになった。

Logging with Elasticsearch, Fluentd, and Kibana (EFK)

まずElastic Search Service(ESS)を構築します。自分は業務でESSに触ったことがなかったので新鮮でした。
それとは並行して、fluentdのdaemonsetを作成していきます、一つ驚きだったのは、fluentdのdeploymentです。fluent/fluentd-kubernetes-daemonsetのimageかつ、fluentdの設定をConfigMapで持つ場合には、多少工夫をしなくてはいけないようです。initContainersでConfigMapをマウントして、/fluent/etc配下にコピーする必要性があるようです。 (コンテナを扱うものとして恥ずかしくて仕方なかったものとしては/var/log/containers/*.logにコンテナのログが吐かれることを知らなかったことです)
このDaemonSetが稼働するようになると、CloudWatchにデータが流れるようになります。
CloudWatchの画面の「Action」ボタンからStream to Amazon ElasticSearch Serviceを選択するとESSに流せるようになります。簡単!ただそのデータ投入はLambdaを使ってやるようで、Roleの準備とコストの考慮が必要になります。

いざKibanaにログが入るとどうでしょう!?バージョン6.3のKibanaの画面きれい…! f:id:jrywm121:20191209185335p:plain

感想

Workshopは質問出来てなんぼという感じがしました。強みはいろんなことを気軽に聞けるところ。
自分の英語力がもっと高ければそういった機会を活かせたように感じました。

【AWS Re:Inventレポート】CON208-R1 - [REPEAT 1] Build your microservices application on AWS Fargate

Build your microservices application on AWS Fargate

Fargateの初心者向けセッションです。
選ぶときに興味のあるトピックであれば、レベル関係なく受けようと思っていたのが良くなかったです。このセッションが4日間で受けたWorkshopのどれよりも簡単で少し物足りない感じがありました。それと疲れが非常に溜まっており体力的に限界だったのもあり、全て終わらせて途中で抜けてきました。

導入

ECS、特にFargateを使う上でどんな利点があるかを説明してくれました。EC2インスタンスを意識する必要が無いとかそんなような説明だったと思います。後は、AWSのプロダクトなので、完全に他のAWSサービスと統合されていてそれが強みとも言っていました。
資料は下記リンクです。

ecsworkshop.com

業務で使っているのはawsコマンドですが、Workshopではecs-cliを利用しました。そういえばECS CLIのv2が出るってコンテナワークロードに出てきていたような…?
CloudFormationでクラスターとALB(+TargetGroup)を作成するところからスタートです。

完成したあとの構成は下記。 f:id:jrywm121:20191207015823p:plain

Workshopの流れ

まずFrontendのRailsのアプリからデプロイしていきます。docker-composeの構文に少し似てますよね。envsubstってなんだろ?って思ったんですが、テンプレートエンジンみたいで、環境変数を埋め込んでくれるようです。普通に使っていきたい。
通常CloudFormationで埋め込むパラメーター周りをecs-cli使うと、コマンド引数に持たせる感じになるようです。ファイルに持たせることも出来るんでしょうか?宣言的じゃないと使うのには躊躇があります。Fargateだと、aws-vpcモードがデフォルトだからか、vpcも指定が必要になってくるようです。自分が注目したのは、--private-dns-namespace--enable-service-discoveryです。

cd ~/environment/ecsdemo-frontend
envsubst < ecs-params.yml.template >ecs-params.yml

ecs-cli compose --project-name ecsdemo-frontend service up \
    --create-log-groups \
    --target-group-arn $target_group_arn \
    --private-dns-namespace service \
    --enable-service-discovery \
    --container-name ecsdemo-frontend \
    --container-port 3000 \
    --cluster-config container-demo \
    --vpc $vpc

ServiceDiscoveryがEnableです。確かECSはRoute53で実現されていたはずと思ってRoute53を見てみます。
Private Hosted Zoneが作成されて、それが--private-dns-namespaceの引数に渡されているものと対応しています。そして、それぞれのタスクがAレコードで入ってきていますね。DNSラウンドロビンで振り分けられる形になるわけです(おそらく…)。ヘルスチェックもRoute53から行われる形になりますね。

f:id:jrywm121:20191207015201p:plain

恐ろしいことにあとこの作業をただただ2回繰り返します。
最後にローカルでのテスト方法を行います。明快でタスク定義をdocker-compose.yamlにtranlateするコマンドがあるので、それを変換してdocker-composeを起動させるだけです。なんだか物足りない…。

感想

このWorkshopは出なくても良かったかも知れません。結局4日間でExpo行けていないので、もっと早めに切り上げてExpo行くなど柔軟に行動すべきでした。

【AWS Re:Inventレポート】DOP201-R2 - [REPEAT 2] DevOps essentials: Introductory workshop on CI/CD practices

DevOps essentials: Introductory workshop on CI/CD practices

米食べたい気持ちが最高潮に達してしまった3日目2つ目のワークショップです。 AWSのCodeシリーズを使ったWorkshopです。CodeBuild/CodeDeployは使ってみたほうがいいんだろうなとは昔から思っていたのですが、仕事に即活きるかとそうではないものだったため、ずっと手を出せずにいました。

Workshopの流れ

最初にDevOpsとは何かという説明から入りました。Shared Responsbilityのお話とかですね。実践するとどんな利益があるのか?頻度の高いDeliveryやReliabilityの向上に約立つなど基本的な内容が多かったように感じます。そこからCodeシリーズを使ってCI/CDはどのように実現できるかというざっくりとしてお話がありました。どのプロダクトがどのフェーズの役割を担っているか説明が終わった後に実際にWorkshopに入りました。

f:id:jrywm121:20191206034518p:plain

資料はGitHubにて既に公開されていました。

github.com

最終的には下記の図のようになります。

https://github.com/awslabs/aws-devops-essential/raw/master/img/CICD_DevOps_Demo.png

前提

一番最初に思わず「?」となってしまうことがありました。Prerequisitesとして、CodeCommitで構成するために必要な鍵を生成しろとあるんですが、Cloud9を使う場合には必要ありません。そして、その直後からCloud9を使います!はて?なぜ必要だったのかいまだに謎です。

起点はもちろんCodeCommitからになります。あまりガシガシとは使えていませんが、正直、GitHubやBitbucketにくらべ、物足りない印象は拭えませんでした。サンプルコードはJavaのようです。

CodeBuild

Codeシリーズで使用するRoleとS3バケットをCloudFormationで作成し、いざCodeBuildの登場です。
CodeBuildはProjectという単位でパイプライン群を分けていくようです。このプロジェクトでは、ソースとなるコードとアウトプットになるS3バケットが同じになるので、リポジトリと1対1で紐づくイメージを持っています。Jenkinsとかで言うところのパイプラインに相当すると認識です。また、実行する環境(Dockerイメージ)も共通となります。今回はJavaがインストールされたコンテナイメージを使用しています。
buildspec.yml というファイルを作成し、その中にビルド工程を宣言していくようです。実はJenkins以外のCI/CDをあまり使ったことが無いのですが、yamlで書くのはすごく今どきって感じがしますよね。GitHub ActionsやCircle CIがそうなので。
.artifact.filesで指定したものが最終的にzipに固めてS3にアップロードされます。

version: 0.1

phases:
  install:
    commands:
      - echo Nothing to do in the install phase...
  pre_build:
    commands:
      - echo Nothing to do in the pre_build phase...
  build:
    commands:
      - echo Build started on `date`
      - mvn install
  post_build:
    commands:
      - echo Build completed on `date`
artifacts:
  files:
    - target/javawebdemo.war
  discard-paths: no

CodeCommitの直下にあるbuildspec.yml を読み取るので、作成したファイルをgit pushして上げて、CLIからaws codebuild start-build --project-name devops-webapp-projectってな感じです。CloudWatch Eventをトリガーにすることも出来るようですね。マージとかを契機にするには、その辺を組み込まなきゃいけないのが若干手間に感じました。

CodeDeploy

EC2インスタンスVPCを作成するCloudFormationを展開させます。なおEC2のUserDataでCodeDeploy Agentがインストールされているそうです。
deployment-groupというのを作っていきます。Applicationという括りの中にあって、どうやら本番・検証などのステージごとに作るみたいです。今回はEC2のタグでフィルターを掛けてKey=Name,Value=DevWebApp01を1つのグループとしています。appspec.ymlというファイルでこちらは定義していきます。

version: 0.0
os: linux
files:
  - source: /target/javawebdemo.war
    destination: /tmp/codedeploy-deployment-staging-area/
  - source: /scripts/configure_http_port.xsl
    destination: /tmp/codedeploy-deployment-staging-area/
hooks:
  ApplicationStop:
    - location: scripts/stop_application
      timeout: 300
  BeforeInstall:
    - location: scripts/install_dependencies
      timeout: 300
  ApplicationStart:
    - location: scripts/write_codedeploy_config.sh
    - location: scripts/start_application
      timeout: 300
  ValidateService:
    - location: scripts/basic_health_check.sh

合わせてbuildspec.ymlを修正します。直でCodeDeployが指定できるのはいいですね。どっちもAWSがやっている強みが出てますね。

f:id:jrywm121:20191206120955p:plain

CodePipeline

はいやっとパイプラインで統合できます。
これはGUIで作成していきます。これは本当に要求されるまま一つ一つ設定していくだけでした。
その後は本番用にdeployment-groupを作成し、Manual Judgmentを組み込みました。

f:id:jrywm121:20191206122216p:plain

感想

CodeStarというのを使えばこれらが一発ででき出来上がるというので、そちらも試してみたくなりました。普通に使い勝手が良かったような印象はあります。EC2へのデプロイだったので、ECSやEKSで使いますか?と言われると首を捻ってしまうかもです。

【AWS Re:Inventレポート】AIM223-R4 - [NEW LAUNCH!] [REPEAT 4] AWS DeepComposer: Get started with generative AI

AWS DeepComposer: Get started with generative AI

火曜のKeynoteの後に見たら偶然予約できました。おそらく新セッションが出てくるタイミングでUnreservedされた座席があったのだと思います。Walk-Upの列はとんでもないことになっていました。

正直、機械学習についての知識が全くない状態ではWorkshopの後半は、shift+Enterを繰り返すだけのただの人形と成り果ててしまいます。自分は人形と化しました。 悲しいですね。

GANsに関する説明

機械学習は3つに分類されるというお話から始まりました。正直自分が知っていたのはこのレベルまでです。

その中でGANsはUnsupervised learningに分類されるものだそうです。
generatorとdiscriminatorという2つのネットワークを利用するそうな。generatorはその名のとおり、物を生み出す側で、DeepComposerでは音楽を生み出します。discriminatorはそれを評価してフィードバックすることで、よりクオリティを上げていくというものだそうです。説明の中では、オーケストラに例えていました。generatorは演奏者たち、そしてdiscriminatorは指揮者にあたるもののようです。素人でもどこか腑に落ちる(ような気持ちになる)説明でした。

軽く説明を受けた後に簡単な小テストが行われました。上位に入るとスピーカーがもらえたようです。テスト自体は結構簡単だったのですが、なにより速さが足りない。スピーカーをもらうことが出来ませんでした。

サンプルのモデルでGANsを体験してみる

AWSコンソールからDeepComposerのページに飛んでみます。アカウントを頂いたのですが、どうやらre:Invent最終日の24時まで有効なようです。SageMaker使う部分に関してはお金かかると思いますし、結構複雑なアーキテクチャ組んでたので太っ腹ですね!

DeepComposerをPCにつなげて、実際に弾き、それを録音することで音をインプットさせます。そのインプットした音を、モデルを用いてアレンジさせます。サンプルのモデルとして用意されていたのは、「Pop」「Rock」「Symphony」などの5種類です。
みなさん思い思いにDeepComposerを奏でて、モデルによってアレンジさせていました。

SageMakerを利用してモデルを作ってみる

恥ずかしながら、まったく分かりませんでした!

SageMakerからJupiterNotebookを起動させると、音楽生成GANsに関する基礎知識とそれに対応するPythonの構文がざーっと書かれていました。一応それぞれGoogle翻訳にかけて読みましたが、後半はわからない単語の応酬でなかなか厳しいものがありました。

かろうじてわかったのはモデルを生成する部分のAWSアーキテクチャのみでした。

f:id:jrywm121:20191206032558p:plain

DeepComposerは無事ゲットすることが出来ました!セッションを受けてると、SWAG行ったときに貰えるようです。めちゃめちゃ嬉しい。

【AWS Re:Inventレポート】HAC301-R1 - AWS GameDay: Main event countdown (PM)

AWS GameDay: Main event countdown (PM)

2日目の午後からは、GameDayに参加してきました。
午前中は何をしていたかというとAndy JessyのKeynoteを見てきました。プレゼンの合間に生バンドの演奏が挟まり、それぞれのトピックのトレンドを象徴するかのような曲が流れました。例えば、QueenDon't Stop me nowなど…。いろんな発表がありましたが、個人的に周囲含め一番盛り上がったのはEKS on Fargateでした。あとAWS Graviton第2世代のM6gインスタンスにはとても期待を持っています。

GameDayが始まる前に

アメリカに渡ってきてからの2日間で自分が思ったより英語の聞き取りが出来ないこと、言葉も全然思ったように出てこないことを認識していました。そのため、チームを組んだときに言語の壁で足を引っ張ってしまうのでは無いかと心配でした。もし、日本人4人で出れると有り難いなーなんて思っていたら、直前でなんとか組むことができました。自分はチームの他のメンバ全員と初対面でしたが、皆さん優しくて非常に助かりました。

GameDayで大変だったこと

内容とか書こうと思ったんですが、外部に垂れ流していいやつか分からなかったので、ぼやかします。 システムの構成が中途半端になっているので、その部分の補完を行い、来る高トラフィックに備えるというのが趣旨でした。サービスの1つはEKS上で構築されていたので、自分がそこを担当することになりました。EKSやっているのが活きて本当に良かったです。
単純にそれだけなら簡単なんですが、妨害が入ります。ネットワーク層での構成がゴリゴリ変えられて、普通にサービスダウンしました。そういった妨害が入ることが頭に無かったので(説明をちゃんと聞いてなかった)、「ぼくなんかやってしまった?やってしまったの?」とパニクりました。特に踏み台にアクセスできなくなり、NewRelicにもデータ飛ばなくなったときはパニック最高潮でした。
結果、指揮を取ってくれていた方が自分にヒントをくれたおかげで原因に気づくことができました。気持ちよかったです。

GameDayで得られたもの

普段触らないサービスに触れたのは良かったと思います。良かった反面、やはり使い慣れていないサービスを使うのはかなり難しそうで、チームの方の中の一人はその部分に注力してくださっていたのですが、ハマりポイントもあったようで本当に大変そうでした。

思い込みがいろんな問題の解決を遅くしてしまったように感じます。普段の障害調査もこういったふうに思い込みのせいで原因究明に行き詰まってしまっていたことがもしかしたらあったのかもと思いました。気づきを得られたのはとても良かったです。

あとニット帽を得ました。かわいいです。

結果

80ぐらいいるチームの中で22位でした。一時は1位だったときもあったので悔しいですが、後半一度かなり落ちたので盛り返せたほうかなと思っています。AWS Summitでやってほしいなと思う内容でした。

チームメンバの方とはJapan Nightでそのままお話出来たのでとても嬉しかったです。

f:id:jrywm121:20191205073028p:plain

【AWS Re:Inventレポート】CON209-R - [REPEAT] Using AWS App Mesh to monitor and control your first containerized app

Using AWS App Mesh to monitor and control your first containerized app

1日目としては3回目のWorkshopになります。Walk-Upで着いたのが30分前くらいだったのですが、すんなり入れました。Bellagioが会場だったのですが、セッションが少ない会場の一つだったためWalk-Upが増えにくいのかもしれません。賭けに出て良かった。
ちなみに列で待っていたときに、WeaveWorksのお兄さんらしき人がルービックキューブをくれました。 かわいい。

f:id:jrywm121:20191204223546p:plain

ざっくり言うとAppMesh導入したらどうなるの的な話でした。なんだか講師陣も優しく、声をかけてくれるしとても暖かかったように感じます。当たり前なんですがWorkshopでも会場や雰囲気によって温度感が全然違いますね。
あと、EKSのWorkshopのときにも思ったのですが、Workshopの会場はディスプレイ用意されていることが多いです。つなげるコード持ってくのがいいと思いました。自分はそもそもアメリカにも持ってきていないので断念しています。

Workshopの流れ

ECS, EKS, EC2 の順にそれぞれに対してAppMeshの導入を行いました。
実は最後にCloudMapも残っていたのですが、時間が余っているにも関わらず切られてしまいました。正直、CloudMapでサービスディスカバリしたかったです。自分でやるしか無いかと思ってはいますが、無料利用枠に入っているのか割と不安です。
EKSのときのWorkshopと同じでCloud9のセットアップから行っています。

資料はこちら

www.appmeshworkshop.com

ベースラインのスタック作成

AppMeshを導入する前+Kubernetesリソース作成する前の構成はCloudFormationで作成していきます。フロントエンドのRubyはEC2のAutoScalingGroupで、バックエンドのCrystalがFargateとEKSクラスターという構成でデプロイされます。ASGとFargateの前には当然ながらロードバランサもいます。
自分がやったときには既にスタックは作成されていて実際に作成というのは行われませんでした。

https://www.appmeshworkshop.com/images/app_mesh_architecture/AppMeshWorkshop.png

NodeJsサービスのデプロイ

既に存在するEKSクラスターに対して、nodejsのサービスをデプロイしていきます。DeploymentとServiceをapplyするだけの簡単なお仕事です。その後に、フロントエンドのサービスからアクセスできるように、Route53にServiceリソースの向き先の入ったレコードを追加します。
フロントエンドのサービスのELBにアクセスすると、下記のような画面が表示され、3つのサービスが構成されていることが確認できます。

f:id:jrywm121:20191204231206p:plain

Crystal(Fargate)のメッシュ化

メッシュの作成

まずaws create-meshコマンドでメッシュを作成します。名前はappmesh-workshopとしています。「サービスメッシュはその内部に存在するサービス間のトラフィックの論理境界」としかその後の説明にないんですが、あまりピンと来ません。このコマンドでやっているのは結局コントロールプレーンの作成なのではと勝手に思っています(どうなんでしょう?)。

Virtual Serviceの作成

Virtual ServiceはVirtual Nodeによって提供されるrealなサービスの抽象化とのこと。…分からないです。Virtual NodeはASGやAmazon ECS Service, Kubernetesのdeploymentなど、特定のタスクグループへの論理ポインタを指す。これは分かりやすい。serviceDiscoveryの設定やlogging、listener(healthcheck)などの設定ができることからも非常に分かりやすい。そのVirtual Nodeを作成した後に、対応するVirtual Serviceを作っていく。Virtual Serviceに設定するのはVirtual Nodeの名前とサービス名にあたるFQDN。 今回はサービス名としてcrystal.appmeshworkshop.hosted.localを指定したので、Virtual Serviceの作成によってappmeshworkshop.hosted.localというprivate hosted zoneが作成され、Aレコードとしてcrystal.appmeshworkshop.hosted.localが登録されます。

Envoy Proxyの作成

AWSのAppMesh統合ではiptableを書き換えることでコンテナへの通信をインターセプトしているそう。Crystalのポート3000に通信がきたら、代わりにEnvoyがリッスンする15000ポートに流します。処理した後はEnvoyからCrystalへ通信を転送します。そのためレスポンスもEnvoyを通すことになります。
タスク定義にサイドカーのEnvoyの定義を追加してあげるだけはなく、proxyConfigurationというものも構成します。ここでTYPE: APPMESHを指定することで、指定したcontainerNameのコンテナに通信をインターセプトして流す形になります。
フロントエンドRubyのEC2にsshしてcrystal.appmeshworkshop.hosted.localに対して通信を行うと、Fargateの手前のinternal ALBに対して通信されます。curl -vで確認するとEnvoyから通信されていることが確認できるという流れになるようです。

NodeJS(EKS)のメッシュ化

メッシュ自体は既にappmesh-workshopという名前で作成されていますので、Vitrtual Serviceの作成とEnvoy Proxyの作成という形になるかと思います。

HELMでApp Mesh用のパッケージ導入

AppMesh用のCRDをapplyしていきます。リソースは下記リンクです。その後にhelmでeks/appmesh-controllereks/appmesh-injectというパッケージをインストールします。後者はmutating admission webhookらしいので、おそらくマニフェスト登録したときに、勝手にEnvoy Proxyを注入してくれるやつです。

github.com

Virtual Serviceの作成

Virtual NodeもVirtual ServiceもCRDで先程定義されたので、マニフェストをapplyして作成完了です。Virtual Serviceはパスルーティングも可能なんですね。小出しにそういう情報を出してくれるあたりが憎いです。kubectl label namespace appmesh-workshop-ns appmesh.k8s.aws/sidecarInjectorWebhook=enabledでnamespaceにlabelingすると、admission webhookが有効になるようです。podをdeleteするとenvoyがある状態で上がってきます。フロントエンドRubysshすると、Virtual Serviceリソースの.metadata.nameに記載したFQDNでアクセスできます。

Ruby(EC2)のメッシュ化

ECSのときと同じようにawsコマンドでVirtual NodeとVirtual Serviceを作成します。SSM Agentを使用して、Envoy Proxyを注入することで作業は完了です。
SSM Agentに関する知識が無かったので、ここは脳死でコピペしていました。

Loggingの有効化

Container InsightとX-rayの有効化を行いました。ECSはタスク定義のログ定義とX-Rayサイドカーコンテナの注入、KubernetesはContainer InsightのデプロイとHelmでX-rayのパッケージをインストールすることで出来ました。

感想

AppMesh全然わからんという状態からちょっと分かる状態に持っていけるのは、Workshopのいいところですよね。CloudMapもやりたかった惜しい!