コンテナへのネットワーク(HTTP)アクセスの確認

コンテナへのネットワークアクセスを確認するために、Dockerイメージ「nginx」を導入し、確認してみます。

(参考)
「Docker入門(第二回)~Dockerセットアップ、コンテナ起動~ | さくらのナレッジ」
https://knowledge.sakura.ad.jp/13795/

まずは、「docker pull」コマンドにて、nginxのDockerイメージを取得します。

$ docker pull nginx:1.14
1.14: Pulling from library/nginx
6ae821421a7d: Already exists
7edc8c3fac48: Pull complete
a19c4a4a77fe: Pull complete
Digest:  sha256:d1eed840d5b357b897a872d17cdaa8a4fc8e6eb43faa8ad2febb31ce0c537910
Status: Downloaded newer image for nginx:1.14

nginx」とだけ指定すると、最新のバージョン(latest)が取得されます。今回は(特に意味はありませんが)バージョン 1.14 を指定して取得してみます。

docker images」コマンドで取得したイメージのリストを確認してみます。

$ docker images
REPOSITORY       TAG           IMAGE ID         CREATED         SIZE
nginx            1.14          1293e2b0a1af     2 weeks ago     109MB

nginx:1.14」のDockerイメージのサイズは109MBのようです。ちなみに「nginx:1.14-alpine」と指定すると。。。

$ docker images
REPOSITORY      TAG             IMAGE ID        CREATED          SIZE
nginx           1.14-alpine     66952fd0a8ef    3  weeks ago     16MB

なんとサイズは16MB! この場合、Alpine Linuxという軽量なLinuxがOSになります。

取得したnginxイメージよりコンテナを起動します。

$ docker run -d --name nginx-container -p 8080:80 nginx:1.14
cb0a6dc4871d43ca67751698c432886bee9683ea6c1b11cdf8a707980e25833d

docker run」コマンドのオプションは以下のとおり。

  • -d … コンテナをバックグラウンドで実行します
  • -name … コンテナの名前を付けます
  • -p … ポートフォワード設定「ホスト側ポート:コンテナ側ポート」

すると最初にこのようにポートフォワード設定込みのrunを実行した場合は、Windows Defender ファイアウォールのダイアログが現れます。
Dockerの仮想ネットワークライブラリ「VPNkit」のアクセスを許可します。
(ちなみに、「VPNkit」の場所は、C:\program files\docker\docker\resources\vpnkit.exe です)

docker ps」コマンドにて、実行されているコンテナの一覧が表示されます。「docker ps -a」と指定した場合は、停止中のコンテナも含めて表示されます。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                   CREATED             STATUS              PORTS                   NAMES
cb0a6dc4871d        nginx:1.14          "nginx -g 'daemon of…"    13 hours ago        Up 46 seconds       0.0.0.0:8080->80/tcp    nginx-container

見ると、nginxのデーモンが既に走っていて、8080番ポートがコンテナの80番ポートにフォワーディングされているのが確認できます。

それでは、WWWブラウザで「http://localhost:8080/」にアクセスしてみます。
ブラウザ上に「Welcome to nginx!」と表示されればOKです。

{4B8262CE-8D97-4387-939E-A870FADBD3DF}

(curlにて確認)

$ curl -I http://localhost:8080/
HTTP/1.1 200 OK
Server: nginx/1.14.2
:

続いて、「docker exec」コマンドにて、コンテナに接続してみます。

(書式)
docker exec [オプション] [コンテナ] [コマンド]

  • -d …コンテナにて指定したコマンドをバックグラウンドで実行します
  • -i …ホストの標準入力をコンテナの標準入力に接続します
  • -t …コンテナに疑似仮想端末(tty)を割り当てホストの標準出力と接続します

bashコマンドを指定すると、コンテナ内のbashが起動します。

$ docker exec -it nginx-container bash

コンテナのシェルにて色々調べてみます。

root@cb0a6dc4871d:/# cat /etc/os-release

PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
:

OSはDebianのようですね。
次に、nginxの設定ファイル(default.conf)の内容を確認してみます。

root@cb0a6dc4871d:/# grep -v ^.*# /etc/nginx/conf.d/default.conf |  grep -v ^$
server {
    listen       80;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

ドキュメントルートは「/usr/share/nginx/html」のようなので、このディレクトリに適当なHTMLファイル「hello.html」を作成してみます。

root@cb0a6dc4871d:/# echo "<h1>Hello World</h1>" > /usr/share/nginx/html/hello.html

実際に作られたかどうか確認します。

root@cb0a6dc4871d:/# cat /usr/share/nginx/html/hello.html
<h1>Hello World</h1>

exitコマンドでコンテナのシェルから抜けます。
それでは、ホスト側のWWWブラウザにて「http://localhost:8080/hello.html」にアクセスしてみます。

{ED9CD3F9-EC91-4157-829C-1CE02AB9E3E9}

先ほど作成したHTMLファイルの内容が表示されました。

(curlにて確認)

$ curl -i http://localhost:8080/hello.html
HTTP/1.1 200 OK
Server: nginx/1.14.2
:
Accept-Ranges: bytes
<h1>Hello World</h1>

ここで、「docker stop」コマンドにて、一旦コンテナを停止してみます。

$ docker stop nginx-container
nginx-container

nginxへのアクセスは拒否されます。

$ curl -i http://localhost:8080/hello.html
curl: (7) Failed to connect to localhost port 8080: 接続を拒否されました

またコンテナを起動してみます。今度は「docker start」コマンドです。

$ docker start nginx-container
nginx-container

先ほどのページにアクセスできます。

$ curl -i http://localhost:8080/hello.html
HTTP/1.1 200 OK
Server: nginx/1.14.2
:Accept-Ranges: bytes
<h1>Hello World</h1>

再度またコンテナを停止して、

$ docker stop nginx-container
nginx-container

docker rm」コマンドにて、nginxのコンテナを削除します

$ docker rm nginx-container
nginx-container

「docker ps -a」コマンドにて、コンテナが削除されているのを確認します。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES

コンテナを削除してしまうと、先ほどコンテナ内で作成したHTMLファイル(hello.html)も無くなります。コンテナにて永続的にデータを残したい場合は、ホスト側ディレクトリをコンテナ側のディレクトリにマウントさせます。

(以降、ホスト側とコンテナ側でシェルを区別するために、ホスト側のプロンプトを [foo@host]$ で記載します。)

まずは、ホスト側でカレントディレクトリ上に適当なディレクトリ(例として、「htdocs」)を作成し、そこに適当なHTMLファイル(例として、「test.html」)を作成しておきます。

[foo@host]$ mkdir htdocs
[foo@host]$ echo "<h1>Share contents</h1>" > htdocs/test.html

このHTMLファイルをコンテナのWebサーバ(nginx)のコンテンツとして表示できるようにしてみます。とりあえず確認。

[foo@host]$ cat htdocs/test.html
<h1>Share contents</h1>

docker run」コマンドにて、「-v」オプションを指定して起動します。

  • -v [ホスト側ディレクトリ]:[コンテナ側ディレクトリ]… ホスト側ディレクトリを指定したコンテナ側ディレクトリにマウントします

ホスト側ディレクトリは、絶対パスで指定する必要がありますので、カレントディレクトリを示す環境変数 PWD を使用して、「-v $PWD/htdocs:/usr/share/nginx/html」のように指定します。

ホスト側ディレクトリ $PWD/htdocs → コンテナ側ディレクトリ /usr/share/nginx/html

それでは、ちょっと長くなりますが docker run コマンドにてコンテナを作成および実行します。

[foo@host]$ docker run -d --name nginx-container -p 8080:80 -v $PWD/htdocs:/usr/share/nginx/html nginx:1.14
0aba15c3534dd1199dcc06d4136a14da8bad65a41898d954b02524df76ce3900

コンテナは無事に生成されたようです。
それではホスト側からコンテナのWebサーバにアクセスしてみます。

(curlにて確認)

[foo@host]$ curl http://localhost:8080/test.html

404 Not Found
<h1>404 Not Found</h1>

<hr />

nginx/1.14.2

あれれー、「404 Not Found」ってなってるよー(´・ω・`)

ということは、/usr/share/nginx/html/test.html は存在しない、つまりホスト側ディレクトリとのマウントがうまくいっていないことになります。

元々、このDockerサーバは、Docker for Windows で動いていますので、同じコマンドを今度はWindows Power Shell で実行してみます。

PS C:\Users\foo\Workspace> docker run -d --name nginx-container -p 8080:80 -v $PWD/htdocs:/usr/share/nginx/html nginx:1.14
c5160935d71ce8e2caaad650c87bf627ea15191b5320f431d9ee47ba421c5090
PS C:\Users\foo\Workspace>

それではホスト側からコンテナのWebサーバにアクセスしてみます。

(curlにて確認)

[foo@host]$ curl http://localhost:8080/test.html
<h1>Share contents</h1>

うまくいきました。
その理由は、Docker for WindowsでのDockerクライアントを利用しているせいだと思います。

WSL上とPower Shell上、それぞれにて環境変数 PWD の値を確認してみます。

まずは、WSL上のbashにて、PWDの値を確認してみます。

[foo@host]$ echo $PWD
/home/foo/Workspace

続いて、Windows Power Shellにて、PWDの値を確認してみます。

PS C:\Users\foo\Workspace> echo "$PWD"
C:\Users\foo\Workspace

Docker for WindowsのDockerエンジンは、後者の方のパス(「C:\」で始まるパス)を要求してくるのです。

これの解決法については、また後日記事としてまとめます。

最後に、nginxのコンテナとイメージを削除しておきます。Dockerイメージの削除は「docker rmi」コマンドにて行います。

[foo@host]$ docker rm nginx-container
[foo@host]$ docker rmi nginx

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中