【AWS】手を動かしながら学ぶAWS Finchを使ってみよう

## はじめに

この記事では 手を動かしながらAWSが提供するコンテナ開発用のオープンソースクライアント、Finch を学習していく記事です。主な内容としては実践したときのメモを中心に書きます。
（忘れやすいことなど）誤りなどがあれば書き直していく予定です。

## Finchとは

コンテナ開発用のオープンソースクライアントです。

AWSのGAアナウンスでは以下のように説明されています。

> One year ago AWS announced a brand new open source project, Finch, a command line developer tool for building, running, and publishing Linux containers on macOS. The team and our growing community have been busy this year and we are excited to announce today that Finch has reached its 1.0 milestone for general availability (GA) and is ready for download at https://github.com/runfinch/finch/releases/tag/v1.0.0. 

要約するとFinchは、macOS上でLinuxコンテナを構築、実行、公開するためのコマンドラインツール
そして、GAとなったバージョンは`v1.0.0`であることです。

また、実装面においては下記のようにも記されています。

> Finch depends on several open source projects, including Lima and nerdctl, and we’ve been actively collaborating in those projects. Lima provides the virtual machine in which a small Linux OS image runs the container runtime components. These runtime components include nerdctl, a wrapper for containerd that provides the common container lifecycle command line capabilities that developers are used to

要点を見ていくと

- Finchは、Limaやnerdctlを含むいくつかのオープンソースプロジェクトに依存
- Limaは、小さなLinux OSイメージがコンテナー・ランタイム・コンポーネントを実行する仮想マシンを提供
- 仮想マシンにはコンテナ・ライフサイクルのコマンドライン機能を提供するcontainerdのラッパーであるnerdctlが含まれる

機能面にフォーカスしていくと

> Two specific features we contributed include container image signing, and support for both creating and running images using Seekable OCI (SOCI), an open source technology from AWS that enables containers to launch faster by lazily loading the container image.

つまりは

- コンテナイメージの署名
- Seekable OCI（SOCI）を使用したイメージの作成と実行の両方へのサポート

Seekableとは：コンテナイメージを遅延ロードすることでコンテナの起動を高速化するAWSのオープンソース技術

[Ready for Flight: Announcing Finch 1.0 GA! - 参考](https://aws.amazon.com/jp/blogs/opensource/ready-for-flight-announcing-finch-1-0-ga/)

コマンドはDockerとほぼ同じ感触で使える点もポイントが高いです。
説明書きだけを読んでいてもわからないことが多いので早速触って行きたいと思います。

## 前提

アナウンスにもあるとおり、MacOSのみに対応しているようです。今回はApple Sillicon Chip(M2)でやっていきたいと思います。

具体的な環境は以下に記載

- MacBook
    - Apple M2
    - 24 GB
    - Sonoma 14.0 (23A344)

- Finch
    - finch version v1.0.0

## セットアップ

触ってみる前にセットアップをしたいと思います。まずはインストールします。

```bash
brew install finch
```

次は仮想マシンを立ち上げます。

```bash
finch init
```

これでセットアップ完了です。

## 準備運動

[以前の記事](https://qiita.com/ymd65536/items/68b68465635841a62556)を参考にfinchでコマンドを実行したいと思います。

### プロセスチェック

コンテナのプロセスをチェックするコマンドです。

``` bash
finch ps
```

単純に`ps`しても良いのですが、実際には`-a`の方をよく使うかなと思います。

```bash
finch ps -a
```

### レジストリからイメージを取得

nginxのイメージを取得するコマンドです。

``` bash
finch pull nginx
```

pullするときはタグを指定してpullすることが多いです。これはDockerfileでも同様です。

### 保存されているイメージ一覧を表示

保存されているイメージの一覧を取得します。

```bash
finch images
```

### dockerイメージからコンテナを起動

ポート80番でnginxを起動するコマンドです。

```bash
finch run -p 80:80 --name nginx_web --detach nginx
```

オプションがたくさんついていますが、以下のような意味があります。

- `-p`
  - ポートを指定する
- `-d`
  - コンテナをバックグラウンドで実行し、コンテナIDを表示
- `--name`
  - コンテナ起動時にコンテナに名前をつける

※`--rm`と`--detach`は同時に指定できないようです。

- `--rm`
  - コンテナ終了時にコンテナを削除する


実行されているかどうかを確認する。

```bash
finch ps
```

コンテナを停止します。

```bash
finch stop nginx_web
```

コンテナを削除します。

```bash
finch rm nginx_web
```

### ボリュームマウントをして起動する場合

`--volume`をつけるとホストのストレージボリュームを関連付けます。

```bash
finch run --detach --volume "$(pwd)":/usr/share/nginx/html -p 80:80 --name nginx_web nginx
```

コンテナを停止します。

```bash
finch stop nginx_web
```

コンテナを削除します。

```bash
finch rm nginx_web
```

### コンテナからイメージを作成

起動中のコンテナからイメージを作成します。コンテナからイメージを作成しておくと
万が一Dockerfileを消失してしまった場合でもコンテナの情報をもとにDockerfileを再構成できます。

```bash
finch commit nginx_web oreno
```

### コンテナに対してコマンドを実行

まずはコンテナを起動します。

```bash
finch run -p 80:80 --name nginx_web --detach nginx
```

指定したコンテナに対してコマンドを実行します。コンテナの後ろに実行するコマンドを入力します。下記の例では `sh`を実行しています。

```bash
finch exec -it nginx_web sh
```

プロンプトが変わるのでいくつかコマンドを入力してみましょう。

シェルを切り替え

```bash
bash
```

ホスト名などを表示

```bash
uname -a
```

ディレクトリを見渡す

```bash
ls -la
```

nginxで表示されているhtmlソースを出力する。

```bash
cat /usr/share/nginx/html/index.html
```

aptでパッケージリストを参照する。

```bash
apt list
```

環境変数を参照する。

```bash
env
```

コンテナから出る。

```bash
exit
```

```bash
exit
```

コンテナを停止します。

```bash
finch stop nginx_web
```

### メタデータを見る

イメージおよびまたはコンテナがどのような構成になっているかを参照するコマンドです。

イメージを見る場合

```bash
finch inspect nginx
```

コンテナを見る場合

```bash
finch inspect nginx_web
```

### コンテナのログを表示 (Log)

コンテナで発生したログを参照するコマンドです。コンテナのデバッグでお世話になります。

``` bash
finch logs nginx_web
```

### コンテナを削除する

コンテナを削除します。

```bash
finch rm nginx_web
```

### イメージを削除する

イメージIDを指定してイメージを削除します。

```bash
finch rmi nginx
```

### 環境を確認

コンテナの稼働状況を見る。

```bash
finch ps -a
```

保存されているイメージを見る。

```bash
finch images
```

## もうちょっとひねりを入れてコマンドを入力

dockerでは`--digests`や`--format`に対応していました。finchではできるのでしょうか。
試してみましょう。

### CSV形式で保存されているイメージ情報を参照

`--digest`と`--format`を使って`finch images`の表示方法を変えてみましょう。

```bash
finch images --digests --format='{{.ID}},{{.Repository}},{{.Tag}},{{.Digest}},{{.Size}}'
```

実行結果

```text
be29ad08087d,oreno,latest,sha256:be29ad08087dfad95a8e1a09b9ef8a3c4795b245b56d7b785a099c0096b32515,197.5 MiB
```

見事に通りました。

#### --filter=referenceを使って該当のイメージのみ表示

お次は`--filter`を使った表示です。
dockerでは該当のイメージ名だけ取得したい場合に利用できるオプションでした。

下記のコマンドを実行します。

```bash
finch images --format='{{.Repository}}' --filter=reference='oreno'
```

実行結果※

```text
oreno
```

※`finch commit nginx_web oreno`で作成した新しいイメージを表示しています。

#### `<none>`となっているイメージのみ表示

中間イメージにも使われていないような不要なイメージ、Tagが`<none>`となっているものについて
表示したい場合、dockerでは`-f "dangling=true"`を利用しました。

finchでは利用できるのでしょうか。

```
finch images -f "dangling=true"
```

コマンドは通りました。`<none>`がない場合`dangling=false`を実行します。

```bash
finch images -f "dangling=false"
```

### イメージを削除する

dockerでは`docker images`と`dangling=true`を併用すると不要なイメージを削除できました。
finchではできるのでしょうか。

```bash
finch rmi -f `finch images -f "dangling=true" -q`
```

コマンドは通りました。`<none>`がない場合`dangling=false`を実行します。

```bash
finch rmi -f `finch images -f "dangling=false" -q`
```

### 24時間以内に使っていないイメージを削除

下記のコマンドはdockerでは24時間以内に使っていないイメージを削除します。

```bash
docker image prune -a --force --filter "until=24h"
```

finchでは使えるでしょうか。

```bash
finch image prune -a --force --filter "until=24h"
```

実行できませんでした。

```
FATA[0000] unknown flag: --filter                       
FATA[0000] exit status 1 
```

`finch image prune --help`を見るとどうやら`-a`や`-f`には対応しているようです。

正しくは下記のコマンドですが、`--filter`が効かないので工夫が必要です。

```bash
finch image prune -a --force
```

### コンテナを一掃する系のコマンド

下記のコマンドはdockerではすべてのコンテナを削除するコマンドです。

```bash
docker rm -f $(docker ps -a -q)
```

finchでは動くのでしょうか。

```bash
finch rm -f $(finch ps -a -q)
```

問題なく動作しました。準備体操でお気付きかもしれませんが、これくらいならできそうですね。

### コンテナを一掃する系のコマンド（条件付き）

dockerでは停止済みのコンテナだけ削除したい場合は下記のコマンドが有効でした。

```bash
docker rm $(docker ps -a -q --filter "status=exited") && docker ps -a
```

finchでは動くのでしょうか。

まずはコンテナを起動します。

```bash
finch run -p 80:80 --name nginx_web --detach nginx
```

コンテナを停止します。

```bash
finch stop nginx_web
```

最後に下記のコマンドを実行します。

```bash
finch ps && finch rm $(finch ps -a -q --filter "status=exited") && finch ps -a
```

問題なく動作しました。

### systemサブコマンド

Dockerでは`df`が利用できましたが、finchではどうでしょうか。

```bash
finch system df
```

残念ながら`events`と`info`と`prune`のみ対応しています。

ちなみに`docker system df`と実行すると`Images`,`Containers`,`Local Volumes`,`Build Cache`の4つの状態が表示されます。
それぞれイメージの容量、コンテナの容量、コンテナのボリューム容量、ビルド時に利用するキャッシュが表示されます。

最後に環境を掃除して終わりましょう。

```bash
finch system prune
```

## 他気になったこと

### Dockerとローカルのイメージレジストリを共有するか

`しない`が正解（現段階では）

## まとめ

今回はGAされたfinchを使ってみました。dockerのコマンドとほぼ互換性があるので使いこなせれば、大活躍しそうです。個人的には使いたいコマンドの組み合わせがほぼ動いたので業務でも使えそうな感じがしています。

また、最近は制約のある環境、たとえば、SSLがないとレジストリからイメージをダウンロードができない環境でコンテナを使うこともあるのでさまざまな環境下でも利用できるのかはチェックできていません。またの機会にチェックしたいと思います。

なお、今回は`nerdctl`を使いませんでしたが、`nerdctl`にフォーカスした検証をするのも良いかもしれません。次回の楽しみにとっておきたいと思います。

## 参考

- [コンテナ開発用のオープンソースクライアント「Finch」のご紹介](https://aws.amazon.com/jp/blogs/news/introducing-finch-an-open-source-client-for-container-development/)

## おわり