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