Dockerハンズオン
私が、Dockerハンズオンを行った資料を再編したものです。
また、この記事は 一関高専 Advent Calendar 2023アドベントカレンダーの1日目です。
概要
Dockerとは
コンテナを便利に使うためのツール
コンテナとは、
これは違う
新しい仮想化技術
概念図
従来の仮想化技術
ホストOSの上に仮想化ソフトウェアを用いて、ゲストOSをエミュレートしていた。
OSのイメージを用いて、ゲストOSをインストールする必要があった。
例:
- QEMU
- Hyper-V
- VirtualBox
- VMware
コンテナの仮想化技術
ホストOSのカーネルを共有して、ホストOSの上でコンテナを動かす。
カーネルとは
OSの中核となる部分のこと。ハードウェアを直接制御する部分。
カーネルが、ハードウェアを直接制御することで、アプリケーションがハードウェアを直接制御する必要がなくなり、ハードウェアに関係なくアプリケーションを動かすことができるようになる。
Open Container Initiative(OCI)でコンテナのフォーマットやランタイムの実装が決められている。
イメージを使用して、コンテナを作成することができる。
設計図と製品の関係に似ている
設計図 → イメージ
製品 → コンテナ
オブジェクト思考のクラスとインスタンスの関係に似ている
クラス → イメージ
インスタンス → コンテナ
より詳細な解説
Linuxは、すべてのプロセスに対して、プロセスIDを割り当てている。プロセスIDは、プロセスを一意に識別しさまざまな制御を行っている。
このプロセスIDに加えてどのnamespaceに属しているかという情報を付与し、プロセスをコンテナごとの分離している。
こうすることで、コンテナでの仮想化を実現している。
イメージとは
コンテナの元となるテンプレート。
コンテナを動かすために必要な情報(ファイル、さまざまなコンフィグ)をひとまとめにしたもの。
コンテナのメリット
- 仮想環境の作成の時に、イメージだけでいい
- 手間が少ない
- ISOファイルをわざわざ準備しなくていい
- イメージはすぐに使える状態のため、簡単に作成ができる
- 複数台のマシーンに複数のコンテナを一気にデプロイできる
- 手間が少ない
- 軽い
- OSまでエミュレートする必要がないため
- それぞれのカーネルで必要な処理が一つのカーネルで済むため
- 一つのサーバに今まで以上の仮想マシーンが載っけられる
また、これらのことにより扱いが簡単なため、開発でもDockerが用いられる。
開発環境をイメージごと運用環境へデプロイ
従来:インストールをサーバごとに直接やる必要があった。
Dockerを使うメリット
- イメージの作成を容易に行える
- イメージを手作業で作るのはすごいめんどくさい
- 設定ファイルを作ってビルドするだけ
- Docker Hub でイメージが共有されている
- 100,000 を超えるイメージ
- 公式が出しているイメージも多い
- 言語がすでに入っているイメージを用いれば開発環境がすぐに作れる
- イメージを手作業で作るのはすごいめんどくさい
- コマンド一つで、簡単にデプロイ
- イメージとコンテナの管理をどちらもやってるから、簡単
ハンズオン
Dockerのインストール
Docker Desktop は企業等では有料な場合があるため注意
インストールができない場合
Github アカウントを持っていれば、Github Codespaceを用いてDockerを触ってみることができる
- https://github.com/aoki-taquan/docker-in-docker を開く
- 右上のCode > Codespaces > Create New Codespaceをクリック
- ブラウザ版のVSCodeがDockerが入っているマシーンにリンクされて開くため、そこのターミナルを
Hello World
Dockerアプリを起動する
Dockerは、デーモンプロセスとして動くため、windowならタスクトレイ、 Macはメニューバーに表示されているだけの場合もある
docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
719385e32844: Pull complete
Digest: sha256:c79d06dfdfd3d3eb04cafd0dc2bacab0992ebc243e083cabe208bac4dd7759e0
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
やっていること、
'hello-world'というイメージがローカルにない
Unable to find image 'hello-world:latest' locally
そのためDocker Hubから、'hello-world'というイメージを探してダウンロードする(pull)
latest: Pulling from library/hello-world
719385e32844: Pull complete
Digest: sha256:c79d06dfdfd3d3eb04cafd0dc2bacab0992ebc243e083cabe208bac4dd7759e0
Status: Downloaded newer image for hello-world:latest
イメージをもとにコンテナが立ち上がり、Hello from Docker!と説明書きをprintしてくれている
Hello from Docker!
...
基本的な使い方
イメージの確認
以下のコマンドで、ローカルにあるイメージを確認できる
docker images
先ほどのhello-worldがローカルにあることがわかる
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 9c7a54a9a43c 6 months ago 13.3kB
それぞれの意味
REPOSITORY | イメージの名前 |
TAG | イメージのバージョン |
IMAGE ID | イメージを一意に識別するためのID |
CREATED | イメージが作成された日時 |
SIZE | イメージのサイズ |
IMAGE IDや、REPOSITORYとTAGを組み合わせて、イメージを指定することができる
イメージの取得
docker pull <イメージ名>:<タグ>
タグを省略すると、latestが指定される
Ubuntuを取得してみる
docker pull ubuntu:latest
ubuntuのイメージが取得できることがわかる
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest e4c58958181a 8 weeks ago 77.8MB
hello-world latest 9c7a54a9a43c 7 months ago 13.3kB
versionを指定してみる
docker pull ubuntu:3.10
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python 3.10 c2fedeb2859f 6 weeks ago 1GB
ubuntu latest e4c58958181a 8 weeks ago 77.8MB
hello-world latest 9c7a54a9a43c 7 months ago 13.3kB
イメージからコンテナを作成する
docker run <イメージ名>:<タグ>
すぐ終わる
docker run ubuntu:latest
以下のコマンドで起動することで、shellを操作できる
docke run -it ubuntu:latest
bashを起動したいなら、
docker run -it ubuntu:latest bash
解説
オプションの意味
i: 標準入力を割り当てる
t: tty(仮想コンソール)を割り当てる
イメージを指定した直後に、コマンドを指定すると、コンテナが起動した直後にそのコマンドが実行される
docker run -it <イメージ名> <コマンド>
shellから抜ける方法
-
exit
コンテナが終了する -
Ctrl + P + Q
コンテナは終了せず、バックグラウンドで実行され続ける
runとexecでShellから抜ける時の挙動の違い
run | exec | |
---|---|---|
exit | コンテナが終了する | バックグラウンドで実行され続ける |
Ctrl + P + Q | バックグラウンドで実行され続ける | バックグラウンドで実行され続ける |
コンテナの確認
以下のコマンドで、起動中のコンテナを確認できる
docker ps
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
停止しているコンテナも含めて確認できる
docker ps -a
a オプションをつけると、停止しているコンテナも表示される
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27bc600a2586 ubuntu "/bin/bash" 8 hours ago Exited (255) 8 hours ago happy_shockley
8b0d689cb3b5 hello-world "/hello" 27 hours ago Exited (0) 27 hours ago brave_brown
コンテナを削除する
前の章で確認した、コンテナを削除する
それぞれのSTATUSを見て、削除していく
docker ps -a
起動状態から停止状態にする
以下のコマンドで、起動中のコンテナを停止する
docker stop <コンテナID>
停止状態のコンテナを削除する
docker rm <コンテナID>
操作の結果、適切にコンテナの状態が変化していることがわかる
docker ps -a
イメージを削除する
削除するイメージを確認する
docker images
削除コマンド
docker rmi <イメージID>
ubuntuを削除する
docker rmi ubuntu
ubuntuのイメージが削除されたことがわかる
docker images
コンテナにストレージをマウントする方法
docker run -it -v <ホスト側のディレクトリ>:<コンテナ側のディレクトリ> <イメージ名>
docker run -it -v .:/root/moutfolder ubuntu
lsをすることで docker run
した場所のファイルがマウントされていることがわかる
ls /root/moutfolder
その他
exec
docker exec <コンテナID> <コマンド>
実行中のコンテナに対して、コマンドを実行するコマンド
attach
docker attach <コンテナID>
実行中のコンテナにアタッチするコマンド
コンテナを自作してみよう
Dockerでは、Dockerfileというファイルを書くことで簡単にイメージを作成することができる
Dockerfileの書き方
構文
FROM <ベースとなるイメージ>
RUN <コマンド>
FROMでベースとなるイメージを指定する
RUNでFROMで指定したイメージに対して、コマンドを実行する
他にもファイルや環境変数、ネットワークの設定ができるため、詳しくは公式ドキュメントを参照
ubuntuに、vim、treeを追加でインストールするDockerfile
vim:テキストエディタ
tree:ディレクトリ構造を表示するコマンド
FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y vim tree
Dockerfileからイメージを作成する
docker build -t <イメージ名>:<タグ> <Dockerfileのパス>
-t: イメージ名とタグを指定するオプション
<Dockerfileのパス>は、DockerFileがあるディレクトリのパスを指定する
docker build -t my-ubuntu:latest .
イメージが作成されたことがわかる
docker images
イメージからコンテナを作成する
docker run -it my-ubuntu:latest
vimやtreeがインストールされていることがわかる
vim
tree
Docker Compose
複数のコンテナを一括で管理するためのツール
Dockerには、コンテナ毎に1つのプロセスだけ実行というポリシーがある。
Dockerfile のベストプラクティス — Docker-docs-ja 1.9.0b ドキュメント
しかし、複数のコンテナを一括で管理したい場合がある。
例えば、Webアプリケーションを作成する場合、WebサーバとDBサーバを別々のコンテナで管理したい。
このような場合に、Docker Composeを用いると便利
詳細は省きます。
Docker Compose とは — Docker-docs-ja 1.9.03 ドキュメント
VScode Remote Container
開発環境で、一々Dockerをアタッチするのは面倒
VSCode のRemote SSH のような感覚で使いたい
Dev Containers を用いると、わざわざDockerfileを書かずに、Microsoftが作ってくれているテンプレートをもとにDocker開発環境を作成することができる
使い方
- VSCodeの拡張機能から、Dev Containersをインストールする
- 左したの >< をクリックし、Reopen in Containerをクリックする
- テンプレートが表示されるので、適当なものを選択する
- オプションが表示されるが、基本的にはデフォルトで問題ない
- しばらく待つと、コンテナが立ち上がる
これだけで、言語ごとの開発環境が立ち上がる
競合等が、起きることがない(最高😆)
行われていること、
そのフォルダに、 .devcontainer > .devcontainer.jsonというファイルが作成される
そこにテンプレートから選んだものの設定が書かれている
この設定をもとに、コンテナが立ち上がる
このファイルごと、gitでソースコードを共有することで、ほぼ同一の開発環境を複数人で共有できる
まとめ
Dockerは、コンテナを簡単に扱うためのツール
Discussion