読者です 読者をやめる 読者になる 読者になる

$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

Dockerで立てたコンテナにsshで接続する

tech operation

 最近Dockerをちょっと触っていて、とりあえずDockerでコンテナを立ててsshでつなぐということをやってみた。

Dockerを入れる

macだとDockerが入っているvagrant環境があるのでそれを落としてくる。
http://docs.docker.io/en/latest/installation/vagrant/

$ git clone https://github.com/dotcloud/docker.git
$ cd docker
$ vagrant up

これでDockerが動くvagrant環境が出来た。今後の作業はこのvagrantにsshした状態で行う。

$ vagrant ssh

sshdが起動したコンテナにつなぐ

 http://docs.docker.io/en/latest/examples/running_ssh_service/ この辺を参考に。

 まずsshdが入っているコンテナを取ってきて、sshdを立てたコンテナを作る。

$ docker pull dhrp/sshd
$ docker run -d -p 22 dhrp/sshd /usr/sbin/sshd -D

 docker runに-pをつけると指定したportへのport forwardをしてくれる。Dockerのコンテナを立てる時は一つフォアグラウンドで動いているジョブがないとコンテナが消えてしまうので、sshd -Dしてフォアグラウンドで動かす。

 あとはここに対してsshする。port forwardingの状況はdocker psすると分かる。

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                   NAMES
a81ce161b769        dhrp/sshd:latest    /usr/sbin/sshd -D   6 seconds ago       Up 6 seconds        0.0.0.0:49154->22/tcp   angry_pare
$ ssh 127.0.0.1 -p 49154

 これで普通にDockerで立てたコンテナにSSHできるようになった。ここまでは簡単。

port forwardingせずに接続

 これport forwardingせずに接続できるんかなと思ったら普通に出来た。まず-pオプションを抜いて起動する。

$ docker run -d dhrp/sshd /usr/sbin/sshd -D

 port forwardingされていない。

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
5ce88edee4d2        dhrp/sshd:latest    /usr/sbin/sshd -D   2 seconds ago       Up 2 seconds                            angry_fermat

 docker inspectすると内部情報がいろいろわかり、ここでIPも分かる。

$ docker inspect 5ce88edee4d2
# ...
    "NetworkSettings": {
        "IPAddress": "172.17.0.9",
        "IPPrefixLen": 16,
        "Gateway": "172.17.42.1",
        "Bridge": "docker0",
        "PortMapping": null,
        "Ports": {}
    },
# ...

 あとはここに直接接続。

$ ssh 172.17.0.9

vagrantの外からdockerのコンテナのsshdにつなぐ

 これやってみたかったけど、やり方分からなかったので、何勉強したら分かるようになるか知りたい。

(12/8 12:30 追記)
いろいろ調べてみたらいくつか方法ありそうだった。

vagrantからmacにport forwardして繋ぐ

mac -> vagrant -> dockerと二段port forwardingする。実はこれはdockerのVagrantfileを見ると環境変数を立てるとport forwardしてくれるようになっていた。https://github.com/dotcloud/docker/blob/master/Vagrantfile#L163..L175

というわけで

$ FORWARD_DOCKER_PORTS=1 vagrant up

して、vagrant内でsshd起動。

$ vagrant ssh
$ docker run -d -p 22 dhrp/sshd /usr/sbin/sshd -D
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                   NAMES
677f9dd2576f        dhrp/sshd:latest    /usr/sbin/sshd -D   28 minutes ago      Up About a minute   0.0.0.0:49153->22/tcp   backstabbing_babbage

この時点でlocalhostの49153 portは、vagrantの49153にport forwardされ、さらにdockerコンテナの22にport forwardされる。なので繋ぐには

$ ssh 127.0.0.1 -p 49153

vagrantにprivate IPを割り振る

macにport forwardしたくない時はvagrantにprivate IPを割り当ててしまうと良い。以下の様な設定をVagrantfileに書くとprivate IPが付く。

Vagrant.configure("2") do |config|
  config.vm.network "private_network", ip: '192.168.50.5'
end

あとはvagrant up後にこのIPに対してsshする。

$ ssh 192.168.50.5 -p 49153

dockerコンテナにglobal IPを割り振る

 最終的にはdockerコンテナにprivateネットワーク内からはどこからでも接続できるprivate IPを割り当てられると良いと思うんだけど、これは勉強不足でどうすればいいかわからない。https://github.com/jpetazzo/pipework あたりを勉強するとできるのかもしれない。

https://github.com/jpetazzo/pipework

やりとり








まとめ

 とりあえずDockerの基本みたいなところをやった。imageを作っておくと1秒かからずに起動するというのは非常にお手軽で良い感じだった。