虚無ありき

うるせーーーしらねーーー

CWL(CommonWorkflowLanguage) の NetworkAccess について

tl;dr

  • cwltool が生成する docker container の中から、host の network にアクセスしたいケースがあった
    • ローカルファイルサーバのファイルを取ってくるケースなど
  • cwltool により docker run の command が生成されるため色々辛い
  • cwlVersion v1.1.0 から実装される NetworkAccess を使ってなんとかする

Environment

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.6 LTS
Release:    16.04
Codename:   xenial
$ docker --version
Docker version 18.09.5, build e8ff056
$ python3 -V
Python 3.5.2
$ cwltool --version
/usr/local/bin/cwltool 1.0.20190228155703

Docker Use Host Network

Docker Docs - Use host networking

  • コンテナにホストネットワークドライバーを接続する
    • Linux のみで動作し、Docker for Mac や Docker for Windows では動作しない
    • docker run 時に --net=host をつける
    • /etc/hosts なども host のものを使うことが出来る

試しにやってみる、まずローカルサーバを立てておく。

$ pwd
/home/ubuntu/cwltool-net-test
$ ls
memo.md  net-test.cwl
$ python3 -m http.server --bind localhost 8000 > /dev/null 2>&1 &
[1] 2409
$ curl  -fsSL localhost:8000/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href="memo.md">memo.md</a></li>
<li><a href="net-test.cwl">net-test.cwl</a></li>
</ul>
<hr>
</body>
</html>

まずは、--net=host を付けない場合、

$ docker run --rm appropriate/curl curl -fsSL localhost:8000/
curl: (7) Failed to connect to localhost port 8000: Connection refused

次に、--net=host を付けた場合、

$ docker run --rm --net=host appropriate/curl curl -fsSL localhost:8000/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href="memo.md">memo.md</a></li>
<li><a href="net-test.cwl">net-test.cwl</a></li>
</ul>
<hr>
</body>
</html>

host に立てた server から取得できた。

CWL NetworkAccess

5.15 NetworkAccess

Indicate whether a process requires outgoing IPv4/IPv6 network access. Choice of IPv4 or IPv6 is implementation and site specific, correct tools must support both.

If networkAccess is false or not specified, tools must not assume network access, except for localhost (the loopback device).

If networkAccess is true, the tool must be able to make outgoing connections to network resources. Resources may be on a private subnet or the public Internet. However, implementations and sites may apply their own security policies to restrict what is accessible by the tool.

Enabling network access does not imply a publically routable IP address or the ability to accept inbound connections.

とのこと。

また、CWL の標準処理系である cwltool の help によると、

$ cwltool --help | grep net
  --custom-net CUSTOM_NET
                        Passed to `docker run` as the '--net' parameter when

という Option が存在している。

つまり、cwl file に NetworkAccess を追加し、 --custome-net host Option を渡せば、host の network にアクセスできる。


まず、失敗するケースの cwl command line tool を書いた。

class: CommandLineTool
cwlVersion: v1.0
requirements:
  DockerRequirement:
    dockerPull: appropriate/curl:latest
baseCommand: curl
arguments:
  - "-fsSL"
  - "localhost:8000"
inputs: []
outputs: []

これを実行すると、

$ cwltool net-test.cwl
/usr/local/bin/cwltool 1.0.20190228155703
Resolved 'net-test.cwl' to 'file:///home/ubuntu/cwltool-net-test/net-test.cwl'
[job net-test.cwl] /tmp/c2q72jah$ docker \
    run \
    -i \
    --volume=/tmp/c2q72jah:/IGKaZw:rw \
    --volume=/tmp/4p2_8ny2:/tmp:rw \
    --workdir=/IGKaZw \
    --read-only=true \
    --user=1000:1000 \
    --rm \
    --env=TMPDIR=/tmp \
    --env=HOME=/IGKaZw \
    --cidfile=/tmp/fa6lf9vt/20190425050648-304775.cid \
    appropriate/curl:latest \
    curl \
    -fsSL \
    localhost:8000
curl: (7) Failed to connect to localhost port 8000: Connection refused
[job net-test.cwl] Max memory used: 0MiB
[job net-test.cwl] completed permanentFail
{}
Final process status is permanentFail

失敗している。


次に、NetworkAccess を追加する。この際、 cwlVersionv1.1.0-dev1 になる。

class: CommandLineTool
cwlVersion: v1.1.0-dev1
requirements:
  DockerRequirement:
    dockerPull: appropriate/curl:latest
  NetworkAccess:
    networkAccess: true
baseCommand: curl
arguments:
  - "-fsSL"
  - "localhost:8000"
inputs: []
outputs: []

これで、cwltool に --custom-net host Option を渡し実行してみる。

この際、cwlVersion: v1.1.0-dev1 を用いているため、--enable-dev Option も渡さなければならない。

$ cwltool --enable-dev --custom-net host net-test.cwl
/usr/local/bin/cwltool 1.0.20190228155703
Resolved 'net-test.cwl' to 'file:///home/ubuntu/cwltool-net-test/net-test.cwl'
[job net-test.cwl] /tmp/q1z2jsai$ docker \
    run \
    -i \
    --volume=/tmp/q1z2jsai:/qfcEJr:rw \
    --volume=/tmp/5h6avo69:/tmp:rw \
    --workdir=/qfcEJr \
    --read-only=true \
    --net=host \
    --user=1000:1000 \
    --rm \
    --env=TMPDIR=/tmp \
    --env=HOME=/qfcEJr \
    --cidfile=/tmp/d2vdphx0/20190425051126-429824.cid \
    appropriate/curl:latest \
    curl \
    -fsSL \
    localhost:8000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href="memo.md">memo.md</a></li>
<li><a href="net-test.cwl">net-test.cwl</a></li>
</ul>
<hr>
</body>
</html>
[job net-test.cwl] Max memory used: 0MiB
[job net-test.cwl] completed success
{}
Final process status is success

出来た。

ちゃんと --net=host が追加されている。

Summary

  • cwltool に --net=host, --enable-dev Option を渡す
  • cwl file の cwlVersionv1.1.0-dev1 にして、NetworkAccess を追加する