はじめに
本連載は、WANTEDLY TECH BOOK 2を抜粋し、再編集したものになります。第1回と第2回の担当は、Wantedly インフラチームの坂部(@koudaiii)です。第1回である本記事では「変化に強いインフラはWantedlyにとってなぜ必要か」「これまでどのように変化に強いインフラに取り組んできたのか」といったことを中心にご紹介します。第2回では、例として架空のサービスを実際に作る上での手順を紹介する予定です。
変化に強いインフラの必要性
Wantedlyのインフラチームは「変化に強いインフラ」づくりを目指しています。変化に強いインフラとは、どういった状態を指すのでしょうか。その話をする前に、まずはWantedlyが大事にしている文化の一つを紹介します。
Code wins Arguments
Code wins Arguments は、仮説を証明するために何時間も議論するのではなく、実際に動くものを作ってユーザーの反応を確かめてみようという姿勢のことです。限られた情報の中で「決断」を繰り返し、失敗しても、そこから学びを得て、どんどんと前に進んでいくことでプロダクトも組織も成長していくと考えます。
インフラチームでは、このCode wins Argumentsを可能にするインフラづくりが求められています。そのため、以下2つを可能にする取り組みを行っています。
- 既存のアプリでも新規アプリでもどんどんデプロイできる
- 議論や権力ではなく、まず出してみて結果を見る文化を可能にする
変化に強いインフラとは、変化を避けるインフラではなく、むしろ変更を前提としたインフラを指します。インフラチームではCode wins Argumentsを可能にするインフラを実現するため変化に強いインフラが必要と考え、日々改善に取り組んでいます。
変化に強いインフラの取り組み(1)
セルフサービス化
既存のアプリでも新規アプリでも、どんどんデプロイを可能にするためには大きな課題がありました。デベロッパーが創造したプログラムをインフラチームに依頼しないとデプロイができない仕組みになっている点です。
Wantedlyがスタートした頃は、デベロッパーの人数とサービスが今ほど多くはなく、その都度インフラチームがデプロイの仕組みを構築する運用で問題ありせんでした。しかし、どんどんデベロッパーとサービスが増えるにしたがって、インフラチームの作業待ちが発生するようになり、ボトルネックになっていきました。
プログラムをデプロイする仕組みを作るには、下図にあるような作業が必要です。DNSやLoad Balancer、Cache、DB、Serverの準備といったさまざまな作業をインフラチームが行う必要があり、デベロッパーはインフラチームの作業完了を待たなければなりません。
そこでインフラチームの解決策として、人員を増やすのではなくインフラのセルフサービス化を実施することにしました。DNSやDB、Load BalancerなどをHashiCorp社のOSSであるTerraformを用いることにより、APIを通してリソースを構築できるようにしました。また、アプリケーションの部分についてはDockerを用いて、全てのアプリケーションをコンテナのイメージにし、なるべくデベロッパー側で利用する言語やフレームワーク、バージョンをインフラチームなしで自由に変更できるようにしました。
コンテナ技術(Docker)のメリット
コンテナ技術(Docker)は効率よくリソースを使いながら、どこでも利用可能かつスケールすることが容易です。コンテナ技術(Docker)はVMやサーバーとは異なり、プロセス単位で扱います。つまり、アプリケーションに必要なものを隔離されたリソースで実行する技術です。具体的にはカーネルの機能を使って「隔離された空間でプロセスを実行」「プロセスに対して、リソース制限」を行います。例えば以下のメリットがあります。
- プロセス単位のシンプルな構成
- 一つ一つが管理しやすい
- ミドルウェアを試しやすい/入れやすい
- プロセスの起動の速さ
プロセス単位といったシンプルな構成により、従来の仮想化技術に比べて起動が早く、隔離された空間を利用できます。そのため、コンテナごとにミドルウェアやアルゴリズムをこだわって決めることができます。
デリバリー
Dockerはホストとなる場所がローカルPCでもサーバーでも同じデリバリー方法を使用します。具体的にはdocker pullコマンドを打つだけで簡単にコンテナのイメージを取得できます。また、ローカルPC上で開発したコンテナのイメージをdocker pushし、サーバーに提供することも可能です。
- 作業範囲
- 開発のしやすさ
- リリースのしやすさ
VMベースでは複数のアプリケーションを起動しようとした場合に、ローカルPCのリソースが不足してしまいます。かと言ってローカルPC上で直接アプリケーションを起動させたとしても、利用する各ミドルウェアのバージョンが一致しているとは限りません。違うバージョンのミドルウェアを同時に動かすといった作業が必要です。こうしたリソースの効率化とミドルウェアの依存関係もなるべくコンテナにすることで、シンプルにコンテナを起動するだけで済みます。VMとは違い、必要最低限のプロセスを起動するだけなので、リソースを最小限に保つことができ起動も早いです。
また、Dockerを使ったコンテナ技術は、Dockerfileという単一のファイルで完結するためシンプルです。ファイルの中身はシェルスクリプトのようになっており、上から順番に実行されるため初見の人でも何をやっているのかなんとなく理解することができます。そして、Dockerfileからビルドしたコンテナのイメージは開発環境(development)→テスト環境(qa)→本番環境(production)と、一貫して同じものを利用できます。ローカルPCでもサーバーでも基本的にdocker runをすることでコンテナが起動するだけなので、うまくデリバリーのフローを抽象化させてくれます。