PRIME TECH TALK #4 Docker編(1) タコパするかも
開催日 2019年12月26日
PRIME TECH TALK #4 Docker編(1) タコパするかも に参加してきました。
一度、記事を削除ししまったので再投稿です。
Dockerのドキュメントを参加者でみつつ、Dockerを勉強します。
こちらを手始めに始めます。
Docker 概要
Dockerが提供するのは、コンテナ と呼ばれる、隔離された環境です。
Docker エンジン
Dcoker エンジン は、Docker CLI(コマンド群)、REST API、デーモンプロセスの3つの構成要素からなります。
Docker エンジン構成フロー図があります。
外周にネットワーク、コンテナ、イメージ、データボリュームを、Docker CLIが操作(管理)します。
Docker CLI が RESTAPI APIを通して、Docker デーモンを操作します。
ここまででたキーワードを詳しく。
ネットワーク は、コンテナ間の通信を行います。
コンテナ は、ディレクトリや、フォルダーのようなイメージです。
元は、Linuxの機能の一つであるコンテナを使ってプロセス(実行環境)を分離します。コンテナの由来は、コンテナ船のコンテナから。
一つのカーネルを共有できます。
コンテナ化したアプリは、Docker エンジン が入る、サーバーや、OS上で動く事ができます。
カーネル は、OSの中核部分にあるソフトウエアの事を言います。
イメージ は、階層(レイヤー)にわかれていてコンテナを作る時に、並列にダウンロードするテンプレートの事をいいます。
イメージにはアプリケーションの実行に必要なもの(コード、ランタイム、依存関係および必要なその他のファイルシステムオブジェクト)が含まれています。
ランタイム は、アプリケーションが実行時に必要なものを表します。
データボリューム 記憶媒体のようなもので、データを保存する場所です。
データボリュームとコンテナの違いは、コンテナ上のデータは、コンテナを廃棄すると消滅しますが、データボリューム上のデータは残ります。
Docker CLI は、Dockerコマンドを使えるようにする、コマンドラインツールです。
REST API とは、DockerコマンドからDockerデーモンを利用するための、通信規約です。
Docker オブジェクトとは、イメージ、コンテナ、ネットワーク、データ・ボリュームなどです。
Docker のアーキテクチャ
アーキテクチャの図で、会場は盛り上がりました。レジストリのアイコンはなんだ?
まず初めに、
こちらは、Ubuntu アイコンです。
続いて、CentOS アイコンです。
redis アイコンでした。
Docker デーモン
Docker クライアント
この二つは読んでおいた方がいいかと思います。
Docker レジストリ
Docker イメージの保管場所、Docker hub があり、Githubの様なサービス。
Docker イメージを共有できる場所です。
コンテナを実行すると何が起きますか?
docker run コマンドは、コンテナを起動するときに使います。
イメージの取得、コンテナの作成、コンテナの起動まで行ってくれるコマンドです。
docker run コマンドは、各機能を分けて実行できます。
イメージの取得 → $ docker pull
コンテナの作成 → $ docker create
コンテナの起動 → $ docker start
これらを $ docker run がまかなってます。
名前空間
コンテナが起動してて名前空間を利用してコンテナの分割ができます。
コントロールグループ
コントロールグループはハードウエアを制御できます。
Docker Desktop のインストール
事前にDocker ID が必要です。
上記サイトよりDocker ID を取得します。
Download from Docker Hub をクリックします。
上記URLより、Download from Docker Hub をクリックします。
指示に従い、macにインストールします。
インストールされたDockerのバージョンを確認する
ターミナルより、
$ docker --version
結果
Docker version 19.03.5, build 633a0ea
hello-worldを表示する
$ docker run hello-world
Hello from Docker!
解説
docker run コマンドを使い、hello-world イメージの取得、コンテナの生成、コンテナの起動まで行います。
hello-world はc言語でできていて、hello-world イメージがあるGithubを参照すると、C言語でできていて、複数のファイルからなっている事がわかります。
ローカルにダウンロードしたイメージを見てみる
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest aaa111a11aa1 12 months ago 1.84kB
起動中のコンテナの一覧を表示する
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
おかしいなぁ。表示されなーーい。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
A11a1111a1a1 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago agitated_mendeleev
表示された。
解説
STSTUS exited (0) コンテナが停止していた様です。
-a 引数をつけることで、停止したコンテナも表示できます。
アプリケーションを作り始めるを皆でチャレンジ
参照している日本語ドキュメントは、Dockerを使いPythonのアプリケーションを作成します。
Dockerfileでコンテナの定義
DockerfileはDocker imageを作るときに使用します。
まずは、空のディレクトリを作り移動します
$ mkdir hatodocker0 && cd hatodocker0
Dockerfile を作成する
$ touch Dockerfile
解説
Dockerfileは、テキスト形式のドキュメントなので拡張子がありません。
Dockerfileを修正
作った、Dockerfile をエディターで修正します。
上記リンクにあるファイルを貼り付けてください。
修正した、Dockerfileをみると、 app.py と requirements.txtが記述があります。各ファイルを作ります。
$ touch app.py
$ touch requirements.txt
ここまででhatodocker0ディレクトリの中身は、
Dockerfile app.py requirements.txt
の三つのファイルを作成しました。
続いて、app.py requirements.txtの修正します。
上記URLから、各ファイルの中身をエディター作り込みます。
先ほどの pip install -r requirements.txt という記述がありますが、ここでいう先ほどとは、Dockerfileに記載があります。
アプリの構築
Docker イメージの作成
$ docker build -t friendlyhello .
解説
docker build コマンドは、Dockerfileとコンテキスト(build に使用する階層のディレクトリパス)を使い、イメージを作成します。
-t 引数で、後に続くタグを指定します。
. 最後のピリオドは、Dockerfileがある階層でパスを表します。
イメージの確認
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
friendlyhello latest a8a1aa9a7a5a 7 minutes ago 159MB
python 2.7-slim 52306684a6a8 2 days ago 148MB
hello-world latest aaa289a99aa9 13 months ago 1.84kB
アプリの実行
$ docker run -p 4000:80 friendlyhello
File "app.py", line 6
SyntaxError: Non-ASCII character '\xe3' in file app.py on line 6, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
むむ。SyntaxErrorだと。古いとはいえ、公式ドキュメントの日本語訳ではないのか。app.pyにエラーが。
app.py を見ていましょう。line 6あたりがポイントのようです。redisが警告しているようです。
しかしながら、 Redis は実行できないため(Python ライブラリをインストールしただけであり、 Redis 自身は入っていません)、実行を試みても失敗し、エラーメッセージを表示するでしょう。
これか。公式の日本語訳エラーがでるサンプルを記載しないでほしい。と心に思いつつ。Redis を使わずに、Python を使いつつ、Hello, world!と表示してみます。
requirements.txt
のRedisを消す。
app.pyのredisを消す。
修正後のファイルは、
from flask import Flask
import os
import socket
app = Flask(__name__)
@app.route("/")
def hello():
html = "<h1>Hello, world!</h1>"
return html.format()
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
Dockerfileを修正します。
# 公式 Python ランタイムを親イメージとして使用
FROM python:3
# 作業ディレクトリを /app に設定
WORKDIR /app
# 現在のディレクトリの内容を、コンテナ内の /app にコピー
ADD . /app
# requirements.txt で指定された必要なパッケージを全てインストール
RUN pip install --no-cache-dir -r requirements.txt
# ポート 80 番をコンテナの外の世界でも利用可能に
EXPOSE 80
# 環境変数の定義
# ENV NAME World
# コンテナ起動時に app.py を実行
CMD ["python", "app.py"]
それでは再度実行しましょう!
Docker imageの作成
$ docker build -t friendlyhello .
Docker コンテナの起動
$ docker run -p 4000:80 friendlyhello
確認
ブラウザーで、 http://localhost:4000 を入力すると、Hello, world! と表示できたことを確認します。
サーバーの停止方法
CTRL+C
Docker イメージ を確認する
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
friendlyhello latest d41b2f04cbba 16 minutes ago 942MB
<none> <none> c8c1fe9b7b5b About an hour ago 159MB
python 2.7-slim 52306684f6d8 2 days ago 148MB
python 3 eeadc22d21a9 2 days ago 933MB
hello-world latest fce289e99eb9 13 months ago 1.84kB
解説
ダンウロードされた、イメージが表示されます。
<none> というイメージがありますが、これは、同じ名前のイメージを作り直すとできます。
Docker では、同じ名前のイメージを作ることができません。
古いイメージは、イメージ名がなくなり、<none>となります。
コンテナのプロセスを停止する
$ docker ps -a
friendlyhello の CONTAINER ID を控えます。
$ docker stop CONTAINER ID
Docker イメージの共有
Docker イメージの共有には、Dockerhubを使用します。
Docker ID でログイン
ローカルマシンから、Dockerの公開レジストリにログインします。
先にDocker ID を使い、Docker Hubにログインしている事。
$ docker login
Authenticating with existing credentials...
Login Succeeded
Docker イメージにタグをつける
docker tag image ユーザ名/リポジトリ:タグ
とあるりますが、タグをつけるコマンドは、docker tagでimageは、元のイメージ名(REPOSITORY)を指定します。
ユーザ名/リポジトリ:タグ は、Docker Hubのユーザー名/Dcoker Hubに使うリポジトリ名を指定します。
:コロンで、タグ名を指定します。
元のイメージIDの確認
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
friendlyhello latest a11a1a11aaaa 11 hours ago
REPOSITORY を控えます。
ユーザー名を確認する
ブラウザーより、
を開きます。
画面上部メニュー右にあるユーザー名を控えます。
Dcoker Hubに使うリポジトリ名を作ります。
タグを作ります。
$ docker tag 元のイメージ名 DockerHubのユーザ名/登録したいリポジトリ名:登録したいタグ名
の順に控えた情報を入れて変更したら確認します。
タグ付けしたイメージの確認
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
Dockerhubのユーザー名/登録したいリポジトリ名 タグ名 a11a1a11111a 11 hours ago
Docker hubにimageの送信
$ docker push Dockerhubのユーザー名/登録したいレポジトリ名:登録したいタグ名
Docker hub をブラウザーから確認すると、リポジトリが追加された事がわかります。
リモート・リポジトリにあるイメージの取得と実行
$ docker run -p 4000:80 Dockerhubのユーザー名/レポジトリ名:タグ名
空のディレクトリに移動します。
$ mkdir hatodocker1 && cd hatodocker1
著者のレポジトリ
$ docker run -p 4000:80 watata/get-started:part1
$ docker run -p 4000:80 arm4/get-started:part1
確認
サーバーが起動されるので、 http://localhost:4000/ で確認します。
control + cでサーバーを停止します。
イメージの確認
$ docker images | grep get-started
arm4/get-started part1 1a11aa1a11aa 5 weeks ago 159MB
解説
| grep で and (なおかつ)grep get-startedを含むimageを表示しました。
このnoteでは、イメージを作成して、Dockerhubに公開することができるようになりました。次回はDockerfileリファレンスを勉強します。
プラスワン
コンテナを削除する方法
このコマンドは、コンテナを削除するので注意!!
-aq
a 全てのコンテナから、IDのみ表示
$ docker rm $(docker ps -aq)
削除したらコンテナを確認する
$ docker ps -a
イメージとコンテナについて、理解するには、
謎の生命体の生成を例にとるとわかりやすい
謎の生命体を作る設計図を、イメージ
謎の生命体 が コンテナ
生まれるし
眠らされる
息がえる
から謎の生命体がわかりやすい。
この記事が気に入ったらサポートをしてみませんか?