ランサーズ(Lancers)エンジニアブログ > DevOps > 開発環境のDocker化 その後

開発環境のDocker化 その後

kanazawa|2016年12月19日
DevOps

インフラエンジニアの金澤です。

開発環境をDocker化してから1年経ちましたので、その後のアップデートについて書きたいと思います。

前提

ランサーズでは、Dockerを開発を以下の目的で導入しました

  • PCリソース(HDD、メモリ)を削減
    • コンテナ単位でサーバーを構成し、VMを1つに統一
  • 本番環境のサーバー構成と極力互換性を保つ
    • 開発環境との差異による障害発生を未然に防ぐ

そのため、Dockerのベストプラクティスではないことも行っております。
例えば、以下のようなことも行っております。

  • 1コンテナに複数サービスを稼働
    • sshdも稼働
  • サービスをフォアグラウンドで稼働
    • /etc/init.dのスクリプトで稼働
  • 軽量化よりも利便性を優先
    • 便利なパッケージはインストール

Amazon Linuxコンテナ

2016年11月に、Amazon LinuxのコンテナイメージがDocker Hubから提供されました。

今まで、本番AWSのEC2ではAmazon Linuxを利用していたのに対し、開発環境のコンテナはCentOS6を利用していました。
パッケージバージョンの細かい差異が問題になることがありましたが、開発用コンテナもAmazon Linuxで構築することができるようになり、その問題がなくなりました。
また、ランサーズでは、本番EC2と開発用コンテナに対し同じAnsibleのplaybookで構築していましたが、OS間の差異を吸収する処理がほとんどなくなりました。

DockerfileのFROMに以下のように記述することでAmazon Linuxのコンテナイメージを利用することができます。

FROM amazonlinux:2016.09

ただし、EC2のAmazon Linuxと完全に同じではないので注意する必要があります。

/etc/sysconfig/networkがない

これが原因で、開発環境のDockerコンテナ構築時にAnsibleのPlaybookが失敗することがあります。
また、ランサーズのDocker環境では/etc/init.d/の起動スクリプトでサービスを起動していますが、ここで/etc/sysconfig/networkを参照していることがあり、起動に失敗することがあります。
そのため、Dockerfileで構築時に/etc/sysconfig/networkを配置する等の対策をしています。

viがインストールされていない

EC2のAmazon Linuxにインストールされていたパッケージで、Amazon Linuxコンテナにインストールされていないものがたくさんあります。
viもその1つです。コンテナにviは必ずしも必要ありませんが、CentOS6コンテナにはviがインストールされていたので、それを利用していた方のために、viをインストールしています。

docker-compose対応

Docker導入段階でもdocker-composeは検討しておりましたが、コンテナ単位での細かい制御をしたいため、シェルスクリプトで運用していました。
その中で、コンテナ起動後にipコマンドで固定IPを付与する処理も行ってましたが、最近のDockerでは固定IPで運用できるようになりましたので、それに合わせてdocker-composeも導入し始めました。

docker-compose.ymlで、以下のように172.21.0.0/16のネットワークを新規に構築します。

networks:
  lancers:
    driver: bridge
    ipam:
      driver: default
      config:
      - subnet: 172.21.0.0/16
        gateway: 172.21.0.1

Appコンテナでは以下のように設定します。
ipv4_addressで固定IPアドレスを設定し、hosts設定はextra_hostsに記述しています。
コンテナのビルドは個人では行わず、構築済のコンテナをpullしています。
registryコンテナ経由で5000番ポートで取得しています。

services:
  app:
    image: localhost:5000/app:latest
    hostname: app
    networks:
      lancers:
        ipv4_address: 172.21.6.11
    extra_hosts:
       - "dev.lancers.jp:172.21.50.11"
       - "dev-img.lancers.jp:172.21.50.11"
…
    container_name: app-6-11
    volumes:
      - ~/www:/var/www

registryコンテナの起動は以下の通り。
構築したコンテナは東京リージョンのS3に格納しているため、AWSのアクセスキーを指定して起動します。

services:
  registry:
    image: registry:2.2
    container_name: registry
    ports:
      - 5000:5000
    environment:
      REGISTRY_STORAGE_S3_ACCESSKEY: XXXXXXXX
      REGISTRY_STORAGE_S3_SECRETKEY: xxxxxxxx
      REGISTRY_STORAGE_S3_BUCKET: docker-registory-lancers
      REGISTRY_STORAGE_S3_REGION: ap-northeast-1
      REGISTRY_STORAGE_S3_ROOTDIRECTORY: /
      REGISTRY_STORAGE: s3

registryコンテナは、コンテナをpull、updateするときのみに利用するため、registry.ymlファイルとして個別に定義しています。
registryコンテナを利用するときのみ、以下のコマンドで起動します。

docker-compose -f registry.yml up -d

ランサーズのDocker環境では、AWSのELBに相当するelbコンテナを用意しています。
elbコンテナに80番、443番のポートフォワーディングを設定しており、ランサーズのAppコンテナを始め、各種サービスのコンテナはすべてelbコンテナ経由でアクセスしています。

services:
  elb:
    image: localhost:5000/elb:latest
    hostname: elb
    networks:
      lancers:
        ipv4_address: 172.21.50.11
    extra_hosts:
       - "dev.lancers.jp:172.21.6.11"
       - "dev-img.lancers.jp:172.21.6.11"
…
       - "dev-engineer.blog.lancers.jp:172.21.4.51"
…
    container_name: elb-50-11
    ports:
      - 80:80
      - 443:443

以上、概要を説明させていただきましたが、docker-composeについては、複数サービスへの対応や、記述の最適化等でもっと工夫できる余地がありますので、また機会がありましたら別途書かせていただきたいと思います。

Docker for Mac(Windows)対応

VirtualBoxを利用しない、ハイパーバイザー型のDocker for Mac(Windows)がリリースされましたので、こちらも利用を開始しました。

運用面での変更点

IPアドレス

今までのDocker ToolboxでのDocker Machineと運用面で大きく変わるのは、DockerのIPアドレスです。
Docker Toolboxのときは、デフォルトで作成されるVirtualBox VMのIPアドレスは、192.168.99.100になります。
ローカルPC上のhostsにこのIPアドレスに対して、dev.lancers.jp等のドメインを記述していましたが、Docker for Mac(Windows)の場合は、このIPが127.0.0.1になります。

ディレクトリ共有

ソースをローカルPCで修正するために、Docker Mount + VirturlBox共有フォルダでソースを共有していましたが、Docker for Mac(Windows)では、VitrualBox共有フォルダがなくなりました。
Docker Toolboxのときは、VirtualBoxの共有フォルダ設定で、個人PCの作業ディレクトリの違いを吸収できたのですが、Docker for Mac(windows)ではこれがなくなるため、docker run時のマウント設定で調整する必要があります。

コンテナへのログイン

ランサーズのDocker環境ではsshdを稼働させており、docker-toolboxでは

docker-machine ssh xxxxx

として、docker-machineのVMにログイン後、sshコマンドで各種コンテナに一般ユーザーでログインしていました。
Docker for Mac(windows)では、docker-machine sshのログインプロセスがなく、ローカルPCから直接docker exec等でrootでログインするプロセスになります。

Kitematicを利用するとGUIから手軽にdocker execができますので、これを利用するのも良いと思います。
Kitematic

※ちなみに、Windows版KitematicでEXECを実行すると、Power Shellが起動します。私は、WindowsでDockerを操作するときはCygwin(Cygterm)を利用していたのですが、この環境だとdocker execが上手く動きません。そのため、Kitematicを利用していますが、ここでターミナルを選べないのが現状ちょっと辛いところです。

※sshを利用する方法として、どれかのコンテナの22番をポートマッピング設定し、それを踏み台にするという手は残っています。

Docker for Mac(Windows)のメリット

PC起動時のDocker設定が必要ない

PC起動時にDocker for Mac(Windows)を自動起動する設定にしておけば、事前準備が必要なくなります。
つまり、PCを起動する度に、以下のコマンドを打たなくても良くなります。

<

div class=”code panel pdl conf-macro output-block” data-hasbody=”true” data-macro-name=”code”>

<

div class=”codeContent panelContent pdl”>

<

div id=”highlighter_272017″ class=”syntaxhighlighter sh-midnight nogutter php”>

docker-machine start xxxxx
eval "$(docker-machine env xxxxx)"

Docker for Mac(Windows)のデメリット

複数のDocker VMの起動

VitualBoxを利用していたときは、例えば、192.168.99.100、192.168.99.101と2つのVMを作成し、それぞれのVM上でDockerコンテナを稼働することが手軽にできましたが、それができなくなります。

OS対応

ハイパーバイザーをサポートしたOSでないと動作しません。
Docker for MacはMacOS 10.10.3(Yosemite)以降の対応となります。
Docker for WindowsはWindows10以降の対応となります。

Linuxデスクトップ対応

Linuxデスクトップを利用するエンジニアも増えたため、Linux環境にも対応しました。

Linux環境でも、dockerとdocker-composeをインストールすれば、Mac、Windowsとほぼ同じように使えます。
違う点は、デフォルトでローカルPCからDockerコンテナのIPアドレスで直接コンテナにアクセスすることができることです。

Docker for Mac(Windows)のときと同様、VirtualBoxはないので、作業ディレクトリをDockerコンテナと共有する場合は、Docker Mountで動的に共有ディレクトリを調整する必要があります。

アップデートの移行状況

現在は、社内のアーリーアダプター中心に、順次アップデートを適用して頂いています。
現状の環境でも特に支障なく開発ができていますので、アップデートできる方からゆるやかに移行が進んでいる段階です。
今後も、互換性を保ちながら移行を進めていきたいと思います。