のらぬこの日常を描く

ノージャンルのお役立ち情報やアニメとゲームの話、ソフトウェア開発に関する話などを中心としたブログです。

俺の右腕に眠りし黒竜よ!力を貸してくれっ! ドッカァー!コンポォォーーッズ!!

どうものらぬこです。

某社関係者のどなたかが、類似するエントリー名で記事書いてたら申し訳ないので一応検索してみたのですが、そういうのはなさそうなので、取り敢えずこのフレーズ頂いときます<(__)>*1

というわけで、今回は Docker の話をしようと思います。

www.docker.com

dockerとは

今更な話だし、検索すれば答えもたくさん出てくるだろうけど、取り敢えず僕の理解では「軽量でそこそこセキュアで再利用可能なアプリケーションorデータコンテナ」という認識です。

コンテナは基本的にはLinuxOSベースの仮想環境です。マイクロソフト社に御布施をしてWindows Server 2016を導入すれば、Windowsベースの仮想環境を用意することも可能みたいです。 でもそんなお金ないし、僕は今のところその必要性も感じてないので、触ってみたことはありません。

なお、コンテナはあくまで仮想環境なので、実PCで直接動かすことはできません。Dockerというソフトウェアを使って、ホストOSの上に構築した仮想的なLinux環境として動かします。

僕がDockerを触ってみようと思った訳

現在の職場、メイン言語はPHPです*2

さて、PHPを使われている方の間では常識なのかもしれませんが、このPHPという言語はなかなか曲者で、マイナーバージョンレベルの更新ですら(7.0->7.1等)、上位互換性(バージョンアップしても今まで動いてたコードはちゃんと動くように作ってるよ的な)が割りと確保されていないことも多いという、個人的には割りとFA?って感じの特徴があります。

ローカルで確認したいとき等、一々PHPのバージョン切り替えるのめんどいし、そういえばdockerとか使えばなんか色々はかどるんじゃないかなとなんとなく思ったのが、最近dockerの勉強を始めたきっかけです

dockerの全貌をなんとなく理解してみる

ある概念を新しく勉強するときは、自分の知っている類似の概念に置き換えてイメージしていくと理解がしやすいと考えています。

dokcerもそんな感じで覚えていきました。

  • docker hub

    • githubみたいなもの。汎用的なものから特定用途向けまで、様々なDocker Imageが公開されている。
      • 基本的には、public公開。docker hubにお金を払えばプライベートなものも作れるし、自分で Dokcer hubみたいなのを立てることも可能(プライベートレジストリと呼ぶ)。
    • githubと違うのは、githubでは様々なプラットフォームで動くアプリケーションやらライブラリ等、様々な種類のものが公開されているけど、docker hubで公開されているのは DockerImageと呼ばれるカスタマイズされたLinuxの起動イメージ or それを作るための設定ファイル
  • Docker Image

    • UbuntucentOSなどのLiveCD(DVD)メディア的なもの。docker hubに公開されているものをそのまま使うこともできるし、自分でほぼ一から作ることもできる。また、docker hubで公開されているイメージをさらに自分でカスタマイズすることもできる。
    • LiveCDと違うのは以下の2つ。
      • LiveCDと違って、PCから直接起動することはできない。   * 代わりに、DockerEngineと呼ばれる、DockerImageを動かすための仮想環境を構築するソフトウェア(VMWareとかVirtualPCみたいなやつ)使って、起動中のOSの上に仮想的なLinux環境を新しく立ち上げる(この起動中の環境のことをコンテナっていう)。
      • LiveCDは読み取り専用だけど(HDDとかUSBメモリーをマウントすればもちろんマウント先には書き込み可能)、DockerImageには書き込みもできる。
        • /root だろうが /etc だろうがどこでも書き込み可能。
        • 書き込まれた内容ははDockerImageの中に直接保存されるのではなく、「どのファイルをどういう風に書き換えた」という差分情報のみがDocker Imageとは別の場所に保存されるため、追加、削除、変更内容は元のイメージには影響しない。
          • たとえ「rm -rf /」してしまい絶望に飲み込まれたとしても、元のイメージから新しいコンテナを起動すれば全ての変更は無かったことになっています。
  • Dockerfile

    • 自分好みのDcker Image を作るための設定ファイル
      • 「元となるDockerImage+それに対しての変更箇所」みたいなことを書いていく感じ。
        • 例えば、素のUbuntu16.04イメージにに apache2をapt-getでインストールして、/etc/apache2/httpd.conf をローカル環境のファイルで置き換える みたいなことを書いていく。
  • Docker Container

    • 起動中のDockerImageのことをコンテナって呼びます。
    • 1つのイメージから複数のコンテナを起動することができます。
      • 1つのイメージから複数のコンテナを起動しても、それらはお互いに干渉しません。
        • 例えば、コンテナAで /etc/apache2/httpd.conf を書き換えても、その変更は コンテナBには適用されません。
    • 色々な種類のイメージを用意すれば、色々な種類のコンテナを同時に起動することも勿論できます
    • コンテナのリソース(ファイルシステムだったりネットワークリソースだったり)は基本的に隔離されているので、共有はできない。
      • ただし、起動時にパラメータで指定したり、Dockerfileに設定を記載しておくことで、ネットワークの特定のポートを使用して通信したり、ファイルシステムの特定のパスをホストOS(Docker Containerを動かしているOS)と共有することなどが可能。
  • docker-compose

    • 本エントリーのタイトルにもなった、なんとなくかっこいいコマンド
      • このフレーズは、前職の馬場さん(仮名)によって生み出されたもので、サービスをデプロイするには、このフレーズを馬場さん(仮名)にシャウトしていただかなければならないという暗黙のルールがありました。
        • ただし、「俺の右腕に~」の部分は本人が恥ずかしがって省略されていました
    • 複数の Dockerコンテナが連携して動作するようなシステム(例えば、nginx+PHPが動いてるコンテナとPostgreSQLが動いているコンテナとRedisが動いているコンテナ、など)で、複数コンテナの連携(ネットワークの接続設定やファイルシステムの共有っぽい設定、各コンテナの起動順序など)をいい感じにいろいろやってくれる、確かにすごいコマンド。
    • それぞれのコンテナをどういう風に連携させるのかは docker-compose.yml というファイルに書いておく。
    • 現在勉強中。

dockerの使い方

動作環境やインストール方法、動作原理なんかは検索すれば腐るほど出てくるのでその辺は書きません。

ここでは、使い始めるとかならず使うコマンドを、僕がよく使うコマンドを中心に備忘録的にまとめておきます。

Docker hubからImage 取得

$ docker pull <リポジトリ名:タグ名>
* alpine:latest -> 軽量コンテナ向け
* busybox:latest -> データコンテナ向け

alpine linux + apache な Dockerfile

  • alpine linux は、Docker Image(基本パック)のサイズ僅か6Mb程のとてもコンパクトなlinuxDistribution
  • 起動後のシェルで # apachectl startapacheが起動する
    • # wget http://localhost:80/ で index.html が落ちてくれば成功
FROM alpine:3.6

RUN apk add --no-cache apache2 apache2-utils && \
    mkdir /run/apache2 && \
    chown apache:apache /run/apache2

Dockerfile -> image 作成

$ docker build [-t <イメージにつける名前] .

作成済Imageの一覧を出力

$ docker images

不要になったImage 削除

$ docker rmi <リポジトリ名:タグ名 or イメージID>

Imageをまとめて削除

$ docker images | awk '{print $3}' | xargs docker rmi
* 一部を消したいときは間にgrepなどでフィルタ

作成済Imageからコンテナを作成&起動

オプションがいっぱいありますが、コンテナのTCPポートをホストOS(Dockerを起動しているOS)のTCPポートにマップしたり、ホストOSのファイルシステムパスをコンテナから見えるようにしたりといろいろな設定ができます

$ docker run [-d] [-it] [-p <ホストポート番号>:<コンテナポート番号>] [-v <ホストパス>:<コンテナパス>] [--rm] [--name <コンテナにつける名前>] <イメージ名:タグ名 or イメージID> <起動時に実行するコマンド>

コンテナ一覧

$ docker ps
* 起動中コンテナ

$ docker ps -a
* 停止中コンテナ

コンテナの内部情報を表示

$ docker inspect <コンテナ名 or コンテナID>

コンテナ->イメージ作成

これは、動作中のコンテナのファイルシステムの状態をDocker Imageとして保存するコマンドです。

$ docker commit <コンテナ名 or コンテナID> <イメージ名>

Container 削除

$ docker rm <コンテナ名 or コンテナID>

Container まとめて削除

$ docker ps -a | awk '{print $1}' | xargs docker rm
* 一部を消したいときは間にgrepなどでフィルタ

参照されていないデータボリュームを削除

$ docker volume ls
$ docker volume prune

Dockerの使いどころ

Dockerの使いどころを僕なりに考えてみました。

開発環境として

例えば、Java,PHP,Ruby等の開発言語 + RDB + Redis + ElasticSearch等のシステムをローカル環境で構築するのはちょっと大変ですが、Dockerで nginxのコンテナ、Java(+ApplicationServer)のコンテナ、RDBのコンテナ…等を用意して、それらの関連を docker-compose.yml で管理してあげれば色々楽ができそうです。

チーム開発をしているような場合には、新しいメンバーが入ってきたときも、それぞれのツールの指定されたバージョンをダウンロードして手順書に従ってインストールなんて面倒なことを毎回やらなくても、Docker入れて、そこのdocker-compose.yml使えば環境できるという状態にすることもできるはずと思います。

例えば、PHPのバージョンアップテストをしたい等の目的で、一時的に複数バージョンのPHPを使いたいときなども、なんかうまくやってくれるはず!

開発周辺ツールのホスト環境として

jenkins とか redmine とか selenium + firefox driver の docker imageや docker-compose.yml などは検索すれば簡単に見つかります。

それぞれの環境のために、サーバ用意してOS入れてRubyだのJavaだの入れてRDB入れてREADME.md見ながらconfig設定して〜をやらなくても、簡単に環境を作ることができるはずです。

「コピペ万歳」です!

テストデータがたっぷり詰まったRDBの格納場所として

このエントリー内では特に説明しませんでしたが、Dokcerはアプリケーションコンテナとして使用する方法の他に、データコンテナとして使用することもできます。

マスターデータのみが入ったクリーンな環境や、リグレッションテスト向けに、毎回同じテストデータが入った環境を簡単に作ることができるようになります。

最後に

Dockerをうまく活用できれば確かに色々捗ることも増えそうです。

でも、夢は広がっていますが、この辺を正しく理解して活用出来るようになるには、もう少し勉強が必要のようです。

余談ですが、1冊くらい書籍も読んでおこうかと思って、先日オライリー本を買いました。

安定のオライリー品質で、内容もわかりやすいし翻訳もとても読みやすいです。

Docker

Docker

というわけで、今回の話は以上となります。

お読みいただいてありがとうございました。

*1:しかし、あれだ、このタイトルSEOに全く優しくないな・・・

*2:swiftでiOSアプリ書いたりRubyでbatch書いたりJAVAで技術検証的な目的でテストサイト作ったりもしてます