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 のアーキテクチャ

アーキテクチャの図で、会場は盛り上がりました。レジストリのアイコンはなんだ?

まず初めに、

画像1

こちらは、Ubuntu アイコンです。

画像2

続いて、CentOS アイコンです。

画像3

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 をブラウザーから確認すると、リポジトリが追加された事がわかります。

スクリーンショット 2020-02-06 16.31.40

リモート・リポジトリにあるイメージの取得と実行

$ 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

イメージとコンテナについて、理解するには、

謎の生命体の生成を例にとるとわかりやすい

謎の生命体を作る設計図を、イメージ

謎の生命体 が コンテナ

生まれるし

眠らされる

息がえる

から謎の生命体がわかりやすい。

この記事が気に入ったらサポートをしてみませんか?