« 2014年10月 | メイン | 2015年4月 »

2014年12月

2014年12月30日 (火)

DockerでLinux仮想デスクトップサーバをつくる話

こんにちは。エンジニアの佐藤です。2014年も残すところわずかとなりましたが、今回は再びDockerの話題を取り上げさせていただきたいと思います。(前回のDockerでLAMPサーバをつくる話も合わせてご覧ください。)今回ご紹介したいのは、DockerでLinux仮想デスクトップサーバーを作成する方法です。

仮想デスクトップとは

ものすごく簡単に言うと、ネットワーク経由でデスクトップ画面を配信する機能です。Windowsでは「ターミナルサービス」や「リモートデスクトップサービス」などと呼ばれています。サーバ上で仮想デスクトップサーバなるサービスを実行して接続を待ちます。クライアントはビューワーアプリで接続してデスクトップを表示し、リモートコンピュータを操作します。

何の役に立つの?

仮想デスクトップの主な用途は 1)データセンターに格納されたサーバマシンを遠隔で管理する。2)一台のアプリケーションサーバを安価なシンクライアント経由で共有する。の2つです。

なぜDockerで仮想デスクトップ?

他の環境への引っ越しが非常に楽になります。つまり手元のパソコンで調整した開発環境をわずかなコマンド実行で隣のコンピュータに移すことができます。仮想デスクトップですので、物理的な画面を持たないクラウドインスタンスなどへも全く同じ手順で引っ越すことが可能です。例えばAWS EC2の開発環境をGoogle Compute Engineへ乗せ換える、というようなことが可能になります。Dockerなしでは、こういうことは難しいと思います。

仮想デスクトップサーバ「コンテナ」の作成

それでは実際の手順ですが、以下のような手順で実行可能です。

  1. Dockerのインストール
  2. Dockerのストレージを「devicemapper」に設定
  3. Ubuntuの最新イメージをDocker hubからpull
  4. /bin/bashでスタート
  5. Linuxデスクトップのセットアップ
  6. 仮想デスクトップのセットアップ
  7. 起動スクリプトを書く
  8. イメージを保存して、docker run
  9. クライアントからの接続

前回のDockerでLAMPサーバをつくる話と基本的には同様です。ただしいくつか注意する点があります。

1. Dockerのインストール

今どきのLinuxディストリビューションでは、コマンド一発です。

# apt-get install docker.io

2. Dockerのストレージを「devicemapper」に設定

いきなり「?」な内容ですが、この手順を実行しないまま既定のAUFSでDockerを実行すると一部のコマンド実行が失敗してしまいます。(この点については後述します。)

# vi /etc/default/docker
(以下の行を設定)
DOCKER_OPTS="-s=\"devicemapper\""
# service docker restart

3. Ubuntuの最新イメージをDocker hubからpull

これはコマンド一発です。

# docker pull ubuntu:latest

4. /bin/bashでスタート

次に「bash」コマンドを指定してコンテナをスタートします。この時「-i -t」オプションを指定し、コンテナ内で起動したbashの標準入力と標準出力を、今まさにdockerコマンドを打っているターミナルに接続します。

# docker images | grep ubuntu  <-- UbuntuのイメージIDを確認
ubuntu              latest              5506de2b643b        9 weeks ago         197.8 MB
# docker run -i -t 5506 /bin/bash <-- bashを指定してコンテナを起動。イメージIDは前方一致で指定できる。
bash-4.1# whoami <-- コンテナ内のbashのプロンプト
root

5. Linuxデスクトップのセットアップ

ここが結構難所でした。今どきのデスクトップ(Gnomeなど)はUX改善のためGPUを活用していることが多く、これがDockerとぶつかります。また、仮想デスクトップはネットワーク経由でデスクトップ画像を送信するので、派手なUXでは転送容量が膨張して足かせです。そこで数あるLinuxデスクトップの中から、LXDEを選びます。日本語入力にはGoogle日本語入力のLinux版であるMozcを選びました。

# apt-get install openssh-server lxde mozc-server uim uim-mozc fonts-takao
# locale-gen en_US.UTF.8

このインストールは800MBほどのダウンロードになるので結構時間がかかります。 注意する必要があるのが、2行目のコマンドでロケールを作成するところです。このコマンドを実行しないと、ターミナル上で日本語表示ができなくなります。

6. 仮想デスクトップのセットアップ

Linuxの仮想デスクトップソフトはいろいろありますが、筆者がおすすめなのはTigerVNCです。Fedoraにも収録されており、MacOS X、Windows、Linuxに対応しています。ここでは現時点の最新版1.4.0のLinux版をダウンロードします。ダウンロードしたらアーカイブを展開し、ファイルをコピーしてインストールします。

# tar xzf tigervnc-Linux-x86_64-1.4.0.tar.gz
# cp -rf usr/bin /usr
# cp -rf usr/lib64 /usr
# cp -rf usr/share /share

次に仮想デスクトップをスタートするときのスクリプトを作成し、これにLXDEデスクトップを起動するコマンドを追加します。

# adduser hoge <= 実際にデスクトップにログインするユーザを作成
(中略)
# su hoge
$ vncserver <= 既定の起動スクリプト作成のため一回起動
(パスワードを求められるので適当に設定)
$ vncserver -kill :1 <= 起動スクリプトが生成するので、一旦終了
$ vi ~/.vnc/xstartup
(以下のようにxstartupファイルを修正)
# xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" & <= コメントアウト
# twm & <= コメントアウト
startlxde & <= 追加

7. 起動スクリプトを書く

コンテナが起動した時に仮想デスクトップサーバが起動するように、以下のように作成します。(起動スクリプトについては前回のDockerでLAMPサーバをつくる話5. 最後に起動スクリプトを書く も合わせてご覧ください。)

# vi /root/start.sh
#! /bin/bash
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8

service rsyslog start
service ssh     start
sudo -u hoge -H vncserver

term() {
    sudo -u hoge -H vncserver -kill :1
    service ssh     stop
    service rsyslog stop
}

trap "term; exit" SIGHUP SIGINT SIGTERM

while true; do
    sleep 1
done

8. イメージを保存して、docker run

セットアップ作業が終わったコンテナを終了し、イメージを作成します。

# exit  <-- コンテナを終了
exit
# docker ps -l <-- コンテナのIDを確認
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES 
ad8596fad31e        ubuntu:latest      "/bin/bash"         51 minutes ago      Exited (1) 3 seconds ago
# docker commit ad85 vncserver01 <-- イメージを作成

いよいよ起動ですが、ここで2点注意することがあります。

  1. 「--privilege=true」オプションを指定する。(このオプションを設定しないと、日本語入力のMozcが動きません。) ※1
  2. 仮想デスクトップ接続用ポート5901番をホストに接続する。

実際のコマンドは以下のようになります。

# docker run --privileged=true -p 5901:5901 vncserver01 /root/start.sh

すべてがうまく行けば、これでサーバは仮想デスクトップの接続待機となったはずです。

9. クライアントからの接続

ここでではWindows 8.1マシンから接続してみます。 先ほどのTigerVNCのダウンロードサイトから、今度はWindows版をダウンロードします。ダウンロードした実行ファイルを実行するとインストーラが開始されます(ここではTigerVNCをサービスとして登録するオプションは設定しません。) インストーラが終了したら、「TigerVNC Viewer」を起動します。 接続先を問われるので、ホスト名:ポート番号形式で指定し、Connectをクリックします。パスワードを聞かれますので入力すると、LXDEデスクトップが表示されるはずです。 ここまで来れば、あとはほとんど通常のLinuxデスクトップと同様に使えます。

未解決の問題

「ほとんど通常のLinuxデスクトップと同様に使えます」とは言ったものの、実は問題点もあります。筆者が直面した問題をいくつか上げておきたいと思います。

Google Chromeが起動後しばらくするとクラッシュ(回避方法あり ※2)

これが一番困っている問題です。巷のサイトにはChromeの起動オプション「--no-sandbox」を設定する方法が紹介されていますが、このオプションを設定しても回避できません。 (なお、Firefoxは問題なく実行できます。)

tcpdumpが実行できない(回避方法あり)

tcpdumpとは、コマンドで実行できるパケットキャプチャツールです。便利なのですが、Dockerのストレージが既定の「aufs」のままだと起動できません。ストレージに「devicemapper」を指定することで回避できます。

コンテナ内の/etc/hostsが変更できない(回避方法あり)

これはDockerの制約です。(最新のDockerでは回避されているかもしれません。)回避方法は少々複雑です。

  1. Dockerを実行するLinux(Dockerホスト)にdnsmasqをインストールして起動
  2. docker runで仮想デスクトップサーバのコンテナを実行するとき、オプション「--dns="172.17.42.1"」を追加する。
  3. コンテナ内の/etc/hostsに名前を追加する代わりに、Dockerホストの/etc/hostsを修正してdnsmasqを再起動

まとめ

一般的にDockerは、サービスの実装インフラ技術として取り上げられることがほとんどだと思いますが、今回ご紹介したようにデスクトップ環境を実装することも可能です。 こんなことをして何の役に立つのか?と思われる方も多いと思いますが、この技術を使うと、ソフト開発作業などのいわゆる「パソコン仕事」をほとんどすべてクラウドに収容することができます。Dockerですので、手元のパソコンからクラウドインスタンスへの移行は相当に省力化されます。 筆者の勝手な見解かもしれませんが、もはや手元にハイパフォーマンスのコンピュータを用意する時代は、終わったような気がします。

2016-06追記

※1: 2016-06現在は、Mozcの実行に--privilege=trueは不要になっています。 ※2: docker runの時にオプション「-v /dev/shm:/dev/shm」を付けると回避できます。元ネタはこちら

採用情報

株式会社フレクトでは、事業拡大のため、
・Salesforce/Force.comのアプリケーション開発
・HerokuやAWSなどのクラウドプラットフォーム上での
Webアプリケーション開発
エンジニア、マネージャーを募集中です。

未経験でも、これからクラウドをやってみたい方、
是非ご応募下さい。

フレクト採用ページへ

会社紹介

株式会社フレクトは、
認定コンサルタント
認定上級デベロッパー
認定デベロッパー
が在籍している、セールスフォースパートナーです。
また、heroku partnersにも登録されています。
herokuパートナー
株式会社フレクトのSalesforce/Force.com
導入支援サービス
弊社の認定プロフェッショナルが支援致します。
・Visualforce/Apexによるアプリ開発
・Salesforceと連携するWebアプリ開発
も承っております。
セールスフォースご検討の際は、
お気軽にお問合せください。

2024年3月

          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
ブログ powered by TypePad