Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Docker と継続的インテグレーション
14/02/12 Docker Meetup in Tokyo #1
Kazuki Suda
! @superbrothers
" github.com/superbrothers
# 本日のお話

Docker での
ビルド -> テスト -> プッシュの自動化
# アジェンダ
-

CI ワークフロー 構成編

-

Dockerfile のテスト
-

ベースとなるイメージの実装

-

テストの準備と実行

-

CI ワークフロー ジョブスクリプト編

-

デモ

-

まとめ
# デモコードあります

https://github.com/ydnjp/
docker-continuous-integration-workflow
# CI ワークフロー 登場人物編
!

ビルド -> テスト -> プッシュの自動化
## 登場人物
Jenkins

Docker レジストリ

#

$
Git リポジトリ

Docker 入りスレーブ
## ワークフロー

ビルド

テスト

プッシュ

docker build

serverspec

docker push
# Dockerfile のテスト
## ディレクトリ構造
├──Gemfile
├──Gemfile.lock
├──Rakefile
├──dockerfiles
│
├──base
│
│
├──Dockerfile
│
│
└──keys
│
│
├──id_rsa
│
...
## Dockerfile の配置
├──Gemfile
dockerfiles/<image-name> で
├──Gemfile.lock
Dockerfile を配置する
├──Rakefile
├──dockerfiles
│
├──b...
## spec の配置
├──Gemfile
spec/<image-name> で
├──Gemfile.lock
├──Rakefile
スペックを配置する
├──dockerfiles
│
├──base
│
│
├──Dockerfil...
serverspec は ssh を通して
コンテナとやりとりするので
sshd 入りのベースとする
イメージを用意します
(base イメージ)

├──Gemfile
├──Gemfile.lock
├──Rakefile
├──docke...
dockerfiles/base/Dockerfile
FROM ubuntu:13.10
!
ENV DEBIAN_FRONTEND noninteractive
!
RUN apt-get -q update && apt-get -y u...
## ベースイメージのビルドとコンテナの起動

% docker build -t base dockerfiles/base
!

% docker run -d -p 22 base /usr/sbin/sshd -D

22番ポートが b...
## ベースイメージのポイント

-

ノーパスキーを利用しよう

-

root にパスワードを設定しちゃダメ!
# serverspec を使ったテストの準備と実行
## serverspec を使ったテスト実行の流れ

1. イメージからコンテナを起動する
-

CMD /usr/sbin/sshd -D

-

22番ポートを bind する

2. bind されたポートに対して SSH を使って s...
spec/spec_helper.rb (前編)
c.before :all do
(略)…
host = File.basename(Pathname.new(file).dirname)
!

if c.host != host
Docke...
spec/spec_helper.rb (後編)
c.ssh.close if c.ssh
base イメージに追加した公開鍵と
c.host = host
対の秘密鍵を使う
options = {
:keys => [File.expand_...
spec/base/sshd_spec.rb
require 'spec_helper'
!
describe package('openssh-server') do
it { should be_installed }
end
!
desc...
## テストの実行

$ bundle exec rake spec
/usr/bin/ruby1.9.1 -S rspec spec/base/sshd_spec.rb
.........
!
Finished in 2.21 seconds...
ベースとなるイメージの実装が終わったので
本来必要なイメージを
実装する準備が整いました(長い)

例として jenkins イメージを作ります

(ここからは早送り
## jenkins イメージ
├──Gemfile
├──Gemfile.lock
├──Rakefile
├──dockerfiles
│
├──base
│
│
├──Dockerfile
│
│
└──keys
│
│
├──id_rs...
dockerfiles/jenkins/Dockerfile

FROM base
base をベースとするので、sshd 入り
!
RUN apt-get -q -y install openjdk-7-jre-headless && apt...
# docker build, push の Rake タスク化
!

繰り返し行うことはタスクにまとめましょう
## docker build
イメージが base に依存しているので、
base から順番にビルドする
% bundle exec rake docker:build

docker build -t base dockerfiles/ba...
# CI ワークフロー ジョブスクリプト編
!

ビルド -> テスト -> プッシュの自動化
## ジョブスクリプト

ベースは出来ているのでこれだけです。
デモ
## まとめ

-

ビルド、テスト、プッシュの自動化ができました

-

毎日自動でまわすことで常に最新のセキュリティ
アップデートを当て続けることもできます

!

次は継続的デリバリーに向けて?
# デモコードあります (再掲)

https://github.com/ydnjp/
docker-continuous-integration-workflow
ありがとうございました
Dockerと継続的インテグレーション
Dockerと継続的インテグレーション
Upcoming SlideShare
Loading in …5
×

Dockerと継続的インテグレーション

12,703 views

Published on

2014/02/12 Docker Meetup in Tokyo #1 での発表内容です。
デモコード: https://github.com/ydnjp/docker-continuous-integration-workflow

Published in: Technology

Dockerと継続的インテグレーション

  1. 1. Docker と継続的インテグレーション 14/02/12 Docker Meetup in Tokyo #1
  2. 2. Kazuki Suda ! @superbrothers " github.com/superbrothers
  3. 3. # 本日のお話 Docker での ビルド -> テスト -> プッシュの自動化
  4. 4. # アジェンダ - CI ワークフロー 構成編 - Dockerfile のテスト - ベースとなるイメージの実装 - テストの準備と実行 - CI ワークフロー ジョブスクリプト編 - デモ - まとめ
  5. 5. # デモコードあります https://github.com/ydnjp/ docker-continuous-integration-workflow
  6. 6. # CI ワークフロー 登場人物編 ! ビルド -> テスト -> プッシュの自動化
  7. 7. ## 登場人物 Jenkins Docker レジストリ # $ Git リポジトリ Docker 入りスレーブ
  8. 8. ## ワークフロー ビルド テスト プッシュ docker build serverspec docker push
  9. 9. # Dockerfile のテスト
  10. 10. ## ディレクトリ構造 ├──Gemfile ├──Gemfile.lock ├──Rakefile ├──dockerfiles │ ├──base │ │ ├──Dockerfile │ │ └──keys │ │ ├──id_rsa │ │ └──id_rsa.pub │ └──jenkins │ ├──Dockerfile │ └──start-jenkins.sh └──spec ├──base │ └──sshd_spec.rb ├──jenkins │ └──jenkins_spec.rb └──spec_helper.rb
  11. 11. ## Dockerfile の配置 ├──Gemfile dockerfiles/<image-name> で ├──Gemfile.lock Dockerfile を配置する ├──Rakefile ├──dockerfiles │ ├──base │ │ ├──Dockerfile │ │ └──keys │ │ ├──id_rsa │ │ └──id_rsa.pub base イメージ │ └──jenkins │ ├──Dockerfile │ └──start-jenkins.sh └──spec ├──base jenkins イメージ │ └──sshd_spec.rb ├──jenkins │ └──jenkins_spec.rb └──spec_helper.rb
  12. 12. ## spec の配置 ├──Gemfile spec/<image-name> で ├──Gemfile.lock ├──Rakefile スペックを配置する ├──dockerfiles │ ├──base │ │ ├──Dockerfile │ │ └──keys │ │ ├──id_rsa │ │ └──id_rsa.pub │ └──jenkins │ ├──Dockerfile │ └──start-jenkins.sh dockerfiles 以下に └──spec ├──base 対応する形です │ └──sshd_spec.rb ├──jenkins │ └──jenkins_spec.rb └──spec_helper.rb
  13. 13. serverspec は ssh を通して コンテナとやりとりするので sshd 入りのベースとする イメージを用意します (base イメージ) ├──Gemfile ├──Gemfile.lock ├──Rakefile ├──dockerfiles │ ├──base │ │ ├──Dockerfile │ │ └──keys │ │ ├──id_rsa │ │ └──id_rsa.pub │ └──jenkins │ ├──Dockerfile │ └──start-jenkins.sh └──spec ├──base │ └──sshd_spec.rb ├──jenkins │ └──jenkins_spec.rb └──spec_helper.rb ssh ログインに使う ノーパスキーです
  14. 14. dockerfiles/base/Dockerfile FROM ubuntu:13.10 ! ENV DEBIAN_FRONTEND noninteractive ! RUN apt-get -q update && apt-get -y upgrade ! # Install openssh-server for serverspec sshd をインストール RUN apt-get -q -y install openssh-server && apt-get clean RUN mkdir /var/run/sshd RUN mkdir /root/.ssh && chmod 600 /root/.ssh ノーパスの ADD keys/id_rsa.pub /root/.ssh/authorized_keys 公開鍵を追加 RUN chown root:root /root/.ssh/authorized_keys ! # Ubuntu 13.10 additional steps for SSHD Service RUN sed -i 's/.*session.*required.*pam_loginuid.so.*/session optional pam_loginuid.so/g' /etc/pam.d/sshd RUN echo LANG="en_US.UTF-8" > /etc/default/locale
  15. 15. ## ベースイメージのビルドとコンテナの起動 % docker build -t base dockerfiles/base ! % docker run -d -p 22 base /usr/sbin/sshd -D 22番ポートが bind されたポートを指定して ノーパスキーの秘密鍵を使うとログインできる
  16. 16. ## ベースイメージのポイント - ノーパスキーを利用しよう - root にパスワードを設定しちゃダメ!
  17. 17. # serverspec を使ったテストの準備と実行
  18. 18. ## serverspec を使ったテスト実行の流れ 1. イメージからコンテナを起動する - CMD /usr/sbin/sshd -D - 22番ポートを bind する 2. bind されたポートに対して SSH を使って spec を流し込む - ノーパスの秘密鍵を使います - bind されたポートは inspect で取得 - 1 -> 2 を最後まで繰り返す 3. 利用したコンテナを殺して削除する
  19. 19. spec/spec_helper.rb (前編) c.before :all do (略)… host = File.basename(Pathname.new(file).dirname) ! if c.host != host Docker イメージごとにコンテナを起動 ## Start container and retrieve port number of sshd container = Docker::Container.create( docker-api 使ってます :Image => "#{host}", :Entrypoint => ['/usr/sbin/sshd'], :Cmd => ['-D'], sshd を起動させる :ExposedPorts => {'22/tcp' => {}}, :User => 'root' ).start( :PortBindings => { コンテナの22番ポートを 親のホストに bind '22/tcp' => [{:HostIp =>‘127.0.0.1’}] } ) 使ったコンテナはあとで sleep 1 停止、削除するのでとっておく containers << container
  20. 20. spec/spec_helper.rb (後編) c.ssh.close if c.ssh base イメージに追加した公開鍵と c.host = host 対の秘密鍵を使う options = { :keys => [File.expand_path('../../dockerfiles/base/keys/id_rsa', __FILE__)], :port => container.json['HostConfig']['PortBindings']['22/tcp'][0] ['HostPort'] HostConfig から bind されたポートを } 取得する c.ssh = Net::SSH.start('0.0.0.0', 'root', options) end 接続先はローカルホストで root ユーザ end ! c.after(:suite) do 利用したコンテナを ## Kill and delete containers 殺して削除する containers.each {|container| container.kill.delete } end
  21. 21. spec/base/sshd_spec.rb require 'spec_helper' ! describe package('openssh-server') do it { should be_installed } end ! describe file('/var/run/sshd') do it { should be_directory } end ! describe file('/root/.ssh') do it { should be_directory } it { should be_mode 600 } end パッケージが正しく インストールされているか ディレクトリが存在するか ディレクトリが存在するか
 パーミッションが正しいか spec の記述については serverspec 公式の ドキュメントを確認してください
  22. 22. ## テストの実行 $ bundle exec rake spec /usr/bin/ruby1.9.1 -S rspec spec/base/sshd_spec.rb ......... ! Finished in 2.21 seconds 9 examples, 0 failures
  23. 23. ベースとなるイメージの実装が終わったので 本来必要なイメージを 実装する準備が整いました(長い) 例として jenkins イメージを作ります
 (ここからは早送り
  24. 24. ## jenkins イメージ ├──Gemfile ├──Gemfile.lock ├──Rakefile ├──dockerfiles │ ├──base │ │ ├──Dockerfile │ │ └──keys │ │ ├──id_rsa │ │ └──id_rsa.pub │ └──jenkins │ ├──Dockerfile │ └──start-jenkins.sh └──spec ├──base │ └──sshd_spec.rb ├──jenkins │ └──jenkins_spec.rb └──spec_helper.rb Dockerfile はここ spec はこちら
  25. 25. dockerfiles/jenkins/Dockerfile FROM base base をベースとするので、sshd 入り ! RUN apt-get -q -y install openjdk-7-jre-headless && apt-get clean ! # Install Jenkins jenkins のセットアップ(略) RUN mkdir /opt/jenkins … FROM base としているので、そのままで sshd を起動したコンテナを起動させることができます ! あとは spec を実装したら完了です (spec を先に実装することで TDD もできちゃう) spec の実装は省略します
  26. 26. # docker build, push の Rake タスク化 ! 繰り返し行うことはタスクにまとめましょう
  27. 27. ## docker build イメージが base に依存しているので、 base から順番にビルドする % bundle exec rake docker:build
 docker build -t base dockerfiles/base (略)... ## docker push docker tag でプライベートレジストリの情報を付けたのち、 順番に push する % bundle exec rake docker:push docker tag base 0.0.0.0:5000/base docker push 0.0.0.0:5000/base (略)... 実装はデモコードの Rakefile を参照してください!
  28. 28. # CI ワークフロー ジョブスクリプト編 ! ビルド -> テスト -> プッシュの自動化
  29. 29. ## ジョブスクリプト ベースは出来ているのでこれだけです。
  30. 30. デモ
  31. 31. ## まとめ - ビルド、テスト、プッシュの自動化ができました - 毎日自動でまわすことで常に最新のセキュリティ アップデートを当て続けることもできます ! 次は継続的デリバリーに向けて?
  32. 32. # デモコードあります (再掲) https://github.com/ydnjp/ docker-continuous-integration-workflow
  33. 33. ありがとうございました

×