タグ: CoreOS

Dockerで作るPHPの実行環境サンプル

ファイル一式: https://github.com/mistymagich/vagrant-docker-php

php,nginx,mysqlのコンテナを動かして、PHPを実行させるサンプル環境です。

vagrantとvirtualboxもしくはdockerがインストールされているlinuxから起動できます。

必要なもの

  • Vagrantを使う方式
  • Dockerから起動する方式
    • DockerがインストールされたLinux
      バージョン 1.5.0 以上

セットアップ

  • Vagrantを使う方式
        > git clone https://github.com/mistymagich/vagrant-docker-php.git
        > cd vagrant-docker-php
        > vagrant up
    

    CoreOSが立ち上がるので、PuTTYなどでSSHでログインする (接続先は vagrant ssh-configで確認)

        $ cd /vagrant
        $ /vagrant/docker-build.sh
    
  • Dockerから起動する方式
        $ git clone https://github.com/mistymagich/vagrant-docker-php.git
        $ cd vagrant-docker-php
        $ chmod +x *.sh
        $ sudo ./docker-build.sh
        $ sudo echo '127.0.0.1 sandbox.local' >> /etc/hosts
    

    Ubuntu/Debianでdockerコマンドが docker.io1 になっている場合、docker-build.sh、docker-run.shの

    DOCKER=docker
    

    DOCKER=docker.io
    

    に変更したのち実行する。

起動

$ sudo ./docker-run.sh

正常に起動できれば、ブラウザで

http://sandbox.local

でアクセスするとPHPInfoが表示されます。

MySQLコンテナとの接続サンプルは

http://sandbox.local/dbconnect.php

にあります。

構造

Nginxコンテナ

コンテナ名:sandbox-nginx

公式Nginxコンテナをもとに、ホスト名sandbox.localに対して、PHPコンテナを参照する設定追加しています。
ドキュメントルートはsrc/public
拡張子がPHPならPHPコンテナにあるPHP-FPMを通して実行されます。

MySQLコンテナ

コンテナ名:sandbox-mysql

公式MySQLコンテナをそのまま利用しています。

データの永続化はしていません。

docker-run.sh実行時にsrcディレクトリにあるinit.sqlを実行することで、データベース・テーブル・データのインポートを行っています。

sanbox.localに対して3306にアクセスすることでMySQLコンテナにアクセスできます。

ユーザー名はroot、パスワードはdocker-run.shでMySQLコンテナ起動時にMYSQL_ROOT_PASSWORDで指定している値です。(編集していない場合、mysecretpw)

PHP(FPM)コンテナ

コンテナ名:sandbox-php

公式PHPコンテナのFPMをもとに、以下のモジュールを追加しています。

  • pdo
  • pdo_mysql
  • gd
  • mysqli
  • mcrypt
  • mbstring
  • iconv

関係図

関係図

PHP(FPM)コンテナはホスト名mysqlでMySQLコンテナにアクセスできます。
Nginxコンテナはホスト名phpでPHP(FPM)コンテナを参照しています。

PHPMyAdminを動かすサンプル

  1. PHPMyAdminをダウンロード
  2. 解凍して、中にあるPHPファイルをsrc/publicにコピー(すでにあるファイルは削除する)
  3. config.sample.incをconfig.incにリネーム
  4. config.incを編集

    ホスト名を変更

     /* Authentication type */
     $cfg['Servers'][$i]['auth_type'] = 'cookie';
     /* Server parameters */
    -$cfg['Servers'][$i]['host'] = 'localhost';
    +$cfg['Servers'][$i]['host'] = 'mysql';
     $cfg['Servers'][$i]['connect_type'] = 'tcp';
    

    末尾に追加

     $cfg['CheckConfigurationPermissions'] = false;
    
  5. http://sandbox.localにアクセス
  6. ID:root / PW:mysecretpw (docker-run.shのMySQLコンテナ起動時のMYSQL_ROOT_PASSWORDで指定している値)

その他

  • docker-run.sh実行時にすべてのコンテナを削除します。
  • コンテナが正常に動かない場合、docker ps -aでコンテナIDを調べ、docker logs コンテナID で原因となるメッセージが出力されることがあります。

  1. Ubuntu/Debianの場合、dockerコマンドがdocker.ioになっているため、いまさら聞けないDocker入門(2):ついに1.0がリリース! Dockerのインストールと主なコマンドの使い方 (1/3) – @ITにあるようにしてdockerコマンドを利用できるようにする方法もあります。 

Dockerのプライベートレジストリ(docker registry v1)に対してCoreOS上でdocker pushをhttpsではなくhttpで行う

あるサーバ(ホスト名:example.com)にdockerをインストールしておき、

$ docker run -p 5000:5000 registry

でDockerのプライベートレジストリを動かしているとします。

それに対して、クライアント側としてcoreos上で構築したdockerイメージをpushしようとする際、

$ docker tag XXXXXXXXXXXX example.com:5000/imagename
$ docker push example.com:5000/imagename

としますが、https通信が必要なため、

FATA[0004] Error: v1 ping attempt failed with error: Get https://example.com:5000/v1/_ping: EOF.
If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry example.com:5000` to the daemon's arguments.
In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/example.com:5000/ca.crt

となってしまいます。

解決するためには

クライアント側のdockerサービスに対して

  • insecure-registryオプションをつけてhttpアクセス
  • 証明書を正しくインストールしてhttpsアクセス

のどちらかが必要になり、httpで通信するためには前者の対応が必要になります。

dockerサービスの起動オプションにinsecure-registryを渡すためには、CoreOSが持っているcloud-initの機構を利用して

coreos:
  units:
    - name: docker.service
      drop-ins:
        - name: 50-insecure-registry.conf
          content: |
            [Service]
            Environment=DOCKER_OPTS='--insecure-registry="example.com:5000"'

でCoreOSインスタンスを起動することで

$ docker tag XXXXXXXXXXXX example.com:5000/imagename
$ docker push example.com:5000/imagename
The push refers to a repository [example.com:5000/imagename] (len: 1)
Sending image list
Pushing repository example.com:5000/imagename (1 tags)
XXXXXXXXXXXX: Image successfully pushed
XXXXXXXXXXXX: Image successfully pushed
XXXXXXXXXXXX: Image successfully pushed
Pushing tag for rev [XXXXXXXXXXXX] on {http://example.com:5000/v1/repositories/imagename/tags/latest}

とhttpでpushが可能になります。

CoreOS Vagrantを使っている場合

user-data.sampleuser-dataにリネームして、そこに上記の内容を追記したのち、vagrant upします。

Vagrantfile単体でcoreosを使っている場合

CoreOS Vagrantの記述を利用

  1. Vagrantfileと同じ場所にuser-dataという名前のファイルを作成し、上記の内容を記述します。
  2. Vagrantfileに下記内容を追加
    CLOUD_CONFIG_PATH = File.join(File.dirname(__FILE__), "user-data")
    if File.exist?(CLOUD_CONFIG_PATH)
      config.vm.provision :file, :source => "#{CLOUD_CONFIG_PATH}", :destination => "/tmp/vagrantfile-user-data"
      config.vm.provision :shell, :inline => "mv /tmp/vagrantfile-user-data /var/lib/coreos-vagrant/", :privileged => true
    end
    
  3. vagrant up

参考

Customize with Cloud-Config
https://coreos.com/docs/cluster-management/setup/cloudinit-cloud-config/
Docker Private Registry – Qiita (設定ファイルを書き換える方法)
http://qiita.com/megmogmog1965/items/0c9a95bcf7f054f5c065

Windows上でcoreos-vagrantとsynced_folder

Windows+VirtualBoxでCoreOSをVagrantを使って起動した際、ホスト側のフォルダを共有フォルダでゲスト側にリンクさせる。

config.rb.sampleをconfig.rbに変更し

#$share_home=false

$share_home=true

にしてvagrant upをすると、

> vagrant up
Bringing machine 'core-01' up with 'virtualbox' provider...
==> core-01: Importing base box 'coreos-alpha'...
==> core-01: Matching MAC address for NAT networking...
==> core-01: Checking if box 'coreos-alpha' is up to date...
==> core-01: Setting the name of the VM: coreos-vagrant_core-01_1425462114328_13396
No synced folder implementation is available for your synced folders!
Please consult the documentation to learn why this may be the case.
You may force a synced folder implementation by specifying a "type:"
option for the synced folders. Available synced folder implementations
are listed below.

docker, nfs, rsync, smb, virtualbox

となってしまい、CoreOSが起動しない。そこで、Windows上でNFSが扱えるvagrant-winnfsdプラグインをインストールする。

> vagrant plugin install vagrant-winnfsd
> vagrant up
Bringing machine 'core-01' up with 'virtualbox' provider...
==> core-01: Importing base box 'coreos-alpha'...
==> core-01: Matching MAC address for NAT networking...
==> core-01: Checking if box 'coreos-alpha' is up to date...
==> core-01: Setting the name of the VM: coreos-vagrant_core-01_1425462958797_25829
==> core-01: Clearing any previously set network interfaces...
==> core-01: Preparing network interfaces based on configuration...
    core-01: Adapter 1: nat
    core-01: Adapter 2: hostonly
==> core-01: Forwarding ports...
    core-01: 22 => 2222 (adapter 1)
==> core-01: Running 'pre-boot' VM customizations...
==> core-01: Booting VM...
==> core-01: Waiting for machine to boot. This may take a few minutes...
    core-01: SSH address: 127.0.0.1:2222
    core-01: SSH username: core
    core-01: SSH auth method: private key
    core-01: Warning: Connection timeout. Retrying...
==> core-01: Machine booted and ready!
==> core-01: Setting hostname...
==> core-01: Configuring and enabling network interfaces...
==> core-01: Exporting NFS shared folders...
==> core-01: Preparing to edit nfs mounting file.
[NFS] Status: halted
[NFS] Start: started
==> core-01: Mounting NFS shared folders...

CoreOSにログインすると

core@core-01 ~ $ ls
C:
core@core-01 ~ $ mount
:
:
172.17.8.1:/C/Users/XXXXX on /home/core/C:/Users/XXXXX type nfs (rw,relatime,vers=3,rsize=32768,wsize=4096,namlen=255,hard,nolock,proto=udp,timeo=11,retrans=3,sec=sys,mountaddr=172.17.8.1,mountvers=3,mountport=1058,mountproto=udp,local_lock=all,addr=172.17.8.1)

となり、ホームディレクトリ同士がリンクされています。どちらかでファイルを変更するともう片方に反映されます。あとは必要に応じて、config.rbの$shared_foldersに設定を追加していきます。
ただし、ゲストOS上で、シンボリックリンクやソケットファイルなどの特殊なファイルを作成しようとするとエラーになります。

core@core-01 ~/C:/Users/XXXXX $ touch aaa
core@core-01 ~/C:/Users/XXXXX $ ln -s aaa bbb
ln: failed to create symbolic link 'bbb': Input/output error

検証環境

VirtualBox
4.3.22
ホストOS
Windows 8.1 64ビット版
Vagrant
1.7.2

coreos-vagrantとvagrant-hostmanager

VagrantでVirtualBox上にあるCoreOSに、vagrant-hostmanagerプラグインを使用してWindowsのhostsファイルにホスト名とIPの対応を追加させる。

事前準備

  • Vagrantのバージョンを1.5以上にする
  • vagrant-hostmanagerをインストールする
    vagrant plugin install vagrant-hostmanager
    
  • coreos-vagrantをクローンする
    git clone https://github.com/coreos/coreos-vagrant
    

設定

Vagrantfileを編集する

--- a/Vagrantfile
+++ b/Vagrantfile
@@ -68,6 +68,13 @@
   Vagrant.configure("2") do |config|
     config.vbguest.auto_update = false
   end

+  if Vagrant.has_plugin?("vagrant-hostmanager")
+    config.hostmanager.enabled = false
+    config.hostmanager.manage_host = true
+    config.hostmanager.ignore_private_ip = false
+    config.hostmanager.include_offline = true
+  end
+
   (1..$num_instances).each do |i|
     config.vm.define vm_name = "%s-%02d" % [$instance_name_prefix, i] do |config|
       config.vm.hostname = vm_name
@@ -130,6 +137,10 @@
       Vagrant.configure("2") do |config|
         config.vm.provision :shell, :inline => "mv /tmp/vagrantfile-user-data /var/lib/coreos-vagrant/", :privileged => true
       end

+      if Vagrant.has_plugin?("vagrant-hostmanager")
+        config.vm.provision "shell", inline: "touch /etc/hosts"
+        config.vm.provision :hostmanager
+      end
     end
   end
 end

Vagrantで起動

vagrant up

hostsファイルの確認

ホスト名は、core-0X (Xは生成したインスタンス個数を1から順に)というホスト名がそれぞれ割り当てられる。)

vagrant upでCoreOSを2つ立ち上げた後のhostsファイル

参考

検証環境

VirtualBox
4.3.22
ホストOS
Windows 8.1 64ビット版
Vagrant
1.7.2