Skaffoldで誰でも簡単に開発を始められる世界に

こんにちは。
株式会社ユーザベース SaaS事業 板倉です。

私たち Product Teamではkubernetesを用いた開発・運用を行っています。
今回はkubernetesを用いた開発をする際に利用しているSkaffoldについて書いていこうと思います。

Skaffoldとは

Skaffoldを端的に説明すると、kubernetesを用いた開発プロセスを容易にするツールです。
Skaffoldのサイトには以下のように説明があります。

Skaffold handles the workflow for building, pushing and deploying your application, allowing you to focus on what matters most: writing code.

https://Skaffold.dev/

Skaffoldを使うとイメージのビルド、プッシュ、デプロイを行ってくれます。私たちはコードを書くことに集中することができます。

私たちProduct TeamとSkaffold

Product TeamでSkaffoldを導入し利用し始めたのは2021年8月頃です。

導入前はそれぞれのステップでシェルスクリプトを作って実行していました。

  1. ソース + Dockerfileでイメージをビルド (build.sh)
  2. kubernetesにデプロイ (deploy.sh)
  3. デプロイされたServiceに対してport-forwardを設定 (port-forward.sh)

導入後は上記1~3が skaffold dev --port-forward を実行するだけになりました。
しかもプロセスを止めるとkubernetesからリソースを削除してくれます。これにより不要なリソースが残り続けることがなくなりました。

私たちの開発プロセスについて

実際にどう使っているかを説明する前に、まずは、私たちが採用しているマイクロサービスアーキテクチャに則った開発プロセスを簡単に紹介しようと思います。

何かのAPIを開発する際に別のAPIやDBを使用しているケースがほとんどです。
例として、あるユーザーストーリーを実現するためにxxxx-api、yyyy-api、zzzz-apiの3つのAPIの開発を行います。
以降、下の絵をもとに説明していこうと思います。

API構成の例

私たちはエンドツーエンドのテスト(以降E2E)をまず書き、次に実装するというTDDを採用しています。
E2Eを実行する際は全てのAPIがkubernetes上で実行し、テストを流します。

E2E実行時のテスト実行環境とAPI実行環境の関係

次にAPIの実装に移りますが、ここではAPI自体はホストマシン側のプロセスで実行しながら依存するものだけをkubernetes上で実行します。

開発時の開発対象と依存関係にあるAPIのイメージ

最後にE2Eを実行するために最初のステップと同様、全てのAPIをkubernetes上で実行しテストを流します。
テストが通ればこのxxxx-apiの開発は終わりです。

ユーザーストーリーを実現するにはyyyy-apiやzzzz-apiの開発も行わないといけません。
yyyy-apiやzzzz-apiについても上記の流れで開発を行なっています。

実際にどう使っているか

これからskaffoldをどのように使っているかを説明します。

Skaffoldはこちらの例にもあるように複数のAPIについてまとめて定義することが可能です。

https://github.com/GoogleContainerTools/skaffold/tree/main/examples/microservices

私たちもこの仕組みを使い、依存関係のものを個別に立ち上げることなく簡単にE2Eと実装を行うことができるようにしています。
今回は上記の例とは別のやり方を紹介したいと思います。

requiresを使った例

先ほどの例と違うのは、APIとDBをそれぞれ個別のskaffold.yamlに定義します。
プロセスに合わせたskaffold.yamlを作成し、必要に応じて依存関係 (requires)にAPIやDBを追加します。
次の図はe2eを実行する際に使用するファイルの例です。 e2eでは全てがkubernetes上で実行したいので、依存関係に全てのファイルを設定します。

skaffold.yaml(e2e実行用)

e2eを実行する際のYAMLを実際に書いてみると以下のようになります(上図で言うと赤いファイル)。

apiVersion: skaffold/v4beta7
kind: Config
requires:
  - path: xxxx-api/skaffold.yaml
  - path: xxxx-db/skaffold.yaml
  - path: yyyy-api/skaffold.yaml
  - path: zzzz-api/skaffold.yaml

(個別の各skaffold.yamlについては省略します)

開発時に使うYAMLは上記のe2eで使うファイルからxxxx-apiをrequiresから除外したものを利用します。
私たちがこのやり方でファイルを作成する際は、以下のようにプロセスに合わせてファイルを作っています。

プロセス ファイル名
開発 deps.yaml
E2E e2e.yaml

必要に応じて使うファイルを指定するだけでよく、基本的に実行時に必要なオプションはe2e、開発で同じです。 skaffold dev -f deps.yaml --port-forward -n xxxx

マイクロサービスの例 とこちらでどちらが良いというのはないと思います。
それぞれメリットデメリットがあると思うので、自分たちのチームや開発プロセスに合わせて使いやすい方法を取り入れることが大事ですね。

導入前と何が変わったか

Skaffoldが全てのシェルの代わりをしてくれるようになリました。
Skaffoldの公式サイトでも書かれていますが、git cloneskaffold runをするだけで誰でも簡単に開発を始められるようになりました。

share with other developers - Skaffold is the easiest way to share your project with the world: git clone and skaffold run

最後に

今回はSkaffoldの紹介とマイクロサービス開発での使用例を書いてみました。
git cloneskaffold run を一度体験していただけると Skaffold のありがたさを実感できると思います。
機会があればぜひ試してみてください。

Page top