PLAY DEVELOPERS BLOG

HuluやTVerなどの日本最大級の動画配信を支える株式会社PLAYが運営するテックブログです。

HuluやTVerなどの日本最大級の動画配信を支える株式会社PLAYが運営するテックブログです。

Finch: AWS 発のコンテナ開発用オープンソースクライアント

OTTサービス事業部の杉嵜 諒吾(すぎさき りょうあ)と申します。初見で読めない名前ですね。幼少期は電話で伝えるのが大変でしたが、IT技術の普及によりそんな苦労も無くなりました。

今回は、2022年11月にAWSから発表された Finch の紹介です。世のエンジニアがre:Invent 2022に期待を膨らませる最中、Amazon Web Servicesブログにて発表された コンテナ開発用オープンソースクライアント で、そのままre:Inventでも紹介されました。記事執筆時では v0.3.0 で正式版ではありませんが、Dockerに替わるクライアントとして事業部内でも関心を示すエンジニアが出てきたので、今回調査してみました。

github.com

Finch概要

前述の通りFinchはコンテナ開発用のツールです。AWSを中心に開発されているクライアントですが、Apache License 2.0のオープンソースで提供されているので、クライアントをそのまま無料で使うことができ、他のプログラムに組み込む2次利用も許可されています。なおAWSから発表されたプロジェクトではありますが、実体は既存のオープンソースコンポーネントを統合したものです。READMEの記述では、以下の4つが主要コンポーネントとして挙げられています。

  • containerd : コンテナランタイム
  • nerdctl : containerd用CLI
  • moby/buildkit : コンテナイメージのビルドツール
  • Lima : Linux仮想マシン

現状これらを組み合わせただけではありますが、各コンポーネントを個別にインストールして設定して、コンポーネント毎のコマンドを確認して...という作業の手間は想像に難くないでしょう。

ひとまず使ってみた

現行のv0.3.0ではIntel MacとM1 Macのみサポートとなります。後述しますが、WindowsやLinuxへの対応は予定されていますので今後に期待しましょう。

※以降の実行例ではFinch v0.2.0を使用しています。一通り検証した後にv0.3.0が出ましたが、機能面の変更が少なかったのでそのまま記事に採用しました(v0.3.0更新内容)。

Finchチュートリアル

最初のv0.1.0ではHomebrew未対応でしたが、v0.1.1で対応されたのでここでもHomebrewを使ってインストールしていきます。なおGUIはまだありませんが、GitHubのREADMEではbrew install --caskと、caskオプション付きで手順が記載されてるので、GUIの実装も考えてるようです*1。インストールしたら確認のためにバージョンを表示してみましょう。

% brew install --cask finch
==> Downloading https://github.com/runfinch/finch/releases/download/v0.2.0/Finch-v0.2.0-x86_64.pkg
(中略)
🍺  finch was successfully installed!
% finch --version
INFO[0000] Using default values due to missing config file at "/Users/r.sugisaki/.finch/finch.yaml" 
INFO[0000] "/Users/r.sugisaki/.finch" directory doesn't exist, attempting to create it 
finch version v0.2.0
% cat /Users/r.sugisaki/.finch/finch.yaml
cpus: 2
memory: 2GiB

バージョンを表示するだけのコマンドで何やらINFOメッセージが出てきました。Finchは実行時に設定ファイルが存在しない場合、設定ファイルを作成する仕様になっています。ファイルの中身はcpus, memoryの2項目だけで、PCスペックに応じて値が生成されます。

次に、Finch用の仮想マシンを立ち上げる必要があるので、finch vm initで作成します。初回のマシン作成は数分かかり、そのまま仮想マシンが起動した状態になります。なお私の環境ではsshに関するFATALエラーが出力されましたが、この後の動作確認では問題ありませんでした。この件はissueも作成されているので、開発陣も認知しています。

% time finch vm init  
INFO[0000] Initializing and starting Finch virtual machine... 
INFO[0146] Finch virtual machine started successfully   
FATA[0146] failed to setup ssh client: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain 
finch vm init  1.51s user 0.68s system 1% cpu 2:26.43 total

仮想マシンが起動したらREADME記載のイメージfinch/hello-finchを実行してみましょう。DockerのCLIに存在するコマンドは、finchでも基本的に同じ形式で使えます。

 % finch run --rm public.ecr.aws/finch/hello-finch 
public.ecr.aws/finch/hello-finch:latest:                                          resolved       |++++++++++++++++++++++++++++++++++++++| 
index-sha256:a71e474da9ffd6ec3f8236dbf4ef807dd54531d6f05047edaeefa758f1b1bb7e:    done           |++++++++++++++++++++++++++++++++++++++| 
manifest-sha256:2f848edb93f7d0cfa20d7dc7add84586fe06d258d6dd54422d8015c584ff3b9e: done           |++++++++++++++++++++++++++++++++++++++| 
config-sha256:50c36f221209ea6829db90eff11db167d8cc22abf7c2c0f1e7f4a0c701c0592f:   done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1:    done           |++++++++++++++++++++++++++++++++++++++| 
layer-sha256:cb7e3bc996dd3208c5b4560d5f6571486e2fe90b5a1cc384e2d6af0dc07de02a:    done           |++++++++++++++++++++++++++++++++++++++| 
elapsed: 3.3 s                                                                    total:  1.0 Mi (322.3 KiB/s)                                     

                            @@@@@@@@@@@@@@@@@@@                                 
                        @@@@@@@@@@@@    @@@@@@@@@@@                             
                      @@@@@@@                  @@@@@@@                          
                    @@@@@@                        @@@@@@                        
                  @@@@@@                            @@@@@                       
                 @@@@@                      @@@#     @@@@@@@@@                  
                @@@@@                     @@   @@@       @@@@@@@@@@             
                @@@@%                     @     @@            @@@@@@@@@@@       
                @@@@                                               @@@@@@@@     
                @@@@                                         @@@@@@@@@@@&       
                @@@@@                                  &@@@@@@@@@@@             
                 @@@@@                               @@@@@@@@                   
                  @@@@@                            @@@@@(                       
                   @@@@@@                        @@@@@@                         
                     @@@@@@@                  @@@@@@@                           
                        @@@@@@@@@@@@@@@@@@@@@@@@@@                              
                            @@@@@@@@@@@@@@@@@@


Hello from Finch!

デカデカとアスキーアートを出力するだけのイメージで、--rmオプションが付いてるのでそのまま削除されます。なおFinch用のイメージというわけでもなく、DockerのCLIでも同じように動作します。

Dockerコマンドでの実行結果(クリックで展開)

% docker run --rm public.ecr.aws/finch/hello-finch
Unable to find image 'public.ecr.aws/finch/hello-finch:latest' locally
latest: Pulling from finch/hello-finch
ec080f7c92e9: Pull complete 
4f4fb700ef54: Pull complete 
Digest: sha256:a71e474da9ffd6ec3f8236dbf4ef807dd54531d6f05047edaeefa758f1b1bb7e
Status: Downloaded newer image for public.ecr.aws/finch/hello-finch:latest

                            @@@@@@@@@@@@@@@@@@@                                 
                        @@@@@@@@@@@@    @@@@@@@@@@@                             
                      @@@@@@@                  @@@@@@@                          
                    @@@@@@                        @@@@@@                        
                  @@@@@@                            @@@@@                       
                 @@@@@                      @@@#     @@@@@@@@@                  
                @@@@@                     @@   @@@       @@@@@@@@@@             
                @@@@%                     @     @@            @@@@@@@@@@@       
                @@@@                                               @@@@@@@@     
                @@@@                                         @@@@@@@@@@@&       
                @@@@@                                  &@@@@@@@@@@@             
                 @@@@@                               @@@@@@@@                   
                  @@@@@                            @@@@@(                       
                   @@@@@@                        @@@@@@                         
                     @@@@@@@                  @@@@@@@                           
                        @@@@@@@@@@@@@@@@@@@@@@@@@@                              
                            @@@@@@@@@@@@@@@@@@


Hello from Finch!

Visit us @ github.com/runfinch

Dockerで動かしてもfrom Finch!になるのは正しい仕様です。

Dockerチュートリアル on Finch

ではDockerのチュートリアル用イメージではどうなるかですが、docker runfinch runに変えるだけで特に危なげなく実行できます。

% finch run -d -p 3000:80 docker/getting-started ; finch ps
docker.io/docker/getting-started:latest:                                          resolved       |++++++++++++++++++++++++++++++++++++++| 
index-sha256:d79336f4812b6547a53e735480dde67f8f8f7071b414fbd9297609ffb989abc1:    done           |++++++++++++++++++++++++++++++++++++++| 
manifest-sha256:d819f321a1850678676fc16cdf8d80f3041a3407285856ba59cf6235bbdbb9dd: done           |++++++++++++++++++++++++++++++++++++++| 
(中略)
elapsed: 19.5s
2eb53e0de76a260218b70664d739c4ac8a7b96415ccc6bb687a3cc8d57fbd424
CONTAINER ID    IMAGE                                      COMMAND                   CREATED                   STATUS    PORTS                   NAMES
2eb53e0de76a    docker.io/docker/getting-started:latest    "/docker-entrypoint.…"    Less than a second ago    Up        0.0.0.0:3000->80/tcp    getting-started-2eb53

docker/getting-started on Finch!

このチュートリアルではイメージビルドのコマンドとしてdocker buildと記載していますが、これもfinch buildにてビルドを実行できますし、FinchのためにDockerfileを再編集する必要もありませんでした。他にも、チュートリアルに記載されているコマンドの大半はdockerfinchに置き換えるだけで、同じ機能を持つものが実行できてしまいます(流石に Docker Desktop のGUIを使った手順までは再現できませんが…)。

# Docker
% docker build -t getting-started .
% docker run -dp 3000:3000 getting-started
% docker ps
% docker stop <the-container-id>

# Finch
% finch build -t getting-started .
% finch run -dp 3000:3000 getting-started
% finch ps
% finch stop <the-container-id>

コンテナ技術は既に標準化が進んだ技術であるため、これ以外でも今までDockerで使っていたイメージをそのままFinchで使うことができます。加えてFinchに組み込まれているnerdctlが、Dockerクライアントで実装されているコマンドやオプションと同じコマンドを模して作られているため、Finchでも同じように使うことができます。この仕様が故に、Dockerから移行して使い始めても使用感がほとんど変わらずに使い続けることができたり、Docker前提で書かれたマニュアルやブログ記事等のナレッジがFinchにも流用しやすいことが大きな強みとなるでしょう。

Finch Compose

Dockerには複数のコンテナを同時に管理・実行するためにdocker composeコマンドがあり、その構成をymlファイルで定義し管理できる仕組みがあります。となると、finch composeと打てば同じことができそうですね。というわけでDocker公式のサンプルを使ってやってみましたが、

% git clone https://github.com/docker/awesome-compose
% cd apache-php

% finch compose up -d
(中略)
--------------------
   1 | >>> # syntax=docker/dockerfile:1.4
   2 |     
   3 |     FROM --platform=$BUILDPLATFORM php:8.0.9-apache as builder
--------------------
error: failed to solve: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/tmp/buildkit-metadata1408976894" to rootfs at "/run/config/buildkit/metadata": mount /tmp/buildkit-metadata1408976894:/run/config/buildkit/metadata (via /proc/self/fd/6), flags: 0x1021: operation not permitted: unknown
FATA[0001] error while building image apache-php_web: exit status 1 
FATA[0001] exit status 1          

コケた。。。

とはいえ、エラーメッセージを見ればDockerfileの1行目の記述でコケているのは明白ですね。これはDockerfileビルダーを指定する記述ですが(syntaxディレクティブ)、ここの処理が上手くいってないようです。細かい原因はまだ分かりかねますが、ひとまず今回実行しようとしたapache-phpでは、Dockerfile先頭のこの記述を削除しただけでなんとか構築できました。

% finch compose up -d --build

% curl localhost
<h1>Hello World!</h1> 

他のサンプルも構築してみましたが、同じようにsyntaxディレクティブでコケたものや、一部イメージだけ立ち上がらないものもありました。逆に普段の業務で使っているファイルで構築した際は難なく立ち上がったので、各プロジェクトでどのような記述をしているかに依存するところかもしれません。

使ってみた所感

繰り返しにはなりますが、最初に仮想マシンを立てたあとはdockerコマンドと同じように使えるので、少なくともCLIは学習コスト無しで移行できることでしょう。使い方によってはaliasを設定するだけで移行できるかもしれません。コンテナ実行中にFinchの処理やPCが重くなるようなことは無かったので、finch vm initが数分かかることだけ気をつければ、コンテナ開発も滞りなく進められそうです。

新規開発で使うには十分使えると思いますが、既存プロジェクトのコンテナ開発をFinchに移行するにはまだ不安が残ります。Finch Composeの項で起きたように、元々使えてたファイルが互換性の無さや不具合で使えず修正する...ということになりかねません。尤も、正式版では無い故に当然のリスクではあります。今後のバージョンアップに期待しましょう。

今後の展望

READMEの末尾にWhat's next?という章で、ホストOSとしてWindowsとLinuxのサポート予定が明記されています。また記載はないですが、M2 Macへの対応もされていくことでしょう。なおAWSのクラウドサービスとの連携が気になる人も多いでしょうが、こちらはFinchの拡張機能としての実装を考えているようです。

We know that AWS customers will want extensions that make it easier for local containers to integrate with AWS cloud services. However, these will be opt-in extensions that don’t impact or fragment the open source core or upstream dependencies that Finch depends on. 引用元 : Introducing Finch: An Open Source Client for Container Development | AWS Open Source Blog

では開発体制はどうかというと、既に継続的な開発体制が整えられたようで、2022年11月の発表から3回のアップデートが行われています。本当は、年明け前にv0.1.1を2週間ぐらい使って出てきた「finch compose exec等 compose のコマンドが不足気味で〜」という話を書くつもりでしたが、Finch v0.2.0(というよりnerdctl v1.1.0)でfinch composeのコマンドが大幅に追加されたので、記事にする前に解決しちゃいました。「使ってみた所感」が大幅に削れてしまったのはやむなし。

他にもFinch本体での修正が入っている上、Finch内で使う他のコンポーネントもバージョンアップしているので、全体ではかなりのスピード感で改修されていることが分かります。元々Finchが出る前から、containerd等のContributorsにもAWSのエンジニアがいたりしましたが、Finch発表後の数か月だけでもAWSが本腰を入れて取り組んでいる様子が伺え、今後の改修にも期待が持てるでしょう。

re:Invent2022で発表されたアップデートの数々と比べるとどうしても地味ではありますが、コンテナ開発で用いるツールとして大きな選択肢となり得ることでしょう。自分としても、正式版リリースや大幅なアップデートが出てないか引き続きウォッチしていきます。

余談:レジストリ

2023年1月現在、「Docker Desktopのサブスク価格高くなった!やめたい!」という本音を抱えてる人も多いでしょう。価格改定があった直後に「Docker Desktopの代替となり得るツール登場!」みたいなニュース記事も増えたので、コスト増に悩まされた挙句にFinchを知り、この記事へ辿り着いた方々もいるかもしれません。故にFinchのv1.0.0がリリースされた暁には、Finch正式リリースと称してまたニュースが書かれ、実際にDocker Desktopのサブスクリプションを解約してFinchに乗り換えるプロジェクトも出てくることでしょう。

移行の際にはクライアント本体の動作確認が行われるでしょうが、それ以外にレジストリの利用に関しても注意が必要です。Docker Desktopのサブスクリプションには、Docker Hubの利用に関する制限も含まれます。自前のリポジトリが無くなることに関してはイメージの移行なり破棄なりするでしょうが、ここで注意すべきはImage Pull Rateです。

DockerやFinchの各種コマンドでイメージをpullするとき、通常はDocker Hubからのpullになります。前述のImage Pull Rateはこのpullのレート制限の話で、サブスク未加入で認証してない場合は6時間で100pullまでとなります。この時、pull回数はクライアント側のIPごとにカウントされることに気をつけましょう。例えばオフィスのネットワーク経由でpullしていると、ゲートウェイのグローバルIPが制限対象になるので社員みんなで回数上限に達してしまい誰もpullできなくなる事態が起きかねません。クラウドサービスからpullする場合は構築にもよりますが、他のアカウントとIPが共有になる場合は初回からいきなりpullできない事態も有り得ます。過去には、AWS CodeBuildでPullする場合は他のAWSアカウントともIPが被り得るので、1回目のつもりでもいきなりエラーが出てしまうことがあると話題になりました*2。このレート制限の話ばかりは、Finch自体がいくらアップデートしても付いて回る課題となるでしょう。

レジストリの代替案としてAWSに目を向けると、Amazon ECRが候補に上がります。元よりAWSにリリースする場合、AWS CLIから認証をした上でpushするケースも多いでしょうが、このECRの運用を見直し、Docker Hubでやってたイメージ管理を併せて行う形になります。ストレージや通信での従量課金が課されるので使い過ぎには注意ですが、大抵の場合はDockerのサブスク料金を下回るかと思います。また公開リポジトリを提供するAmazon ECR Publicもあり、Dockerオフィシャルイメージはこちらでも利用可能です。Docker Desktopからの移行を考えてる方は、ECRの利用も検討しましょう。

なおレジストリにAmazon ECR Publicを使う場合、イメージを指定する時にレジストリのドメインpublic.ecr.awsを記述することで可能です。また公開されているイメージはAmazon ECR Public Galleryで検索できるので、併せてご覧ください。

% finch run --rm public.ecr.aws/finch/hello-finch 

gallery.ecr.aws

関連リンク

AWS re:Invent
AWS re:Invent 2022 | Amazon Web Services

Finch GitHub
GitHub - runfinch/finch: The Finch CLI an open source client for container development

Finchの主要コンポーネント
containerd – An industry-standard container runtime with an emphasis on simplicity, robustness and portability
GitHub - containerd/nerdctl: contaiNERD CTL - Docker-compatible CLI for containerd, with support for Compose, Rootless, eStargz, OCIcrypt, IPFS, ...
GitHub - moby/buildkit: concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit
GitHub - lima-vm/lima: Linux virtual machines, typically on macOS, for running containerd

Finch発表時のAWSブログ
Introducing Finch: An Open Source Client for Container Development | AWS Open Source Blog
コンテナ開発用のオープンソースクライアント「Finch」のご紹介 | Amazon Web Services ブログ

Docker
Docker: Accelerated, Containerized Application Development
Pricing | Docker


弊社も当面はAWSを使い続けるでしょうし、個人的にもre:Invent 2022で気になったサービスはあったので、私から発信できる内容があれば今後も記事にしたいと思います。

以上、杉嵜 諒吾が執筆しました。

*1:caskはGUIアプリをhomebrewでインストールする際のオプションです。最近のhomebrewでは、caskオプション無しでもインストールできるようになりました。

*2:https://dev.classmethod.jp/articles/codebuild-has-to-use-dockerhub-login-to-avoid-ip-gacha/