ラベル Mac の投稿を表示しています。 すべての投稿を表示
ラベル Mac の投稿を表示しています。 すべての投稿を表示

12.16.2015

Manipulating Many Servers by Using parallel-ssh

parallel-ssh を使って複数サーバを同時に操作する

 

tl; dr

  • 2台〜100台程度のサーバに対して、同じオペレーションを同時に実行したい
  • parallel-ssh (pssh) の各種コマンドを使うと便利
  • ただし、リモートサーバで sudo が必要な場合は Ansible 等の他ツールが必要

 

parallel-ssh のセットアップ

 

インストール

parallel-ssh - PSSH: Parallel SSH Tools - Google Project Hosting
  • Mac
    $ brew install pssh
  • RHEL系
    # yum install pssh
ホストリストの準備
  • 任意のパスにテキストファイルを作成
    server-1
    server-2
    server-3 root
  • 1行ずつ、接続先サーバのホスト名またはIPアドレスを記述
  • ログインユーザの指定も可能

 

目的別コマンド実行例

 

SSH 認証のための設定

parallel-ssh を使うには、各サーバに SSH で接続できることが前提となる。
ssh-copy-id コマンドを利用して、~/.ssh/id_rsa の内容を登録する場合は以下。

$ for h in $(cat ~/hosts); do ssh-copy-id $h; done

 

pssh の使い方
  • 基本形
    $ pssh -h ~/hosts -i 'hostname'
    [1] 04:09:13 [SUCCESS] server-1
    server-1
    [2] 04:09:13 [SUCCESS] server-2
    server-2
  • ホスト名を直接指定
    $ pssh -H server-1 -H server-2 -i 'hostname'
    [1] 04:09:13 [SUCCESS] server-1
    server-1
    [2] 04:09:13 [SUCCESS] server-2
    server-2
  • タイムアウトを無制限に
    $ pssh -h ~/hosts -t 0 -i 'hostname'
    [1] 04:09:13 [SUCCESS] server-1
    server-1
    [2] 04:09:13 [SUCCESS] server-2
    server-2
  • アウトプットをすぐに表示
    $ pssh -h ~/hosts -P 'hostname'
    server-1: server-1
    [1] 04:13:28 [SUCCESS] server-1
    server-2: server-2
    [2] 04:13:28 [SUCCESS] server-2
    
  • リモートでバックグラウンド実行
    $ pssh -h ~/hosts -i 'nohup your_command > /path/to/output 2>&1 </dev/null &'
    [1] 04:13:28 [SUCCESS] server-1
    [2] 04:13:28 [SUCCESS] server-2
    
    バッファの影響で、標準出力の出力先ファイルがリアルタイムに更新されない場合がある。
    対応にはハックが必要: linux - redirect nohup stdout and flush - Stack Overflow

 

ファイル転送
  • ローカルからリモートに転送
    $ prsync -h ~/hosts -av /data/input/ /data/input/
    • パスの末尾にスラッシュを付けると、ディレクトリ間の同期となる。(rsync の仕様)
    • -z (圧縮オプション) は付けると CPU がボトルネックになって大幅に性能が劣化する場合がある。ナローバンドでなければ、付けないほうが良さそうだ。
  • リモートからローカルに転送
    $ pssh -h ~/hosts -p 4 -i 'rsync -e "ssh -o StrictHostKeyChecking=no" -av \
    /data/output/ server-1:/data/output/'
    • 全サーバから server-1 に集約する例
    • -p オプションを指定して、並列度を制限している。
      こうしないと、コネクションが多すぎて接続できない場合がある。
    • rsync -e "ssh -o ..." という書式で SSH オプションを指定。
      ここではホストキーのチェックを回避している。

 

リモートサーバで sudo が必要な場合
  • Ansible で代用
    $ ansible -i ~/hosts all --sudo -K \
    -a 'bash -c "cd /path/to/your/app && make install"'
    

 

References

11.08.2015

Universal Use of 'subprocess' Module in Python

Python: バージョン・OS 透過的な subprocess モジュールの利用

 

Python のバージョン (2.6 / 2.7 / 3.2 / 3.3 / 3.4 / 3.5) や、OS環境 (Linux / Mac / Windows /CygWin) に依存せずに外部コマンドを実行するコードを書きたい。

 

ワークアラウンド

なかなか一筋縄ではいかない。

Python3.2 + POSIX環境 では、コマンドラインを bytes で渡してはいけない

以下のようなエラーが出る。

>>> import subprocess
>>> subprocess.call(b'echo')
TypeError: expect bytes or str, not int

subprocess モジュールの中で、args が文字列かどうかを判定するときに bytes である場合の考慮が不足しており、bytes の個々の要素(int)に対して分割が行われてしまうため。

対策は、コマンドラインをリストとして渡せばよい。以下のように対策する。(args が bytes である場合)

import sys

if sys.version_info[:2] == (3, 2):
    args = [args]

 

Python3 + Windows環境では、コマンドラインと環境変数のキー・値を bytes で渡してはいけない

以下のようなエラーが出る。

>>> import subprocess
>>> subprocess.call(b'cmd /C echo x')
    needquote = (" " in arg) or ("\t" in arg) or not arg
TypeError: argument of type 'int' is not iterable

bytes に対する in オペレーションに失敗しているが、これといった対策が見当たらない。bytes で渡すのをやめて、str で渡すことにする。(その場合、コマンドライン文字列のエンコードは指定できない)

import sys
import six
if six.PY2 or sys.platform != 'win32':
    # この場合だけ bytes にエンコード

env の指定についても同様。キーだけではなく、値も bytes が許容されていないので注意。

 

POSIX環境 + shell=True のとき、args をリストとして渡してはいけない

リストの2番目以降の引数が評価されない。

>>> import subprocess
>>> subprocess.call(['echo', '3'], shell=True)

0

ワークアラウンドとしては、subprocess.list2cmdline を使って適切な文字列を生成する。

import sys
import subprocess
if shell and sys.platform != 'win32':
    args = [subprocess.list2cmdline(args)]

 

外部コマンドについて

 

sleep

Windows 7 以降は「timeout」というコマンドが標準装備されているが、Python から実行すると標準入力が奪われてしまい不都合だった。


結局、Python の time モジュールを使うのが一番簡便だという結論に。

import subprocess
subprocess.call('python -c "import time;time.sleep(2)"')

 

プロセステーブルの取得

11.03.2015

How to Clear Terminal Screen in Various Systems

ターミナルの画面を消去する方法

 

特別なインストールなしで実現したい。

  • POSIX互換環境(Linux/Unix/Mac): clear
  • Windows
    • コマンドプロンプト (cmd.exe): cls
    • CygWin (2011以前): cmd /c cls
    • CygWin (mintty): echo -en "\ec"

CygWin の闇は深い。

 

 

References

11.03.2014

Mac: Upgrading to OS X Yosemite

Mac: OS X Yosemite にアップグレードした際のメモ

 

reattach-to-user-namespace のアップデート

HomeBrew でインストールした reattach-to-user-namespace で警告が出た。

warning: reattach-to-user-namespace: unsupported new OS, trying as if it were 10.6-10.9
warning: _vprocmgr_move_subset_to_user failed
warning: reattach-to-user-namespace: unable to reattach

reattach-to-user-namespace の最新版をインストールすればよい。

$ brew upgrade reattach-to-user-namespace

 

テキストエディタなどで Ctrl-N (カーソルを一行下へ移動) が効かなくなる

なぜか、システム環境設定 Keyboard -> Input Sources -> Japanese -> Windows-like shortcuts に
チェックが入っていると、Emacs ライクなキーバインドである Ctrl-N が効かなくなるようだ。

チェックオフにして解決。

Screenshot 11 3 14 13 33

ハードウェアドライバの更新

9.02.2014

C++: How to Get Per-Core CPU Usage in Mac

C++: Mac環境でコア単位のCPU使用率を測定する

 

環境
  • OS X: 10.9

 

コード
#include <stdio.h>
#include <unistd.h>
#include <mach/mach_host.h>
#include <mach/processor_info.h>
#include <iostream>

using namespace std;

class CpuUsage {
 public:
  CpuUsage(int core): core_(core) {
    prev = updated_ticks_(core);
  }

  float get() {
    Ticks t = updated_ticks_(core_);
    unsigned long long int used = t.used() - prev.used();
    unsigned long long int total = t.total() - prev.total();
    prev = t;
    return (float)used / (float)total * 100.0f;
  }

 private:
  struct Ticks {
    unsigned long long int usertime;
    unsigned long long int nicetime;
    unsigned long long int systemtime;
    unsigned long long int idletime;

    unsigned long long int used() { return usertime + nicetime + systemtime; }
    unsigned long long int total() { return usertime + nicetime + systemtime + idletime; }
  } prev;

  int core_;

  Ticks updated_ticks_(int core) {
    unsigned int cpu_count;
    processor_cpu_load_info_t cpu_load;
    mach_msg_type_number_t cpu_msg_count;

    int rc =  host_processor_info(
      mach_host_self( ),
      PROCESSOR_CPU_LOAD_INFO,
      &cpu_count,
      (processor_info_array_t *) &cpu_load,
      &cpu_msg_count
    );
    if (rc != 0) {
      printf("Error: failed to scan processor info (rc=%d)\n", rc);
      exit(1);
    }

    if (core < 0 || cpu_count <= core) {
      printf("Error: invalid core number: %d\n", core);
      exit(1);
    }
    unsigned long long int usertime = cpu_load[core].cpu_ticks[CPU_STATE_USER];
    unsigned long long int nicetime = cpu_load[core].cpu_ticks[CPU_STATE_NICE];
    unsigned long long int systemtime = cpu_load[core].cpu_ticks[CPU_STATE_SYSTEM];
    unsigned long long int idletime = cpu_load[core].cpu_ticks[CPU_STATE_IDLE];

    Ticks t = {usertime, nicetime, systemtime, idletime};
    return t;
  }

};

int main() {
  CpuUsage a(0), b(1), c(2), d(3);
  sleep(1);
  printf("%6.2f, %6.2f, %6.2f, %6.2f\n", a.get(), b.get(), c.get(), d.get());
  sleep(1);
  printf("%6.2f, %6.2f, %6.2f, %6.2f\n", a.get(), b.get(), c.get(), d.get());
  sleep(1);
  printf("%6.2f, %6.2f, %6.2f, %6.2f\n", a.get(), b.get(), c.get(), d.get());
  return 0;
}

(need improvement)

 

実行例
 78.00,  72.73,  85.00,  72.00
 78.00,  57.00,  72.00,  56.57
 82.00,  83.00,  90.00,  88.00

 

 

References

7.03.2014

Docker: docker-attach - Helper Script for Entering a Running Container

Docker: 起動しているコンテナの中に入るための便利スクリプト

 

Dockerコンテナ (libcontainer) に入るときは、ssh でも nsinit でもなく nsenter が一番いいらしい。

そのラッパーシェルを docker-attach という名前で書いていたが、自分が使いやすいようにバージョンアップしてみた。

 

リポジトリ

 

備考
  • Mac上でも boot2docker VM上でも同じシンタックスで利用可能
  • 事前に boot2docker VM上で セットアップ が必要
  • READMEはそのうち書く。リポジトリ構成も整理する予定

 

使い方




引数なしで実行
$ docker-attach
 NO.  CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
 [1]  77c4f673e22d        centos:latest       /bin/sleep 1000     6 seconds ago       Up 5 seconds                            insane_poincar
 [2]  bf55f24e0231        centos:latest       /bin/sleep 1000     7 seconds ago       Up 6 seconds                            goofy_darwin
 [3]  ae214f93be56        centos:latest       /bin/sleep 1000     8 seconds ago       Up 8 seconds                            furious_laland
 [4]  2af5192ee5a6        centos:latest       /bin/sleep 1000     10 seconds ago      Up 9 seconds                            mad_einstein
 [5]  ff2b4987e717        centos:latest       /bin/sleep 1000     11 seconds ago      Up 11 seconds                           agitated_meitn
 [6]  0b2168db31db        centos:latest       /bin/sleep 1000     13 seconds ago      Up 12 seconds                           focused_bell
 [7]  89bce218d973        centos:latest       /bin/sleep 1000     14 seconds ago      Up 14 seconds                           stoic_fermi
 [8]  d9767d3d8551        centos:latest       /bin/sleep 1000     16 seconds ago      Up 15 seconds                           insane_tesla
 [9]  ddd3b0e67a1c        centos:latest       /bin/sleep 1000     17 seconds ago      Up 17 seconds                           furious_meitne
 [10] d4eea7f883d6        centos:latest       /bin/sleep 1000     19 seconds ago      Up 18 seconds                           condescending_

Enter number (1-10): 5
-sh-4.1# hostname
ff2b4987e717
-sh-4.1# exit
logout

docker ps の結果とプロンプトが出るので、入りたいコンテナを数字で指定する。

コンテナIDを引数に指定して実行
$ docker-attach 77c4
-sh-4.1# hostname
77c4f673e22d
-sh-4.1# exit
logout

コンテナID(識別可能な先頭の数文字でよい)がわかっている場合は、直接そのコンテナの中に入れる。

コンテナIDとコマンドを引数に与えて実行
$ docker-attach bf55 cat /etc/redhat-release
CentOS release 6.5 (Final)

コンテナの中で指定したコマンドが実行される。

ヘルプ
$ docker-attach --help
Usage: /usr/local/bin/docker-attach [CONTAINER [COMMAND [CMD_ARGS...]]]

 

 

 

Related Posts

7.02.2014

Docker: How to Dive Into a Container on the boot2docker VM, Improved

Docker: boot2docker VM で起動中のコンテナの中に入ってシェルを立ち上げる方法, 改良版

 

boot2docker 上で起動したコンテナに入ってシェル操作を行う方法。

nsinit を使う よりも、nsenter の方が少ない手順とコストで実現できた。

 

環境

  • OS: Mac OS X 10.9 (Mavericks)
  • boot2docker: v1.0.1

 

リポジトリ

 

事前準備

  • VirtualBox のインストール
  • boot2docker 最新版のインストール (OS X インストーラ の利用を推奨: 詳細手順)
    • インストール前に VirtualBox の全ての VM、GUI を停止すること
    • 既に boot2docker VM が存在している場合は以下のコマンドを実行 (元の環境は削除される)
      $ boot2docker halt
      $ boot2docker delete
      $ boot2docker download

 

セットアップ

 

1. boot2docker VM の作成・ログイン
Mac$ boot2docker init
Mac$ boot2docker up
Mac$ boot2docker ssh

以下の手順は boot2docker VM 上で実行。

 

2. util-linux 拡張機能のダウンロード
docker@boot2docker:~$ tce-load -w util-linux
ncurses.tcz.dep OK
Downloading: udev-lib.tcz
Connecting to repo.tinycorelinux.net (89.22.99.37:80)
udev-lib.tcz         100% |*********************************************************************************************| 45056   0:00:00 ETA
udev-lib.tcz: OK
Downloading: ncurses-common.tcz
Connecting to repo.tinycorelinux.net (89.22.99.37:80)
ncurses-common.tcz   100% |*********************************************************************************************| 12288   0:00:00 ETA
ncurses-common.tcz: OK
Downloading: ncurses.tcz
Connecting to repo.tinycorelinux.net (89.22.99.37:80)
ncurses.tcz          100% |*********************************************************************************************|   148k  0:00:00 ETA
ncurses.tcz: OK
Downloading: util-linux.tcz
Connecting to repo.tinycorelinux.net (89.22.99.37:80)
util-linux.tcz       100% |*********************************************************************************************|   992k  0:00:00 ETA
util-linux.tcz: OK

/tmp/tce/optional (/mnt/sda1/tmp/tce/optional) 配下にファイルがダウンロードされる。

 

3. util-linux 拡張機能 ファイルの永続化

先ほどダウンロードしたファイル群のある optional ディレクトリごと、永続ディスクである /var/lib/boot2docker 配下に移動する。

docker@boot2docker:~$ sudo mv /tmp/tce/optional /var/lib/boot2docker/

 

4. docker-attach スクリプトのダウンロード

コンテナにアタッチするための便利シェル、docker-attach を /var/lib/boot2docker/bin 配下にダウンロードする。

docker@boot2docker:~$ sudo mkdir -p /var/lib/boot2docker/bin
docker@boot2docker:~$ sudo curl -o /var/lib/boot2docker/bin/docker-attach \
https://raw.githubusercontent.com/mogproject/docker-attach/master/docker-attach
docker@boot2docker:~$ sudo chmod +x /var/lib/boot2docker/bin/docker-attach
  • スクリプトの中身は、コマンドライン引数として渡されたコンテナIDからプロセスIDを検索して
    そこにオプション付きの nsenter を実行しているのが主処理。
    CONTAINER_ID=$1
    PID=$(docker inspect --format '{{.State.Pid}}' $CONTAINER_ID)
    sudo nsenter --mount --uts --ipc --net --pid --target $PID

 

5. bootlocal.sh スクリプトのダウンロードと実行

boot2docker VM は起動時に /var/lib/boot2docker/bootlocal.sh が存在すれば、それを実行する。

このシェルの中で util-linux のインストールとコマンドのリンクを行い、boot2docker 再起動後も元の状態を復元できるようにしている。

docker@boot2docker:~$ sudo curl -o /var/lib/boot2docker/bootlocal.sh \
https://raw.githubusercontent.com/mogproject/docker-attach/master/bootlocal.sh
docker@boot2docker:~$ sudo chmod +x /var/lib/boot2docker/bootlocal.sh
docker@boot2docker:~$ sudo /var/lib/boot2docker/bootlocal.sh
boot2docker: 1.0.1
             master : cad5ece - Fri Jun 20 02:03:40 UTC 2014
udev-lib.tcz: OK
ncurses-common.tcz: OK
ncurses.tcz: OK
util-linux.tcz: OK

 

実行例

  • 適当なコンテナを起動し、コンテナIDを確認 (boot2docker上でも、Macからでも可)
    $ docker run -d -t centos /bin/sleep 1000
    $ docker run -d -t centos /bin/sleep 1000
    $ docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    f8c149734c7a        centos:latest       /bin/sleep 1000     5 minutes ago       Up 2 minutes                            naughty_sinoussi
    701810969c35        centos:latest       /bin/sleep 1000     5 minutes ago       Up 2 minutes                            sleepy_bell
    
  • boot2docker上で docker-attach を実行してコンテナにアタッチ
    docker@boot2docker:~$ docker-attach 701810969c35
    root@701810969c35:/# cat /etc/redhat-release
    CentOS release 6.5 (Final)
    root@701810969c35:/# exit
    logout
    docker@boot2docker:~$ 
    
  • Macからも、同じ docker-attach スクリプトを使って直接アタッチ可能
    Mac$ sudo curl -o /usr/local/bin/docker-attach \
    https://raw.githubusercontent.com/mogproject/docker-attach/master/docker-attach
    Mac$ sudo chmod +x /usr/local/bin/docker-attach
    Mac$ docker-attach f8c149734c7a
    -sh-4.1# cat /etc/redhat-release
    CentOS release 6.5 (Final)
    -sh-4.1# exit
    logout
    Mac$
    

 

ワンライナーでのセットアップ

セットアップ用のシェルも作った。

docker-attach/setup_boot2docker.sh at master · mogproject/docker-attach

  • boot2docker上で
    $ curl https://raw.githubusercontent.com/mogproject/docker-attach/master/setup_boot2docker.sh | /bin/sh
    
  • または、Mac上で
    $ boot2docker ssh '/bin/sh -c "curl https://raw.githubusercontent.com/mogproject/docker-attach/master/setup_boot2docker.sh | /bin/sh"'
    

 

References

6.24.2014

Docker: How to Run 'nsinit' in the boot2docker VM

Docker: boot2docker VM の中で nsinit を実行する方法

 

2014-07-02 追記:
nsinit ではなく nsenter を使えば、同じことをよりシンプルに実現できました。

参考: docker - nsinit が上手く行かなくて困っていたら nsenter があまりにもあっさりだった件 - Qiita

環境

  • OS: Mac OS X 10.9 (Mavericks) (boot2docker が動作すれば他の環境でも手順は同じはず)
  • boot2docker: v1.0.1

 

事前準備

  • VirtualBox のインストール
  • boot2docker 最新版のインストール (OS X インストーラ の利用を推奨: 詳細手順)
    • インストール前に VirtualBox の全ての VM、GUI を停止すること
    • 既に boot2docker VM が存在している場合は以下のコマンドを実行 (元の環境は削除される)
      $ boot2docker halt
      $ boot2docker delete
      $ boot2docker download

 

作業手順

 

boot2docker VM の作成・ログイン
Mac$ boot2docker init
Mac$ boot2docker up
Mac$ boot2docker ssh
GCC + golang コンパイル環境の準備
docker@boot2docker:~$ tce-load -wil compiletc go
nsinit のビルド
docker@boot2docker:~$ sudo GOPATH=$HOME/go go get github.com/docker/libcontainer/nsinit
docker@boot2docker:~$ sudo cp -f $HOME/go/bin/nsinit /usr/local/bin/

これで /usr/local/bin/nsinit が作成される。

2014-07-02 追記
nsinit リポジトリの状況によって、ここでハマるケースがいくつか報告されています。

やはり nsenter の利用をお勧めします。

参考: RHEL/CentOS 6で Docker に nsinit/nsenter する - Qiita

 

コンテナアタッチ用 便利シェルの作成

以下の内容で /usr/local/bin/docker-attach というシェルを書き、実行権限を付ける。

#!/bin/sh
[[ -n "$1" ]] || { echo "Usage: `basename $0` <partial container ID or name>"; exit 0 ; }
FULL_ID=$(docker inspect --format='{{.Id}}' $1)
sudo /bin/sh -c "cd /var/lib/docker/execdriver/native/$FULL_ID && nsinit exec bash"
コマンドの永続化

このままだと、nsinit, docker-attach は boot2docker VM を停止すれば消滅してしまう。

永続化されるディスクの /var/lib/boot2docker の中にコマンドを移動し、bootlocal.sh を使って起動時に再配備されるようにする。

docker@boot2docker:~$ sudo mkdir /var/lib/boot2docker/bin
docker@boot2docker:~$ sudo mv -i /usr/local/bin/nsinit /usr/local/bin/docker-attach /var/lib/boot2docker/bin/

/var/lib/boot2docker/bootlocal.sh を以下の内容で作成し、実行権限を付与。

#!/bin/sh
ln -s /var/lib/boot2docker/bin/nsinit /usr/local/bin/nsinit
ln -s /var/lib/boot2docker/bin/docker-attach /usr/local/bin/docker-attach

シェルを実行してリンクを張り直す。

docker@boot2docker:~$ sudo /var/lib/boot2docker/bootlocal.sh

 

稼働中の Docker コンテナの中に入る例

 

適当なコンテナの起動

任意のコンテナをデーモンモードで起動し、コンテナIDを確認

docker@boot2docker:~$ docker run -d -t centos /bin/sleep 1000
af1ebb57b1cbd0c1f3e02e3f164deb30d2b2ead95f5291545c757c5d33ac6ef7
docker@boot2docker:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
af1ebb57b1cb        centos:latest       /bin/sleep 1000     3 seconds ago       Up 3 seconds                            jolly_poincare
コンテナにアタッチして bash で操作
docker@boot2docker:~$ docker-attach af1e
bash-4.1# cat /etc/redhat-release
CentOS release 6.5 (Final)
bash-4.1# exit
exit

sshd なしで、稼働中のコンテナで bash を扱うことができた。

 

ワンライナーでセットアップする

コピペも面倒、という人向け(自分も含む)にセットアップ用のシェルを書いた。

実行例

docker@boot2docker:~$ curl https://raw.githubusercontent.com/mogproject/docker-attach/scripts-for-nsinit/setup_boot2docker.sh |/bin/sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2552  100  2552    0     0   7973      0 --:--:-- --:--:-- --:--:--  9522
2014-06-24 15:59:05 [INFO] Script started.
2014-06-24 15:59:05 [INFO] Creating directory /var/lib/boot2docker/bin
2014-06-24 15:59:05 [INFO] Installing compilers
gcc.tcz.dep OK
gcc_libs-dev.tcz.dep OK
cloog.tcz.dep OK

(中略)

Downloading: compiletc.tcz
Connecting to repo.tinycorelinux.net (89.22.99.37:80)
compiletc.tcz        100% |*********************************************************************************************|  4096   0:00:00 ETA
compiletc.tcz: OK
Downloading: go.tcz
Connecting to repo.tinycorelinux.net (89.22.99.37:80)
go.tcz               100% |*********************************************************************************************| 36288k  0:00:00 ETA
go.tcz: OK
2014-06-24 16:02:15 [INFO] Building /var/lib/boot2docker/bin/nsinit
2014-06-24 16:03:19 [INFO] Downloading /var/lib/boot2docker/bin/docker-attach
2014-06-24 16:03:19 [INFO] Downloading /var/lib/boot2docker/bootlocal.sh
2014-06-24 16:03:20 [INFO] Linking commands in /usr/local/bin
2014-06-24 16:03:20 [INFO] Script ended successfully.

 

 

References

5.24.2014

How to Install MathJax on Blogger

BloggerでMathJaxを使う方法

 

Blogger テンプレートの編集

こちらの解説 (Getting Started — MathJax 2.3 documentation) にあるように、HTMLソースのHEADブロックの中に以下のタグを埋め込めばいい。

<script type="text/javascript"
  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<script type="text/x-mathjax-config">  
  MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
</script>

Blogger の管理画面から、テンプレート -> HTML の編集 を行い、<head> … </head> の間の適当な場所に
タグを貼り付けて「テンプレートを保存」。

テンプレート -> バックアップ/復元 の機能を利用して、事前・事後にバックアップを取っておくと安心。

 

MarsEdit プレビューテンプレートの編集

ブログ作成ツール MarsEdit のプレビュー画面でも数式を表示したい。

これには SyntaxHighlighter 同様のトリックが必要となる。

テンプレートのBODYブロック内(</body>の直前)に以下のスクリプトを埋め込んだら、プレビュー画面でも MathJax が処理されるようになった。

<script type="text/javascript">
  function refreshMathJax() {
    MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
    setTimeout("refreshMathJax()", 5000);
  }
  refreshMathJax();
</script> 

 

出力サンプル

When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$

When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$

Mac: Displaying Text as What I Wrote in TextEdit

Mac の TextEdit でテキストファイルを開いたのに、HTMLがレンダリングされてイライラ

TextEdit でファイルを開いた場合、ファイルの拡張子に関係なく
ファイルの中身がHTMLっぽい場合 (htmlタグがあるなど) は HTML ファイルとして認識されてしまうようだ。

Preference -> Open and Save -> Display HTML files as HTML code instead of formatted text

にチェックを付けたら、とりあえずファイルの内容がそのまま表示されるようになった。

こういうストレス仕様は即刻やめてほしい。

4.30.2014

How to Integrate Clipboard; Mac + tmux + Emacs in Terminal

Mac + tmux + ターミナル上のEmacs でクリップボードを連携する方法

 

tmux 上で Emacs を利用する場合、
OS のクリップボードとその内容をシームレスに連携するためには多少の手順が必要となる。

 

手順

 

1. Emacs の設定

Emacs 初期設定ファイル (~/.emacs/init.el など) に以下の内容を記述。

(defun copy-from-osx ()
  (shell-command-to-string "pbpaste"))

(defun paste-to-osx (text &optional push)
  (let ((process-connection-type nil))
    (let ((proc (start-process "pbcopy" "*Messages*" "pbcopy")))
      (process-send-string proc text)
      (process-send-eof proc))))

(setq interprogram-cut-function 'paste-to-osx)
(setq interprogram-paste-function 'copy-from-osx)

 

2. reattach-to-user-namespace のインストール

tmux 内部での Mac OS X クリップボードのやりとり (pbcopy/pbpaste) を可能にするツール。

Homebrew でインストールするのが一番簡単だ。

$ brew install reattach-to-user-namespace

 

3. tmux の設定

tmux 初期設定ファイル (~/.tmux.conf) に以下の内容を記述し、tmux を再起動。

set-option -g default-command "reattach-to-user-namespace -l zsh"
  • 参考: tmux 再起動
    $ tmux kill-server

 

これで

  • Mac でクリップボードにコピー => tmux 上の emacs で貼付け (C-y)
  • tmux 上の emacs でコピー (M-w) => Mac で貼付け

が可能となった。

 

References

4.07.2014

Docker: b2d-pipework - Installation Helper Script

b2d-pipework - 固定IPアドレス持ちDockerコンテナ環境構築のためのヘルパースクリプト

 

Mac + boot2docker + pipework を導入するための一連の作業をシェルスクリプトにした。

たとえば、インストール処理は以下のような流れ。

  • Homebrew を利用して docker および boot2docker パッケージの最新版をインストール
  • あらかじめ作成した profile ファイルに従って boot2docker VM (VirtualBox) を作成
  • SSH鍵($HOME/.boot2docker/id_rsa)を新規作成し、boot2docker VM にパスワードなしでログイン可能に
  • boot2docker VM 内に最新版の pipework をインストール
  • 192.168.99.0/24 のアドレスで、VirtualBox ホストオンリーネットワークを構築

ドキュメントは今のところ日本語のみ。 

 

 

Related Posts

3.24.2014

Docker: How the networking of Mac + boot2docker + Pipework works

Docker: Mac + boot2docker + Pipework で構築した環境のネットワーク周りについて

 

自分自身の理解のためにネットワーク構成を可視化してみる。

 

環境

  • OS: Mac OS X 10.9 (Mavericks)
  • VirtualBox: 4.3.6
  • boot2docker: v0.7.0 (Docker 0.9.0 を含む)
  • jpetazzo/pipework (最終コミット: 2014-03-15 時点)

 

構成イメージ

 

1. boot2docker インストール直後

Docker の内部ネットワークとして 172.17.0.0/16 のIPアドレスが各コンテナに割り当てられるが、
静的なアドレスを指定することはできない。
また、Macから直接そのIPアドレスへは到達できないので、VirtualBox と Docker の二段階の
ポートフォワーディングを経由してアプリケーションへアクセスするのが一般的である。

コンテナ間通信可否については、Docker デーモンの -icc オプション、および
コンテナ起動時の --link オプションによって制御可能。

1

2-1. Pipework でブリッジを作成

boot2docker VM上で Pipework を実行し、各コンテナをブリッジインタフェース br1 に対応させたところ。
コンテナ内部に eth1 インタフェースが作成され、指定した IPアドレスが割り振られる。

これで固定のIPアドレスを使ったコンテナ間通信が可能になる。
ただし、boot2docker VM からそのアドレスへのアクセスはまだできない。

以下は、コンテナに 192.168.99.0/24 ネットワークのアドレスを割り当てる例。

2 1

2-2. ブリッジにIPアドレスを割り当てる

boot2docker VM 上で、ブリッジに接続するためのIPアドレスを割り振れば、
boot2docker VM から各コンテナに固定アドレスを使った接続が可能になる。

ただし、この方法では Mac から直接コンテナにアクセスすることはできない。

2 2

3-1. VirtualBox のホストオンリーアダプタを作成する

VirtualBox の機能でホストオンリーネットワークを作成し、boot2docker VM のアダプタにも静的なIPアドレスを
設定する。

これで、Mac から boot2docker VM へ固定のIPアドレスでアクセスできるようになる。

3 1

3-2. ホストオンリーアダプタに対して Pipework を実行する

さいごに、boot2docker のホストオンリーネットワーク用アダプタ eth1 に対して Pipework を実行する。
ブリッジインタフェース以外に対して Pipework を実行すると、macvlan ブリッジが設定されるようだ。 

このようなネットワーク構成であれば、もはや VirtualBox + Docker の多段ポートフォワーディングは必須でない。

3 2

 

 

 

Related Posts

 

References

3.23.2014

Docker: boot2docker SSH Login without Password

Docker: boot2docker VM にパスワード無しで SSH 接続する方法

 

通常の Linux サーバ同様、ssh-keygen コマンドで作ったキーペアの公開鍵をリモートサーバ上に置けば
boot2docker VM に対してもノンパスワードで接続できる。

ただし、例によって boot2docker を再起動しても設定が永続化されるようにするためには
少々の細工が必要となる。

 

作業手順

 

1. 秘密鍵、公開鍵のペアを作成

キーペアを新規に作成し、~/.boot2docker/id_rsa として保存する例。

Mac$ ssh-keygen -t rsa -f $HOME/.boot2docker/id_rsa

プロンプトが出るのでパスフレーズを2回入力。(空でもよい)

 

2. 公開鍵を boot2docker VM の中に置く

公開鍵を永続化するため、/home/docker などではなく、/var/lib/boot2docker/keys というディレクトリを作って
そこに配備することにする。

(ちなみに /var/lib/boot2docker/ssh という既存のディレクトリには sshd サーバの設定情報が保存されている)

Mac$ scp -P 2022 ~/.boot2docker/id_rsa.pub docker@localhost:
docker@localhost's password:    ### tcuser と入力
Mac$ boot2docker ssh
docker@localhost's password:    ### tcuser と入力
boot2docker$ sudo mkdir /var/lib/boot2docker/keys
boot2docker$ sudo mv -i ./id_rsa.pub /var/lib/boot2docker/keys/

 

3. VM起動時に実行されるシェルスクリプトを記述する

もちろん、このままではSSH鍵を使ったログインを行うことはできない。

以下にような内容の /var/lib/boot2docker/bootlocal.sh を作成して、authorized_keys ファイルを動的に生成する。
このシェルスクリプトはVM起動時に自動的に実行される。

boot2docker$ sudo vi /var/lib/boot2docker/bootlocal.sh
boot2docker$ cat /var/lib/boot2docker/bootlocal.sh
#!/bin/sh

mkdir -p /home/docker/.ssh
cat /var/lib/boot2docker/keys/*.pub > /home/docker/.ssh/authorized_keys
boot2docker$ sudo chmod +x /var/lib/boot2docker/bootlocal.sh
boot2docker$ exit

 

4. boot2docker の再起動と接続確認

これで、boot2docker を再起動し ssh コマンドに秘密鍵のパスを渡せば、
ノンパスワードでのログインができるはずだ。

Mac$ boot2docker restart
Mac$ boot2docker ssh -i ~/.boot2docker/id_rsa

問題が発生した場合は、boot2docker ssh -v コマンド(-vvv でも可)で調査。

 

作業シェル記述例

楽をするため、この一連の作業をシェルスクリプトで書く。

適当な作業ディレクトリで実行。

#!/bin/bash

KEY_NAME=id_rsa
PRIVATE_KEY=$HOME/.boot2docker/$KEY_NAME
PUBLIC_KEY=$PRIVATE_KEY.pub
BOOTLOCAL_TMP=/tmp/bootlocal.sh

# Create SSH key pair
if [[ ! -f $PRIVATE_KEY ]]; then
    mkdir -p $HOME/.boot2docker
    ssh-keygen -t rsa -f $PRIVATE_KEY
fi

# Create bootlocal.sh
cat <<EOF > $BOOTLOCAL_TMP
#!/bin/sh

mkdir -p /home/docker/.ssh
cat /var/lib/boot2docker/keys/*.pub > /home/docker/.ssh/authorized_keys
EOF

# Upload public key and bootlocal.sh to VM
boot2docker start
scp -P 2022 $PUBLIC_KEY $BOOTLOCAL_TMP docker@localhost:

# Install files in VM
boot2docker ssh sudo install -D -o root -g root -m 644 ./$KEY_NAME.pub /var/lib/boot2docker/keys/
boot2docker ssh sudo install -o root -g root -m 755 ./bootlocal.sh /var/lib/boot2docker/

# Clean bootlocal.sh
rm -f $BOOTLOCAL_TMP

# Restart boot2docker
boot2docker restart

途中でプロンプトが何回か出るので、その都度、手で入力すること。(改善の余地あり)

 

 

 

Related Posts

3.22.2014

How to Connect Directly to the Docker Container on boot2docker with Static IP Address

Docker: boot2docker 上の Docker コンテナに狙ったIPアドレスで直接接続する方法

 

boot2docker を導入した Mac OS 環境で {Mac, boot2docker VM, Dockerコンテナ} の三者を
同一のネットワークに所属させ、それぞれに対して固定IPアドレスでアクセスできるようにしたい。

ただし pipework の README にもあるように、闇雲にこの方式を採用するのはお勧めしない。

 

環境

  • OS: Mac OS X 10.9 (Mavericks)
  • VirtualBox: 4.3.6
  • boot2docker: v0.7.0 (Docker 0.9.0 を含む)
  • jpetazzo/pipework (作業手順の中でダウンロードする)

 

事前準備

  • boot2docker のセットアップ
    boot2docker ssh が実行できる状態となっていること。
  • Mac から docker コマンドが利用できること
    Docker クライアントがインストールされていて、環境変数 DOCKER_HOST が
    tcp://127.0.0.1:4243 のように設定されていること
  • IP アドレス/ネットワークの決定
    VirtualBox のホストオンリーネットワーク上に静的に設定するIPアドレスを決める。
    今回の例では以下のように設定。
    • Gateway: 192.168.99.1/24
    • boot2docker VM (Dockerホスト): 192.168.99.2/24
    • Dockerコンテナ1: 192.168.99.101/24
    • Dockerコンテナ2: 192.168.99.102/24

作業手順

コマンドはすべて Mac上で実行するべく記述している。

1. boot2docker VM 起動時処理の追加

boot2docker では、Docker の実行環境それ自体が Docker コンテナとして構築されている。
そのため、boot2docker ssh でネットワーク周りの設定をしても、boot2docker VM を再起動すると
設定が初期化されてしまう。

/var/lib/boot2docker/bootlocal.sh を作成すれば、VM(の中のコンテナ?)起動時にこのシェルが実行される。
永続化したい処理はここに書くのがセオリーだ。

  • boot2docker 起動
    $ boot2docker up
  • pipework 最新版のダウンロード
    $ boot2docker ssh " \
    sudo mkdir -p /var/lib/boot2docker/bin && \
    sudo curl -o /var/lib/boot2docker/bin/pipework https://raw.githubusercontent.com/jpetazzo/pipework/master/pipework && \
    sudo chmod +x /var/lib/boot2docker/bin/pipework"
    

    pipework の実行ファイル(実態はシェルスクリプト)を永続化対象の /var/lib/boot2docker/bin 配下に
    置き、VM 起動時に /usr/local/bin/pipework へシンボリックリンクを張る戦略。
  • bootlocal.sh の作成
    $ boot2docker ssh "sudo bash -c '
    echo -e \"ln -s /var/lib/boot2docker/bin/pipework /usr/local/bin/pipework
    \nip addr add 192.168.99.2/24 dev eth1
    \nip link set eth1 up\" > /var/lib/boot2docker/bootlocal.sh
    && chmod +x /var/lib/boot2docker/bootlocal.sh
    '"
    

    ここで、boot2docker VM のIPアドレスを指定する。

    実際の bootlocal.sh は以下のような内容になる。(shebang を付けたほうがいいかもしれない)

    ln -s /var/lib/boot2docker/bin/pipework /usr/local/bin/pipework
    ip addr add 192.168.99.2/24 dev eth1
    ip link set eth1 up

 

2. VirtualBox ホストオンリーアダプタの設定

VirtualBox の GUI でも操作可能だが、スクリプト化したいのでコマンドで実行してみる。

  • 目的に適したアダプタが既に存在するかどうか確認
    $ VBoxManage list -l hostonlyifs
    IPアドレス(192.168.99.1)、ネットワークマスク(255.255.255.0)が一致するものが存在していれば、
    そのアダプタを利用する。
  • アダプタが存在していなければ、新規作成
    $ VBoxManage hostonlyif create
    0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
    Interface 'vboxnet0' was successfully created
    $ VBoxManage hostonlyif ipconfig vboxnet0 --ip 192.168.99.1 --netmask 255.255.255.0
    $ VBoxManage list -l hostonlyifs
    
    表示されたインタフェース名に対して変更を施し、確認。
  • boot2docker 停止
    $ boot2docker stop
  • boot2docker VM にホストオンリーインタフェースを追加
    $ VBoxManage modifyvm boot2docker-vm --nic2 hostonly --hostonlyadapter2 vboxnet0
    $ VBoxManage modifyvm boot2docker-vm --nicpromisc2 allow-all
    先ほど作成したホストオンリーアダプタの名前(ここでは vboxnet0)を指定。
    nic1 は NATアダプタとして既に存在しているので、ここでは nic2 を作成する。
    Docker コンテナ間の通信を可能とするため、Promiscuous Mode の設定を変更する。
  • boot2docker 起動
    $ boot2docker up
  • 疎通確認
    $ ping 192.168.99.2
    $ ssh docker@192.168.99.2
    まずは boot2docker VM (Dockerホスト) に対して直接アクセスできるようになった。

 

3. コンテナの起動と pipework の実行

ここでは、CentOS 6.4 上で sshd が動くだけの Docker コンテナ (mogproject/sshd Repository | Docker Index) を
2つ立ち上げて、pipework の動作を確認してみる。

  • コンテナの起動
    $ CID1=$(docker run -d -t mogproject/sshd)
    $ CID2=$(docker run -d -t mogproject/sshd)
    $ docker ps
  • pipework の実行
    $ boot2docker ssh sudo pipework eth1 $CID1 192.168.99.101/24
    $ boot2docker ssh sudo pipework eth1 $CID2 192.168.99.102/24
    コンテナID と IPアドレスを指定し、boot2docker VM上のホストオンリーアダプタ(eth1)と対応付ける。
  • 疎通確認
    $ ping 192.168.99.101
    $ ping 192.168.99.102
    $ ssh ssh-user@192.168.99.101    ### パスワードも ssh-user
    [ssh-user@xxxxxxxxxxxx ~]$ ping 192.168.99.102
    [ssh-user@xxxxxxxxxxxx ~]$ exit
    $ ssh ssh-user@192.168.99.102
    [ssh-user@xxxxxxxxxxxx ~]$ ping 192.168.99.101
    [ssh-user@xxxxxxxxxxxx ~]$ exit
    
    Mac から Docker コンテナに直接アクセスできる。
    さらに、そのIPアドレスを使ってコンテナ間通信もできるようになった。

このように、pipework のおかげで Docker コンテナの活用の幅はますます広がりそうだ。

なお、pipework の設定は、コンテナが停止すると同時に削除される。

 

 

 

References

3.14.2014

Using Docker 0.9 in Mac

Mac で Docker 0.9 を使う

 

Mac 用に最適化された docker クライアントと boot2docker VM を使って Docker 0.9 環境を構築する。

2014-03-15 追記

すでに boot2docker が Docker 0.9 に対応された(Releases · boot2docker/boot2docker)ので
もはや下記手順は必要ない。

また、Homebrew でのインストールを半自動化するシェルを書いた。

 

環境

  • ホストOS: Mac OS X 10.9 (Mavericks)
  • VirtualBox: 4.3.6

 

事前準備

既に docker クライアントや boot2docker をインストールしてある場合は
不要な混乱を避けるため一旦削除しておく。

  • Homebrew でインストールした場合の例
$ brew install docker
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/docker-0.8.0.mavericks.bottle.tar.gz
Already downloaded: /Library/Caches/Homebrew/docker-0.8.0.mavericks.bottle.tar.gz
==> Pouring docker-0.8.0.mavericks.bottle.tar.gz
    /usr/local/Cellar/docker/0.8.0: 8 files, 18M
$ docker version
Client version: 0.8.0
Go version (client): go1.2
Git commit (client): cc3a8c8d8ec57e15b7b7316797132d770408ab1a

xxxx/xx/xx xx:xx:xx Can't connect to docker daemon. Is 'docker -d' running on this host?

現時点では、まだ 0.9 に対応していないようだった。

  • アンインストール
$ brew uninstall docker
$ brew uninstall boot2docker

 

手順

 

Docker OS X Client のインストール

以下の公式ドキュメントに従って作業。

適当な作業ディレクトリに移動して、シェルで以下のコマンドを実行する。
環境変数 DOCKER_HOST は今後も使い続けるのでシェルのrcスクリプトに書いておくと良い。

$ curl -o docker https://get.docker.io/builds/Darwin/x86_64/docker-latest
$ chmod +x docker
$ sudo mv -i docker /usr/local/bin/
$ export DOCKER_HOST=tcp://127.0.0.1:4243

確認

$ docker version
Client version: 0.9.0
Go version (client): go1.2.1
Git commit (client): 2b3fdf2
xxxx/xx/xx xx:xx:xx Cannot connect to the Docker daemon. Is 'docker -d' running on this host?

この時点ではサーバ接続が失敗する。

 

boot2docker のインストール

引き続き作業ディレクトリで実行。

$ curl https://raw.github.com/boot2docker/boot2docker/master/boot2docker > boot2docker
$ chmod +x ./boot2docker
$ sudo mv -i boot2docker /usr/local/bin/

起動とログイン

$ boot2docker init
$ boot2docker up
$ boot2docker ssh
docker@localhost's password:    <=== tcuser と入力
                        ##        .
                  ## ## ##       ==
               ## ## ## ##      ===
           /""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
           \______ o          __/
             \    \        __/
              \____\______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
boot2docker: 0.6.0
docker@boot2docker:~$ docker version
Client version: 0.8.1
Go version (client): go1.2
Git commit (client): a1598d1
Server version: 0.8.1
Git commit (server): a1598d1
Go version (server): go1.2
Last stable version: 0.9.0, please update docker

バージョン 0.8.1 だった。

  • SSHの問題が発生した場合は、「ssh -v -o StrictHostKeyChecking=no -o LogLevel=quiet -o UserKnownHostsFile=/dev/null -p 2022 docker@localhost」といったコマンドで原因調査。

/etc/ssh_config に以下のようにパスワード認証を優先する設定を追加することで改善する場合がある。

PreferredAuthentications password,gssapi-with-mic,hostbased,publickey,keyboard-interactive
  • boot2docker コマンドには、b2d などのエイリアスを付けると便利だと思う

 

boot2docker のビルド

現時点(2014-03-13)では、boot2docker は Docker 0.9 に対応していない。

Issue もあるので近日中に対応するものと思われるが、今回は練習も兼ねて
自分でisoファイルをビルドし直して最新化してみる。

boot2docker 自体が Docker を利用しているので、先ほど導入した古い boot2docker 環境でビルドを行う。

$ boot2docker up
$ boot2docker ssh
docker@boot2docker:~$ git clone https://github.com/boot2docker/boot2docker.git
docker@boot2docker:~$ cd boot2docker
docker@boot2docker:~/boot2docker$ docker pull boot2docker/boot2docker:base
docker@boot2docker:~/boot2docker$ docker build -t boot2docker --rm rootfs/

docker@boot2docker:~/boot2docker$ docker rm build-boot2docker    # 未作成ならエラーとなるが問題なし
docker@boot2docker:~/boot2docker$ docker run --privileged -name build-boot2docker boot2docker
docker@boot2docker:~/boot2docker$ sudo docker cp build-boot2docker:/boot2docker.iso .
docker@boot2docker:~/boot2docker$ exit

docker pull は長時間(数分〜数十分)を要する場合がある。
rootfs のビルドの過程で最新版の docker プログラムが取得される。

ISO ファイルが出来上がったら、Mac上にコピーしてくる。
boot2docker-docker-0.9.iso とリネームして保存するなら以下のようなコマンドだ。

$ scp -P 2022 docker@localhost:boot2docker/boot2docker.iso ~/.boot2docker/boot2docker-docker-0.9.iso

 

boot2docker VM の再作成

先ほど作成したVMは一旦削除。

$ boot2docker stop
$ boot2docker delete

boot2docker 用の profile ファイルを書くことで ISOファイルのパス、VMのメモリサイズなどを指定できる。
今回はISOのパス変更のほか、メモリ容量を 2GB に増やしてみた。

$ vi ~/.boot2docker/profile
$ cat ~/.boot2docker/profile
VM_MEM=2048
BOOT2DOCKER_ISO=${BOOT2DOCKER_CFG_DIR}/boot2docker-docker-0.9.iso

VM作成

$ boot2docker init
$ boot2docker up
$ docker version
Client version: 0.9.0
Go version (client): go1.2.1
Git commit (client): 2b3fdf2
Server version: 0.9.0
Git commit (server): 2b3fdf2
Go version (server): go1.2.1

無事、Docker 0.9 の環境が Mac + boot2docker で使えるようになった。

最後にポートフォワーディングの設定を実施。

$ boot2docker stop
$ for i in {49000..49900}; do
   VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port$i,tcp,,$i,,$i";
   VBoxManage modifyvm "boot2docker-vm" --natpf1 "udp-port$i,udp,,$i,,$i";
  done
$ boot2docker start

設定には数分かかる。

運用にあたっては、コンテナ起動時に各種サービスポートをVM上の 49000-49900 ポートとバインドさせる。
その後 Mac から localhost:49000-49900 へアクセスすれば、コンテナの内部へ接続することが可能となる。

 

 

References

 

Related Posts

3.02.2014

Mac: How to Upgrade to SciPy 0.13

Mac: SciPy のアップグレード

 

目的

過去に scipy 0.11.0 をインストールした Mac で、scipy.spatial.Voronoi などの新しめのライブラリを利用したい。

今回、scipy 0.13.3 にアップグレードするまでの過程をメモとして残しておく。

 

環境
  • OS: Mac OS X 10.9 (Mavericks)
  • Homebrew インストール済み
  • Python 2.7.5
  • pip インストール済み
  • scipy: 0.11.0 -> 0.13.3
$ pip show scipy
---
Name: scipy
Version: 0.11.0
Location: /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python
Requires:
$ python
Python 2.7.5 (default, Aug 25 2013, 00:04:04)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import scipy
>>> scipy.__version__
'0.11.0'
>>> from scipy.spatial import Voronoi
Traceback (most recent call last):
  File "", line 1, in
ImportError: cannot import name Voronoi
>>>

 

手順

愚直に sudo pip install --upgrade scipy コマンドを叩くと、以下のエラーとなった。

error: library dfftpack has Fortran sources but no Fortran compiler found

Fortran のコンパイラが必要らしい。

 

1. gFortran のインストール

Homebrew で Fortran コンパイラ、gFortran をインストール。

$ brew install gfortran
(略)
$ gfortran -v    ### 確認
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gfortran/4.8.2/gfortran/libexec/gcc/x86_64-apple-darwin13.0.0/4.8.2/lto-wrapper
Target: x86_64-apple-darwin13.0.0
Configured with: ../configure --prefix=/usr/local/Cellar/gfortran/4.8.2/gfortran --datarootdir=/usr/local/Cellar/gfortran/4.8.2/share --bindir=/usr/local/Cellar/gfortran/4.8.2/bin --enable-languages=fortran --with-system-zlib --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-cloog=/usr/local/opt/cloog --with-isl=/usr/local/opt/isl --disable-cloog-version-check --disable-isl-version-check --enable-checking=release --disable-stage1-checking --disable-libstdcxx --enable-lto --disable-nls --disable-multilib
Thread model: posix
gcc version 4.8.2 (GCC)

 

2. scipy のアップグレードインストール

これでビルドが行える状態になった。所要時間は10分程度。

$ sudo pip install --upgrade scipy
(略)
$ pip show scipy    ### 確認
---
Name: scipy
Version: 0.13.3
Location: /Library/Python/2.7/site-packages
Requires:

ところが、いざ python を使ってみるとバージョンが元のままである。

$ python -c 'import scipy; print(scipy.__version__)'
0.11.0

 

3. 旧バージョンのライブラリの退避

どうやらライブラリパスの関係で、旧バージョンの scipy が検出されている様子。

旧バージョンの scipy インストール先をディレクトリごと退避したら、新しいバージョンが無事使えるようになった。

$ sudo mv -i /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy /tmp/_OLD_scipy    ### 適宜削除
$ python -c 'import scipy; print(scipy.__version__)'
0.13.3

 

補足. Python3 対応

Python3 側は numpy、scipy ともに未導入だったので新規インストールを実施。

$ python3
Python 3.3.2 (default, Jan 13 2014, 17:04:15)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import scipy
Traceback (most recent call last):
  File "", line 1, in
ImportError: No module named 'scipy'
>>>
$ sudo pip3 install numpy
$ sudo pip3 install scipy
$ sudo ln -s /usr/X11/include/freetype2/freetype/ /usr/X11/include/freetype    ### 注1参照
$ sudo pip3 install matplotlib
$ python3 -c 'import scipy; print(scipy.__version__)'   ### バージョン確認
0.13.3

これで Python3 でも scipy 0.13.3 が使えるようになった。

 

注1) freetype のシンボリックリンクを作らないと、以下のエラーとなってしまった。

/usr/X11/include/ft2build.h:56:10: fatal error: 'freetype/config/ftheader.h' file not found

#include <freetype/config/ftheader.h>

         ^

1 warning and 1 error generated.

error: command 'clang' failed with exit status 1

(そもそも /usr/X11/include が存在しない場合には、「brew install freetype libpng」
「brew link --overwrite freetype」「xcode-select --install」といった準備が必要かもしれない)

 

 

 

References

1.06.2014

Vagrant: Creating CentOS 6.5 Docker Host

Vagrant: CentOS 6.5 Docker 母艦の建造

 

Vagrant 1.4 で Docker へのプロビジョニング対応 (Vagrant 1.4 - Vagrant) が行われたことで
ローカルマシン(VirtualBox)上での Docker ホストOS の構築はより一層簡単になった。

尚、Ubuntu ホストであればこちらの手順通り、公式リポジトリをそのまま使えばよい。

 

事前準備

 

環境
  • ローカルマシン: Mac OS X 10.9.1
    • Vagrant: 1.4.2 (確認は「vagrant -v」)
    • VirtualBox: 4.3.6
  • Docker ホスト (母艦): CentOS 6.5
    • Docker: 0.7.2 (確認は「docker -v」)
  • Docker コンテナ: CentOS 6.4

 

母艦の立ち上げ

基本的には適当なディレクトリに Vagrantfile を作成して、「vagrant up」するだけ。

Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "opscode-centos65"
  config.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box"

  config.vm.provider :virtualbox do |vb|
    vb.name = "docker1"
    vb.customize ["modifyvm", :id, "--memory", 1024]
  end

  config.vm.network :private_network, ip: "192.168.33.10"

  config.vm.provision :docker do |d|
    d.pull_images "centos:6.4"
  end
end
  • 8行目: OpsCode 提供の CentOS 6.5 box をダウンロードして利用
  • 11-12行目: VirtualBox の VM に docker1 という名前を付け、メモリを少し増やす
  • 15行目: Docker コンテナへ直接アクセスしたいので、静的アドレスを割り振った方が便利
    (ネットワークアドレスは VirtualBox の仮想ネットワークアダプタの設定に依存。
    デフォルトでは host-only ネットワークが 192.168.33.0/24 として構築されている)
  • 17-19行目: Docker のプロビジョニング設定。ここでは centos:6.4 のイメージを pull している。
    これを記述することで、Docker 自体のインストール、サービスへの登録が自動的に行われる。

 

仮想マシンの作成

単に「vagrant up」でもよいが、ゴミの消去も含めたシェルスクリプトを書いて実行した。

#!/bin/bash


### Clean.
vagrant destroy --force

### Create VirtualBox image and boot.
vagrant up

### Print status.
vagrant status

実行結果は以下のとおり。プロビジョニングの工程で Docker のインストールが行われている。

[default] VM not created. Moving on...
Bringing machine 'default' up with 'virtualbox' provider...
[default] Importing base box 'opscode-centos65'...
[default] Matching MAC address for NAT networking...
[default] Setting the name of the VM...
[default] Clearing any previously set forwarded ports...
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Running 'pre-boot' VM customizations...
[default] Booting VM...
[default] Waiting for machine to boot. This may take a few minutes...
[default] Machine booted and ready!
[default] Configuring and enabling network interfaces...
[default] Mounting shared folders...
[default] -- /vagrant
[default] Running provisioner: docker...
[default] Installing Docker (latest) onto machine...
[default] Pulling Docker images...
[default] -- Image: centos:6.4
Current machine states:

default                   running (virtualbox)

The VM is running. To stop this VM, you can run `vagrant halt` to
shut it down forcefully, or you can run `vagrant suspend` to simply
suspend the virtual machine. In either case, to restart it again,
simply run `vagrant up`.

ちなみに、vagrant-vbguest プラグインがインストールされている場合には以下のようなビルドエラーが発生した。

Building the OpenGL support module[FAILED]
(Look at /var/log/vboxadd-install.log to find out what went wrong)
Doing non-kernel setup of the Guest Additions[  OK  ]
Installing the Window System drivers[FAILED]
(Could not find the X.Org or XFree86 Window System.)
An error occurred during installation of VirtualBox Guest Additions 4.3.6. Some functionality may not work as intended.
In most cases it is OK that the "Window System drivers" installation failed.

X Window はインストールされていないので無視してよさそうだが、OpenGL のほうは少し気になる。

 

母艦への接続

「vagrant ssh」で母艦に接続した後、docker コンテナを立ち上げて
/etc/redhat-release ファイルの中身を参照してみた。

$ vagrant ssh
Last login: Thu Dec  5 05:57:05 2013 from 10.0.2.2
[vagrant@localhost ~]$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              6.4                 539c0211cd76        9 months ago        300.6 MB
[vagrant@localhost ~]$ sudo docker run centos:6.4 /bin/cat /etc/redhat-release
CentOS release 6.4 (Final)

Cent OS 6.4 のコンテナが起動したことが確認できた。

 

 

 

References

 

Related Posts

8.29.2013

Mac: How to Improve Your Performance with Alfred

Mac: Alfred 活用術

 

Alfred は、Mac を使うなら是非インストールしておきたいフリーソフト。

呼び出し用のキーバインド(私は option + SPACE に設定)を叩いた後、テキストを数文字打って
Enter を押すだけで様々なアプリケーション・OS機能を呼び出すことができる。

WEB のカスタムサーチは特に秀逸で、

  • 「ds キーワード」と打って Dash と連携させたり
  • 「r チケット番号」と打って Redmine のチケットを直接呼び出したり
    • Search URL: (ご利用中のRedmineのURL)/{query}
    • Keyword: r
  • 「a 英単語」または「a 日本語の単語」と打って アルク の和訳・英訳辞書を直接呼び出したり
    • Search URL: http://eow.alc.co.jp/search?q={query}
    • Keyword: a

することが可能だ。 

有料の PowerPack を使えば、より生産性が上がるらしいので目下検討中。

8.26.2013

Mac: How to Use Option as Meta Key in KeySnail

Mac: KeySnail で option キーを メタキーとして使う方法

 

Firefox の (主にEmacsユーザ向けの) キーボード・ブラウジング環境構築プラグイン KeySnail を使っている。

これを Mac 環境で使用したところ、option キーをメタキーとして使おうとしてもうまくいかず、
メタキーを使うキーバインドが一切動作しない状況に陥った。

試行錯誤の末、正しく動作するようになったのでその方法を記録しておく。

 

環境

  • Hardware: MacBook Air (USキーボード)
  • OS: OS X 10.8
  • Firefox: 23.0.1
  • KeySnail: 2.0.1

事象

デフォルト状態の KeySnail では、Altキー・Command キーの入力がメタキーとして解釈される。
keysnail/wiki/howto.ja.wiki at master · mooz/keysnail

Firefox では、Mac の optionキーが Altキーの働きと同等となるので、
optionキーを使ってメタキーのキーバインド (M-w, M-x など) ができると期待した。

(Command キーをメタキーとして扱うのは違和感があるのであまり使いたくない。) 

ところが optionキーを使ったメタキー操作は全く動作しない。

  • control と option を同時に押した時のキーバインドは正しく動作する。(C-M-r など)
  • C-q でエスケープしたあとに option+x などと入力しても、表示されるのは「null」

 

原因

OS X では (デフォルト状態では)、option キーを押しながら他のキーを入力すると特殊文字(å∫ç∂...)の入力が
行われる。

これらのキーを押下したときのイベントでは event.altKey が true にならないので
メタキーかどうかを判定する key.isMetaKey 関数を素通りしてしまう。

 

対応方法

key.keyEventToString 関数をフックして、イベントを特定するための文字列を書き換えればそれなりに動くようだ。

charCode を取得し、特殊文字 かどうかを判定した上で "M-" で始まる文字列に置換する。
(例えば、∑ (charCode=8721) が入力されたらなら "M-w" に置き換える)

このような処理を行う option-as-meta というプラグインが既に存在していたので、それをそのまま利用する。

これで optionキーをメタキーとして使えるようになった。

 

補足

optionキーではなく ESCキーをメタキーとして使用したいのであれば、「Metaplus」プラグインを利用するのが
最も確実な方法と思われる。

Plugin · mooz/keysnail Wiki