DebianにDockerをインストールして基本的なコマンドを使ってみる

前提

以下の環境にDockerを導入する

要素 バージョン
Debian 8.6
Docker 1.13.0

概要

Debian8.6にDocker1.13.0をインストールし、そこでCentOSのコンテナを作成する。コンテナで適当に作業を行い、コミットして再利用するところまでをチュートリアルする。Dockerそのものに関する説明はそんなに無い。Dockerfileによる構築も扱わない。Dockerの雰囲気が味わえれば良いかなぐらい。

Dockerとは

Dockerはサーバ仮想化ソフトウェアの一つ。ただし、VMWareなどの、ハイパーバイザ型における完全な仮想化を提供するのではなく、ホストOSのカーネルを共有し、その上に「コンテナ」と呼ばれるOSのシステムレベルで仮想化されたゲストOSを取り扱う。

つまり、VMWareなどの仮想化と比べると不完全な仮想化で、ゲストOSの独立レベルは低い。Dockerではそのような構成にすることで以下のメリットが得られる。

  • 個別にOSを立ち上げる必要がないので作成や起動、破棄が高速
  • 使用する資源(CPU/メモリ/ストレージ)が少ない
  • オーバーヘッドが少なく性能劣化が殆ど無い

よって、Dockerの使い方としては、永続的に稼働している環境というよりは、頻繁に作成、破棄が行われる使い捨ての環境に用いることが向いていると言える。

個人的には開発環境を手軽に構築、共有するのに使っていけたら良いなと思う

Dockerのインストール

DockerはホストOSのカーネルを共有するので、当然Linux上に構築するのが望ましい。一応WindowsやMacでもDockerを導入することができるが、本記事ではMac上に構築したDebianの上にDocker環境を構築する。

例によってapt-getでインストールしたいところだが、Debianに標準で含まれてるaptリポジトリにdockerが含まれていないので、手作業でリポジトリを追加する必要がある。

/etc/apt/sources.list

が、aptのリポジトリリストなので、これに以下を追記する。ドメイン的に日本のDebian公式リポジトリなんだと思う。

deb http://ftp.jp.debian.org/debian/ sid main
deb-src http://ftp.jp.debian.org/debian/ sid main

で、アップデート

$ sudo apt-get update

dockerをインストール

$ sudo apt-get install docker.io

インストールできたことを確認

docker -v
Docker version 1.13.0, build 49bf474

Dockerイメージのインストール

Dockerでコンテナを作成するためには、元となるイメージが必要になる。

Dockerには、DockerイメージのリポジトリであるDockerHubを通じて、Dockerイメージを共有する機能があるので、今回はそちらからCentOSのDockerイメージをインストールする。

権限周りがやかましいのでここからはsudo権限を持たせる

$ sudo -s
# whoami
root

DockerHubからDockerイメージをダウンロードする場合は、docker pullコマンドを使用する。今回はCentOSをダウンロードする。

# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
93857f76ae30: Already exists
Digest: sha256:4eda692c08e0a065ae91d74e82fff4af3da307b4341ad61fa61771cc4659af60
Status: Downloaded newer image for centos:latest

ダウンロード済みのDockerイメージの一覧の確認は、docker imagesコマンドで行う。centosのDockerイメージがダウンロードされていることが確認できる。

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              a8493f5f50ff        3 weeks ago         192 MB

Dockerイメージが仮想マシンのイメージと同じようなものと考えると、192MBというのは実に小さい。仮想マシンイメージと異なり、カーネルが含まれていないからである。

DockerコンテナによるHello World

DockerコンテナはDockerイメージから生成される仮想環境の実体である。一つのイメージから複数のコンテナを生成できるので、オブジェクト指向におけるクラスとインスタンスの関係のようなものだ。

コンテナ起動は、docker run コマンドを用いる。といっても、コンテナはホストOSのカーネルを用いてプロセスを実行するものなので、どんなプロセスを実行するかを指定する必要がある。

ここでは、”Hello Docker World”という文字列をechoするプロセスを実行するだけのコンテナを立ち上げてみる。

# docker run centos echo "Hello Docker World!"
Hello Docker World!
#

“Hello Docker World!” の文字列が出力され、コマンドの実行は終了する。ではこの時コンテナはどのような状態なのか、docker psコマンドで確認する。psコマンドは基本的にプロセスが動いているコンテナの一覧を表示するが、-aオプションを付与することで終了しているコンテナも表示する。

# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                          PORTS               NAMES
627496810cd6        centos              "echo 'Hello Docke..."   About a minute ago   Exited (0) About a minute ago                       angry_blackwell

627496810cd6がコンテナのID(ユニーク)で、angry_blackwellがコンテナの名称である。名称はユニークでない可能性もあるが、コンテナ生成時に任意の名称を付けることができる。

このコンテナはコマンド”echo ‘Hello Docker…”を実行完了し、Exited状態に移行している。

コンテナの削除

前項で作成したコンテナは、Hello Docker World!を出力してお役御免なので、docker rmコマンドを用いて削除する。削除の際はコンテナIDがコンテナ名を指定する。特に重複の可能性がないのであれば、可読性のあるコンテナ名を使ったほうが良さそう。

# docker rm angry_blackwell
angry_blackwell

削除されたことを確認

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

コンテナを作成し、アクセスする

“アクセスする”という言い方には語弊がある気がするが、つまりSSHでアクセスしたときみたいにコンテナ内でシェルを使いたいということである。前項の用に、コンテナを起動する際にプロセスを指定することで、コンテナはプロセスを実行し、実行完了するまで稼働し続ける。

つまり、コンテナで実行するプロセスにシェルを指定してあげればよい。ここではbashを用いてシェルを利用することにする。また、-itオプションを付与することで、現在の標準入出力を引き継ぐことができるので、シェルを利用するためには必須となる。

# docker run -it centos /bin/bash
[root@a3936fcb8f31 /]# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

コンテナ内でシェルを利用できるようになり、catコマンドでコンテナ内のOS情報ファイルを出力できていることがわかる。CentOSと書かれているが、実際にはホストOSであるDebianのカーネルを利用している。ややこしい。

コンテナ内でRubyをインストールする

コンテナ内に開発環境を作る、というほど大層なことは本記事では行わないが、その前進としてRubyをインストールして、適当なスクリプトを作成してみる。

カーネルはDebianのものを使ってるが、コンテナはCentOSなので、apt-getではなくyumを用いてRubyをインストールする。ここではRubyのバージョンとかは気にせず、簡単にインストールできる方法を用いる。

[root@a3936fcb8f31 /]# yum install ruby

インストールできたことを確認。どうやらこのコンテナ内のyumで標準でインストールできるRubyは2.0.0らしい。だいぶ古い。

[root@a3936fcb8f31 /]# ruby -v
ruby 2.0.0p648 (2015-12-16) [x86_64-linux]

適当にスクリプトを作成する。と思ったらvimも入っていないので先にvimをインストールする

[root@a3936fcb8f31 /]# yum install vim

インストールしたvimで、/fizzbazz.rb を作成する。フィズバズについてはWikipediaを参照。ここでは、コマンドライン引数Nを取り、1〜Nに対してのフィズバズを行うプログラムを作成する。カッコいいアルゴリズムでも使おうと思ったが、コードの内容は本記事とは関係ないので普通に書く。

N = ARGV[0].to_i
N.times do |m|
  if m % 3 == 0 && m % 5 == 0
    puts "Fizz Buzz"
  elsif m % 3 == 0
    puts "Fizz"
  elsif m % 5 == 0
    puts "Buzz"
  else
    puts m
  end
end

実行してみるとこんな感じ

root@a3936fcb8f31 /]# ruby /fizzbazz.rb 10
Fizz Buzz
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz

フィズバズを持つDockerイメージを作成する

前項では、コンテナ内でRubyとvimのインストール及びフィズバズプログラムの作成を行った。しかし、これからはあくまでコンテナ内に存在するだけで、元となったDockerイメージに存在するものではない。したがって、本コンテナを削除してしまえば前項の作業は水の泡となってしまい、再利用することができない。

そこで、本コンテナを元にしたDockerイメージを新たに作成する。つまり、「CentOSのイメージ」を元に、「CentOSの中にRubyとVimとフィズパズスクリプトが入ったイメージ」を作成するということだ。

コンテナからイメージを作成するには、docker commitコマンドを用いる。以下では、”unruffled_blackwell”(本コンテナの名前)を元に、”fizzbazz”というイメージを作成する。

# docker commit unruffled_blackwell fizzbazz
sha256:7bf2cab2f57325c76c67affd54f7545ecc7ecde41925e7cd2404ba6c602e05a7

イメージが作成されたことを確認。RubyとVimを入れたせいで容量がかなり増えている。それでも348MBだが。

# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
fizzbazz            latest              7bf2cab2f573        26 seconds ago      348 MB
centos              latest              a8493f5f50ff        3 weeks ago         192 MB

作成したイメージから新たにコンテナを生成する

とりあえず先程Rubyやvimをインストールしたコンテナはもう不要なので削除する。以下は全てのコンテナを削除するおまじない的なコマンド。といっても、「全てのコンテナ一覧のコンテナIDのみ標準出力し、それらをdocker rmの引数にする」という一連の処理を行っているだけ。

# docker ps -aq | xargs docker rm
a9f5293d88a0
a3936fcb8f31
0357fffe82b2

これでRubyやVimがインストールされたコンテナが削除された。インストール作業は水の泡となってしまった。

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

ということはもちろん無く、以下のように先程作成したコンテナを用いてフィズバズプログラムを実行できることが確認できる。

# docker run fizzbazz ruby /fizzbazz.rb 10
Fizz Buzz
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz

まとめ

以上より、Dockerを用いることで非常に手軽にCentOSの環境を導入し、そこでRubyの開発環境(の卵)を作成することができた。さらに、Ruby開発環境を持ったCentOSのイメージを作成し、手軽に再利用できるようになった。

また、本記事では割愛しているが、DockerHubを用いて、本記事で作成したイメージをpushすることで、他のユーザがそれを再利用することもできる。逆に他のユーザが作成したイメージからコンテナを作成することもでき、例えばRubyの開発環境に留まらず、Ruby on railsの開発環境一式が揃ったイメージなども数多く出回っている。

つまり、今後何らかの技術を使って開発を行いたくなったら、その開発環境に適合するイメージを探して、docker pullするだけでスグに環境構築を行えるということだ。
完全に適合したイメージが無ければ、近いものをpullし、自分でカスタマイズしてcommit,pushすればさらに特定の目的に特化したイメージを流通させることができる。

今回、本記事を書くために初めてDockerを利用したが、まだまだ使いみちは模索中で、基礎的なコマンドしか抑えられていないので、今後はさらに実用的な使い方ができるように勉強し、実務にも取り入れられたらなと画策している。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です