Dockerに今さら入門してみる(Part 1)~環境構築とコンテナの使用方法~
「Dockerを使えば簡単に環境構築出来るよ」と耳にタコが出来るほど聞くけど、「フーン、そうなんだ」と聞き流していました。 「新年度も始まったし新しいことに挑戦するか」ということで今さらですが、Docker入門をしてみました。
書いていることに誤りがある場合は、ご指摘頂けるとありがたいです。
Part 1では環境構築とコンテナの操作を行っています。
Dockerとは
Dockerとは、Linuxのコンテナ技術をベースに作成された、仮想化技術のことです。
- コンテナとは?
また、公式ページでのコンテナの説明
A container is launched by running an image. An image is an executable package that includes everything needed to run an application--the code, a runtime, libraries, environment variables, and configuration files. コンテナはimage
何がうれしいの?
1, 軽量
Dockerが主流になる前までは、VirtualBoxなど従来のハイパーバイザ型の仮想化が主流でした。 (ハイパーバイザー)http://wa3.i-3-i.info/word12196.htmlという仮想マシンをホストOS上に作成するし、その上にホストOSを稼働させる方式です。 これによりホストOSとゲストOSの分離を実現していました。 しかし、仮想マシンとゲストOSの(イメージファイル)http://wa3.i-3-i.info/word15853.html必要になりオーバーヘッド増えます。
Dockerは各アプリケーションをLinuxのコンテナ技術によって、
ホストOSのKernelは共有しつつも、各コンテナ内のアプリケーションを分離した名前空間の中で実行できます。
(コンテナで区切られた空間それぞれに別のバージョンのMySQLが存在しても競合しない) 単に名前空間を分離しているだけなので、仮想マシンのエミュレーションも行われないため、イメージサイズも抑えられ 軽量化が可能です。
(https://www.ogis-ri.co.jp/otc/hiroba/technical/docker/part1.htmlより)
2. 様々な環境にデプロイできる
Windows, Macをはじめ、AWSなど様々な環境で動作させることが可能です。
環境構築
実行環境
- Windows 10
- DockerToolbox
DockerToolboxのインストール
ここから、DockerToolboxをインストール docs.docker.com
インストールのマニュアルは以下を参照 docs.docker.com
動作確認のためコマンドを入力
$ docker info error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.37/info: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.
エラーが発生したため、、、 dockerでネットワークエラー - This is a Penを参考に解決。 1. Dockerマシンの再度作成
$ docker-machine rm default $ docker-machine create default --driver virtualbox
- 環境変数を設定
eval` "$(docker-machine env default)"`
実行したら、以下の様なメッセージが出た。
Error checking TLS connection: Error checking and/or regenerating the certs: There was an error validating certificates for host "192.168.99.103:2376": x509: certificate signed by unknown authority You can attempt to regenerate them using 'docker-machine regenerate-certs [name]'. Be advised that this will trigger a Docker daemon restart which might stop running containers.
言われるがまま、docker-machine regenerate-certs
を実行。
再度、環境変数の確認。
$ sudo eval` "$(docker-machine env default)"` bash: export DOCKER_TLS_VERIFY="1" export DOCKER_HOST="tcp://192.168.99.103:2376" export DOCKER_CERT_PATH="C:\Users\Shusaku SAHASHI\.docker\machine\machines\default" export DOCKER_MACHINE_NAME="default" export COMPOSE_CONVERT_WINDOWS_PATHS="true" # Run this command to configure your shell: # eval $("C:\Program Files\Docker Toolbox\docker-machine.exe" env default): No such file or directory
その後、言われるがまま、
eval $("C:\Program Files\Docker Toolbox\docker-machine.exe" env default):
を実行したら治りました。
公式チュートリアルをやってみる。
Docker公式サイトのチュートリアルをこなしていきます。 docs.docker.com 公式文章を読んでいると、コンテナはimageから生成されるらしい。
Dockerのバージョンを確認する
> docker --version Docker version 18.03.1-ce, build 9ee9f40
Dockerコンテナのインストール
Dockerのコンテナイメージのインストールを行う。
今回インストールを行うのはhello-world
> docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 9bb5a5d4561a: Pull complete Digest: sha256:f5233545e43561214ca4891fd1157e1c3c563316ed8e237750d59bde73361e77 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 a mbitious, 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/engine/userguide/
Docker上でアプリケーションを動かく際の構成
Dockerでアプリケーションを作成する際には、場合により3つの階層構造を構成する必要があるみたいです。(下に行くほど低レイヤー)
- Stack
- サービスをどのようにインターラクションするか。
- Service
- プロダクト内の各コンテナをどの様に動かすかを決める。
- Container <- ここからチュートリアルが始まります。
Dockerfile
の作成
Dockerfile
はコンテナ内の環境を定義するファイル。- ネットワークインターフェイスやデスクドライブはDockerホスト内にすでに存在する。
- ポートマッピングやオレオレファイルのコピーは自分で行ってね! <- これを行うのがDockerfile
- 一度Dockerfileを作ってしまえば、同様の設定を持つコンテナをコピーすることが可能。
- Dockerfileで環境を作成した後に、Pythonなどのアプリ系をいれる。
Dockerfileを書いてみる。
Dockerfile リファレンス — Docker-docs-ja 17.06.Beta ドキュメントを参考にしならが、一部コマンドの解説を入れています。 下記の3ファイルを同じフォルダに格納する。
# Use an official Python runtime as a parent image FROM python:2.7-slim # Set the working directory to /app WORKDIR /app # Copy the current directory contents into the container at /app ADD . /app # Install any needed packages specified in requirements.txt RUN pip install --trusted-host pypi.python.org -r requirements.txt # Make port 80 available to the world outside this container EXPOSE 80 # Define environment variable ENV NAME World # Run app.py when the container launches CMD ["python", "app.py"]
FROM
命令で(ベースイメージ)http://docs.docker.jp/glossary.html#base-imageを指定します。ベースイメージとは、親イメージを持たないイメージのことです。
RUN
命令は既存イメージ上の新しい例やで、あらゆるコマンドを実行しその結果をコミットする命令です。
CMD
命令は、コンテナ実行時のデフォルトを提供します 。
CMD ["パラメータ1", "パラメータ2"...]
と指定することで起動時のパラメータを定義
Dockerは、カーネルの上に多階層のImageレイヤーがあり、一番下にベースとなるImageがあります。これは概ね、DebianとかUbuntuなどのOSに相当する部分です。そして、この上に、ミドルウェアの層が重なります。たとえば、emacsやApacheなどです。それぞれのレイヤーは、下位のレイヤーを参照しています。下位のレイヤーは読み取り専用です。また、最上位のレイヤーは、書き込みできるようになっていて、下位のレイヤーに機能を付け足して独自のImageになりえます。この書き込む操作がCommitです。 https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2016/05/screenshot-2016-05-01-2.46.19-640x359.png dev.classmethod.jpより
requirements.txt
Flask Redis
app.py
from flask import Flask from redis import Redis, RedisError import os import socket # Connect to Redis redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2) app = Flask(__name__) @app.route("/") def hello(): try: visits = redis.incr("counter") except RedisError: visits = "<i>cannot connect to Redis, counter disabled</i>" html = "<h3>Hello {name}!</h3>" \ "<b>Hostname:</b> {hostname}<br/>" \ "<b>Visits:</b> {visits}" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits) if __name__ == "__main__": app.run(host='0.0.0.0', port=80)
Dockerfile
からimgaeファイルの作成をする。また、requirement.txt
とapp.py
はADDコマンドに使用する。
Docker imageを作成する。
docker build -t friendlyhello .
Dockerでアプリを立ち上げる。
docker run -p 8000:80 driendlyhello
-p
オプションで、外部からアクセスされるポート番号:コンテナ側のポート番号を指定
今回の場合、PCのポートを4000として、コンテナ側のポート番号を80とている。
ブラウザでlocalhost:4000
へアクセスしてみたが、このサイトにアクセスできません
と出た。
これは、Dockerのアドレスにアクセスしていないから。
(VirtualBoxを使用していない場合は、localhost:4000でアクセス可能。)
上記を参考に、dockerのアドレスを取得
docker-machine ip 192.168.99.103
http://192.168.99.103:4000
で起動を確認できた。
本来は-b
オプションを付けていないのでCTRL + C
でストップするはずなのだが、
Windowsの場合は明示的にstop
コマンドを入力しないとコンテナが止まらないらしい。
コンテナをバックグラウンドで実行・停止
-b
コマンドでバックグラウンド実行が可能。
docker run -b -p 4000:80 friendlyhello
また、停止したいときはstop
コマンドを使用する。
しかし、コマンドではcontainre idが必要なため、docker container ls
でidを取得する。
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES af241aaad6d1 friendlyhello "python app.py" 16 minutes ago Up 16 minutes 0.0.0.0:4000->80/tcp admiring_morse $ docker stop af241aaad6d1 af241aaad6d1