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.

【dots. IT勉強会】開発環境のDocker化

5,980 views

Published on

dots. IT勉強会で発表させて頂きました、ランサーズ開発環境のDocker移行に関する資料です。

サービスの拡張に伴い、多数の開発環境が必要になったため、それを効率良く管理するためDockerを採用した話です。

・既存開発環境との互換性維持
・本番環境との構成共通化
・非エンジニアでも構築、運用できる仕組み

を意識した、目的達成の手段としてのDocker運用方法を紹介いたしました。

Published in: Engineering
  • Be the first to comment

【dots. IT勉強会】開発環境のDocker化

  1. 1. 開発環境のDocker化 http://www.lancers.jp/ 「時間と場所にとらわれない、新しい働き方を創る」 [2016/03/30 dots. IT勉強会] ランサーズ株式会社 インフラエンジニア 金澤 裕毅 [Kanazawa Yuki]
  2. 2. © 2016 for LANCERS, inc All Rights Reserved 自己紹介 • 氏名 • 金澤 裕毅 • 入社時期 • 2013年11月 • 業務内容 • ランサーズの運用監視 • AWS全般 • 開発支援 • 開発環境構築 • インフラ関連の支援 • 情報システム業務 • 社内LAN構築 • 社内サーバー運用 • PC関連 • その他 • 趣味 • 将棋とか(一応初段)
  3. 3. © 2016 for LANCERS, inc All Rights Reserved 本日お話しさせていただく内容 ランサーズ開発環境の歴史 Docker導入の経緯 Docker導入の基本方針 直面した問題とその解決方法 Docker移行結果 今後の展望
  4. 4. © 2016 for LANCERS, inc All Rights Reserved ランサーズ開発環境の歴史 Docker導入の基本方針 直面した問題とその解決方法 Docker移行結果 今後の展望 Docker導入の経緯
  5. 5. © 2016 for LANCERS, inc All Rights Reserved ランサーズ開発環境の歴史(2008 ~ 2010) • 開発人数:2人 • PC環境 • Windowsデスクトップ • 開発環境 • Linuxサーバーに直接ログイン • CentOS • 開発ツール • ソース管理:SVN • 直接ログインしてVimで開発
  6. 6. © 2016 for LANCERS, inc All Rights Reserved ランサーズ開発環境の歴史(2011 ~ 2013) • 開発人数:4人~10人 • PC環境 • Windowsデスクトップ • デザイナーはMac • 開発環境 • 社内開発サーバー(VMWare ESXi) • 開発ツール • ソース管理:SVN • 直接ログインしてVimで開発 • ssh経由でIDEを使う人も
  7. 7. © 2016 for LANCERS, inc All Rights Reserved ランサーズ開発環境の歴史(2014 ~ 2015) • 開発人数:10人~20人 • PC環境 • Windowsデスクトップ • エンジニアもMacに移行し始める • 開発環境 • VirtualBox + Vagrant • Ansibleで個人PC内に開発環境を構築 • 開発ツール • ソース管理:SVN→Githubに移行 • PC上のエディタで開発 • VirtualBox共有フォルダ • PHP Stormでデバッグする人も
  8. 8. © 2016 for LANCERS, inc All Rights Reserved ランサーズ開発環境の歴史(2016 ~ ) • 開発人数:20人以上 • PC環境 • ほとんどMac • Windowsは数人 • 開発環境 • VirtualBox + Docker Toolbox • Dockerfile + Ansibleでコンテナ構築 • 開発ツール • ソース管理:Github • PC上のエディタで開発 • VirtualBox共有フォルダ + Dockerマウント • PHP Stormのデバッグも可能
  9. 9. © 2016 for LANCERS, inc All Rights Reserved Docker導入の経緯 Docker導入の基本方針 直面した問題とその解決方法 Docker移行結果 今後の展望 ランサーズ開発環境の歴史
  10. 10. © 2016 for LANCERS, inc All Rights Reserved Vagrant + Ansible時代の開発環境構成 192.168.33.11 HDD 50GB メモリ 2GB App(ランサーズ本体) Apache 2.2 (80) PHP 5.3 MySQL 5.6 (3306) Memcached(11211) Virtual Box VM CentOS 6
  11. 11. © 2016 for LANCERS, inc All Rights Reserved Vagrant + Ansible時代の開発環境構成 192.168.33.11 HDD 50GB メモリ 2GB App(ランサーズ本体) Apache 2.2 (80) PHP 5.3 MySQL 5.6 (3306) Memcached(11211) 192.168.33.12 HDD 50GB メモリ 1GB メッセージ(チャット) Nginx(3443) node.js(3001) Redis(6379) Virtual Box VM CentOS 6
  12. 12. © 2016 for LANCERS, inc All Rights Reserved Vagrant + Ansible時代の開発環境構成 192.168.33.11 HDD 50GB メモリ 2GB App(ランサーズ本体) Apache 2.2 (80) PHP 5.3 MySQL 5.6 (3306) Memcached(11211) 192.168.33.13 HDD 50GB メモリ 1GB WordPress (コーポレート、ブログ等) Apache 2.4(80) PHP 5.5 MySQL 5.6(3306) 192.168.33.12 HDD 50GB メモリ 1GB メッセージ(チャット) Nginx(3443) node.js(3001) Redis(6379) Virtual Box VM CentOS 6
  13. 13. © 2016 for LANCERS, inc All Rights Reserved Vagrant + Ansible時代の開発環境構成 192.168.33.11 HDD 50GB メモリ 2GB App(ランサーズ本体) Apache 2.2 (80) PHP 5.3 MySQL 5.6 (3306) Memcached(11211) 192.168.33.13 HDD 50GB メモリ 1GB WordPress (コーポレート、ブログ等) Apache 2.4(80) PHP 5.5 MySQL 5.6(3306) 192.168.33.12 HDD 50GB メモリ 1GB メッセージ(チャット) Nginx(3443) node.js(3001) Redis(6379) 192.168.33.15 HDD 50GB メモリ 1GB 認証システム Virtual Box VM CentOS 6
  14. 14. © 2016 for LANCERS, inc All Rights Reserved VMを1つにまとめる 192.168.33.11 HDD 50GB メモリ 2GB App(ランサーズ本体) Apache 2.2 (80) PHP 5.3 MySQL 5.6 (3306) Memcached(11211) Virtual Box VM CentOS 6
  15. 15. © 2016 for LANCERS, inc All Rights Reserved VMを1つにまとめる 192.168.33.11 HDD 50GB メモリ 2GB App(ランサーズ本体) Apache 2.2 (80) PHP 5.3 MySQL 5.6 (3306) Memcached(11211) メッセージ(チャット) Nginx(3443) node.js(3001) Redis(6379) Virtual Box VM CentOS 6
  16. 16. © 2016 for LANCERS, inc All Rights Reserved VMを1つにまとめる 192.168.33.11 HDD 50GB メモリ 2GB App(ランサーズ本体) Apache 2.2 (80) PHP 5.3 MySQL 5.6 (3306) Memcached(11211) メッセージ(チャット) Nginx(3443) node.js(3001) Redis(6379) WordPress Apache 2.4(80) PHP 5.5 MySQL 5.6(3306) Virtual Box VM CentOS 6
  17. 17. © 2016 for LANCERS, inc All Rights Reserved Vagrant + Ansible時代の問題点 • 構築に時間がかかる • PHP、MySQLのビルド時間:1.5時間 • MySQLのインポート時間:2.5時間以上 • 構成更新時の問題 • Appサーバーに新しいミドルウェアを追加 • Ansible Playbookにプルリクを投げる • 誰が検証するの? • 検証中は開発できない • 再構築も時間がかかる(元に戻らないリスクも) • 誰もPlaybookを更新しなくなる • 更新差分は手動でカバー • 原因不明のエラーがさらに増える • DB構成の変更 • 都度、手動でALTER TABLE、INSERT、UPDATEを実行 • 抜け漏れがあると復元困難に • Windows環境での構築が不安定 • VitualBox、Vagrant、Ansibleのバージョン相性がシビア • 成功率50%以下
  18. 18. © 2016 for LANCERS, inc All Rights Reserved Docker導入の基本方針 Docker導入の経緯 直面した問題とその解決方法 Docker移行結果 今後の展望 ランサーズ開発環境の歴史
  19. 19. © 2016 for LANCERS, inc All Rights Reserved Docker導入の基本指針 • 利用面 • Vagrant時代の利便性を維持 • PC上のエディタで開発可能 • SQLクライアントでDB参照可能 • PHPStorm(Xdebug)でステップ実行可能 • 個人で構築はしない • コンテナをpullするだけ • MySQLもDBインポート済のものをpull • コンテナ構築は特定の人が行う • 当日から開発可能にする • 構築時間は30分以内に抑える • 非エンジニアでも簡単に構築可能に • 構成面 • HDD20GB、メモリ2GBのVMで動作可能 • 本番環境と極力同じ構成にする • 本番サーバーと共通のAnsible Playbookを使う
  20. 20. © 2016 for LANCERS, inc All Rights Reserved ランサーズの本番環境 EC2 App S3 ELB EC2 instance Wordpress CloudFront SQS Cloud Search Route53 EC2 instance WebSocket ランサーズ コーポレート ブログ オウンドメディア ErastiCache Memcached ErastiCache Redis Aurora Reader Aurora Writer メッセージ • EC2は固定IPで運用
  21. 21. © 2016 for LANCERS, inc All Rights Reserved Dockerを使った開発環境構成 192.168.99.100 HDD 50GB メモリ 2GB 172.17.6.11 App(ランサーズ本体) Apache 2.2 (80) PHP 5.3 172.17.4.51 WordPress (コーポレート、ブログ等) Apache 2.4(80) PHP 5.5 172.17.106.55 認証システム Nginx (443) Unicorn (3000) 172.17.4.152 メッセージ(チャット) Nginx(3443) node.js (3001) 172.17.50.11 ELBエミュレーション Apache 2.2 (80) 172.17.51.11 RDSエミュレーション MySQL 5.6(3306) 172.17.52.12 ErastiCache エミュレーション Redis(6379) 172.17.52.11 ErastiCache エミュレーション Memcached(11211) マネージド系コンテナ Dockerfileで構築 EC2系コンテナ Dockerfile + Ansible で構築 Docker リポジトリ ディレクトリ 共有
  22. 22. © 2016 for LANCERS, inc All Rights Reserved Dockerを使った開発環境構成 Virtualbox VM Docker Machine 172.17.6.11 App ランサーズ本体 172.17.4.51 WordPress コーポレート、ブログ SSH 172.17.51.11 MySQL 3306 9000 172.17.4.152 WebSocket メッセージサービス ディレクトリ 共有 SQLクライアント 開発環境(エディタ)ターミナル • Vagrant時代の利便性を維持
  23. 23. © 2016 for LANCERS, inc All Rights Reserved コンテナ更新のフロー EC2 MySQLデータ 開発用データ App Ansible WordPress MySQL WebSocket WordPress App WebSocket MySQL Registry Registry 旧開発サーバーを CoreOS化 Playbook docker push docker pull docker build Docker Registry コンテナ
  24. 24. © 2016 for LANCERS, inc All Rights Reserved 直面した問題とその解決方法 Docker導入の経緯 Docker導入の基本方針 Docker移行結果 今後の展望 ランサーズ開発環境の歴史
  25. 25. © 2016 for LANCERS, inc All Rights Reserved Dockerの思想 • 1コンテナ1サービス • フォアグラウンドでサービスを起動 • sshdは稼働しない • コンテナは極力軽く • 固定IPではない • Dockerが動的にIPを割り当てる
  26. 26. © 2016 for LANCERS, inc All Rights Reserved Dockerの思想を回避 • 1コンテナ1サービス • →細工して複数サービスを起動 • フォアグラウンドでサービスを起動 • →細工してバックグラウンドで起動 • sshdは稼働しない • → SSHでログイン • AnsibleもSSH経由で実行 • コンテナは極力軽く • → MySQLのデータをインポート • 数GBのコンテナが誕生 • 固定IPではない • Dockerが動的にIPを割り当てる • →加えて固定IPを付与
  27. 27. © 2016 for LANCERS, inc All Rights Reserved 複数サービスをバックグラウンド起動 • docker run時に起動用シェルを常駐 • 起動用シェル内に複数サービスを記述 #!/bin/sh /sbin/service sshd start /sbin/service httpd start while true do sleep 10 done service.sh # service.shをコンテナに配置 COPY ./service.sh /root/ RUN chmod 744 /root/service.sh # 起動時にservice.shを実行 CMD ["/root/service.sh"] Dockerfile
  28. 28. © 2016 for LANCERS, inc All Rights Reserved 固定IPの付与 • docker run、docker start後にdocker execコマンドで付与 • ip addr add で付与(CentOS6の場合) 172.17.0.2 ELB DOCKER_ID=$(docker inspect --format="{{.Id}}" $DOCKER_NAME) IP_STATIC=172.17.51.11 NIC=eth0 docker exec $DOCKER_ID ip addr add $IP_STATIC/16 dev $NIC 172.17.0.2 172.17.51.11 ELB IMAGE_NAME=elb:latest DOCKER_NAME=elb-50-11 docker run ¥ --name $DOCKER_NAME ¥ --hostname $DOCKER_NAME ¥ … 起動時に Dockerが動的に IPを付与 起動後に ip addrで固定 IPを付与
  29. 29. © 2016 for LANCERS, inc All Rights Reserved コンテナのビルド • マネージド系のサービスはDockerfileのみで構築 • EC2で構築するサービスはDockerfile + Ansibleで構築 • 本番EC2と共通のPlaybookを利用 • Ansible用のコンテナを用意(コンテナ間でssh接続) EC2 ELB Ansible MySQL Registry Playbook docker push docker tag MySQLデータ開発用データ Base CentOS6 App ansible Docker Shell docker build DBインポートした イメージを commit
  30. 30. © 2016 for LANCERS, inc All Rights Reserved Docker Registryコンテナ Ansible 各種コンテナ 各種コンテナ RegistryRegistry docker push docker pull docker build docker run -d ¥ --name registry ¥ -p 5000:5000 ¥ -e REGISTRY_STORAGE_S3_ACCESSKEY=XXXXXXXX ¥ -e REGISTRY_STORAGE_S3_SECRETKEY=xxxxxxxx ¥ -e REGISTRY_STORAGE_S3_BUCKET=docker-registory-lancers ¥ -e REGISTRY_STORAGE_S3_REGION=ap-northeast-1 ¥ -e REGISTRY_STORAGE_S3_ROOTDIRECTORY=/ ¥ -e REGISTRY_STORAGE=s3 ¥ registry:2.2 • Docker Hub等のリポジトリはほとんどが海外 • 巨大コンテナ(MySQLとか)の受け渡しに時間がかかる • Docker Registoryコンテナを起動して東京RのS3に格納 Docker Shell ansible Playbook
  31. 31. © 2016 for LANCERS, inc All Rights Reserved ELBコンテナ • SSL Terminateをエミュレートしたリバースプロキシ • プロキシ時にX-Forwarded Protoヘッダを追加 • ログイン時のhttps強制リダイレクト判定で利用 EC2 App ELB EC2 instance wordpress Route53 App WordPress ELB SSL Terminate <VirtualHost *:80> ServerName dev.lancers.jp ServerAlias *.lancers.jp RequestHeader set X-Forwarded-Proto "http" RewriteEngine On RewriteCond %{SERVER_NAME} ^(.*).lancers.jp$ RewriteRule ^/(.*) http://%1.lancers.jp/$1 [P,L,QSA] </VirtualHost> <VirtualHost *:443> ServerName dev.lancers.jp ServerAlias *.lancers.jp … SSLCertificateKeyFile /etc/pki/tls/private/lancers.jp.key RequestHeader set X-Forwarded-Proto "https" RewriteEngine On RewriteCond %{SERVER_NAME} ^(.*).lancers.jp$ RewriteRule ^/(.*) http://%1.lancers.jp/$1 [P,L,QSA] </VirtualHost> <VirtualHost *:80> ServerName dev.lancers.co.jp ServerAlias *.lancers.co.jp RequestHeader set X-Forwarded-Proto "http" RewriteEngine On RewriteCond %{SERVER_NAME} ^(.*).lancers.co.jp$ RewriteRule ^/(.*) http://%1.lancers.co.jp/$1 [P,L,QSA] </VirtualHost> hosts https://www.lancers.jp/ http://www.lancers.co.jp https://dev.lancers.jp http://dev.lancers.co.jp http://dev.lancers.co.jp http://dev.lancers.jp http://www.lancers.jp/ https→http変換
  32. 32. © 2016 for LANCERS, inc All Rights Reserved 共有フォルダ設定 • Vagrant時代の利便性を維持 • PC上のエディタで開発可能 • VirtualBoxの共有フォルダ設定 + • docker run時のマウント設定 AppWordPress WebSocket ディレクトリ 共有 開発環境(エディタ) docker run ¥ --name $DOCKER_NAME ¥ -v /Users/www:/var/www ¥ --hostname $DOCKER_NAME ¥ --privileged ¥ -d $IMAGE_NAME
  33. 33. © 2016 for LANCERS, inc All Rights Reserved ポートフォワーディング設定 • Vagrant時代の利便性を維持 • PC上のSQLクライアントから直接アクセス可能 172.17.6.11 App 172.17.4.51 WordPress 172.17.51.11 MySQL 3306 172.17.4.152 WebSocket SQLクライアント 172.17.4.51 ELB WWWブラウザ 443 80 3443 IMAGE_NAME=mysql:latest DOCKER_NAME=mysql-51-11 IP_STATIC=172.17.51.11 PORT=3306 docker run ¥ --name $DOCKER_NAME ¥ --hostname $DOCKER_NAME ¥ -p $PORT:$PORT ¥ …
  34. 34. © 2016 for LANCERS, inc All Rights Reserved コンテナ起動スクリプト IMAGE_NAME=elb:latest DOCKER_NAME=elb-50-11 IP_STATIC=172.17.50.11 PORT=80 PORT2=443 docker run ¥ --name $DOCKER_NAME ¥ --hostname $DOCKER_NAME ¥ -p $PORT:$PORT ¥ -p $PORT2:$PORT2 ¥ --add-host=dev.lancers.jp:172.17.6.11 ¥ … --add-host=dev-img.lancers.jp:172.17.6.11 ¥ … --add-host=dev-wst.lancers.jp:172.17.4.152 ¥ … --add-host=dev.lancers.co.jp:172.17.4.51 ¥ --privileged ¥ -d $IMAGE_NAME DOCKER_ID=$(docker inspect --format="{{.Id}}" $DOCKER_NAME) DIR=$(cd $(dirname $0); pwd) cd $DIR . ../function.sh set_timezone "Japan" set_static_ip "$IP_STATIC" set_timezone() { docker exec $DOCKER_ID ¥cp -f /usr/share/zoneinfo/$1 /etc/localtime } set_static_ip() { IP_STATIC=$1 NIC_CENTOS6=eth0 docker exec $DOCKER_ID ip addr add $IP_STATIC/16 dev $NIC_CENTOS6 } ポートフォワーディング設定 hosts設定 (Dockerfileで設定不可) run.sh function.sh 固定IPの付与 TimeZone設定 (Dockerfileで設定不可) • 非エンジニアでも操作できる仕組み • dockerコマンドを使わず、シェル1発で起動
  35. 35. © 2016 for LANCERS, inc All Rights Reserved コンテナ更新スクリプト #!/bin/sh REGISTORY=localhost:5000 REPOSITORY=websocket TAG=latest DOCKER_NAME=websocket-4-152 DIR=$(cd $(dirname $0); pwd) cd $DIR . ../function.sh set -x ./stop.sh rm update_image "$REGISTORY" "$REPOSITORY" "$TAG" " $DOCKER_NAME" ./run.sh update_image() { REGISTORY=$1 REPOSITORY=$2 TAG=$3 DOCKER_NAME=$4 IMAGE_ID=$(docker images | grep $REGISTORY | grep $REPOSITORY | grep $TAG | awk '{print $3}') docker rmi -f $IMAGE_ID docker start registry sleep 5 docker pull $REGISTORY/$REPOSITORY:$TAG docker tag $REGISTORY/$REPOSITORY:$TAG $REPOSITORY:$TAG } #!/bin/sh DOCKER_NAME=websocket-4-152 docker stop $DOCKER_NAME if [ "${1}" = "rm" ]; then docker rm $DOCKER_NAME fi update.sh function.sh stop.sh コンテナプロセス 削除 レジストリコンテナ 起動 コンテナプロセス 停止 コンテナイメージ 削除 コンテナイメージ ダウンロード コンテナイメージ タグ設定 • シェル1発で一連の更新処理を実行(もっと効率化できるかも) コンテナプロセス 起動 コンテナプロセス 停止&削除 コンテナイメージ 更新
  36. 36. © 2016 for LANCERS, inc All Rights Reserved Docker移行結果 Docker導入の経緯 Docker導入の基本方針 直面した問題とその解決方法 今後の展望 ランサーズ開発環境の歴史
  37. 37. © 2016 for LANCERS, inc All Rights Reserved コンテナあたりのリソース消費量 コンテナ メモリ使用量 ストレージ使用量 MySQL 819.8MB 6351.0MB App 657.0MB 812.7MB ELB 20.09MB 426.6MB WebSocket 18.46MB 886.1MB Memcached 26.71MB 348.7MB Redis 10.28MB 558.6MB WordPress 161.3MB 832.1MB KPI 21.59MB 576.3MB Registry 16.42MB 223.4MB 合計 1751.65MB ≒ 1.75GB 11015.5MB ≒ 11GB • VMサイズ • HDD:20GB • メモリ:2GB ランサーズ稼働に 最低限必要なコンテナ レジストリコンテナの メモリ消費は20MB以下
  38. 38. © 2016 for LANCERS, inc All Rights Reserved 運用の効率化 Vagrant + Ansible時代 Docker時代 開発環境構築方法 個々でAnsibleで構築 特定の人が構築してpush 個々で構築済のコンテナをpull 構築時間 4時間以上or不可能 約30分 開発方法 PC上のエディタで開発 VirtualBox共有フォルダ PC上のエディタで開発 VirtualBox共有フォルダ+Dockerマウント XDebugステップ実行 可能 可能 DBのデータ構造変更 手動でSQL実行 MySQLコンテナを破棄&pull ※データを元に戻すのにも重宝 ミドルウェア追加 手動でインストール Appコンテナを破棄&pull • 構築時間の大幅短縮 • コンテナの破棄&pullは予想以上に便利な機能
  39. 39. © 2016 for LANCERS, inc All Rights Reserved Windows環境 • 確実に構築できるようになった • ランサーへの開発依頼もスムーズに • 構成 • Docker ToolBox • Cygwin • unzip • zip • git • openssh • curl • TeraTerm(Cygterm)
  40. 40. © 2016 for LANCERS, inc All Rights Reserved 構築手順書 • GitHub Wikiに手順を集約 • リモートでも構築しやすい環境に
  41. 41. © 2016 for LANCERS, inc All Rights Reserved 今後の展望 Docker導入の経緯 Docker導入の基本方針 直面した問題とその解決方法 Docker移行結果 ランサーズ開発環境の歴史
  42. 42. © 2016 for LANCERS, inc All Rights Reserved 新技術の追従 • ※メリットを吟味しながら採用を検討したい • Docker Compose • シェルの処理を全部置き換えられれば • 固定IPの付与とか • Ansible Docker Connection Plugin • SSHを使わずに構築可能 • Docker for Mac/Windows • VirtualBoxが不要に
  43. 43. © 2016 for LANCERS, inc All Rights Reserved コンテナの軽量化 • ※本番環境との互換性を考慮しながら進めたい • データボリュームコンテナへ分離 • MySQLコンテナ(約1GB) • MySQLデータコンテナ(約5GB) • 軽量OSの利用 • サービスの削除 • sshdとか
  44. 44. © 2016 for LANCERS, inc All Rights Reserved 本番環境への対応 • ※メリットが明確になれば検討するかも • 前準備 • 固定IPをやめる • 内部DNSの導入 • Immutable化 • sshdが不要に • オートスケーリングの後処理が不要に • コンテナを直接デプロイする仕組み • コンテナの軽量化は必須 • AWSのDocker対応サービスの採用も視野 • Elastic BeansTalk • ECS(EC2 Container Service)
  45. 45. ご清聴ありがとうございました! ランサーズ株式会社 インフラエンジニア 金澤 裕毅 [Kanazawa Yuki] 「時間と場所にとらわれない、新しい働き方を創る」 [2016/03/30 dots. IT勉強会] http://www.lancers.jp/

×