Dockerを利用して結合環境を再構築してみた

Dockerを利用して結合環境を構築しました。
今回の記事はその内容を社内のチームに発表した資料の焼き直しです。
自分的にも初めてDockerを触りながらの実験的な取り組みだったので、
特に技術的に掘り下げた内容ではない点ご了承ください。

結構長くなってしまったので、今回は目次をつけます。

▼目次

  1. なぜ仮想化しようと思ったのか?
  2. そもそもDockerとは?
  3. 導入ガイド
  4. 実際に構築したサーバー構成
  5. メリット・デメリット
  6. 課題と積み残し
  7. まとめ
  8. 参考サイト

なぜ仮想化しようと思ったのか?

今まではプロジェクト毎に結合環境がほしい場合に、、、
空いているサーバーとして利用できるマシンを探してそこにミドルウェアのインストールなどを1から構築して利用をしていました。

しかし、参画する案件が増えるにつれて下記の問題に直面しました。

  • 空いてるマシンが見つからない
  • 環境構築に時間がかかる

なんだかんだで結合環境構築に調達から構築完了までに1-2人日ぐらいかかることもあります。

そこで、既にあるサーバーを利用してそこに全部の案件の結合環境を集約することで「調達」と「管理」を楽にしようと思いました。
(Dokerを利用したのはたまたま社内の有志でDockerやりましょうというお話があったのでそこにノリで参加したためですw)

実際のサーバー構成の比較は下記のようになります。

そもそもDockerとは?

まずは前提として、そもそもDockerとは何かという部分をハイライトでおくります。

Docker(ドッカー[2])はソフトウェアコンテナ内のアプリケーションのデプロイメントを自動化するオープンソースソフトウェアである。

Linuxカーネルにおける「libcontainer」と呼ばれるLinuxコンテナ技術[3]とaufsのような特殊なファイルシステムを利用してコンテナ型の仮想化を行う[4]。VMware製品などの完全仮想化を行うハイパーバイザー型製品と比べて、ディスク使用量は少なく、インスタンス作成やインスタンス起動は速く、性能劣化がほとんどないという利点を持つ。dockerfileと呼ばれる設定ファイルからコンテナイメージファイルを作成可能という特性を持つ。一方で、コンテナOSとしてはホストOSと同じLinuxカーネルしか動作しない。
引用 – Wikipedia

Dockerを利用するにあたって下記の概念が大事です。
「Dockerイメージ」「コンテナ」

Dockerイメージは、コンテナのベースになるでOSやミドルウェアの集合体になります。
コンテナは、そのイメージを利用するための箱(文字通りコンテナ)の役割で、実際に動作する個々のアプリケーションになります。

簡単に概念図を作りました。
イメージとコンテナの概念図

詳細については下記のスライドがとてもわかり易かったので是非ご覧ください。

導入ガイド

実際のDockerをインストールしてコンテナの起動までの流れを簡単に説明します。
ホストの環境は下記になります。

# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)

Docker のインストール

公式サイトに従いyumでインストール
Installation on CentOS

# yum update

# tee /etc/yum.repos.d/docker.repo <<-'EOF'
> [dockerrepo]
> name=Docker Repository
> baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
> enabled=1
> gpgcheck=1
> gpgkey=https://yum.dockerproject.org/gpg
> EOF

# yum install docker-engine

# service docker start

# chkconfig docker on

【注意】
セキュリティを気にする環境であればdockerユーザーを作成して適切な権限にて実行を行うこと。
今回はローカル・結合と閉じた世界での構築なのでユーザー作成は省略しています。

Docker イメージ取得

ベースとなるイメージの取得します。
今回はCentOS7をpullしました。

# docker pull centos:centos7
> centos7: Pulling from centos
> 3690474eb5b4: Pull complete
> b48a20c39b28: Pull complete
> c79ebe41b35a: Pull complete
> 2a332da70fd1: Pull complete
> Digest: sha256:c08eb8eea8c4e0f7d7dc38e51c0ac4011e951c895bef89a1ec9f5e0f7ba4372f
> Status: Downloaded newer image for centos:centos7

# docker images
> REPOSITORY      TAG         IMAGE ID         CREATED        VIRTUAL SIZE
> centos          centos7     2a332da70fd1     10 days ago    196.7 MB

コンテナ起動

◆ docker run [オプション] [–name {コンテナ名}] {イメージ名}[:{タグ名}] [コンテナで実行するコマンド]

# docker run -d -it --name sample centos:centos7 /bin/bash
> 5ce157716258f2ff022541831dcfbde41119f5201cf67198b924532e2f69f55b

# docker ps
>CONTAINER ID      IMAGE             COMMAND       CREATED          STATUS          PORTS       NAMES
> 5ce157716258     centos:centos7    "/bin/bash"   4 seconds ago    Up 3 seconds                sample

コンテナへアクセス

◆ docker exec [オプション] [コンテナID] [コンテナで実行するコマンド]

# docker exec -ti 5ce157716258 bash

[root@5ce157716258 /]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)

コンテナの停止

◆ docker stop [コンテナID]
◆ docker start [コンテナID]

# docker stop 5ce157716258
>5ce157716258

# docker ps
>CONTAINER ID    IMAGE    COMMAND    CREATED    STATUS    PORTS    NAMES

// -aオプションで起動していないコンテナも表示
# docker ps -a
>CONTAINER ID     IMAGE             COMMAND         CREATED             STATUS                        PORTS    NAMES
>5ce157716258     centos:centos7    “/bin/bash”     6 minutes ago       Exited (137) 18 seconds ago            sample

# docker start 5ce157716258
>5ce157716258

# docker ps
>CONTAINER ID     IMAGE             COMMAND         CREATED              STATUS          PORTS    NAMES
>5ce157716258     centos:centos7    “/bin/bash”     13 minutes ago       Up 53 seconds            sample

たったこれだけで環境ができます!
(しかも起動が超爆速)

IDの指定がハッシュ値なのでオペミスに注意が必要かなと思いました。

実際に構築したサーバー構成

下記のイメージをローカル環境で構築し、Docker HubにPush ⇒ 結合環境でPullの流れです。
WebについてはFuelPHPで利用するように少しだけhttpd.confをいじっています。
(vhostにしてconfファイルを外だしすれば設定に依存しないWebイメージが作れた気がするの今後の修正課題です。)

作成したDockerイメージ

  1. web
    • CentOS7のイメージ上に構築
    • PHP5.6をソースからインストール
    • Apache2.4をソースからインストール
    • FuelPHP用にDocumentrootの設定をカスタマイズ ← 要改善
  2. mysql
# docker images
> REPOSITORY              TAG       IMAGE ID           CREATED         VIRTUAL SIZE
> my_dockerhub/web        latest    6206f6ec2b42       4 days ago      1.661 GB
> my_dockerhub/mysql      latest    e34685c198a9       2 weeks ago     329 MB

作成したコンテナ

  1. webサーバー用
    • webイメージから各案件毎にWeb用のコンテナを作成
    • ホストへのアクセス時のポートを振り分けることでそれぞれの80番へフォワード
  2. DBサーバー用
    • mysqlイメージからコンテナを作成
    • 全ての案件のスキーマを作成
    • 各Webコンテナから参照
# docker ps
> CONTAINER ID    IMAGE                        COMMAND                 CREATED               STATUS                PORTS                NAMES
> e2e069f1ea7f    my_dockerhub/web:latest      "/bin/bash"             About an hour ago     Up About an hour      0.0.0.0:83->80/tcp   web3
> a4aa9b5727a1    my_dockerhub/web:latest      "/bin/bash"             About an hour ago     Up About an hour      0.0.0.0:82->80/tcp   web2
> 13345770b38b    my_dockerhub/web:latest      "/bin/bash"             About an hour ago     Up About an hour      0.0.0.0:81->80/tcp   web1
> 3a475c8e6cc1    my_dockerhub/mysql:latest    "docker-entrypoint.s    2 hours ago           Up 2 hours            3306/tcp             mysql

コンテナ作成時の設定

Webコンテナの立ち上げ時に、「-p」「–link」「-v」を利用してます。

  1. 「-p」オプションでポートフォワード
    • ホストへアクセスする際のポートを各コンテナの80番に紐付けることで複数Webサーバーの運用が可能になる
    • -pオプションのイメージ

  2. 「-v」オプションでコンテナ⇔ホスト間でディレクトリの共有
    • ホストのディレクトリとWebコンテナのdocumentrootをリンクすることでモジュールに依存しないコンテナ運用が可能になる
    • ホストのディレクトリとDBコンテナの/docker-entrypoint-initdb.dをリンクすることで起動時に初期データの投入が可能になる
    • -vオプションのイメージ

  3. 「–link」オプションでDBコンテナと連携
    • WebサーバーとDBサーバーで別のコンテナ管理が可能になる
    • DB同士をリンクすることでMaster-Slave構成も(たぶん)構築可能(未検証)
    • --linkオプションのイメージ

メリット・デメリット

実際に自分で手を動かして感じた事です。

メリット

  • 環境構築毎に(物理的な)サーバーを用意しなくてよい
  • Docker Hubでイメージを共有することで環境の複製が簡単
  • 環境のクラッシュ&ビルドがとてもはやい

デメリット

  • サーバーの構築方法を覚える機会がなくなる
  • コンテナの削除が結構簡単なのでオペミスによる環境の破壊が怖い
  • 学習コストが(少し)かかる ⇒ 商用利用を考えるのであれば普段の運用通りの専門知識も必要

課題と積み残し

とりあえず一つのサーバーで複数プロジェクトの運用が可能になりました。
今回は「とりあえず構築してみよう」という思いが強かったのでまだまだ改善の余地があります。
下記は現状見えている課題や改善点、できなかったことを備忘録として残します。

  • Dockerfileによるイメージ構築が未着手
  • docker-composeによるdocker runのスクリプト化が未着手
  • WebイメージにFeulPHP用の設定が依存してしまっている
  • Webコンテナがstop ⇔ startのたびにapacheの起動が必要
  • MySQLのMasterSlave構成の構築
  • CI(Jenkins)用のコンテナ作成

などなど…

まとめ

とりあえずDockerにふれてみて思ったのが、
「Docker超便利!!」
ということでした。

当初の目的通り、「物理サーバーの台数削減」「環境構築工数の削減」の2点からコストの削減が期待できそうです。

まだまだ本番環境で利用するには全然知識が足りません。
これからも業界の動向を気にしながら商用で運用する際のベストプラクティスが確立できればいいなと思います。

@作業短縮時間(1人日⇒0.1人日!!)
@保持マシン台数(3台⇒1台)

参考サイト

構築時にお世話になったサイト

Docker Hubのオフィシャルイメージを使ったLAMP環境(Apache+PHP+MySQL)構築
Dockerの公式MySQLイメージの使い方を徹底的に解説するよ
docker コマンド チートシート

商用利用を検討して調べたサイト

Docker を Production で使い続ける理由
Docker を本番環境で4ヶ月運用して分かった HARD THINGS
Dockerによる開発環境から本番環境までの一貫した管理

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る