Skip to content

Instantly share code, notes, and snippets.

@kiyohara
Last active August 29, 2015 14:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kiyohara/b27c777889f462423e69 to your computer and use it in GitHub Desktop.
Save kiyohara/b27c777889f462423e69 to your computer and use it in GitHub Desktop.
Docker を使ったコンテナ制御に関する調査

Docker を使ったコンテナ制御に関する調査

コンテナのテンプレートについて

  • docker の世界では
    • image と呼ばれる
    • aufs の layer 履歴を管理したもの(がほとんど)
    • 作り方は
      • $ docker pull してよそから持ってくる
      • $ dokcer build で新規に作成する
      • $ docker run した結果を commit する
    • /var/lib/docker/{graph,devicemapper} 配下に追加されていく
    • $ docker images で現在保有している image 一覧が確認できる
    • $ docker rmi <image id> で削除できる
    • layer は42枚がデフォルトの limit なので、運用上気をつけた方が良いかも
      • ubuntu:14.04 でもすでに6枚使ってる
      • 変更を入れる時は Dockerfile で basic image から作り直す運用が望ましい
        • 変更 ps を commit する(≒新しくlayer をかぶせる)のではなく
        • パフォーマンス的にも layer は少ない方がベター

コンテナの駆動について

  • 基本的に1ジョブ(コマンド)を1コンテナで動かす思想

    • $ docker run <image id> <run command>
      • ジョブが完了したらそのコンテナは終了
    • 長期間駆動するワーカーとして実行する場合は -d (daemon mode) で駆動させる
      • daemon mode のコンテナは
        • $ docker attach <container id> で接続できる
        • $ docker kill <container id> でシグナルを送れる
  • $ docker run が終了しても container 自体は残っている

    • 実態は image と同等
      • $ docker commitimage として昇格させられる
    • fs 的な変更がなくても、(サイズは小さいが)常に生成される
      • $ docker run <image id> ls とかでも生成される
    • /var/lib/docker/containers 配下に追加されていく
    • $ docker ps -a で確認できる
    • $ docker rm <container id> で削除できる
    • $ docker run --rm で自動的に削除させられる
      • ただし -d(daemon mode) で $ docker run させる場合には指定できない
      • 思想的理由がよくわからないが、Conflicting options: -rm and -d って言われる…
      • ゴミを掃除する仕組みは必要になるかも

コンテナ間通信について

  • 各コンテナは docker の世界に閉じたローカルな IP アドレスを持つ
    • ただし、各コンテナにどのようなアドレスが割り当てられているか知ることが困難
  • 駆動中のコンテナがもつ情報を、別コンテナ駆動時に渡してあげることはできる
    • $ docker run --link=<running container id>:<ref tag> ...
      • 立ち上がったコンテナの環境変数に <ref tag>_ から始まる環境変数がいくつか設定される
      • 中身は <running container id> で指定したコンテナの IP addr 等

コンテナの外部通信について

  • 各コンテナが docker の世界より外と通信する場合は
    • HostOS の docker0 IF を通じて通信をする
    • NAT のように動作し、コンテナからはローカルな IP アドレスで通信しているように見える
      • 実際には HostOS 上でブリッジの機能(brctl まわり)を使っている
    • LISTEN する場合は、HostOS が LISTEN するポートと、コンテナのポートをペアリングする
      • HostOS の 8080 をコンテナの 80 とペアリングする場合は以下
      • $docker run -d -p 8080:80 tcnksm/apache
    • 外部通信をする場合、あくまで HostOS が LISTEN する点は留意
      • 80 などの特定の1ポートで LISTEN できるのは1コンテナだけということ
      • 複数コンテナで受けるならロードバランサとかプロクシとかの仕組みと組み合わせて

性能計測

Host OS

  • Ubuntu 14.04 on VirtualBox on OSX
  • 1 CPU (2.93 GHz Interl Core i7 の 1 core)
  • 6G memory

Container イメージ

以下の Dockerfile を元に $ docker build -t test-container . でビルド

Dockerfile

FROM ubuntu:14.04

ENV DEBIAN_FRONTEND noninteractive

RUN apt-get -y update

RUN apt-get -y install ruby
RUN apt-get -y install git
RUN apt-get -y install curl

RUN gem install awesome_print
RUN git clone https://github.com/kiyohara/docker_deploy_test.git

CMD [ "ruby", "docker_deploy_test/test.rb" ]

docker_deploy_test.git/test.rb

#!/usr/bin/env ruby

require 'awesome_print'
require 'webrick'

include WEBrick

puts 'running test.rb'.cyan

here = File.dirname(__FILE__)

server = HTTPServer.new(
  Port: 8080,
  DocumentRoot: File.join(here, 'public_html')
)
trap('INT') do
  server.shutdown
end
server.start

テストA

  • シナリオ
    1. コンテナ内容 = while true; do echo hello world; sleep 1; done
    2. vagrant up した直後
    3. 100 コンテナ起動(1回目)
    4. 全コンテナ停止
    5. 100 コンテナ起動(2回目)
    6. 全コンテナ停止
    7. 100 コンテナ起動(3回目)
    8. 全コンテナ停止
    9. コンテナ内容 = 前述の Ruby 製 http server
    10. vagrant up した直後
    11. 100 コンテナ起動(1回目)
    12. 全コンテナ停止
    13. 100 コンテナ起動(2回目)
    14. 全コンテナ停止
    15. 100 コンテナ起動(3回目)

$ docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"

$ docker run -d -p 8080 test-container

  • 結果
phase time top の used docker.io の VSS/RSS コンテナ内プロセス の VSS/RSS
1-1 - 0.319G 248M / 19M -
1-2 42.4s 1.010G 3,112M / 79M 4.34M / 0.63M
1-3 10.3s 0.643G 3,130M / 81M -
1-4 40.5s 1.245G 3.153M / 96M 4.44M / 0.67M
1-5 10.3s 0.872G 3.170M / 98M -
1-6 42.3s 1.458G 3.178M / 106M 4.44M / 0.67M
1-7 10.7s 1.089G 3.177M / 105M -
phase time top の used docker.io の VSS/RSS コンテナ内プロセス の VSS/RSS
2-1 - 0.341G 253M / 33M -
2-2 52.5s 2.481G 3.145M / 86M 52.78M / 11.52M
2-3 9.9s 0.733G 3.162M / 90M -
2-4 53.3s 2.747G 3.176M / 103M 52.78M / 11.53M
2-5 9.7s 1.034G 3.176M / 106M -
2-6 59.8s 3.036G 3.184M / 113M 52.78M / 11.53M
2-7 10.3s 1.301G 3.184M / 115M -

top の used はホストOS上から観測

※VSS/RSS はホストOS上で ps を用いて計測

※コンテナ内プロセスの VSS/RSS は 100個のうち1つをランダム抽出

テストB

  • シナリオ

    1. 前述のRuby製 http server コンテナを n1 個起動
    2. http client コンテナを 1 個起動し、内部で curl を 100 回実施した時間を計測 time docker run --link <container_id>:xxx test-container /bin/sh -c 'for i in `seq 1 100`; do curl http://${XXX_PORT_8080_TCP_ADDR}:8080/index.html; done'
  • 結果

n1 time 結果(3回平均)
10 2.845s
100 3.295s

補足(メモ)

  • 基本
    • docker run <docker image ID> <run command>
  • バックグラウンドで走らせる時
    • JOB_ID=$(docker run -d <docker image ID> <run command>)
    • docker log ${JOB_ID} で標準出力が見られる
    • docker kill ${JOB_ID} で SIGKILL
  • 大体はここにのってる
  • docker の操作は docker グループに所属する user でなければならない
    • もしくは root (sudo)
    • vagrant 環境なら、以下のように vagrant ユーザーを docker グループに追加するとよい
      • $ sudo gpasswd -a vagrant docker
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment