コンテナを取り巻く環境を振り返る

九岡佑介氏(以下、九岡):こんにちは。さっそく始めさせていただきます。九岡と申します。freee株式会社でSREの仕事をしています。ソフトウェアエンジニアなんですが、自称しているのはOSSデベロッパーです。

freeeの仕事以外にチャットワークという会社で技術顧問もしています。GitHub、Twitterはmumoshuという名前でやってます。

三度の飯よりOSSのメンテナンスが好きで、趣味と実益を兼ねてkube-awsというKubernetesのインキュベータのプロジェクトのメンテナーをしているのと、そのほかにAzureのbrigadeなど、さまざまなコミュニティを作ってKubernetes関係のOSSをメンテナンスしてます。

今日はKubernetes on AWSだけじゃなくて、それとAWSで利用できる、似たような用途で使えるサービスとを比較しながら使い分けの話をしようと思ってます。

ですが、ポイントになるのがコンテナなのでまずコンテナを取り巻く環境についてみなさんにお話ししようと思ってこんなスライドを作りました。

僕の中でコンテナの話をしようとするとこんないろんなワードが頭に浮かびすぎて、まぁよくわからないんですね。もうなにから話したらいいのか。なので今日はこれだけに話を絞ってお話ししようと思います。

このあと幸いにもASKコーナーがあるそうなので、もしこの中で「具体的なとこぜんぜん書いてないやん」と思われた方はASKのコーナーに来ていただければもっと具体的な話を、泣くまでします。ぜひご活用ください。

(会場笑)

今日持ち帰っていただきたいことはこれだけです。

「Right Abstraction. Right Tool.」ということで、みなさんには抽象レベルの違いを意識できるようになっていただこうと思ってます。

上からで申し訳ないんですが、仮想マシンとコンテナと関数の使い分けの話と、それを踏まえて今後正しいツールを選べるようにです。

最初に言っておきたいのは、Kubernetesは銀の弾丸ではありません。こんなこと言うと自分の首を絞めるようですが、まず、仮想マシンとコンテナと関数とアプリケーションを、みなさんどうマネジメントしようとしているかという話を踏まえながら適切なものを選べるようになっていただきたいと思ってます。

逆に話さないことはこんなことです。

Kubernetesの歴史や特定ツールの使い方、Kubernetesとほかのものの比較などです。つまりググったほうがわかるようなことはお話ししません。話してたら止めてください。

それから話すことは、仮想マシン、コンテナ、関数の使い分け。繰り返しになりますがこれです。あとfreeeの事例を少しだけお話するのと、主題のECSとKubernetesとFaasの使いどころについて。

Faasはほとんど単語あげただけでみなさん考えてくださいって感じになるかもしれないですが、使いどころの話をして、ツールの選定にも少し触れられればと思います。

Kubernetesの登場

アジェンダに戻りますが、今お話ししたのがコンテナを取り巻く環境の話です。これからKubernetesの概要の話をしたいと思います。

Kubernetesの概要。一応AWSのサミットなので、AWSのことはみなさんご存知という前提でお話しします。Kubernetesについてよく知られていることはこれです。GoogleのBorgというシステムが起源になってて、いわゆるコンテナオーケストレーションシステムって呼ばれるものです。

公開されたのは2014年。もう4年前ですね。2年前の2016年にバージョン1.0に到達してます。プロダクションレディってことですね。

もともとCloud Native Computing Foundationという財団で管理されていたんですけど、今年それを卒業して独立したプロジェクトになりました。それぐらいメジャーなプロジェクトってことですね。

Kubernetesについてよく知られてないことが一個だけあるんです。これをみなさんに質問したいと思います。みなさん考えてくださいね。

なぜKubernetesを使うべきじゃないのか? これに即答できる人がいたら、聞かなくても大丈夫です(笑)。またはなぜFaaSを使うべきかってここでは書いているんですが、まあFaaSのところにはいろんなものが入ります。

なぜKubernetesを使うべきじゃないかという話をすると、必然的になぜコンテナを使うのかと、なぜAmazonにもともとあるECSを使うかという話に行き着きます。

スタートアップの課題トレンド

では、オーケストレーション以前に、なんでそもそもコンテナなのかという話ですが。けっこう話題がジャンプするのでみなさんついてきてくださいね。

スタートアップにおける課題のトレンド。僕はスタートアップで働いているので、そういう文脈でKubernetesを見ています。課題のトレンドは、「生産性が上がりません」って話と「エンジニアが足りません」という話です。

生産性というのは、すごい勢いでスタートアップの組織が広大きくなってくるとチーム間の調整コストが高いとか、意思決定に時間がかかるとか、言語とかエディタとかの宗教戦争が起きがちとか。道具にこだわりたい派とかアウトプットにこだわりたい派とか両立したいという欲張りな人とか、いろんな人がいます。

あと、エンジニアが常に足りません。エンジニアの売り手市場なんですが、だからこそ人権費が高沸しますし採用したいけど来ないとか高いとかいろいろあります。

この文脈でMicroservicesアーキテクチャとリモートワークがすごく来てるなという感じがしています。なぜかというと、Microservicesアーキテクチャをすると機能ごとではなくてサービスごとのチームにして、その間はAPIとかで疎結合にして、それぞれチームで独立して働くことができます。

なのでMicroservicesアーキテクチャを使うと、さっき言った「生産性が上がらない」という問題の解決になるんじゃないかという文脈でよくMicroservicesアーキテクチャは取り上げられています。良し悪しは別としてですよ。

あとはMicroservicesアーキテクチャを突き詰めるとPolyglotにできるんですね。言語やフレームワーク選定の自由。さきほど言った宗教戦争がすこし緩和されます。もうすこし言いたいことはありますが次に進みます(笑)。

リモートワーク、これは分散チームの流れですね。若者がチャット慣れしてきてコミュニケーションツール、ChatworkやSlackなどいろいろありますよね。GitHubだけで開発を進めるような会社も出てきました。そういうツールが増えてきたので、必ずしも東京にチーム全員がいなくても同じサービスをみんなで作ることができるようになってきました。

これが「エンジニアが足りません」という問題の解決になるのではないかという文脈で、リモートワークが採用されはじめているように僕には見えています。

仮想マシン・コンテナ・関数の違い

そうした前提でお話を進めていくと、我々はビジネスでSaaSを作っている会社なので、コンピューター上で人のお役に立つものを作ってビジネスをしているわけです。

じゃあ、結局何をやればいいかと言うと、どこかのコンピューター上で我々が作ったソフトウェアを動かすというのは絶対避けて通れないですよね。だとすると、それをどの抽象レイヤー以降でやるかという話があります。

物理マシンを使ってもいいし、仮想マシンを使ってもいいし、コンテナで同じものを動かしてもいいですよね。関数に分けられるなら関数を使ってもいいでしょう。

なんですが、その違いってそもそも何なのか? これは使い分けを考えるうえでは欠かせません。Microservicesアーキテクチャの文脈で言うと、仮想マシン、コンテナ、関数、こんな違いがあると僕は思います。

仮想マシンは言わずと知れたAMIと言われるマシンイメージから作ったりしますよね。物理マシン上で動いてます。でも物理マシン上で動いていることを意識することは少ないかもしれません

あと、1つのマシンで複数プロセスを動かしたりしますね。複数チームのサービスが1つのVMにうっかり乗っちゃったりして、「この機能だけこのサーバーを切り出したいよね。そうすると個別にスケーリングできて嬉しいよね」とか。そういうモチベーションが高まってくると、ある日「コンテナやりたいよね」ってなることがあります。

コンテナはコンテナイメージから作ります。まあ仮想マシンと似てますね。物理マシンか仮想マシンの上でコンテナは動きます。うっかり複数サービスがコンテナに乗ることはあって、そのときにまたVMと同じように「この機能だけコンテナ分割したいな」ということが始まります。

その先にあるのは関数ですね。スクリプトやバイナリから、この関数と呼ばれる単位でアプリケーションをデプロイします。これはマシンやコンテナなど、いわゆるLambdaのようなFaaS上で動きますね。うっかり複数機能が1関数にということはもうないはずです。

それを踏まえると、FaaSの新しさというのは関数をデプロイの単位としたことです。それまでは違ったんですね。

繰り返しになってしまうかもしれませんが、言い方を変えると、マシンへデプロイされるのはアプリケーションバンドルでした。warとかtarballとかrsync元のディレクトリとか、もうちょっとモダン……って言葉はあれですが、コンテナイメージでデプロイしていました。それが関数単位になるんですね。

そうすると「あれ、これまで悩んでたことは全部解決ではないか?」と思うわけです。「FaaS最強では?」と。僕はKubernetesの人という認識ですが、FaaSで済む場合FaaSがベストだと思います。

なぜFunctionでなくコンテナなのか?

ここまでお話したところで、よく知られていないことがもう1個あります。みなさんにまた質問します。なぜ今さらFunctionじゃなくコンテナなのか? Functionのほうがいいんじゃなかったのか? という話なんですね。

運用ツールの違いから見ると、これはわかると思います。例えば仮想マシンを運用しようと思うと、仮想マシンはマシンイメージから作って物理マシン上で動くので、Configration Management、ChefとかAnsibleとかありますね。infra as Codeで管理したりしますね。

コンテナはどうやって運用しましょう。コンテナイメージから作れます。物理マシンか仮想マシンで動きます。DockerとかECSとかKubernetes。やっとKubernetes出てきましたね! こういうもので運用するわけですね。

じゃあ関数はどうするのかと言うと、スクリプトやバイナリから作れます。さっき言いました。マシン、コンテナ、FaaS上で動きます。そうですね、ここからが問題です。Lambdaなのか、OpenFaaSとかOpenWhiskとか、ServerlessってFaaSとどう違うんだっけとか。いろいろ悩みどころが出てきますね。

何が言いたいかというと「Functionのマネジメントってどうしたらいいの?」って、みなさんこの質問に即答できますか?

僕は、考えてまだ即答できないません。だからコンテナを使ってます。関数のオーケストレーションシステムって型とかすごい著名な唯一解ってまだないですよね。

Serverles Frameworkが1番メジャーかもしれないですけど、AWSさんも出てきたし、カバー範囲もそれぞれ違います。僕はまだデファクトがない認識です。だから個人的にはコンテナを使ってますし、たぶんそう考えた人が今コンテナを使っているんだと思います。

まとめますと、なぜ関数じゃなくてコンテナなのか? 我々はそれを使うことがあるか? 比較論で言うと、ツールが揃ってなくて運用が大変だから。これに尽きます。

逆に言うとツールが揃ってなくてもいけるような案件。ちっちゃいマイクロサービスだったらFssSをどんどん活用すべきだと思います。それを使い分けの基準にしていただきたいです。本当に案件と会社とチーム次第ですね。

コンテナオーケストレーションが必要な理由

それでは今コンテナの話が終わりましたので、やっとコンテナオーケストレーションの話をしていきます。コンテナオーケストレーションがどうして必要なのかと言うと、コンテナをデプロイするのにSSHでは済まないんですね。これが1番わかりやすい理由です。

例えば、こんなユースケースを考えてみましょう。「コンテナが落ちたときにほかのノードに自動移行したいな」とかってあるんですね。サーバーが落ちたらそのサーバーで動いている10個のコンテナ全部落ちてサービス落ちました。これは「なんのためにコンテン使ったんだっけ?」ってなっちゃうんですね。

だからほかのノードに自動移行してほしいなってなってくるんですけど。そうするとEC2だとAuto Scalingグループありますよね。コンテナのAuto Scalingグループって何だろう? みたいなことが出てきます。

あとはコンテナをロードバランサにつなぐ。EC2だったらASGにElastic Load Balancerとか。あとALBのTarget Groupとかを差してもらえれば勝手にロードバランスしてくれますよね。

コンテナのロードバランスってどうするんだろう? みたいな。EC2インスタンスをロードバランサにつなぐけどそのポートは、このポートどのコンテナだろ? みたいな話になっちゃうんですね。なのでコンテナオーケストレーションは役立ちますね。

あとは「サーバの余剰リソース内でコンテナ数を増やしたいなー」ってなるんです。例えばすごく大きなEC2インスタンスがあって、1ギガぐらいしかメモリ使わないコンテナが1個しか動いてないです。すごく無駄ですよね。

だったら空いているリソースでコンテナを追加で動かしたい……けれども、それはコンテナではどうするんだろう? ASGだったらちっちゃいEC2インスタンスをたくさん並べてASGでオートスケーリングしましょう。ベストプラクティスあります。でもコンテナはどうなんでしょう? 

あとオートスケーリングですね。これまたASGの話ばっかりで恐縮なんですけど、AWSさんのASGだったら基準とアクションを設定するだけでスケールインもスケールアウトもできますよね。コンテナはどうするんでしょう?

ってなると、なぜKubernetesを使うべきじゃないかという話にまた戻ってきてしまうんですけどね。