インフラエンジニアの金澤です。
開発環境を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ができますので、これを利用するのも良いと思います。
※ちなみに、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で動的に共有ディレクトリを調整する必要があります。
アップデートの移行状況
現在は、社内のアーリーアダプター中心に、順次アップデートを適用して頂いています。
現状の環境でも特に支障なく開発ができていますので、アップデートできる方からゆるやかに移行が進んでいる段階です。
今後も、互換性を保ちながら移行を進めていきたいと思います。