ブログ

ryuzeeによるブログ記事。不定期更新
アジャイル開発に取り組むチーム向けのコーチングや、技術顧問、認定スクラムマスター研修などの各種トレーニングを提供しています。ぜひお気軽にご相談ください(初回相談無料)

5分で分かるDockerのキホン

全国100万人のImmutable Infrastructure職人のみなさんこんにちは。 もう誰も彼もがDockerなので、あんまりブログに書こうという気にもならなかったのですが、知り合いからリクエストを貰ったので、5分くらいで分かるようにかいつまんで概略を説明します。

Dockerとは

  • 詳しくは本家サイト見ればだいたい分かる。
  • 仮想化技術
  • コンテナ単位でパッケージング
    • VirtualBoxとかと違って高速、オーバーヘッドが少ない。chrootに近い。LXCには依存しなくなっている
    • コンテナごとにIDが振られる
    • コンテナは差分保存なのでロールバックも簡単
  • 一回作ればどこでも動く。Javaっぽい
  • Dockerfileでコンテナを作成する
    • Dockerfileの1行ごとにコンテナIDがフラれる
  • 動作環境
    • Linux Kernel 3.8以降 64bit OS
    • Macの場合はVirtualBoxの中で動かす形になる→ boot2docker
    • Windowsの場合もVirtualBoxを使って仮想マシンの中にDocker環境を作ることになる。
  • 何がうれしいの?
    • 高速に起動する。したがってCI用に使ったり、Chefのクックブックの実験環境に使ったり、開発環境に使ったり色々便利。もう本番環境で使っている例も多数
    • コンテナ内に閉じ込めることでポータビリティがあがる。アプリケーションのデプロイ戦略が楽な方に大きく変わりうる
    • 差分で管理されるので配布と再利用が簡単
    • いろんな環境で動く
    • Dockerfileを使ってコードでインフラを管理できる

Ubuntu 12.04 LTS 64bitで動かす

まずKernelを3.8に変更する

sudo apt-get update
sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring
sudo reboot

aptレポジトリを追加してインストール

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
sudo sh -c "echo deb https://get.docker.io/ubuntu docker main /etc/apt/sources.list.d/docker.list"
sudo apt-get update
sudo apt-get install lxc-docker

とりあえずDockerを使ってUbuntuのコンテナを起動する

sudo docker run -i -t ubuntu /bin/bash

初回なのでたくさんイメージをダウンロードするのでちょっと時間がかかるはず。終わると以下のようにログインできている

Unable to find image 'ubuntu' locally
Pulling repository ubuntu
316b678ddf48: Download complete 
a7cf8ae4e998: Download complete 
3db9c44f4520: Download complete 
()
cb12405ee8fa: Download complete 
4d26dd3ebc1c: Download complete 
d4010efcfd86: Download complete 
root@6485cdbce682:/# 

この状態だと、インタラクティブシェルで、exitするとプロセスが終了する。

どのコンテナが起動しているかを確認する

sudo docker ps

として確認すればOK。(ps -a だと停止済のコンテナも含む)

コンテナ自体を削除する場合

以下のようにする(末尾のパラメータはコンテナID)

sudo docker rm 04b26990125f

複数のコンテナをまとめて停止したり削除する

以下のように引数にコマンド実行の結果を渡せばOK。

sudo docker stop `sudo docker ps -aq`
sudo docker rm `sudo docker ps -aq`

独自のイメージを作る

適当に変更を加えたあとにログアウトし、

sudo docker commit コンテナID 適当な名前

のようにする。作ったものを確認するには

sudo docker images 名前

として一覧に出ることを確認すればOK

たとえば

sudo docker commit eb0dd1195df2 ryuzee/apache2

これができれば

sudo docker run -i -t ryuzee/apache2 /bin/bash

にように今度はこれを使うことができる。なお、イメージの名称は、ユーザー名/中身 という形式にするのが推奨

イメージの一覧を取得する

sudo docker images

とすることでイメージの一覧が取得できる。

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              13.10               5e019ab7bf6d        4 weeks ago         180 MB
ubuntu              saucy               5e019ab7bf6d        4 weeks ago         180 MB
ubuntu              12.04               74fe38d11401        4 weeks ago         209.6 MB
()
ubuntu              10.04               3db9c44f4520        4 weeks ago         183 MB
ubuntu              lucid               3db9c44f4520        4 weeks ago         183 MB

Dockerfileでイメージを作る

FROM ubuntu
RUN sudo apt-get update -y
RUN sudo apt-get install apache2 -y
RUN sudo apt-get install memcached -y
RUN sudo apt-get install php5 -y

## 環境変数の設定
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2

## 公開するポートの指定
EXPOSE 80

## コンテナ起動時に実行するコマンドを指定
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]

のように、ベースとするイメージを指定したあと、実行するコマンドを書いていく。これができたら

sudo docker build .

を実行するとビルドされる。ただしこれで作られたイメージには名前がついていないので、

sudo docker build -t 名前 .

のようにすると良い。もしくはあとから名前をつける場合は、

sudo docker tag bc9e46f7accc ryuzee/apache2

のようにする

Dockerfile内で使えるコマンド

FROM <image> 元となるイメージを指定する。:の後ろでタグ指定可能
MAINTAINER <name> メンテナの名前
RUN <command> ビルド中に実行したいコマンドを指定。パッケージのインストールとか設定とか
CMD <command> 起動後のコンテナで実行したいコマンドを指定する。1つしか書けない
EXPOSE <port> [</port><port> ...] 外部に公開するポートを指定
ENV <key> <value> 環境変数の設定
ADD <src> <dest> ファイルを配置。絶対パスで記述する

Dockerfile作成上の注意

  • ENTRYPOINTやCMDは1つのDockerfileの中で1個しか指定できない
  • したがって複数プロセスを起動したい時はsupervisordを使って行う

イメージの削除

以下のように引数にイメージIDを指定する。ただし依存するコンテナが存在する場合は削除できない

sudo docker rmi f6eb3276aab2

ポートの設定

Dockerfileの中でEXPOSEを使って指定するか、起動時に設定する。以下の例では、コンテナ側の80番にポートフォワードするために母艦側で8888を指定している

sudo docker run -d -p 8888:80 ryuzee/apache2

起動サービスの設定

Dockerfileの中でCMDを使って指定するか、起動時に設定する

docker run -d -p 8080:80 ryuzee/apache2 /usr/sbin/apache2 -DFOREGROUND

ローカル側のディスクを共有

あらかじめDockerfileの中で公開するVOLUMEの設定をしておいた上で、起動時に -v を使ってローカル側:コンテナ側の形で指定する。なお、絶対パスで指定する必要がある点には注意。

ログ系とかは外だしにしとくと便利かも。

sudo docker run -p 9999:80 -p 2222:22 -t -v /home/ryuzee/docker/basic/logs:/var/log/apache2 -d ryuzee/basic

イメージの共有

Docker Registryを使って作成したイメージを共有することができる。例えば、パブリックレジストリを使うと世の中に公開したり、他の人が公開しているものを使ったりできる

公式レポジトリとコマンドラインをひもづけるには

sudo docker login

としてログインすればOK

作ったイメージを公開するには、

sudo docker push ryuzee/basic

としてプッシュしてあげれば良い。

以下のようなログが表示される。

The push refers to a repository [ryuzee/basic] (len: 1)
Sending image list
Pushing repository ryuzee/basic (1 tags)
511136ea3c5a: Image already pushed, skipping 
Image f10ebce2c0e1 already pushed, skipping
Image 82cdea7ab5b5 already pushed, skipping
Image 5dbd9cb5a02f already pushed, skipping
Image 74fe38d11401 already pushed, skipping
869d76ced5c7: Image successfully pushed 
(略)
424924b964f9: Image successfully pushed 
4f0307fd0f8f: Image successfully pushed 
d77d7fd91796: Image successfully pushed 
532d67a9eec2: Image successfully pushed 
5804bf0385b9: Image successfully pushed 
Pushing tag for rev [5804bf0385b9] on {https://registry-1.docker.io/v1/repositories/ryuzee/basic/tags/latest}

自分用のDocker registryをたてる

index.docker.io だけでなく、自分でDocker Registryを作ることができる。またこのとき、Amazon S3にファイルが保存できるので、AWS内に仮想マシンをたててDocker使う場合はネットワーク的なメリットもある。

手順

まずS3に適当にバケットを作成しておく。今回は東京リージョンにryuzee-dockerimageという名前で作成。 なお、docker pullして持ってくるregistryは古いので、できればGitHubから最新を持ってきたほうが困らない感じ。

git clone https://github.com/dotcloud/docker-registry
cd docker-registry
sudo docker build -t ryuzee/registry .

コンテナを起動する。-eで環境変数を指定しており、アプリの中で必要なAWSのアクセスキーやシークレットキーを指定している。もちろんコンテナの中にconfig.ymlを置いたり、起動時にVOLUMEを使って設定ファイルを外部から共有してもOK。

sudo docker run \
         -e SETTINGS_FLAVOR=s3 \
         -e AWS_BUCKET=ryuzee-dockerimage \
         -e STORAGE_PATH=/images \
         -e AWS_KEY=AKIXXXXXXXXXXXXXXXXXX \
         -e AWS_SECRET=abcnjsifhAHFkfkjidjdjdjdiki \
         -e SEARCH_BACKEND=sqlalchemy \
         -p 5000:5000 \
         ryuzee/registry

ここまでできたら、まず以下のようにタグをつけて

sudo docker tag bb34bb42eb3a localhost:5000/ryuzee/basic

その後にレポジトリにプッシュする

sudo docker push locahost:5000/ryuzee/basic

Pullしたいときの考えかたも基本的に一緒

sudo docker pull localhost:5000/ryuzee/basic

dockerコマンドでsudo毎回叩くとかありえない人向け

dockerグループに自分を追加してあげることでsudo付けなくてもOKになる。なお作業完了後、シェルの再起動が必要なので、ログアウト/ログインする

sudo groupadd docker
sudo gpasswd -a ryuzee docker
sudo service docker restart

Ubuntu上のVagrantから簡単に操作する

Vagrant 1.6系からDockerに正式対応したので、Ubuntu上だとかなり楽に使える。 Vagrantfileは以下のようになる。

Vagrant.configure("2") do |config|
  config.vm.provider "docker" do |d|
    d.image = "ryuzee/basic"
  end
end

これを用意して、いつもどおり

vagrant up --provider=docker

とすればOK

vagrant sshでログインしてごにょごにょしたい場合は以下のようにhas_sshを有効にしつつ、sshでの接続ユーザー名やキーペア(またはパスワード)とポート番号を指定する(ポート番号を指定しない場合、なぜかBad Portというエラーになるので注意)

Vagrant.configure("2") do |config|
  config.vm.provider "docker" do |d|
    d.image = "ryuzee/basic"
    d.remains_running = false
    d.has_ssh = true
  end
  config.ssh.username = "root"
  config.ssh.password = "root"
  config.ssh.port = "22"
end

さらにコンテナ起動時のCMDを指定したり、ポートマッピングを設定することも可能。

## このあたりが追加になる
d.cmd = ["/usr/sbin/httpd", "-DFOREGROUND"]
d.ports = ["8888:80"]

過去の資産の再利用

Chefとの組み合わせ方

packerを使ってイメージの作成を行えば、過去の資産の再利用が可能。Packerは0.6以上のバージョンにすること。 以下の例では、BerkshelfおよびChef-Soloプロビジョナーとの組み合わせで、Dockerのイメージを作成している。

{
  "builders": [{
    "type": "docker",
    "image": "centos",
    "export_path": "image.tar"
  }],
  "provisioners":[
  {
    "type": "chef-solo",
    "cookbook_paths": ["./vendor-cookbooks/"],
    "run_list": ["timezone", "apache2-simple", "memcached"],
    "json": {"memcached":{"maxcon":"512","cachesize":"512"}},
    "prevent_sudo": true,
    "skip_install": false
  }],
  "post-processors": [{
    "type": "docker-import",
    "repository": "ryuzee/packer-sample",
    "tag": "0.1"
  }]
}

ソースはこちら。 一点気をつける点としては、DockerfileでサポートされているEXPOSEやENDPOINTやCMDなどを現時点ではサポートしていないため、自分でdocker runの際に引数で渡す必要がある。

あとは頼んだ…

  • スクラム実践者が知るべき97のこと
  • 著者/訳者:Gunther Verheyen / 吉羽龍太郎 原田騎郎 永瀬美穂
  • 出版社:オライリージャパン(2021-03-23)
  • 定価:¥ 2,640
  • スクラムはアジャイル開発のフレームワークですが、その実装は組織やチームのレベルに応じてさまざまです。本書はスクラムの実践において、さまざまな課題に対処してきた実践者が自らの経験や考え方を語るエッセイ集です。日本語書き下ろしコラムを追加で10本収録
  • プロダクトマネジメント ―ビルドトラップを避け顧客に価値を届ける
  • 著者/訳者:Melissa Perri / 吉羽龍太郎
  • 出版社:オライリージャパン(2020-10-26)
  • 定価:¥ 2,640
  • プロダクト開発を作った機能の数やベロシティなどのアウトプットで計測すると、ビルドトラップと呼ばれる失敗に繋がります。本書ではいかにしてビルドトラップを避けて顧客に価値を届けるかを解説しています。
  • SCRUM BOOT CAMP THE BOOK 【増補改訂版】
  • 著者/訳者:西村直人 永瀬美穂 吉羽龍太郎
  • 出版社:翔泳社(2020-05-20)
  • 定価:¥ 2,640
  • スクラム初心者に向けて基本的な考え方の解説から始まり、プロジェクトでの実際の進め方やよく起こる問題への対応法まで幅広く解説。マンガと文章のセットでスクラムを短期間で理解できます。スクラムの概要を正しく理解したい人、もう一度おさらいしたい人にオススメ。
  • みんなでアジャイル ―変化に対応できる顧客中心組織のつくりかた
  • 著者/訳者:Matt LeMay / 吉羽龍太郎、永瀬美穂、原田騎郎、有野雅士
  • 出版社:オライリージャパン(2020-3-19)
  • 定価:¥ 2,640
  • アジャイルで本当の意味での成果を出すには、開発チームだけでアジャイルに取り組むのではなく、組織全体がアジャイルになる必要があります。本書にはどうやってそれを実現するかのヒントが満載です
  • レガシーコードからの脱却 ―ソフトウェアの寿命を延ばし価値を高める9つのプラクティス
  • 著者/訳者:David Scott Bernstein / 吉羽龍太郎、永瀬美穂、原田騎郎、有野雅士
  • 出版社:オライリージャパン( 2019-9-18 )
  • 定価:¥ 3,132
  • レガシーコードになってから慌てるのではなく、日々レガシーコードを作らないようにするにはどうするか。その観点で、主にエクストリームプログラミングに由来する9つのプラクティスとその背後にある原則をわかりやすく説明しています。
  • Effective DevOps ―4本柱による持続可能な組織文化の育て方
  • 著者/訳者:Jennifer Davis、Ryn Daniels / 吉羽 龍太郎、長尾高弘
  • 出版社:オライリージャパン( 2018-3-24 )
  • 定価:¥ 3,888
  • 主にDevOpsの文化的な事柄に着目し、異なるゴールを持つチームが親和性を高め、矛盾する目標のバランスを取りながら最大限の力を発揮する方法を解説します
  • ジョイ・インク 役職も部署もない全員主役のマネジメント
  • 著者/訳者:リチャード・シェリダン / 原田騎郎, 安井力, 吉羽龍太郎, 永瀬美穂, 川口恭伸
  • 出版社:翔泳社( 2016-12-20 )
  • 定価:¥ 1,944
  • 米国で何度も働きやすい職場として表彰を受けているメンローの創業者かつCEOであるリチャード・シェリダン氏が、職場に喜びをもたらす知恵や経営手法、より良い製品の作り方などを惜しみなく紹介しています
  • アジャイルコーチの道具箱 – 見える化の実例集
  • 著者/訳者:Jimmy Janlén / 原田騎郎, 吉羽龍太郎, 川口恭伸, 高江洲睦, 佐藤竜也
  • 出版社:Leanpub( 2016-04-12 )
  • 定価:$14.99
  • この本は、チームの協調とコミュニケーションを改善したり、行動を変えるための見える化の実例を集めたものです。96個(+2)の見える化の方法をそれぞれ1ページでイラストとともに解説しています。アジャイル開発かどうかに関係なくすぐに使えるカタログ集です
  • カンバン仕事術 ―チームではじめる見える化と改善
  • 著者/訳者:原田騎郎 安井力 吉羽龍太郎 角征典 高木正弘
  • 出版社:オライリージャパン( 2016-03-25 )
  • 定価:¥ 2,138
  • チームの仕事や課題を見える化する手法「カンバン」について、その導入から実践までを図とともにわかりやすく解説した書籍。カンバンの原則などの入門的な事柄から、サービスクラス、プロセスの改善など、一歩進んだ応用的な話題までを網羅的に解説します。
  • Software in 30 Days スクラムによるアジャイルな組織変革“成功"ガイド
  • 著者/訳者:Ken Schwaber、Jeff Sutherland著、角征典、吉羽龍太郎、原田騎郎、川口恭伸訳
  • 出版社:アスキー・メディアワークス( 2013-03-08 )
  • 定価:¥ 1,680
  • スクラムの父であるジェフ・サザーランドとケン・シュエイバーによる著者の日本語版。ビジネス層、マネジメント層向けにソフトウェア開発プロセス変革の必要性やアジャイル型開発プロセスの優位性について説明
  • How to Change the World 〜チェンジ・マネジメント3.0〜
  • 著者/訳者:Jurgen Appelo, 前川哲次(翻訳), 川口恭伸(翻訳), 吉羽龍太郎(翻訳)
  • 出版社:達人出版会
  • 定価:500円
  • どうすれば自分たちの組織を変えられるだろう?それには、組織に変革を起こすチェンジ・マネジメントを学習することだ。アジャイルな組織でのマネージャーの役割を説いた『Management 3.0』の著者がコンパクトにまとめた変化のためのガイドブック