2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Dockerの便利なコマンドを使ってみよう

Last updated at Posted at 2022-12-06

これは フェンリル デザインとテクノロジー Advent Calendar 2022 4日目の記事です。

shinkai_makkoukujira.png

Dockerを使う方の中には buildup コマンドくらいしか使ったことない方も大勢いるのではないでしょうか。Dockerのコマンド一覧のドキュメントを見てみると、見たことすら無いものもたくさんあると思います。

今回はたくさんある機能の中から、リモートのDockerを便利に使うためのコマンドを2つ紹介したいと思います。

作業環境

以降の作業は以下の環境で実行したものです。

  • PC : MacBook Pro 13-inch 2020
  • OS : macOS Ventura 13.0.1
  • Docker Engine : 20.10.21

docker save / docker load

ビルドしたDockerイメージをリモートのサーバーに持っていきたいけど、レジストリを用意するほどでもない…。そんなときにはこのコマンドを使ってみましょう。

コマンドの使い方は以下のとおりです。

$ docker save [OPTIONS] IMAGE [IMAGE...]
Name, shorthand Default Description
--output , -o Write to a file, instead of STDOUT
$ docker load [OPTIONS]
Name, shorthand Default Description
--input , -i Read from tar archive file, instead of STDIN
--quiet , -q Suppress the load output

引用元 : docker save / docker load

事前に Hello World と出力するだけのDockerイメージを作成しておきます。

Dockerfile
FROM alpine:latest
CMD ["echo","Hello World"]

ビルドと実行をします。

bash
$ docker build -q -t helloworld .
sha256:b8e5160def5593aab3002009595fcdd031d249bbc240f26260090f88bfe36c2f
$ docker image ls helloworld
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
helloworld   latest    b8e5160def55   13 days ago   7.05MB
$ docker run --rm helloworld
Hello World

Hello World と出力されています。

ではこのイメージを docker save コマンドでアーカイブファイルとして出力してみましょう。

bash
$ docker save helloworld > helloworld.tar
$ ls -lah helloworld.tar 
-rw-r--r--  1 yoneda  staff   7.0M 12  4 00:00 helloworld.tar

tar ファイルとして保存されました!

本当に保存されたか確認するために、先程ビルドしたDockerイメージを削除してみましょう。

bash
$ docker rmi helloworld
Untagged: helloworld:latest
Deleted: sha256:b8e5160def5593aab3002009595fcdd031d249bbc240f26260090f88bfe36c2f

イメージの削除ができたので、出力されたアーカイブファイルから docker load コマンドでイメージを読み込ませてみましょう。

bash
$ docker load -q < helloworld.tar 
Loaded image: helloworld:latest
$ docker image ls helloworld
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
helloworld   latest    b8e5160def55   13 days ago   7.05MB

一覧に helloworld のイメージが復活していますね。では実行してみましょう。

bash
$ docker run --rm helloworld
Hello World

Hello World が出力されました!!

このように docker save / docker load コマンドを使うことで、レジストリを用意することなくDockerイメージをファイルとして自由に持ち運ぶことができます。scp コマンドを利用すれば別のサーバーに持っていくこともできますね。

注意点としては、Docker Hub等のレジストリを使う場合にはイメージを複数に分割して並列でアップロード・ダウンロードが実行されるのですが、docker save / docker load の場合は単一のファイルとして転送することになるため、大きなイメージになればなるほど転送時間が長くなってしまいます。gzipで圧縮をするなどの工夫をしましょう。

docker context

リモートのサーバー上で動いているDockerを操作するために、まずはSSHで接続してから、ディレクトリを移動して、dockerコマンドを打ち込んで…。こんな操作を頻繁にしている人も多いのではないでしょうか。そんなときにはこのコマンドを使ってDockerをリモートで操作してみましょう。

まずはリモートで動作するDockerを準備します。ここでは以下のようなAWS EC2を利用します。

  • Instance type : t3.medium
  • AMI ID : ami-072bfb8ae2c884cc4 (Amazon Linux 2 Kernel 5.10)
  • Public IP address : 54.248.12.145

注意点としては、外部からTCP 2375番ポートを経由してDockerを操作することになるため、何らかの手段で経路を確保する必要がある点です。EC2の場合はSystems ManagerのSession Managerを使って2375番ポートをローカルにポートフォワードさせる事を推奨します。

参考URL : SSM Session Managerを使ってポートフォワードする | DevelopersIO

今回は作業を簡易的にするため、EC2インスタンスをパブリックネットワークに作成することでパブリックIPを割り当て、セキュリティグループで該当ポート経由の通信を許可するように設定します。

スクリーンショット

EC2インスタンスの起動が完了したらDockerのインストールと起動をします。

bash (remote)
$ sudo amazon-linux-extras install docker
Installing docker
...
(省略)
...
$ sudo systemctl start docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: https://docs.docker.com
$ sudo docker -v
Docker version 20.10.17, build 100c701

次にDaemon socket optionを使い、TCP 2375番で待ち受ける設定を追加します。/var/lib/systemd/system/docker.serviceExecStart で始まる行を確認します。

/var/lib/systemd/system/docker.service (remote)
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock $OPTIONS $DOCKER_STORAGE_OPTIONS $DOCKER_ADD_RUNTIMES

ここに -H tcp://0.0.0.0:2375 を追加しましょう。

公式ドキュメント : Daemon CLI (dockerd) / Daemon socket option

/var/lib/systemd/system/docker.service (remote)
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock $OPTIONS $DOCKER_STORAGE_OPTIONS $DOCKER_ADD_RUNTIMES

設定を変更したら、Dockerを再起動します。

bash (remote)
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

これでリモート側の準備は完了です。ここからはローカルPC側の設定をしていきます。 docker context create コマンドでリモートのDockerを登録しましょう。

コマンドの使い方は以下のとおりです。

$ docker context create [OPTIONS] CONTEXT
Name, shorthand Default Description
--default-stack-orchestrator (deprecated)Default orchestrator for stack operations to use with this context (swarm|kubernetes|all)
--description Description of the context
--docker set the docker endpoint
--from create context from a named context
--kubernetes (deprecated)(Kubernetes) set the kubernetes endpoint

引用元 : docker context create

--docker オプションを利用して、先程設定したリモートで動いているDockerのエンドポイントを指定します。

bash (local)
$ docker context create --docker host=tcp://54.248.12.145:2375 remote
remote
Successfully created context "remote"

remote という名前で作成が完了しました。それでは --context オプションを付けてローカルからリモートのDockerを操作し、適当なイメージをPullしてみましょう。

bash (local)
$ docker --context remote pull docker/whalesay
Using default tag: latest
latest: Pulling from docker/whalesay
Image docker.io/docker/whalesay:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
e190868d63f8: Pull complete 
909cd34c6fd7: Pull complete 
0b9bfabab7c1: Pull complete 
a3ed95caeb02: Pull complete 
00bf65475aba: Pull complete 
c57b6bcc83e3: Pull complete 
8978f6879e2f: Pull complete 
8eed3712d2cf: Pull complete 
Digest: sha256:178598e51a26abbc958b8a2e48825c90bc22e641de3d31e18aaf55f3258ba93b
Status: Downloaded newer image for docker/whalesay:latest
docker.io/docker/whalesay:latest

Pullが完了しました。リモート側のターミナルに接続してイメージの確認をしてみましょう。

bash (remote)
$ sudo docker image ls
REPOSITORY        TAG       IMAGE ID       CREATED       SIZE
docker/whalesay   latest    6b362a9f73eb   7 years ago   247MB

先程ローカルから操作してPullしたイメージが保存されていることが確認できました。

応用してみる

今回紹介した docker save / docker loaddocker context ですが、組み合わせて使うことができます。前半に docker save で出力した helloworld.tar を、--context オプションを付けてリモートのDockerに docker load で読み込ませてみましょう。

bash (local)
$ docker --context remote load < helloworld.tar 
ded7a220bb05: Loading layer [==================================================>]  7.338MB/7.338MB
Loaded image: helloworld:latest
$ docker --context remote image ls helloworld
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
helloworld   latest    b8e5160def55   13 days ago   7.05MB
$ docker --context remote run --rm helloworld
Hello World

ビルドしたイメージをリモートのDockerに転送して実行することができました。簡易的なデプロイが実現できましたね。

まとめ

たくさんあるDockerの機能の中から、今回は docker save / docker loaddocker context を紹介しました。あまり使っている例を見かけないコマンドたちではありますが、いざ使ってみると「こんなことにも使えるのでは…?」となったのではないでしょうか。

これ以外にもDockerには様々なコマンドが用意されているので、どんどん試してDockerマスターを目指しましょう!!!

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?