2.02.2014

Docker: Creating Development Environment with SSH

Docker: SSH標準装備の開発環境コンテナイメージの作成

 

Docker コンテナ内で完結する開発環境を作って immutable infra を実現したいというのが動機。
コンテナ内の各種ログを確認したり、ちょっとしたファイルを転送したりするために SSH によるログインも可能としたい。 

 

ファイル構成

 

複数プロセスをまとめる Supervisor

Docker は 1つのアプリケーションを 1つのコンテナで動かすのが基本的な考え方。

複数のプロセスをまとめてデーモンとして動作させるためにはプロセス管理ツールが必要。
その現時点のデファクトスタンダードが Python で書かれたツール、Supervisor である。

 

ファイル内容

作業ディレクトリ配下に Dockerfile と supervisord.conf、そして必要であればミドルウェア等の設定ファイルを置く。

CentOS ベースのコンテナであれば、各ファイルの内容は以下のような構成になる。

  • Dockerfile

    ssh-user という OSユーザを作成し(パスワードも ssh-user)、sudo も可能にする。

    FROM centos:6.4
    
    #
    # SSH
    #
    
    RUN yum install -y --nogpgcheck openssh-server sudo
    RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key && ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key && sed -i 's/UsePAM.*/UsePAM no/g' /etc/ssh/sshd_config
    
    # create user
    RUN useradd ssh-user && echo 'ssh-user:ssh-user' | chpasswd && echo 'ssh-user ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
    
    #
    # Supervisor
    #
    
    # enable EPEL repository
    RUN yum install -y --nogpgcheck http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/x86_64/epel-release-6-5.noarch.rpm
    
    # install supervisord
    RUN yum install -y --nogpgcheck supervisor
    
    # settings
    ADD supervisord.conf /etc/supervisord.conf
    RUN mkdir -p /var/log/supervisor
    
    #
    # Other applications here!
    #
    
    EXPOSE 22
    CMD ["/usr/bin/supervisord"]
    
    

    尚、ADD コマンドの後は常に新しいイメージが生成されるようで、キャッシュが使えなくなる。
    Dockerfile を編集して何度もコンテナを作りたい場合は ADD を後回しにした方がいいかもしれない。

  • supervisord.conf
    [supervisord]
    nodaemon=true
    
    [program:sshd]
    command=/usr/sbin/sshd -D
    stdout_logfile=/var/log/supervisor/%(program_name)s.log
    stderr_logfile=/var/log/supervisor/%(program_name)s.log
    autostart=true
    autorestart=true
    

    起動するプロセスを増やしたい場合は、[program:xxx] を増やしてゆけばよい。
    sshd だけは autorestart を有効にした方がいいだろう。

 

Apache + MySQL + PHP 環境のサンプル

例えばお手軽な LAMP環境を使いたい場合は以下のような Dockerfile を作る。

ローカルのみの使用を前提としているので、セキュリティの制限は設けていない。

 

コンテナイメージの作成と起動

 

Docker ホスト SELinux の無効化

まず最初に、Dockerホスト側の SELinux を無効化(/etc/selinux/config -> SELINUX=disabled)する。

これをしないと Dockerコンテナ側で getenforce コマンドがエラーになってしまい、SSH 接続ができなくなる。

(getenforce の中で呼ばれている security_getenforce 関数が負数を返し、結果としてパスワード認証後に通信が切断される。このトラブルシューティングで1日を費やしてしまった)

 

イメージ作成

Docker Registry との連携を考えるなら、イメージの名前にはハイフンではなくアンダースコアを使った方がいい。

$ docker build -t local/apache_mysql_php .

 

コンテナ起動

Dockerホストのポートとの転送設定を -p オプションで指定する。

$ docker run -d -t -p 50000:22 -p 3306:3306 -p 8000:80 local/apache_mysql_php

この例では、SSH(22) を 50000番に、MySQL(3306) はそのまま、Apache(80) は 8000番に割り当てている。

尚、実際の運用では -v /vagrant/app:/app のようにディスクのマウント設定を行い、
アプリケーションの領域を Dockerホストと連携させると良さそうだ。

(さらに Vagrant の synced folder 機能を使って、自分のPCとDockerコンテナのディレクトリを直接リンクさせることもできる)

2014-03-15 追記
環境によっては、docker run に「-t」オプション(pseudo tty 有効化) が必須となるので付けたほうがいい。

 

動作確認

 

Docker

コンテナが起動していることを確認

$ docker ps
CONTAINER ID        IMAGE                           COMMAND                CREATED             STATUS              PORTS                                                                 NAMES
c636e5dbaebf        local/apache_mysql_php:latest   /usr/bin/supervisord   16 seconds ago      Up 14 seconds       0.0.0.0:3306->3306/tcp, 0.0.0.0:50000->22/tcp, 0.0.0.0:8000->80/tcp   angry_pare

 

SSH

ログイン先は Dockerホストの 50000番ポート。

「Dockerホスト」の箇所は環境に合わせて適宜置換(以下同じ)。ログインパスワードは ssh-user。

$ ssh -p 50000 -l ssh-user Dockerホスト
(パスワード入力など)
[ssh-user@70a19c076413 ~]$

 

Apache, PHP

Docker コンテナの中で適当なPHPページを作る。

$ sudo /bin/bash -c "echo '<?php phpinfo(); ?>' > /var/www/html/info.php"

ブラウザで http://Dockerホスト:8000/info.php にアクセスして、phpinfo() の結果が表示されればOK。

 

MySQL

root アカウントで直接操作できるようにしている。

$ mysql -uroot -h Dockerホスト
mysql> select host, user from mysql.user;
mysql> exit

 

これで immutable な開発環境のベースができあがった。

 

 

References

 

0 件のコメント:

コメントを投稿