WEB+DB PRESS

特集3 Docker 実戦投入

第1章 Docker 入門

  • コンテナ型仮想化技術
  • 何を解決するために作られたのか?
    • デプロイの課題
    • Docker は手元のマシンで動いているアプリケーションをそのまま別のマシンまで運ぶことを可能にしてくれる
    • 流通の課題 = デプロイの課題
  • サーバ仮想化
    • VM型仮想化
    • コンテナ仮想化
      • 丸ごと仮想化はしない
      • ゲストOSはホストマシンと同じで
      • 仮想マシンのことをコンテナ
  • Docker がコンテナ型仮想化を選択する理由
    • 必要充分なイメージを作れる
    • パフォーマンス劣化が少ないため
  • Docker のメリット
    • アプリケーション実行環境に必要十分なものをパッケージングし、再現性を保ったままデプロイできる
    • アプリケーションの言語に寄らず、同じやり方でデプロイできる
    • VM と比較してパフォーマンス劣化がなく、仮想マシンの起動が速い
    • それぞれのアプリケーションが独立した環境で実行される
    • パッケージング、デプロイ、起動のどれもが簡単にに行える
  • ワークフロー
    1. 開発者がアプリケーションをイメージに保存
    2. そのイメージをシステム管理者に共有
    3. システム管理者が本番環境までイメージを運ぶ
    4. 開発環境で動いていたアプリケーションをそのまま本番環境で動かす
  • Docker の全体像
    • Docker コンテナ
    • Docker イメージ
      • Dockerfile
    • Docker レジストリ
      • 作成したイメージを補完する場所
      • Docker Hub
  • 環境構築
    • サンプルを動かす
% brew install boot2docker
% boot2docker init
% boot2docker start
% docker -v
% docker pull spesnova/hello-world
% boot2docker ip
% docker run -p 80:4567 spesnova/hello-world bundle exec ruby app.rb

f:id:yossk:20150501224315j:plain

  • build
    • 書き換えて実行してみる
% git clone https://github.com/spesnova/docker-hello-world.git
% cd ./docker-hello-world/
% vi app.rb
% docker build -t=hello-world .
% docker run -p 80:4567 hello-world bundle exec ruby app.rb

f:id:yossk:20150501224328j:plain

  • push
    • Docker Hub にアカウントを作成しておく
    • Docker Hub - Content, Collaboration, Workflows, and More https://hub.docker.com/
% docker login
% docker build -t=アカウント名/hello-world .
% docker push アカウント名/hello-world

f:id:yossk:20150501224357j:plain

第2章 Docker を生かすための原則

  • メリット
    • 再現性が高い
    • ワークフローが統一される
    • Dev(開発者)と Ops(システム運用者)の担当範囲が分離される
  • デメリット
    • コンテナ管理コスト
    • ホストマシン管理コスト
    • 学習コスト
  • シンプルさを優先する
  • 1コンテナ内に1プロセスのみ立てる
    • EFK だと
      • Fuentd コンテナ
      • Elasticsearch コンテナ
      • Kibana コンテナ
    • Rails (Unicorn) コンテナと nginx コンテナ
  • コンテナはいつでも捨てられるようにしておく
  • できる限りすべてをコンテナで行う
    • ホストマシンに直接パッケージをインストールしない
  • Dockerfile をそのまま使う
    • Dockerfile 以外の選択肢
      • docker commit コマンドを使う
      • Chef や Puppet と Packer を組み合わせる
    • Dockerfile を使う理由
      • 記述がシンプルである
      • すべての処理が明示的である
      • 必要なツールが少ない
    • Dockerfile に書けないほど複雑なアプリケーションは出来上がるイメージが大きすぎたり、 起動に時間がかかりすぎたりする可能性があるのでコンテナとして動かすのに向いてない
  • 実践に向けた各ステップ
    1. 何をDockerコンテナとして動かすか決める
    2. Docker イメージをビルドするための環境を準備する
    3. ビルドしたイメージの保存先を決める
    4. コンテナを押せる本番環境を構築する
    5. デプロイなど各種オーケストレーションを自動化する
    6. モニタリング、ログ管理、CI環境を整備する
  • 開発環境を Docker にすべきかどうか
    • 開発環境への導入は別途あとからのほうがよさそう
    • nginx や Redit といったミドルウェアを本番環境と同じバージョンを使ったり

第3章 ビルド環境の構築と Dockerイメージのビルド

% git clone https://github.com/spesnova/docker-example-rails.git
% cd docker-example-rails
% cp .env.sample .env
% rm .ruby-version
% cd coreos
% cp .env.sample .env
% vagrant plugin install dotenv
% vagrant up
% vagrant ssh
core@core-01 ~ $ docker -v
Docker version 1.5.0, build a8a31ef-dirty
  • synced_folder というローカルマシンと VM の間で特定のディレクトリを共有出来る機能
  • ログ出力
  • Dockerfile の作成
    1. Ruby 実行環境のインストール
    2. JavaScript 実行環境のインストール
    3. ソースコードの配置
    4. ライブラリのインストール
    5. アセットファイル(CSSJavaScript など)のプリコンパイル
  • 小さいイメージを作る
    • イメージのビルドや push/pull、コンテナの起動にかかる時間が短くなる
    • レイヤ数を少なくする
    • 1レイヤのサイズを抑える
    • .dockerignore を作る
    • 公式の Language Stack を使わない
      • 最大公約数でパッケージングされているのでサイズが大きい
  • 起動時を考慮する
  • Docker イメージのビルド
    • Automated build はビルドキューが溜まっているときはビルド開始まで待たされる
    • ビルドキャッシュの有効活用
  • Compose を使ったイメージの作成
    • 複数のコンテナ間のボリューム共有やリンク設定を1つの YAML ファイルに定義し、同時に立ち上げることができる
% vagrant up && vagrant ssh
core@core-01 ~ $ docker-compose --version
docker-compose 1.1.0
core@core-01 ~ $ cd ./docker-example-rails/
core@core-01 ~/docker-example-rails $ docker-compose build
core@core-01 ~/docker-example-rails $ docker-compose up -d db
core@core-01 ~/docker-example-rails $ docker-compose run --rm web rake db:create db:migrate
core@core-01 ~/docker-example-rails $ docker-compose up

f:id:yossk:20150501224407j:plain