akiyoko blog

akiyoko の IT技術系ブログです

「【eLV勉強会】Dockerを触ってみよう 〜 初心者向けDockerハンズオン 〜」に参加してきました

会場

CO-CreationLABO
東京都千代田区平河町1-4-3 平河町伏見ビル 2F

全体の感想など

仮想化技術と言うと、開発環境構築のために VMware や VirtualBox、Vagrant を利用することはあったのですが、Docker は今回が初体験でした。Docker については何となく知っていたのですが、やはり実際に触ってみると感覚として理解できますね。


たまたま積ん読になっていた Docker本があったので、勉強会の前にざっと目を通しておこうと思ったのですが、(良いことなのですが)詳しく書かれ過ぎていて結局核心の部分までたどり着かず。。


ついでに言うと、(「さくらのVPS」は以前に使っていましたが)「さくらのクラウド」も初、Docker 専用のホスティングサーバ「Arukas」も初体験でした。ちなみに、Arukas はさくらのインターネットが運営をしていて、今は無償公開中だそうです。



 

Dockerの基本的概念

横田真俊氏(さくらのインターネット)


  • Docker は PyCon 2013 で発表された
  • コンテナと仮想化の違い
  • コンテナはOSの代わりに各コンテナがアプリを稼働させる。ホストマシンの処理負荷が低い
  • コンテナのメリット
    • 処理速度が速い
    • メモリ・ディスクの消費量を抑えられる
    • 一番大きなメリットはポータビリティ


確かに、VirtualBox + Vagrant などの仮想化ツールで開発環境を構築するスタイルだとポータビリティ性に少し難があるように感じますし、仮想マシンの構成を管理するための Infrastructure as Code にしても「Infrastructure as Code の弊害 | Stay Creative !」で言及されているように実態とコードとの乖離が問題となります。そういった意味でも、Docker のポータビリティ容易性は大きな魅力です。

(参考)VagrantとDockerについて名前しか知らなかったので試した - Qiita




 

Dockerハンズオン

ハンズオン資料
qiita.com

  • インストールハンズオン
  • 基礎的なコマンド
  • アプリケーションをインストール
  • Dockerfileを書いてみよう
  • 応用編


 

さくらのクラウドで CentOS7 をインストール

さくらのクラウド にログインして「さくらのクラウド(IaaS)」をクリックします。

f:id:akiyoko:20170121020221p:plain

サービスご利用の流れ| さくらのクラウド」のフローに記載されているように、さくらインターネット会員ID(さくらのVPS を利用していれば既に持っているはず)があればコントロールパネルにログイン可能です。その後、「さくらのクラウド」アカウント(「さくらのクラウド」ユーザーも同時に作成可能)を作成して、クレジットカードを登録すれば利用を開始することができるようになります。


まずはリージョンを「東京第1ゾーン」に変更して、「追加」ボタンをクリック。
f:id:akiyoko:20170121021639p:plain

最小構成で CentOS サーバを作成します。
なお今回は、公開鍵の設定はせずにパスワード認証の設定を行います。
f:id:akiyoko:20170121021704p:plain


全てのステータスが「成功」になると、インスタンスの起動は完了です。
f:id:akiyoko:20170121022504p:plain


接続する IPアドレスは、サーバ一覧の画面から確認することができます。
f:id:akiyoko:20170208080557p:plain


クライアントのターミナルから、

$ ssh root@27.133.xxx.xxx

でログインすることができます(パスワードは作成時に入力したもの)。



コントロールパネルの[詳細]>[コンソール]から Webコンソールを操作することも可能ですが、動作がモッサリしているのでちょっと使い物にならない印象です。。
f:id:akiyoko:20170121022711p:plain
f:id:akiyoko:20170121022728p:plain


CentOS7 上で Docker をインストール

CentOS に Docker をインストールします。

### パッケージ情報を最新化
yum -y update

### docker-engine パッケージをセットアップ
curl -fsSL https://get.docker.com/ | sh

### サービスを有効化
systemctl enable docker.service

### docker デーモンを起動
systemctl start docker

### docker のバージョン確認
docker version


<実際のコマンド>

[root@akiyoko ~]# curl -fsSL https://get.docker.com/ | sh
+ sh -c 'sleep 3; yum -y -q install docker-engine'
warning: /var/cache/yum/x86_64/7/docker-main-repo/packages/docker-engine-selinux-1.12.6-1.el7.centos.noarch.rpm: Header V4 RSA/SHA512 Signature, key ID 2c52609d: NOKEY
docker-engine-selinux-1.12.6-1.el7.centos.noarch.rpm の公開鍵がインストールされていません
Importing GPG key 0x2C52609D:
 Userid     : "Docker Release Tool (releasedocker) <docker@docker.com>"
 Fingerprint: 5811 8e89 f3a9 1289 7c07 0adb f762 2157 2c52 609d
 From       : https://yum.dockerproject.org/gpg
setsebool:  SELinux is disabled.
Re-declaration of boolean virt_sandbox_use_fusefs
Failed to create node
Bad boolean declaration at /etc/selinux/targeted/tmp/modules/100/virt/cil:159
/usr/sbin/semodule:  Failed!
libsemanage.semanage_direct_install_info: Overriding docker module at lower priority 100 with module at priority 400.

If you would like to use Docker as a non-root user, you should now consider
adding your user to the "docker" group with something like:

  sudo usermod -aG docker your-user

Remember that you will have to log out and back in for this to take effect!

[root@akiyoko ~]# yum -y update
読み込んだプラグイン:fastestmirror, priorities
Loading mirror speeds from cached hostfile
No packages marked for update
[root@akiyoko ~]# systemctl enable docker.service
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

[root@akiyoko ~]# systemctl start docker
[root@akiyoko ~]# docker version
Client:
 Version:      1.12.6
 API version:  1.24
 Go version:   go1.6.4
 Git commit:   78d1802
 Built:        Tue Jan 10 20:20:01 2017
 OS/Arch:      linux/amd64

Server:
 Version:      1.12.6
 API version:  1.24
 Go version:   go1.6.4
 Git commit:   78d1802
 Built:        Tue Jan 10 20:20:01 2017
 OS/Arch:      linux/amd64


 

コンテナを起動する(Docker run)

CentOS 上で Ubuntu を利用できるようにします。

### hello-world を起動
docker run hello-world

### Ubuntu コンテナを起動して Ubuntuを操作
docker run -it ubuntu bash

### Ubuntu バージョンを確認
cat /etc/issue


<実際のコマンド>

[root@akiyoko ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
78445dd45222: Pull complete
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
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.
 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://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

[root@akiyoko ~]# docker run -it ubuntu bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
b3e1c725a85f: Pull complete
4daad8bdde31: Pull complete
63fe8c0068a8: Pull complete
4a70713c436f: Pull complete
bd842a2105a8: Pull complete
Digest: sha256:7a64bc9c8843b0a8c8b8a7e4715b7615e4e1b0d8ca3c7e7a76ec8250899c397a
Status: Downloaded newer image for ubuntu:latest

root@030555c1014f:/# cat /etc/issue
Ubuntu 16.04.1 LTS \n \l


 

起動した Ubuntu で curl を利用できるようにする

### Ubuntu のアップデート
apt-get -y update

### curl をインストール
apt-get -y install curl

curl ifconfig.me/ip

### exit でコンテナから抜けられる
exit

### 再度コンテナを動かしてみる
docker run -it ubuntu bash

### 再び IPアドレスを入れようとしても動かない
curl ifconfig.me/ip

exit すると、環境が消えてしまいます。

バックグランド(デタッチドモード)でコンテナを動かす

そこで、今度はバックグラウンドで動かしてみます。

### 今の時刻を毎秒表示するコンテナを起動する
docker run jpetazzo/clock

### バックグランド(デタッチドモード)でコンテナを動かす
docker run -d jpetazzo/clock
  • d オプションを付けると、バックグラウンドで動作させることができます。


 

基礎的なDockerコマンド

### docker ps で今動いているコンテナの確認
docker ps

### docker ps -a で今まで起動したコンテナを確認
docker ps -a

### 「docker ps -l」で直近に操作したコンテナを表示し「docker ps -q」でコンテナのショートIDが表示される。
docker ps -l
docker ps -q


<実際のコマンド>

[root@akiyoko ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
6f89ec594aa2        jpetazzo/clock      "/bin/sh -c 'while da"   5 minutes ago       Up 5 minutes                            suspicious_lalande
[root@akiyoko ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                       PORTS               NAMES
6f89ec594aa2        jpetazzo/clock      "/bin/sh -c 'while da"   5 minutes ago       Up 5 minutes                                     suspicious_lalande
00a52497540f        jpetazzo/clock      "/bin/sh -c 'while da"   6 minutes ago       Exited (0) 5 minutes ago                         admiring_volhard
2ec9602f7828        ubuntu              "bash"                   8 minutes ago       Exited (127) 6 minutes ago                       angry_engelbart
030555c1014f        ubuntu              "bash"                   14 minutes ago      Exited (130) 8 minutes ago                       mad_noether
83b477b7eb2a        hello-world         "/hello"                 16 minutes ago      Exited (0) 16 minutes ago                        reverent_booth
[root@akiyoko ~]# docker ps -l
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
6f89ec594aa2        jpetazzo/clock      "/bin/sh -c 'while da"   5 minutes ago       Up 5 minutes                            suspicious_lalande
[root@akiyoko ~]# docker ps -q
6f89ec594aa2


 

docker logs でコンテナのログを確認する

### コンテナのログを確認
docker logs 6f89ec594aa2

### 指定された数行だけログを確認
docker logs --tail 3 6f89ec594aa2

### リアルタイムでログを確認
docker logs --tail 1 --follow 6f89ec594aa2


 

docker kill、docker stopでコンテナを止める

### デタッチモードで起動したサーバを停止させる
docker kill 6f89ec594aa2
docker stop 6f89ec594aa2

kill よりも stop の方が安全に停止できるそうです。


 

Docker上で Ghost をインストールする

次は、簡易ブログツール「Ghost」を Docker を利用してインストールしてみます。
Ghost は、コマンド一発でインストール可能です。

### -p でポートマッピング可能(Ghost は 2368番ポートで動作する)
docker run -p 80:2368 -d ghost

### ブラウザに作成したサーバのIPアドレスを入力してアクセスができるか確認し、アクセスができるようであればコンテナを停止
docker kill (コンテナのID)


ブラウザから Ghost が動作しているのを確認することができます。
http://27.133.xxx.xxx/
http://27.133.xxx.xxx/admin

f:id:akiyoko:20170207233546p:plain

 

nginx コンテナを立ち上げてページを編集

下記コマンドで nginx を起動します。

docker run -itd -p 80:80 nginx:latest

起動後にブラウザから IPアドレスを入力して nginx の画面を表示し、正常に nginx が起動しているか確認をします。
f:id:akiyoko:20170207233636p:plain

 

nginx コンテナ上にページを作成

### docker psでnginxのコンテナIDを確認
docker ps

### docker exec コマンドで bash の追加プロセスを実行
docker exec -it $(docker ps -ql) /bin/bash

Ubuntu に入れた!

### ps -ef コマンドで nginx コンテナの中での操作を確認
ps -ef

### nginx のドキュメント・ルートにある index.html を書き換える
echo 'hello world' > /usr/share/nginx/html/index.html
cat /usr/share/nginx/html/index.html


ブラウザで確認します。

http://27.133.xxx.xxx/index.html
f:id:akiyoko:20170207233657p:plain


bashを終了します。

exit


 

nginx イメージの作成

### docker commit コマンドで mynginx:1.0 イメージを作成
docker commit $(docker ps -ql) mynginx:1.0

### docker images コマンドで、イメージが作成されたのを確認
docker images

### 作成した mynginx:1.0 イメージを使って、新しいコンテナを実行
docker run -d -p 8080:80 mynginx:1.0

### curl コマンドで、コマンドライン上でポート 8080 を開く
curl http://localhost:8080


<実際のコマンド>

[root@akiyoko ~]# docker commit $(docker ps -ql) mynginx:1.0
sha256:dde66d6cd18fc6d0ead8c88b460d9a54e4668471a44a66b281e37600192053c4
[root@akiyoko ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
mynginx             1.0                 dde66d6cd18f        About a minute ago   181.6 MB
ghost               latest              783cee09899e        11 hours ago         325.8 MB
nginx               latest              a39777a1a4a6        17 hours ago         181.6 MB
hello-world         latest              48b5124b2768        4 days ago           1.84 kB
ubuntu              latest              104bec311bcd        4 weeks ago          128.9 MB
jpetazzo/clock      latest              12068b93616f        23 months ago        2.43 MB

[root@akiyoko ~]# docker run -d -p 8080:80 mynginx:1.0
1d4f406be21b686906f8b68adc283660f3dc0aa762f7113708515c153e78ce49

[root@akiyoko ~]# curl http://localhost:8080
hello world


 

コンテナの停止と削除

### docker ps でコンテナの状態を確認
docker ps

### コンテナを停止するため docker kill コマンドを実行
docker kill $(docker ps -q)

### docker ps では実行中のプロセスはない
docker ps
### docker ps -a でコンテナが停止中であることを確認
docker ps -a

### docker rm コマンドでコンテナ(コンテナ用のイメージ・レイヤとメタ情報)を削除
docker rm $(docker ps -aq)
docker ps -a


 

Dockerfile でイメージの自動構築

### 作業用ディレクトリ mynginx を作成
mkdir mynginx
cd mynginx

### Dockerfile を作成
tee ./Dockerfile <<-'EOF'
FROM nginx:latest
RUN echo "hello world<br />$(date)" > /usr/share/nginx/html/index.html
EOF

### docker build コマンドで mynginx:1.1 イメージを自動作成
docker build -t mynginx:1.1 .

### イメージが作成されたことを確認
docker images

<実際のコマンド>

[root@akiyoko mynginx]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mynginx             1.1                 b9f4ec36b1d3        17 seconds ago      181.6 MB
mynginx             1.0                 dde66d6cd18f        7 minutes ago       181.6 MB
ghost               latest              783cee09899e        11 hours ago        325.8 MB
nginx               latest              a39777a1a4a6        17 hours ago        181.6 MB
hello-world         latest              48b5124b2768        4 days ago          1.84 kB
ubuntu              latest              104bec311bcd        4 weeks ago         128.9 MB
jpetazzo/clock      latest              12068b93616f        23 months ago       2.43 MB
### 作成した mynginx:1.1 イメージを使って、新しいコンテナを実行
docker run -d -p 8888:80 mynginx:1.1

### curl コマンドで、コマンドライン上でポート 8888 を開く
curl http://localhost:8888

<実際のコマンド>

[root@akiyoko mynginx]# docker run -d -p 8888:80 mynginx:1.1
e3566e13cc33662496a82d13e598a04834b1b5f907ac502d55f6510e5c985107
[root@akiyoko mynginx]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                           NAMES
e3566e13cc33        mynginx:1.1         "nginx -g 'daemon off"   11 seconds ago      Up 10 seconds       443/tcp, 0.0.0.0:8888->80/tcp   elated_davinci
[root@akiyoko mynginx]# curl http://localhost:8888
hello world<br />Wed Jan 18 11:47:30 UTC 2017


 

Docker Hub にログイン

アカウント作成
https://hub.docker.com/ から登録し、ログインします。

f:id:akiyoko:20170207233923p:plain


 

サーバから Docker Hub にログイン

docker login コマンドを実行します。

<実際のコマンド>

$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: <自分のDockerHubID>
Password: <パスワード>
Login Succeeded

 

Docker イメージの登録と公開

イメージをタグ付けします。

### docker tags コマンドで mynginx:1.1 イメージに Docker Hub ID の情報をタグ付け
docker tag mynginx:1.1 <自分のID名>/mynginx:1.1

### docker images で確認
docker images

<実際のコマンド>

[root@akiyoko mynginx]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mynginx             1.1                 b9f4ec36b1d3        7 minutes ago       181.6 MB
akiyoko/mynginx     1.1                 b9f4ec36b1d3        7 minutes ago       181.6 MB
mynginx             1.0                 dde66d6cd18f        15 minutes ago      181.6 MB
ghost               latest              783cee09899e        11 hours ago        325.8 MB
nginx               latest              a39777a1a4a6        17 hours ago        181.6 MB
hello-world         latest              48b5124b2768        4 days ago          1.84 kB
ubuntu              latest              104bec311bcd        4 weeks ago         128.9 MB
jpetazzo/clock      latest              12068b93616f        23 months ago       2.43 MB


 

docker push でイメージ送信

DockerHub に作成したイメージを送信します。

### docker push コマンドでイメージを送信
docker push <自分のID名>/mynginx:1.1


<実際のコマンド>

[root@akiyoko mynginx]# docker push akiyoko/mynginx:1.1
The push refers to a repository [docker.io/akiyoko/mynginx]
1022adbe77fc: Pushed
a03d7e02b0d4: Mounted from library/nginx
e04b871e18d3: Mounted from library/nginx
a2ae92ffcd29: Mounted from library/ghost
1.1: digest: sha256:df231d9fd41379c5565d1c529921bdb616fb3ec946f5b02d321bde0cd83d2059 size: 1155


Docker Hub 上にある自分のページを表示し、リポジトリを確認します。

f:id:akiyoko:20170207234126p:plain


不要なイメージの削除

### docker images -q を実行すると、ローカルにあるイメージ ID を表示
docker images -q

### docker rmi で全てのイメージを削除
docker rmi -f $(docker images -aq)


 

Arukas にログイン

DockerHub に登録したイメージを利用して、Arukas 上でアプリケーションを作成します。


https://app.arukas.io/
f:id:akiyoko:20170207234242p:plain

f:id:akiyoko:20170207234320p:plain


Arukas 上でアプリケーションを作成

ダッシュボードにて、「新しいアプリケーションを作成」ボタンをクリック。

f:id:akiyoko:20170207234354p:plain

アプリ作成に必要な各種情報を入力します。

App Name myapp
Image <DockerHubId>/mynginx:1.1(1.1 のタグを忘れずに!)
Port 80

アプリケーションを作成 ボタンをクリック。

f:id:akiyoko:20170207234415p:plain

一覧画面に作成されたアプリケーションが表示されます。


アプリの 起動 ボタンをクリック後、OK をクリックすると、 アプリが起動します。

f:id:akiyoko:20170207234434p:plain

起動後、 Endpoint の URL を開きます。

f:id:akiyoko:20170207234453p:plain

f:id:akiyoko:20170207234518p:plain