2014年4月29日火曜日

Golang Cafe #27を開催しました。

Golang Cafe #27を開催しました。

今回も前回に引き続き、Dockerのソースコードを読み進めました。

前回は、クライアントでのコマンド実行のところまで読んだので、今回は、docker runコマンドの実行部分を読んでみました。

該当の場所は、api/client/command.goの1776行目にある、

func (cli *DockerCli) CmdRun(args ...string) error {

からとなります。

処理の概要は

  1. コマンドの解析(ParseSubCommand)
  2. ContainerIDFileが存在しなければ、ContainerIDFileを生成する。
    1. ただし、ホストの設定(hostConfig)で指定されている場合のみ。
    2. ContainerIDFileは最後に削除する。
  3. cli.call("POST", "/containers/create?")で、デーモン側にコンテナの作成を指示。
    1. ファイルがない(httpのレスポンスが404の時)時は、コンテナImageがないので、imageを作成を指示する。(これも、cli.call())
  4. コンテナの作成の結果を受け取る。
  5. コンテナにattach(cli.hijack("/containers/"+runResult.Get("Id")+"/attach?"))
  6. コンテナの開始(cli.call("/containers/"+runResult.Get("Id")+"/start"))
  7. 結果を取得
結局クライアントからはデーモンに向かってプロセス通信しているだけで、何も処理がありませんでしたので、デーモン側の処理を読むことで、コンテナの配置とか、処理の実行の部分の理解を深めることができそうです。

デーモンはいつ起動させるのか?
Ubuntuだと、サービスとしてPC起動時に起動してしまうようです。また、Macだと、boot2dockerを使ってサービスを起動させた状態で使っています。
Windowsだとどうやら無理みたいですw(中身をみると、syscallをバリバリ使っているので、Windowsとは相性が悪そうです…。)

さて、細かい処理を(複雑で時間がかかるので)見ていないのですが、処理の概要は読めました。

今回のポイントですが、プロセス通信をする時に中身では、httpを使っています。
標準パッケージのnet/http/httputilを使って、http通信をしていました。

httputil.ClientConnを使ったリクエストを行う場合、net.Connを自分で指定させるため、Socketを自分で作ります。今回は、Unixドメインソケットだったり、tcpソケットだったりするわけです。(Macだと-Hオプションで指定したURL(私の環境だとtcp://localhost:[Port])を使ってソケットを生成されるようです)

よく考えると、これまでnet/http周りはじっくり読むということをしていなかったので、またのタイミングで読みたいと思います。

ということで、次回はデーモン側のソースコードを読む予定です。