38
Dockerイメージ構築 実践テクニック Haruka Iwao Storage Solution Architect, Red Hat K.K. February 12, 2015

Dockerイメージ構築 実践テクニック

Embed Size (px)

Citation preview

Page 1: Dockerイメージ構築 実践テクニック

Dockerイメージ構築 実践テクニック

Haruka Iwao Storage Solution Architect, Red Hat K.K.

February 12, 2015

Page 2: Dockerイメージ構築 実践テクニック

自己紹介 •  岩尾 はるか (@Yuryu) •  所属: レッドハット株式会社

– ストレージソリューションアーキテクト – 大手家電メーカー、ソーシャルゲーム会社、

Web広告ベンチャーを経て現職 •  大学・大学院で高性能計算(HPC)、分散ファイルシステムを研究

•  ゲーマーです(主に某国産MMORPG)

Page 3: Dockerイメージ構築 実践テクニック

Dockerイメージの構造

RHEL

nginx

Webサーバー

OSの基本ファイル

OSの基本ファイル

OSの基本ファイル

nginx

nginx HTMLファイル

追加

追加

nginxイメージを元に作成

RHELイメージを元に作成

実体は共有

新規

Page 4: Dockerイメージ構築 実践テクニック

Dockerイメージの作成手順 •  2ステップで作成できます

•  Dockerfile の作成 •  $ docker build -t <tag> Dockerfileの場所

– 例) $ docker build -t yuryu/test .

Page 5: Dockerイメージ構築 実践テクニック

Dockerfileとは •  イメージ作成の手順を書いたもの •  例)

FROM  registry.access.redhat.com/rhel    RUN  yum  -­‐y  install  httpd  ADD  index.html  /var/www/html/index.html    EXPOSE  80    CMD  ["/usr/sbin/httpd",  "-­‐DFOREGROUND"]  

Page 6: Dockerイメージ構築 実践テクニック

Dockerfile 文法 •  FROM - ベースとなるイメージ •  RUN - イメージ構築で実行するコマンド •  ADD - イメージ内にファイルを追加 •  EXPOSE - ポートを外に見せる •  CMD - デフォルトで実行されるコマンド

FROM  registry.access.redhat.com/rhel    RUN  yum  -­‐y  install  httpd  ADD  index.html  /var/www/html/index.html    EXPOSE  80    CMD  ["/usr/sbin/httpd",  "-­‐DFOREGROUND"]  

Page 7: Dockerイメージ構築 実践テクニック

Dockerfile 文法(2) •  MAINTAINER - メンテナを書く •  USER - コンテナ内で実行するユーザー •  WORKDIR - 基準ディレクトリの変更 •  COPY - ホストからファイルのコピー

– ADD が大きすぎるので分割 •  その他リファレンスは下記

– https://docs.docker.com/reference/builder/  

Page 8: Dockerイメージ構築 実践テクニック

作って動かす •  $ docker run で実行

–  -d バックグラウンドで実行 –  -P EXPOSE したポートを割り当て $  mkdir  demo-­‐apache  $  cd  demo-­‐apache  $  curl  -­‐L  -­‐o  Dockerfile  bit.ly/1FA902p  $  echo  “Hello,  Docker!”  >  index.html  $  build  -­‐t  demo-­‐apache  .    $  docker  run  -­‐dP  demo-­‐apache  

Page 9: Dockerイメージ構築 実践テクニック

docker build 実行例 [yuryu@rhel7  docker-­‐apache]$  docker  build  -­‐t  demo-­‐apache  .  Sending  build  context  to  Docker  daemon  3.584  kB  Sending  build  context  to  Docker  daemon    Step  0  :  FROM  registry.access.redhat.com/rhel    -­‐-­‐-­‐>  e1f5733f050b  Step  1  :  RUN  yum  -­‐y  install  httpd    -­‐-­‐-­‐>  Using  cache    -­‐-­‐-­‐>  3679b20fa9ba  Step  2  :  ADD  index.html  /var/www/html/index.html    -­‐-­‐-­‐>  Using  cache    -­‐-­‐-­‐>  db91c285d5ad  Step  3  :  EXPOSE  80    -­‐-­‐-­‐>  Using  cache    -­‐-­‐-­‐>  c9ceb17b169f  Step  4  :  CMD  /usr/sbin/httpd  -­‐DFOREGROUND    -­‐-­‐-­‐>  Using  cache    -­‐-­‐-­‐>  4e99155706f6  Successfully  built  4e99155706f6  

Page 10: Dockerイメージ構築 実践テクニック

docker run 実行例 •  ランダムなポートと、コンテナID、コンテナ名が割り当てられる

[yuryu@rhel7  docker-­‐apache]$  docker  run  -­‐dP  demo-­‐apache  8d6b20a1e23427ad575bed1aee9cbea5406e5ed648a645e955cd6c6c6a34ea0a  [yuryu@rhel7  docker-­‐apache]$  docker  ps  CONTAINER  ID                IMAGE                                COMMAND                                CREATED                          STATUS                            PORTS                                        NAMES  8d6b20a1e234                demo-­‐apache:latest      "/usr/sbin/httpd  -­‐DF      4  seconds  ago              Up  4  seconds                0.0.0.0:49247-­‐>80/tcp        jovial_jones                  

Page 11: Dockerイメージ構築 実践テクニック

いくつかの応用パターン •  固定ポートの割り当て •  コンテナのリンク •  コンテナ内のボリュームを共有 •  コンテナ外とボリュームを共有

Page 12: Dockerイメージ構築 実践テクニック

固定ポートの割り当て •  $ docker run -p <host port>:<guest port> •  $ docker port コマンドでもポートの割り当てを確認できる

[yuryu@rhel7  docker-­‐apache]$  docker  run  -­‐dp  80:80  demo-­‐apache  b027be3d09ace7c8cac594c14d07d3ddda5c32f15e14f8a28297714a69723c54  [yuryu@rhel7  docker-­‐apache]$  docker  port  b027be3d09ac  80/tcp  -­‐>  0.0.0.0:80  

Page 13: Dockerイメージ構築 実践テクニック

コンテナのリンク •  --link <コンテナ名>:alias •  EXPOSEしたポートを環境変数に入れる #  docker  run  -­‐d  -­‐e  MYSQL_ROOT_PASSWORD=root  -­‐-­‐name  mysql  mysql  #  docker  run  -­‐it  -­‐-­‐link  mysql:mysql  mysql  /bin/bash  #  env  |grep  MYSQL_PORT  MYSQL_PORT_3306_TCP_PORT=3306  MYSQL_PORT_3306_TCP=tcp://172.17.0.155:3306  MYSQL_PORT_3306_TCP_PROTO=tcp  MYSQL_PORT_3306_TCP_ADDR=172.17.0.155  MYSQL_PORT=tcp://172.17.0.155:3306  #  mysql  -­‐-­‐host=$MYSQL_PORT_3306_TCP_ADDR  -­‐-­‐port=$MYSQL_PORT_3306_TCP_PORT  -­‐-­‐password=root  

Page 14: Dockerイメージ構築 実践テクニック

ALIAS_PORT_XXX ALIAS_PORT_XXX_TCP ALIAS_PORT_XXX_TCP_PROTO ALIAS_PORT_XXX_TCP_ADDR ALIAS_PORT_XXX_TCP_PORT

コンテナのリンク(図)

提供コンテナ 使うコンテナ link

alias EXPOSE

環境変数

Page 15: Dockerイメージ構築 実践テクニック

コンテナ内のボリューム共有 •  例: VOLUME /var/lib/mysql •  --volumes-from <コンテナ名> で利用 •  Data-only コンテナをベースに使うと良い

#  docker  run  -­‐d  -­‐-­‐name  mysql_volume  mysql  echo  MySQL  Volume  Container  #  docker  run  -­‐-­‐volumes-­‐from  mysql_volume  -­‐d  -­‐e  MYSQL_ROOT_PASSWORD=root  -­‐-­‐name  mysql  mysql  

Docker 1.4以降は docker run の代わりに docker create を利用する (ボリューム生成のタイミングが変更されている)

Page 16: Dockerイメージ構築 実践テクニック

コンテナ外とのボリューム共有 •  -v <host path>:<container path> •  SELinuxの設定が必要

– # chcon -Rt svirt_sandbox_file_t

$  mkdir  mysql-­‐volume;  cd  mysql-­‐volume  $  sudo  chcon  -­‐Rt  svirt_sandbox_file_t  .  $  docker  run  -­‐v  $(pwd):/var/lib/mysql  -­‐-­‐name  mysql  -­‐e  MYSQL_ROOT_PASSWORD=root  -­‐d  mysql  

Page 17: Dockerイメージ構築 実践テクニック

Data-onlyコンテナのバックアップ

•  ホストでボリュームを共有して、tarで固める

$  mkdir  mysql-­‐volume;  cd  mysql-­‐volume  $  sudo  chcon  -­‐Rt  svirt_sandbox_file_t  .  $  sudo  docker  run  -­‐-­‐volumes-­‐from  mysql_volume  -­‐v  $(pwd):/backup  -­‐-­‐name  mysql-­‐backup  fedora  tar  cfz  /backup/mysql-­‐backup.tar.gz  /var/lib/mysql  

$  sudo  docker  run  -­‐-­‐volumes-­‐from  mysql_volume  -­‐v  $(pwd):/backup  -­‐-­‐name  mysql-­‐restore  fedora  tar  xf  /backup/mysql-­‐backup.tar.gz  -­‐C  /    

Page 18: Dockerイメージ構築 実践テクニック

ボリューム共有

Data only コンテナ 使うコンテナ

volumes-from

VOLUME

ホスト

-v <host>:<container>

Page 19: Dockerイメージ構築 実践テクニック

Dockerで作るCI

開発者A

開発者B

コンテナの定義を共有

変更を通知

自動テストを実施

コンテナを取得して開発

開発者C

クラウドへデプロイを指示

GitHub

テスト済みコンテナイメージを クラウドサービスへデプロイ

コンテナイメージを作成

Page 20: Dockerイメージ構築 実践テクニック

今回のデモの定義 •  GitHubで公開中 •  https://github.com/yuryu/docker-­‐jenkins-­‐demo  

Red Hat Enterprise Linux

テスト ソースコードを取得

生成 起動

Page 21: Dockerイメージ構築 実践テクニック

JenkinsのDockerfile FROM  registry.access.redhat.com/rhel  MAINTAINER  Haruka  Iwao    RUN  yum  -­‐y  upgrade    RUN  curl  -­‐o  /etc/yum.repos.d/jenkins.repo  http://pkg.jenkins-­‐ci.org/redhat/jenkins.repo  RUN  rpm  -­‐-­‐import  https://jenkins-­‐ci.org/redhat/jenkins-­‐ci.org.key  RUN  yum  -­‐y  install  jenkins  java  git  docker    ADD  run-­‐jenkins.sh  /root/run-­‐jenkins.sh    EXPOSE  8080    CMD  /root/run-­‐jenkins.sh  

Page 22: Dockerイメージ構築 実践テクニック

run-jenkins.sh #!/bin/sh    JENKINS_HOME="/var/lib/jenkins"  JENKINS_USER="jenkins"  JENKINS_JAVA_OPTIONS="-­‐Djava.awt.headless=true"  JENKINS_PORT="8080"  JENKINS_HANDLER_MAX="100"  JENKINS_HANDLER_IDLE="20"    JAVA_CMD="/usr/bin/java  $JENKINS_JAVA_OPTIONS  -­‐DJENKINS_HOME=$JENKINS_HOME  -­‐jar  /usr/lib/jenkins/jenkins.war"  OPTIONS="-­‐-­‐httpPort=$JENKINS_PORT  -­‐-­‐handlerCountMax=$JENKINS_HANDLER_MAX  -­‐-­‐handlerCountMaxIdle=$JENKINS_HANDLER_IDLE  "    cd  "$JENKINS_HOME"  exec  runuser  -­‐u  $JENKINS_USER  -­‐-­‐  $JAVA_CMD  $OPTIONS

Page 23: Dockerイメージ構築 実践テクニック

SlaveのDockerfile FROM  registry.access.redhat.com/rhel  MAINTAINER  Haruka  Iwao    RUN  yum  -­‐y  upgrade    RUN  yum  -­‐y  swap  -­‐-­‐  remove  fakesystemd  -­‐-­‐  install  systemd  systemd-­‐libs  RUN  yum  -­‐y  install  openssh-­‐server  java-­‐1.7.0-­‐openjdk    RUN  adduser  jenkins  RUN  echo  "jenkins:jenkins"  |  chpasswd  RUN  ssh-­‐keygen  -­‐f  /etc/ssh/ssh_host_rsa_key  -­‐N  ''  -­‐t  rsa  RUN  ssh-­‐keygen  -­‐f  /etc/ssh/ssh_host_dsa_key  -­‐N  ''  -­‐t  dsa  RUN  ssh-­‐keygen  -­‐f  /etc/ssh/ssh_host_ecdsa_key  -­‐N  ''  -­‐t  ecdsa    RUN  yum  -­‐y  install  gcc  gcc-­‐c++  automake  autoconf  make  git  libtool    EXPOSE  22    CMD  ["/usr/sbin/sshd",  "-­‐D"]  

Page 24: Dockerイメージ構築 実践テクニック

Slaveを作るときの注意点 •  RHEL標準のコンテナイメージには

systemdが入っていません •  fakesystemdが入っている •  systemdに依存するパッケージを入れる場合は、本物のsystemdに置き換える – yum -y swap -- remove fakesystemd -- install

systemd systemd-libs •  systemdをinitとして実行する必要は無い

Page 25: Dockerイメージ構築 実践テクニック

Jenkins Docker Plugin •  JenkinsスレーブをDockerで実行 •  テストごとにコンテナを生成、削除

Page 26: Dockerイメージ構築 実践テクニック

DockerにTCPをlistenさせる •  Jenkinsから制御するために必要 •  /etc/sysconfig/dockerを書き換える •  このままだと認証なしに誰でもアクセス可能になるので注意!

OPTIONS=-­‐-­‐selinux-­‐enabled  -­‐H  tcp://172.17.42.1:5555  -­‐H  fd://  

Page 27: Dockerイメージ構築 実践テクニック

Jenkins実行手順 •  Data-onlyコンテナを起動してから、

Jenkins本体を起動する

$  docker  run  -­‐d  -­‐v  /var/lib/jenkins  -­‐-­‐name  jenkins-­‐home  yuryu/demo-­‐jenkins  echo  Data-­‐only  container  for  jenkins  $  docker  run  -­‐-­‐volumes-­‐from  jenkins-­‐home  -­‐d  -­‐p  8080:8080  yuryu/demo-­‐jenkins  

Page 28: Dockerイメージ構築 実践テクニック

Jenkins本体の設定 •  Manage Jenkins > Configure System

Page 29: Dockerイメージ構築 実践テクニック

Dockerの状態を確認 •  Manage Jenkins > Docker

Page 30: Dockerイメージ構築 実践テクニック

プロジェクトの設定

Page 31: Dockerイメージ構築 実践テクニック

今回デモで使うプロジェクト •  簡単なautoconf  /  gtest  を使うCのプロジェクトを用意しました  

•  https://github.com/yuryu/gtest-­‐demo

Page 32: Dockerイメージ構築 実践テクニック

テスト実行中の様子 •  コンテナ内で configure が走っている

Page 33: Dockerイメージ構築 実践テクニック

テスト終了後 •  設定すれば、コンテナをイメージに

commitできる

Page 34: Dockerイメージ構築 実践テクニック

実際にやってみます

Page 35: Dockerイメージ構築 実践テクニック

cAdvisor •  Dockerのための監視ツール

– https://github.com/google/cadvisor

Page 36: Dockerイメージ構築 実践テクニック

cAdvisorの画面

Page 37: Dockerイメージ構築 実践テクニック

cAdvisor起動方法 #  setenforce  Permissive  $  docker  run  \      -­‐-­‐volume=/:/rootfs:ro  \      -­‐-­‐volume=/var/run:/var/run:rw  \      -­‐-­‐volume=/sys:/sys:ro  \      -­‐-­‐volume=/var/lib/docker/:/var/lib/docker:ro  \      -­‐-­‐publish=8080:8080  \      -­‐-­‐detach=true  \      -­‐-­‐name=cadvisor  \      -­‐-­‐volume=/cgroup:/cgroup  \      google/cadvisor:latest

Page 38: Dockerイメージ構築 実践テクニック

ご清聴ありがとうございました