DockerでLinux仮想デスクトップサーバをつくる話
こんにちは。エンジニアの佐藤です。2014年も残すところわずかとなりましたが、今回は再びDockerの話題を取り上げさせていただきたいと思います。(前回のDockerでLAMPサーバをつくる話も合わせてご覧ください。)今回ご紹介したいのは、DockerでLinux仮想デスクトップサーバーを作成する方法です。
仮想デスクトップとは
ものすごく簡単に言うと、ネットワーク経由でデスクトップ画面を配信する機能です。Windowsでは「ターミナルサービス」や「リモートデスクトップサービス」などと呼ばれています。サーバ上で仮想デスクトップサーバなるサービスを実行して接続を待ちます。クライアントはビューワーアプリで接続してデスクトップを表示し、リモートコンピュータを操作します。
何の役に立つの?
仮想デスクトップの主な用途は 1)データセンターに格納されたサーバマシンを遠隔で管理する。2)一台のアプリケーションサーバを安価なシンクライアント経由で共有する。の2つです。
なぜDockerで仮想デスクトップ?
他の環境への引っ越しが非常に楽になります。つまり手元のパソコンで調整した開発環境をわずかなコマンド実行で隣のコンピュータに移すことができます。仮想デスクトップですので、物理的な画面を持たないクラウドインスタンスなどへも全く同じ手順で引っ越すことが可能です。例えばAWS EC2の開発環境をGoogle Compute Engineへ乗せ換える、というようなことが可能になります。Dockerなしでは、こういうことは難しいと思います。
仮想デスクトップサーバ「コンテナ」の作成
それでは実際の手順ですが、以下のような手順で実行可能です。
- Dockerのインストール
- Dockerのストレージを「devicemapper」に設定
- Ubuntuの最新イメージをDocker hubからpull
- /bin/bashでスタート
- Linuxデスクトップのセットアップ
- 仮想デスクトップのセットアップ
- 起動スクリプトを書く
- イメージを保存して、docker run
- クライアントからの接続
前回の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点注意することがあります。
- 「--privilege=true」オプションを指定する。(このオプションを設定しないと、日本語入力のMozcが動きません。) ※1
- 仮想デスクトップ接続用ポート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では回避されているかもしれません。)回避方法は少々複雑です。
- Dockerを実行するLinux(Dockerホスト)にdnsmasqをインストールして起動
- docker runで仮想デスクトップサーバのコンテナを実行するとき、オプション「--dns="172.17.42.1"」を追加する。
- コンテナ内の/etc/hostsに名前を追加する代わりに、Dockerホストの/etc/hostsを修正してdnsmasqを再起動
まとめ
一般的にDockerは、サービスの実装インフラ技術として取り上げられることがほとんどだと思いますが、今回ご紹介したようにデスクトップ環境を実装することも可能です。 こんなことをして何の役に立つのか?と思われる方も多いと思いますが、この技術を使うと、ソフト開発作業などのいわゆる「パソコン仕事」をほとんどすべてクラウドに収容することができます。Dockerですので、手元のパソコンからクラウドインスタンスへの移行は相当に省力化されます。 筆者の勝手な見解かもしれませんが、もはや手元にハイパフォーマンスのコンピュータを用意する時代は、終わったような気がします。
2016-06追記
※1: 2016-06現在は、Mozcの実行に--privilege=trueは不要になっています。 ※2: docker runの時にオプション「-v /dev/shm:/dev/shm」を付けると回避できます。元ネタはこちら
" For example, you might say, "Wow, I really did great in that interview. High protein intake overtime can cause liver and kidney disease, which causes your body to inefficiently process proteins. It is a place where being different is shunned and even punished.
投稿: fantastic four streaming | 2015年8月12日 (水) 02:05
Meal Organizig Blueprint - The most tough activity in any weight loss diet regime is meal arranging.
投稿: Dominick | 2015年8月12日 (水) 13:30