Dockerコンテナ上のプロセスにstraceでアタッチする

## この文章について

Dockerコンテナ上で実行するor実行中のプロセスを `strace` コマンドでトレース・アタッチする方法を説明します。

デバッグや、パフォーマンス測定時に利用してみてください。

**注意**: セキュリティレベルが低下するので、本番機など外部にさらされるコンテナへの実行は行わないでください。あくまで外部から隔離された環境のみとしてください。

筆者の環境

- Docker for Mac 17.03.1-ce-mac12 (17661)
- macOS 10.11.6

## はじめに

Dockerコンテナ上で動くプロセスは、そのままですと `strace` コマンドが正常に動作しません。Dockerコンテナ起動時のオプションを追加する必要があります。

例えば、なにもしないと、次のエラーメッセージが表示され、コンテナ上のプロセスをアタッチすることができません。

```
# ps auxwwf | grep httpd
root        29  0.0  0.0 103368  2108 ?        D+   21:43   0:00  \_ grep httpd
root         1  0.0  0.7 867740 46684 ?        Ss   20:35   0:00 /usr/sbin/httpd -DFOREGROUND
apache       5  0.0  0.1 867740  8560 ?        S    20:35   0:00 /usr/sbin/httpd -DFOREGROUND
apache       6  0.0  0.1 867740  8560 ?        S    20:35   0:00 /usr/sbin/httpd -DFOREGROUND
apache       7  0.0  0.1 867740  8560 ?        S    20:35   0:00 /usr/sbin/httpd -DFOREGROUND
apache       8  0.0  0.1 867740  8560 ?        S    20:35   0:00 /usr/sbin/httpd -DFOREGROUND
apache       9  0.0  0.1 867740  8560 ?        S    20:35   0:00 /usr/sbin/httpd -DFOREGROUND
apache      10  0.0  0.1 867740  8560 ?        S    20:35   0:00 /usr/sbin/httpd -DFOREGROUND
apache      11  0.0  0.1 867740  8560 ?        S    20:35   0:00 /usr/sbin/httpd -DFOREGROUND
apache      12  0.0  0.1 867740  8560 ?        S    20:35   0:00 /usr/sbin/httpd -DFOREGROUND
# strace -p 5
strace: test_ptrace_setoptions_for_all: PTRACE_TRACEME doesn't work: Operation not permitted
strace: test_ptrace_setoptions_for_all: unexpected exit status 1
```

## アタッチ可能にするための起動方法

### コマンド

```
docker run -i -t --cap-add=SYS_PTRACE --security-opt="seccomp=unconfined" [CONTAINER_NAME] /bin/bash
```

`--cap-add=SYS_PTRACE` と `--security-opt="seccomp=unconfined"` が増えています。

### Docker Composeを使っている場合

`docker-compose.yml` に定義を書き足します。

```
version: '2'
services:
  (snip)
  webserver:
    image: hogehoge
    volumes:
      - (snip)
    environment:
      - (snip)
    depends_on:
      - (snip)
    cap_add:
      - SYS_PTRACE
    security_opt:
      - seccomp:unconfined
```

各コンテナの定義の末尾に `cap_add` と `security_opt` の設定を加筆し、コンテナを起動します。既に起動している場合は一度停止させてください。

## そしてアタッチ

```
# ps auxwwf | grep httpd
root       144  0.0  0.0 103368  2088 ?        S+   21:44   0:00  \_ grep httpd
root         1  0.0  0.7 867740 46692 ?        Ss   20:35   0:00 /usr/sbin/httpd -DFOREGROUND
apache       5  0.3  0.8 986776 54444 ?        S    20:35   0:13 /usr/sbin/httpd -DFOREGROUND
apache       6  0.2  0.7 971860 43128 ?        S    20:35   0:09 /usr/sbin/httpd -DFOREGROUND
apache       7  0.1  0.7 971880 46208 ?        S    20:35   0:07 /usr/sbin/httpd -DFOREGROUND
apache       8  0.1  0.7 971856 42884 ?        S    20:35   0:04 /usr/sbin/httpd -DFOREGROUND
apache       9  0.1  0.7 971972 43100 ?        S    20:35   0:05 /usr/sbin/httpd -DFOREGROUND
apache      10  0.1  0.7 970400 44436 ?        S    20:35   0:05 /usr/sbin/httpd -DFOREGROUND
apache      11  0.1  0.6 970472 39508 ?        S    20:35   0:06 /usr/sbin/httpd -DFOREGROUND
apache      12  0.1  0.6 971860 41532 ?        S    20:35   0:05 /usr/sbin/httpd -DFOREGROUND
# strace -p 5
Process 5 attached
(snip)
# strace -tt -p 5 -e trace=file,close,write -o /tmp/strace.log
(ログが出力されることを確認)
```

めでたしめでたし。

## Refrences

* https://docs.docker.com/engine/security/seccomp/
* https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
* https://docs.docker.com/compose/compose-file/
* http://qiita.com/muddydixon/items/d2982ab0846002bf3ea8