前提
- Fly.ioのページについては、2024年8月30日時点の構成で説明しています。
- 検証環境
- MacBook Pro(Intel)
- macOS Sonoma 14.5
- MacBook Pro(Intel)
これまで、Fly.ioで稼働中( fly deploy
コマンドによってデプロイ済み)の仮想マシンにログインするには fly console --machine XXXXXXXXXXXXXX
を利用していましたが、最近、 fly ssh console --machine XXXXXXXXXXXXXX
でもログインできることを知りました。
これらのコマンドの違いがわからなかったので、今回は色々とコマンドを実行して試したことをまとめてみます。
前述のとおり、デプロイ済みの仮想マシンにログインするためのコマンドは以下の2種類があるようです。
fly console
と fly ssh console
は機能的に似ているので、エイリアスのようなものかもしれないと思い「Docs (Fly.io developer documentation)」のページを見てみると、それぞれ独立したページになっており、内容も異なることがわかりました。
まずは fly console
のDocsを読んでみると、「新しい仮想マシン、または、既存の仮想マシンでコンソールを実行する」とのこと。
「既存の仮想マシン」に接続できることはわかりますが、「新しい仮想マシン」という部分がよくわかりませんでした。
また、 console
コマンドは、 console_command
という設定用のフィールドを持つようです。
--machine
については、これまで私が利用していた方法なので、既存の仮想マシンへの接続時に指定するものだということは把握済みです。
--help オプション
fly console --help
を実行すると、Docsのページと同様の説明が記載されていました。
% fly console --help
Run a console in a new or existing machine. The console command is specified by
the `console_command` configuration field. By default, a new machine is created
by default using the app's most recently deployed image. An existing machine
can be used instead with --machine.
Usage:
fly console [flags]
Flags:
-a, --app string Application name
-C, --command string command to run on SSH session
-c, --config string Path to application configuration file
--dockerfile string Path to a Dockerfile. Defaults to the
Dockerfile in the working directory.
--entrypoint string ENTRYPOINT replacement
-e, --env stringArray Set of environment variables in the
form of NAME=VALUE pairs. Can be
specified multiple times.
--file-literal stringArray Set of literals to write to the
Machine, in the form of
/path/inside/machine=VALUE pairs,
where VALUE is the base64-encoded raw
content. Can be specified multiple times.
--file-local stringArray Set of files to write to the Machine,
in the form of
/path/inside/machine=<local/path>
pairs. Can be specified multiple times.
--file-secret stringArray Set of secrets to write to the
Machine, in the form of
/path/inside/machine=SECRET pairs,
where SECRET is the name of the
secret. The content of the secret
must be base64 encoded. Can be
specified multiple times.
-h, --help help for console
--host-dedication-id string The dedication id of the reserved
hosts for your organization (if any)
-i, --image string image to use (default: current release)
--machine string Run the console in the existing
machine with the specified ID
-p, --port strings Publish ports, format:
port[:machinePort][/protocol[:handler[:handler...]]])
i.e.: --port 80/tcp --port 443:80/tcp:http:tls --port 5432/tcp:pg_tls
To remove a port mapping use '-' as handler, i.e.: --port 80/tcp:-
-r, --region string The target region (see 'flyctl
platform regions')
-s, --select Select the machine on which to
execute the console from a list.
-u, --user string Unix username to connect as (default
"root")
--vm-cpu-kind string The kind of CPU to use ('shared' or
'performance')
--vm-cpus int Number of CPUs
--vm-gpu-kind string If set, the GPU model to attach
(a100-pcie-40gb, a100-sxm4-80gb,
l40s, a10, none)
--vm-gpus int Number of GPUs. Must also choose the
GPU model with --vm-gpu-kind flag
--vm-memory string Memory (in megabytes) to attribute to
the VM
--vm-size string The VM size to set machines to. See
"fly platform vm-sizes" for valid values
--volume strings Volume to mount, in the form of
<volume_id_or_name>:/path/inside/machine[:<options>]
--wg Determines whether communication with
remote builders are conducted over
wireguard or plain internet(https)
(default true)
Global Flags:
-t, --access-token string Fly API Access Token
--debug Print additional logs and traces
--verbose Verbose output
それでは、Docsの説明ではよくわからない部分があったので、実際に fly console
を実行してみましょう。
オプション未指定(アプリケーションが存在しない状態)
まず、Fly.io上にアプリケーションが何も存在しない状態で fly console
を実行します。
すると、 app name
(アプリケーション名)が見つからないので、 fly.toml
ファイル内 app
の項目を追加するか、「 -a
」と共に指定せよというエラーが発生しました。
% fly console
Error: the config for your app is missing an app name, add an app field to the fly.toml file or specify with the -a flag
-a オプション(アプリケーションが存在しない状態)
次に、Fly.io上に存在しないアプリケーション名である akase244-hellofly
を指定して実行してみます。
すると、存在しないアプリケーション名なので、 akase244-hellofly
が見つからないというエラーが発生します。
% fly console -a akase244-hellofly
Error: failed to get app: Could not find App "akase244-hellofly"
アプリケーションが存在しない場合の動作は確認できましたので、次はアプリケーションを作成してからコマンドを実行してみます。
以前書いた「Fly.io の「Hands-on」のページに従ってデプロイの練習をやってみた」を参考に、 akase244-hellofly
というアプリケーションを作成します。
% mkdir akase244-hellofly && cd $_
% fly launch --image flyio/hellofly:latest
Fly.ioのアプリケーション一覧の画面に akase244-hellofly
が表示され、アプリケーションが作成されていることが確認できました。
仮想マシン一覧の画面には2台の仮想マシンが作成されていることが確認できました。
先程 fly launch
を実行したディレクトリには fly.toml
ファイルが作成されていますので、こちらを確認すると、 app
の項目にアプリケーション名が指定されていることがわかります。(fly launch
実行時にカレントディレクトリ名がアプリケーション名として採用されるというのがデフォルトの動作のようです)
% grep -E '^app' fly.toml
app = 'akase244-hellofly'
オプション未指定
アプリケーションの準備が整いましたので、この状態で fly console
を実行します。すると「Created an ephemeral machine 〜」というメッセージが表示され、仮想マシンにログインすることができました。
ここで、Docsの「By default, a new machine is created by default using the app's most recently deployed image.」という説明を思い出してみます。
この「ephemeral machine」というのは、直近のデプロイイメージから作られた一時的な仮想マシン環境のようで、この環境にログインすることで構築が正しく行えているかといった調査などの利用用途なのではないかと予想しています。
% fly console
Created an ephemeral machine 32871542ceXXXX to run the console.
Connecting to fdaa:9:4eda:a7b:2de:28da:XXXX:2... complete
32871542ceXXXX:/goapp#
fly console
で接続を維持した状態で仮想マシン一覧を表示すると、先程の2台の状態から1台増えており、「Process」欄に「fly_app_console」と表示されていることが確認できます。
接続した状態の仮想マシンからログアウトすると、この一時的な環境は自動的に削除されるようで、仮想マシン一覧からも表示が消える仕組みになっています。
--machine オプション
次は、 fly console
に「 --machine
」を指定して、作成済みの仮想マシンにログインしてみます。
この方法は、Docsの「An existing machine can be used instead with --machine.」の部分の説明にあたります。
% fly console --machine 4d89440b6eXXXX
Connecting to fdaa:9:4eda:a7b:d86c:5baa:XXXX:2... complete
4d89440b6eXXXX:/goapp#
-a オプション
次に「 -a
」を指定した形式で実行してみます。すると、「Created an ephemeral machine 〜」と表示されました。
つまり、引数に何も指定しない場合と同様で、実行しているディレクトリ直下に fly.toml
が存在しており、その中で app
が指定されている状態と同義の動作のようです。
% fly console -a akase244-hellofly
Created an ephemeral machine e78432e1a3XXXX to run the console.
Connecting to fdaa:9:4eda:a7b:2de:1629:XXXX:2... complete
e78432e1a3XXXX:/goapp#
-c オプション / --config オプション
当然、以下のように「 -c
」または「 --config
」で fly.toml
のパスを個別に指定した場合も同様の動作になります。
% fly console -c fly.toml
Created an ephemeral machine 908016e3cdXXXX to run the console.
Connecting to fdaa:9:4eda:a7b:2de:8331:XXXX:2... complete
908016e3cdXXXX:/goapp#
% fly console --config fly.toml
Created an ephemeral machine 17815615c0XXXX to run the console.
Connecting to fdaa:9:4eda:a7b:2df:8fca:XXXX:2... complete
17815615c0XXXX:/goapp#
-C オプション
「 -C
」は接続と同時に実行するコマンドが指定可能で、コマンド実行後は接続が閉じられるようです。
% fly console -C "cat /etc/os-release"
Created an ephemeral machine 3d8dd79dc9XXXX to run the console.
Connecting to fdaa:9:4eda:a7b:2df:b142:XXXX:2... complete
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.12.0
PRETTY_NAME="Alpine Linux v3.12"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
Waiting for ephemeral machine 3d8dd79dc9XXXX to be destroyed ... done.
console_command
ここで、Docsの「The console command is specified by the console_command
configuration field.」という説明を思い出したので、 fly.toml
に以下のような設定を追加してみます。
% grep -E '^console_command' fly.toml
console_command = 'cat /etc/os-release'
fly.toml
に上記の設定を行った状態で fly console
を実行すると console_command
に指定されたコマンドが実行され、コマンド実行後は接続が閉じられます。
% fly console --machine 4d89440b6eXXXX
Connecting to fdaa:9:4eda:a7b:d86c:5baa:XXXX:2... complete
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.12.0
PRETTY_NAME="Alpine Linux v3.12"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
なお、 fly.toml
の console_command
については、「App configuration (fly.toml)」の「Console command」にて説明されていますので、こちらもあわせてご覧ください。
-s オプション
もう一つ気になるオプションとしては「 -s
」です。Fly.ioではアプリケーション作成時にデフォルトで仮想マシンが2台構築されるため、初期状態で複数台構成となります。
「Select the machine on which to execute the console from a list.」と説明されているので、このオプションを使えば複数台の仮想マシンの中から選択して接続できるようです。
「 -s
」を付与して実行してみると「Use arrows to move, type to filter」と表示され、稼働中の仮想マシン、及び、「create an ephemeral machine」の選択肢が表示されました。
% fly console -s
? Select a machine: [Use arrows to move, type to filter]
> create an ephemeral machine (1 shared CPU, 256 MB of memory)
nrt: 4d89440b6eXXXX fdaa:9:4eda:a7b:d86c:5baa:XXXX:2 XXXXXX-XXXX-1862
nrt: 9185e27eb5XXXX fdaa:9:4eda:a7b:2df:ae29:XXXX:2 XXXXX-XXXXX-6369
上下のカーソルキーを入力すると、以下のように選択肢が切り替わります。
% fly console -s
? Select a machine: [Use arrows to move, type to filter]
create an ephemeral machine (1 shared CPU, 256 MB of memory)
> nrt: 4d89440b6eXXXX fdaa:9:4eda:a7b:d86c:5baa:XXXX:2 XXXXXX-XXXX-1862
nrt: 9185e27eb5XXXX fdaa:9:4eda:a7b:2df:ae29:XXXX:2 XXXXX-XXXXX-6369
また、仮想マシンのIDやIPv6のアドレスなどの値を入力することで、選択肢をフィルタすることも可能です。
% fly console -s
? Select a machine: 4d89 [Use arrows to move, type to filter]
> nrt: 4d89440b6eXXXX fdaa:9:4eda:a7b:d86c:5baa:XXXX:2 XXXXXX-XXXX-1862
fly console
には他にも様々なオプションが指定可能ですが、Docs(--help
)の概要に説明されていた内容については、どのような操作が行えるのか理解できたのではないでしょうか。
続いて fly ssh console
のDocsについて見ていきましょう。
fly ssh console
は「起動中の仮想マシンに接続できる」ようです。すごくシンプルな説明で非常にわかりやすいですね。
--help オプション
fly ssh console --help
を実行すると、Docsのページと同様の説明が記載されています。
% fly ssh console --help
Connect to a running instance of the current app.
Usage:
fly ssh console [flags]
Flags:
-A, --address string Address of VM to connect to
-a, --app string Application name
-C, --command string command to run on SSH session
-c, --config string Path to application configuration file
-h, --help help for console
--machine string Run the console in the existing machine
with the specified ID
-o, --org string The target Fly.io organization
-g, --process-group string The target process group
--pty Allocate a pseudo-terminal (default: on
when no command is provided)
-q, --quiet Don't print progress indicators for WireGuard
-r, --region string The target region (see 'flyctl platform
regions')
-s, --select select available instances
-u, --user string Unix username to connect as (default "root")
Global Flags:
-t, --access-token string Fly API Access Token
--debug Print additional logs and traces
--verbose Verbose output
fly console
の場合と同様に fly ssh console
も色々と実行していきたいところですが、その前に、一旦「akase244-hellofly」のアプリケーションを削除しておきます。
% fly apps destroy akase244-hellofly
Destroying an app is not reversible.
? Destroy app akase244-hellofly? (y/N) y
オプション未指定(アプリケーションが存在しない状態)
Fly.io上にアプリケーションが何も存在しない状態になりましたので fly ssh console
を実行します。
引数に何も指定しない場合と「 -a
」を指定した場合は fly console
と同様のエラーメッセージが表示されています。
% fly ssh console
Error: the config for your app is missing an app name, add an app field to the fly.toml file or specify with the -a flag
-a オプション(アプリケーションが存在しない状態)
% fly ssh console -a akase244-hellofly
Error: get app: Could not find App "akase244-hellofly"
では、再度「akase244-hellofly」のアプリケーションを作成し、2台の仮想マシンが存在する状態を構築します。
オプション未指定
fly ssh console
の引数に何も指定せずに実行すると今度は仮想マシンにログインできました。
% fly ssh console
Connecting to fdaa:9:4eda:a7b:2df:590c:XXXX:2... complete
6e8254d5c3XXXX:/goapp#
ここで疑問が湧きます。Fly.ioはアプリケーションを作成するとデフォルトで2台の仮想マシンが構築されますが、引数に何も指定せずに実行した場合、どちらの仮想マシンに接続されるのでしょうか。
ということで、何度か同じコマンドを実行して接続と切断を繰り返してみると1台目に接続する場合と、以下のように2台目に接続される場合があるとわかりました。(仮想マシンのIDの表示が「6e8254d5c3XXXX」から「908016e3cdXXXX」に変わっています)
つまり、仮想マシンが複数稼働している場合、接続先をどのように選定しているかまではわかりませんが、「いずれかの仮想マシン」につながるようです。
% fly ssh console
Connecting to fdaa:9:4eda:a7b:2de:36bc:XXXX:2... complete
908016e3cdXXXX:/goapp#
-a オプション
上記の「いずれかの仮想マシンにつながる」という動作は「 -a
」、「 -c
( --config
)」を指定した場合も同様で、以下のとおり接続と切断を繰り返すといずれかの仮想マシンにつながることが確認できました。
「 -a
」を指定すると「6e8254d5c3XXXX」に接続する場合と「908016e3cdXXXX」に接続する場合があることを確認。
% fly ssh console -a akase244-hellofly
Connecting to fdaa:9:4eda:a7b:2df:590c:XXXX:2... complete
6e8254d5c3XXXX:/goapp#
% fly ssh console -a akase244-hellofly
Connecting to fdaa:9:4eda:a7b:2de:36bc:XXXX:2... complete
908016e3cdXXXX:/goapp#
-c オプション
「 -c
」を指定すると「6e8254d5c3XXXX」に接続する場合と「908016e3cdXXXX」に接続する場合があることを確認。
% fly ssh console -c fly.toml
Connecting to fdaa:9:4eda:a7b:2df:590c:XXXX:2... complete
6e8254d5c3XXXX:/goapp#
% fly ssh console -c fly.toml
Connecting to fdaa:9:4eda:a7b:2de:36bc:XXXX:2... complete
908016e3cdXXXX:/goapp#
-A オプション
「 -A
」を指定して、仮想マシンごとに割り当てられているIPv6形式のIPアドレスを引数に与えることで、仮想マシンに接続することができます。
% fly ssh console -A fdaa:9:4eda:a7b:2de:36bc:XXXX:2
Connecting to fdaa:9:4eda:a7b:2de:36bc:XXXX:2... complete
908016e3cdXXXX:/goapp#
IPアドレスの値は仮想マシンの詳細画面で確認することが可能です。
もしくは、 fly machine list
を実行すると表示されます。
% fly machine list
2 machines have been retrieved from app akase244-hellofly.
View them in the UI here (https://fly.io/apps/akase244-hellofly/machines/)
akase244-hellofly
ID NAME STATE CHECKS REGION ROLE IMAGE IP ADDRESS VOLUME CREATED LAST UPDATED PROCESS GROUP SIZE
6e8254d5c3XXXX XXXXX-XXXXX-XXXX started nrt flyio/hellofly:latest fdaa:9:4eda:a7b:2df:590c:XXXX:2 2024-09-01T03:46:19Z 2024-09-01T04:18:17Z app shared-cpu-1x:256MB
908016e3cdXXXX XXXXX-XXXXX-XXXX started nrt flyio/hellofly:latest fdaa:9:4eda:a7b:2de:36bc:XXXX:2 2024-09-01T03:46:32Z 2024-09-01T04:06:07Z app shared-cpu-1x:256MB
-s オプション
「 -s
」は「 fly console -s
」とほぼ同等の機能で「ephemeral machine」の選択肢がないバージョンと考えれば良さそうです。
% fly ssh console -s
? Select VM: [Use arrows to move, type to filter]
> nrt: 6e8254d5c3XXXX fdaa:9:4eda:a7b:2df:590c:XXXX:2 XXXXX-XXXXX-XXXX
nrt: 908016e3cdXXXX fdaa:9:4eda:a7b:2de:36bc:XXXX:2 XXXXX-XXXXX-XXXX
-u オプション
最後は「 -u
」を試してみます。「 --help
」に「Unix username to connect as (default "root")」と記載されているとおり、仮想マシンに接続する際のユーザーは通常「root」になっています。
接続後に「 whoami
」を実行すると「root」と表示されます。
% fly ssh console --machine 6e8254d5c3XXXX
Connecting to fdaa:9:4eda:a7b:2df:590c:XXXX:2... complete
6e8254d5c3XXXX:/goapp# whoami
root
「 -u
」を指定したログインに使えそうなユーザーを確認したところ、どうやらなさそうです。
6e8254d5c3XXXX:/goapp# grep -v nologin /etc/passwd
root:x:0:0:root:/root:/bin/ash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
6e8254d5c3XXXX:/goapp#
「 -u
」を指定したログインを検証するために「testuser」を作成します。
6e8254d5c3XXXX:/goapp# adduser testuser
Changing password for testuser
New password:
Retype password:
passwd: password for testuser changed by root
6e8254d5c3XXXX:/goapp#
「 -u
」に「testuser」を指定して接続して、「 whoami 」を実行すると「testuser」と表示されます。
% fly ssh console --machine 6e8254d5c3XXXX -u testuser
Connecting to fdaa:9:4eda:a7b:2df:590c:XXXX:2... complete
6e8254d5c3XXXX:/goapp$ whoami
testuser
console_command
なお、 fly ssh console
の --help
に console_command
の記述がないことでわかるとおり、 console_command
の影響を受けるのは fly console
のみとなります。
fly ssh console
は他にもいくつかオプションが指定可能ですが、主要なオプションについての使用方法がわかったかと思います。
まとめ
- 「
fly console
」、「fly ssh console
」のどちらを使ってもよいが、「fly console
」を利用すると意図せず「ephemeral machine」に接続される場合があるので、どちらを利用するにしても「--machine
」を指定した方がよいのではないかと感じました。 - 「
fly ssh console
」で引数を与えない場合は、意図した仮想マシンに接続できていない可能性がある(例えば、「webアプリケーション用途」と「定期処理用途」で仮想マシンの「PROCESS GROUP」を分けている場合など)ので、こういった場合もやはり「--machine
」を指定した方がよいかと思います。 - 「
fly console
」と「fly ssh console
」では「-a
」を指定した場合の挙動が異なるので、「-a
」はなるべく使わない方がよさそうです。 - これまではFly.ioの画面上や
fly machine list
で仮想マシンのIDを調べて「--machine 6e8254d5c3XXXX
」のように指定していましたが、「fly console
」、「fly ssh console
」のいずれの場合でも「-s
」を指定することで稼働中の仮想マシンを選択して接続できることがわかりました。