docker コマンドが発行するリクエスト

# はじめに
普段意識しませんが、docker コマンドや kubectl コマンドは、API サービスに対し HTTP リクエストを投げています。
今回は何気なく実行している docker コマンドのリクエストの中身を興味本位で見てみました。

# 環境構成
OS：ubuntu 18.04.5
docker-ce：20.10.2

# 前準備
通常は UNIX ドメインソケットで通信を行っているため、今回は TCP の設定を追加します。
docker-ce をインストールした状態で、設定ファイルを変更します。

```shell-session
# 起動オプションを追加
$ vim /lib/systemd/system/docker.service

変更前：ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
変更後：ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://127.0.0.1

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
```

# docker info のリクエストを見てみる
docker コマンドでリクエストを発行してたところを、
tcpdump 使ってリクエストの中身を見てみます。

```shell-session
# -i：インタフェースの設定（any：全てのNIC）
# -A：受信したパケットを ASCII で表示
$ sudo tcpdump -i any port 2375 -A
```

別のターミナルを起動して、docker コマンドを実行します。

```shell-session
# リクエスト先をオプションで追加
# サブコマンド(今回の場合は info )の前で、接続先指定のオプションを指定すること
$ docker -H tcp://127.0.0.1:2375 info
Client:
 Context:    default
 Debug Mode: false
・・・
Server:
 Containers: 1
  Running: 0
  Paused: 0
  Stopped: 1
 Images: 1
 Server Version: 20.10.2
 Storage Driver: overlay2
・・・
WARNING: No swap limit support
```

警告は出ましたが、結果がちゃんと返ってきました。
tcpdump を実行していたターミナルを見てみましょう。
※SYN/FINなどを除外して、抜粋しています

```
05:16:44.346065 IP localhost.34928 > localhost.2375: Flags [P.], seq 1:90, ack 1, win 512, options [nop,nop,TS val 1763342899 ecr 1763342899], length 89
E...|.@.@............p  G+[..Q8.............
i.z3i.z3HEAD /_ping HTTP/1.1
Host: 127.0.0.1:2375
User-Agent: Docker-Client/20.10.2 (linux)


05:16:44.352702 IP localhost.2375 > localhost.34928: Flags [P.], seq 281:3193, ack 183, win 512, options [nop,nop,TS val 1763342906 ecr 1763342900], length 2912
E.....@.@.W.........    G.pQ8..+[...... ......
i.z:i.z4HTTP/1.1 200 OK
Api-Version: 1.41
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/20.10.2 (linux)
Date: Sat, 09 Jan 2021 05:16:44 GMT
Transfer-Encoding: chunked

a82
{"ID":"K5WR:OGR6:DCUW:U6FT:IVPQ:XZGL:VZRO:I2AS:6XFP:CPES:DKDE:5C6E","Containers":1,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":1,"Images":1,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","ipvlan","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","local","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":false,"KernelMemory":true,"KernelMemoryTCP":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":true,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":false,"NFd":23,"OomKillDisable":true,"NGoroutines":34,"SystemTime":"2021-01-09T05:16:44.346767868Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","CgroupVersion":"1","NEventsListener":0,"KernelVersion":"4.15.0-124-generic","OperatingSystem":"Ubuntu 18.04.5 LTS","OSVersion":"18.04","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":[],"AllowNondistributableArtifactsHostnames":[],"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":[],"Secure":true,"Official":true}},"Mirrors":[]},"NCPU":2,"MemTotal":4136148992,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"ubuntu","Labels":[],"ExperimentalBuild":false,"ServerVersion":"20.10.2","Runtimes":{"io.containerd.runc.v2":{"path":"runc"},"io.containerd.runtime.v1.linux":{"path":"runc"},"runc":{"path":"runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"269548fa27e0089a8b8278fc4fc781d7f65a939b","Expected":"269548fa27e0089a8b8278fc4fc781d7f65a939b"},"RuncCommit":{"ID":"ff819c7e9184c13b7c2607fe6c30ae19403a7aff","Expected":"ff819c7e9184c13b7c2607fe6c30ae19403a7aff"},"InitCommit":{"ID":"de40ad0","Expected":"de40ad0"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"Warnings":["WARNING: API is accessible on http://127.0.0.1:2375 without encryption.\n         Access to the remote API is equivalent to root access on the host. Refer\n         to the 'Docker daemon attack surface' section in the documentation for\n         more information: https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface","WARNING: No swap limit support"]}

0
```

ちょっと整形して見やすくすると、

```
# docker クライアント（localhsot:34928） から docker サービス（localhst:2375）にリクエストを受信
# HTTP の HEAD メソッドで /_ping にリクエスト
05:16:44.346065 IP localhost.34928 > localhost.2375: Flags [P.], seq 1:90, ack 1, win 512, options [nop,nop,TS val 1763342899 ecr 1763342899], length 89
HEAD /_ping HTTP/1.1
Host: 127.0.0.1:2375
User-Agent: Docker-Client/20.10.2 (linux)

# docker サービス（localhst:2375） から docker クライアント（localhsot:34928）にレスポンスを受信
# HTTP ステータスコード 200 と json のデータを受信
05:16:44.352702 IP localhost.2375 > localhost.34928: Flags [P.], seq 281:3193, ack 183, win 512, options [nop,nop,TS val 1763342906 ecr 1763342900], length 2912
HTTP/1.1 200 OK
Api-Version: 1.41
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/20.10.2 (linux)
Date: Sat, 09 Jan 2021 05:16:44 GMT
Transfer-Encoding: chunked
{"ID":"K5WR:OGR6:DCUW:U6FT:IVPQ:XZGL:VZRO:I2AS:6XFP:CPES:DKDE:5C6E","Containers":1,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":1,"Images":1,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","ipvlan","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","local","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":false,"KernelMemory":true,"KernelMemoryTCP":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":true,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":false,"NFd":23,"OomKillDisable":true,"NGoroutines":34,"SystemTime":"2021-01-09T05:16:44.346767868Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","CgroupVersion":"1","NEventsListener":0,"KernelVersion":"4.15.0-124-generic","OperatingSystem":"Ubuntu 18.04.5 LTS","OSVersion":"18.04","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":[],"AllowNondistributableArtifactsHostnames":[],"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":[],"Secure":true,"Official":true}},"Mirrors":[]},"NCPU":2,"MemTotal":4136148992,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"ubuntu","Labels":[],"ExperimentalBuild":false,"ServerVersion":"20.10.2","Runtimes":{"io.containerd.runc.v2":{"path":"runc"},"io.containerd.runtime.v1.linux":{"path":"runc"},"runc":{"path":"runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"269548fa27e0089a8b8278fc4fc781d7f65a939b","Expected":"269548fa27e0089a8b8278fc4fc781d7f65a939b"},"RuncCommit":{"ID":"ff819c7e9184c13b7c2607fe6c30ae19403a7aff","Expected":"ff819c7e9184c13b7c2607fe6c30ae19403a7aff"},"InitCommit":{"ID":"de40ad0","Expected":"de40ad0"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"Warnings":["WARNING: API is accessible on http://127.0.0.1:2375 without encryption.\n         Access to the remote API is equivalent to root access on the host. Refer\n         to the 'Docker daemon attack surface' section in the documentation for\n         more information: https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface","WARNING: No swap limit support"]}
```

```json:整形したjson
{
   "ID":"K5WR:OGR6:DCUW:U6FT:IVPQ:XZGL:VZRO:I2AS:6XFP:CPES:DKDE:5C6E",
   "Containers":1,
   "ContainersRunning":0,
   "ContainersPaused":0,
   "ContainersStopped":1,
   "Images":1,
   "Driver":"overlay2",
   "DriverStatus":[
      [
         "Backing Filesystem",
         "extfs"
      ],
      [
         "Supports d_type",
         "true"
      ],
      [
         "Native Overlay Diff",
         "true"
      ]
   ],
   "Plugins":{
      "Volume":[
         "local"
      ],
      "Network":[
         "bridge",
         "host",
         "ipvlan",
         "macvlan",
         "null",
         "overlay"
      ],
      "Authorization":null,
      "Log":[
         "awslogs",
         "fluentd",
         "gcplogs",
         "gelf",
         "journald",
         "json-file",
         "local",
         "logentries",
         "splunk",
         "syslog"
      ]
   },
   "MemoryLimit":true,
   "SwapLimit":false,
   "KernelMemory":true,
   "KernelMemoryTCP":true,
   "CpuCfsPeriod":true,
   "CpuCfsQuota":true,
   "CPUShares":true,
   "CPUSet":true,
   "PidsLimit":true,
   "IPv4Forwarding":true,
   "BridgeNfIptables":true,
   "BridgeNfIp6tables":true,
   "Debug":false,
   "NFd":23,
   "OomKillDisable":true,
   "NGoroutines":34,
   "SystemTime":"2021-01-09T05:16:44.346767868Z",
   "LoggingDriver":"json-file",
   "CgroupDriver":"cgroupfs",
   "CgroupVersion":"1",
   "NEventsListener":0,
   "KernelVersion":"4.15.0-124-generic",
   "OperatingSystem":"Ubuntu 18.04.5 LTS",
   "OSVersion":"18.04",
   "OSType":"linux",
   "Architecture":"x86_64",
   "IndexServerAddress":"https://index.docker.io/v1/",
   "RegistryConfig":{
      "AllowNondistributableArtifactsCIDRs":[
         
      ],
      "AllowNondistributableArtifactsHostnames":[
         
      ],
      "InsecureRegistryCIDRs":[
         "127.0.0.0/8"
      ],
      "IndexConfigs":{
         "docker.io":{
            "Name":"docker.io",
            "Mirrors":[
               
            ],
            "Secure":true,
            "Official":true
         }
      },
      "Mirrors":[
         
      ]
   },
   "NCPU":2,
   "MemTotal":4136148992,
   "GenericResources":null,
   "DockerRootDir":"/var/lib/docker",
   "HttpProxy":"",
   "HttpsProxy":"",
   "NoProxy":"",
   "Name":"ubuntu",
   "Labels":[
      
   ],
   "ExperimentalBuild":false,
   "ServerVersion":"20.10.2",
   "Runtimes":{
      "io.containerd.runc.v2":{
         "path":"runc"
      },
      "io.containerd.runtime.v1.linux":{
         "path":"runc"
      },
      "runc":{
         "path":"runc"
      }
   },
   "DefaultRuntime":"runc",
   "Swarm":{
      "NodeID":"",
      "NodeAddr":"",
      "LocalNodeState":"inactive",
      "ControlAvailable":false,
      "Error":"",
      "RemoteManagers":null
   },
   "LiveRestoreEnabled":false,
   "Isolation":"",
   "InitBinary":"docker-init",
   "ContainerdCommit":{
      "ID":"269548fa27e0089a8b8278fc4fc781d7f65a939b",
      "Expected":"269548fa27e0089a8b8278fc4fc781d7f65a939b"
   },
   "RuncCommit":{
      "ID":"ff819c7e9184c13b7c2607fe6c30ae19403a7aff",
      "Expected":"ff819c7e9184c13b7c2607fe6c30ae19403a7aff"
   },
   "InitCommit":{
      "ID":"de40ad0",
      "Expected":"de40ad0"
   },
   "SecurityOptions":[
      "name=apparmor",
      "name=seccomp,profile=default"
   ],
   "Warnings":[
      "WARNING: API is accessible on http://127.0.0.1:2375 without encryption.\n         Access to the remote API is equivalent to root access on the host. Refer\n         to the 'Docker daemon attack surface' section in the documentation for\n         more information: https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface",
      "WARNING: No swap limit support"
   ]
}
```

HTTP の HEAD メソッドで /_ping にリクエストを発行し、レスポンスが 200 OK で json データが返却されているのがわかります。
docker コマンドは レスポンスの json データを整形し、出力しているのが分かります。

# docker run

今度は ```docker run``` コマンドでコンテナを起動してみましょう。

```
$ docker -H tcp://localhost:2375 run --name alpine -itd alpine /bin/sh
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
801bfaa63ef2: Pull complete
Digest: sha256:3c7497bf0c7af93428242d6176e8f7905f2201d8fc5861f45be7a346b5f23436
Status: Downloaded newer image for alpine:latest
3733e8696b64ed2207d2b10ffe566dc562309a108b91a2e13278a8d749dcc98e
```

tcpdump の結果は以下のとおりです。
※見やすいように整形しています。

```
# HEAD で「/_ping」をリクエスト
05:37:59.128874 IP localhost.34930 > localhost.2375: Flags [P.], seq 1:90, ack 1, win 512, options [nop,nop,TS val 1764617682 ecr 1764617682], length 89
HEAD /_ping HTTP/1.1
Host: localhost:2375
User-Agent: Docker-Client/20.10.2 (linux)

# 200 OK を受信
05:37:59.129029 IP localhost.2375 > localhost.34930: Flags [P.], seq 1:281, ack 90, win 512, options [nop,nop,TS val 1764617682 ecr 1764617682], length 280
HTTP/1.1 200 OK
Api-Version: 1.41
Cache-Control: no-cache, no-store, must-revalidate
Content-Length: 0
Content-Type: text/plain; charset=utf-8
Docker-Experimental: false
Ostype: linux
Pragma: no-cache
Server: Docker/20.10.2 (linux)
Date: Sat, 09 Jan 2021 05:37:59 GMT

# POST でコンテナ作成をリクエスト
05:37:59.129633 IP localhost.34930 > localhost.2375: Flags [P.], seq 90:1799, ack 281, win 512, options [nop,nop,TS val 1764617683 ecr 1764617682], length 1709
POST /v1.41/containers/create?name=alpine HTTP/1.1
Host: localhost:2375
User-Agent: Docker-Client/20.10.2 (linux)
Content-Length: 1536
Content-Type: application/json

{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":true,"OpenStdin":true,"StdinOnce":false,"Env":null,"Cmd":["/bin/sh"],"Image":"alpine","Volumes":{},"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{},"HostConfig":{"Binds":null,"ContainerIDFile":"","LogConfig":{"Type":"","Config":{}},"NetworkMode":"default","PortBindings":{},"RestartPolicy":{"Name":"no","MaximumRetryCount":0},"AutoRemove":false,"VolumeDriver":"","VolumesFrom":null,"CapAdd":null,"CapDrop":null,"CgroupnsMode":"","Dns":[],"DnsOptions":[],"DnsSearch":[],"ExtraHosts":null,"GroupAdd":null,"IpcMode":"","Cgroup":"","Links":null,"OomScoreAdj":0,"PidMode":"","Privileged":false,"PublishAllPorts":false,"ReadonlyRootfs":false,"SecurityOpt":null,"UTSMode":"","UsernsMode":"","ShmSize":0,"ConsoleSize":[0,0],"Isolation":"","CpuShares":0,"Memory":0,"NanoCpus":0,"CgroupParent":"","BlkioWeight":0,"BlkioWeightDevice":[],"BlkioDeviceReadBps":null,"BlkioDeviceWriteBps":null,"BlkioDeviceReadIOps":null,"BlkioDeviceWriteIOps":null,"CpuPeriod":0,"CpuQuota":0,"CpuRealtimePeriod":0,"CpuRealtimeRuntime":0,"CpusetCpus":"","CpusetMems":"","Devices":[],"DeviceCgroupRules":null,"DeviceRequests":null,"KernelMemory":0,"KernelMemoryTCP":0,"MemoryReservation":0,"MemorySwap":0,"MemorySwappiness":-1,"OomKillDisable":false,"PidsLimit":0,"Ulimits":null,"CpuCount":0,"CpuPercent":0,"IOMaximumIOps":0,"IOMaximumBandwidth":0,"MaskedPaths":null,"ReadonlyPaths":null},"NetworkingConfig":{"EndpointsConfig":{}},"Platform":null}

# 404 を受信（イメージがホストにない）
05:37:59.130445 IP localhost.2375 > localhost.34930: Flags [P.], seq 281:533, ack 1799, win 512, options [nop,nop,TS val 1764617684 ecr 1764617683], length 252
HTTP/1.1 404 Not Found
Api-Version: 1.41
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/20.10.2 (linux)
Date: Sat, 09 Jan 2021 05:37:59 GMT
Content-Length: 43

{"message":"No such image: alpine:latest"}

# GET で docker の情報をリクエスト
05:37:59.130755 IP localhost.34930 > localhost.2375: Flags [P.], seq 1799:1892, ack 533, win 512, options [nop,nop,TS val 1764617684 ecr 1764617684], length 93
GET /v1.41/info HTTP/1.1
Host: localhost:2375
User-Agent: Docker-Client/20.10.2 (linux)

# 200 OK を受信（json で docker の情報を取得）
05:37:59.137124 IP localhost.2375 > localhost.34930: Flags [P.], seq 533:3444, ack 1892, win 512, options [nop,nop,TS val 1764617690 ecr 1764617684], length 2911
HTTP/1.1 200 OK
Api-Version: 1.41
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/20.10.2 (linux)
Date: Sat, 09 Jan 2021 05:37:59 GMT
Transfer-Encoding: chunked

{"ID":"K5WR:OGR6:DCUW:U6FT:IVPQ:XZGL:VZRO:I2AS:6XFP:CPES:DKDE:5C6E","Containers":1,"ContainersRunning":0,"ContainersPaused":0,"ContainersStopped":1,"Images":1,"Driver":"overlay2","DriverStatus":[["Backing Filesystem","extfs"],["Supports d_type","true"],["Native Overlay Diff","true"]],"Plugins":{"Volume":["local"],"Network":["bridge","host","ipvlan","macvlan","null","overlay"],"Authorization":null,"Log":["awslogs","fluentd","gcplogs","gelf","journald","json-file","local","logentries","splunk","syslog"]},"MemoryLimit":true,"SwapLimit":false,"KernelMemory":true,"KernelMemoryTCP":true,"CpuCfsPeriod":true,"CpuCfsQuota":true,"CPUShares":true,"CPUSet":true,"PidsLimit":true,"IPv4Forwarding":true,"BridgeNfIptables":true,"BridgeNfIp6tables":true,"Debug":false,"NFd":23,"OomKillDisable":true,"NGoroutines":34,"SystemTime":"2021-01-09T05:37:59.13128067Z","LoggingDriver":"json-file","CgroupDriver":"cgroupfs","CgroupVersion":"1","NEventsListener":0,"KernelVersion":"4.15.0-124-generic","OperatingSystem":"Ubuntu 18.04.5 LTS","OSVersion":"18.04","OSType":"linux","Architecture":"x86_64","IndexServerAddress":"https://index.docker.io/v1/","RegistryConfig":{"AllowNondistributableArtifactsCIDRs":[],"AllowNondistributableArtifactsHostnames":[],"InsecureRegistryCIDRs":["127.0.0.0/8"],"IndexConfigs":{"docker.io":{"Name":"docker.io","Mirrors":[],"Secure":true,"Official":true}},"Mirrors":[]},"NCPU":2,"MemTotal":4136148992,"GenericResources":null,"DockerRootDir":"/var/lib/docker","HttpProxy":"","HttpsProxy":"","NoProxy":"","Name":"ubuntu","Labels":[],"ExperimentalBuild":false,"ServerVersion":"20.10.2","Runtimes":{"io.containerd.runc.v2":{"path":"runc"},"io.containerd.runtime.v1.linux":{"path":"runc"},"runc":{"path":"runc"}},"DefaultRuntime":"runc","Swarm":{"NodeID":"","NodeAddr":"","LocalNodeState":"inactive","ControlAvailable":false,"Error":"","RemoteManagers":null},"LiveRestoreEnabled":false,"Isolation":"","InitBinary":"docker-init","ContainerdCommit":{"ID":"269548fa27e0089a8b8278fc4fc781d7f65a939b","Expected":"269548fa27e0089a8b8278fc4fc781d7f65a939b"},"RuncCommit":{"ID":"ff819c7e9184c13b7c2607fe6c30ae19403a7aff","Expected":"ff819c7e9184c13b7c2607fe6c30ae19403a7aff"},"InitCommit":{"ID":"de40ad0","Expected":"de40ad0"},"SecurityOptions":["name=apparmor","name=seccomp,profile=default"],"Warnings":["WARNING: API is accessible on http://127.0.0.1:2375 without encryption.\n         Access to the remote API is equivalent to root access on the host. Refer\n         to the 'Docker daemon attack surface' section in the documentation for\n         more information: https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface","WARNING: No swap limit support"]}

# POST でイメージ作成（取得）をリクエスト
05:37:59.137800 IP localhost.34930 > localhost.2375: Flags [P.], seq 1892:2091, ack 3444, win 512, options [nop,nop,TS val 1764617691 ecr 1764617690], length 199
POST /v1.41/images/create?fromImage=alpine&tag=latest HTTP/1.1
Host: localhost:2375
User-Agent: Docker-Client/20.10.2 (linux)
Content-Length: 0
Content-Type: text/plain
X-Registry-Auth: e30=

# 200 OK でイメージの取得情報を受信
05:38:03.056642 IP localhost.2375 > localhost.34930: Flags [P.], seq 3444:3716, ack 2091, win 512, options [nop,nop,TS val 1764621610 ecr 1764617691], length 272
HTTP/1.1 200 OK
Api-Version: 1.41
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/20.10.2 (linux)
Date: Sat, 09 Jan 2021 05:38:03 GMT
Transfer-Encoding: chunked

{"status":"Pulling from library/alpine","id":"latest"}

05:38:03.105019 IP localhost.34930 > localhost.2375: Flags [.], ack 3716, win 512, options [nop,nop,TS val 1764621658 ecr 1764621610], length 0
05:38:03.946078 IP localhost.2375 > localhost.34930: Flags [P.], seq 3716:3793, ack 2091, win 512, options [nop,nop,TS val 1764622499 ecr 1764621658], length 77
{"status":"Pulling fs layer","progressDetail":{},"id":"801bfaa63ef2"}

05:38:03.946083 IP localhost.34930 > localhost.2375: Flags [.], ack 3793, win 512, options [nop,nop,TS val 1764622499 ecr 1764622499], length 0
05:38:04.811962 IP localhost.2375 > localhost.34930: Flags [P.], seq 3793:3985, ack 2091, win 512, options [nop,nop,TS val 1764623365 ecr 1764622499], length 192
{"status":"Downloading","progressDetail":{"current":29327,"total":2799066},"progress":"[\u003e                                                  ]  29.33kB/2.799MB","id":"801bfaa63ef2"}

05:38:04.811967 IP localhost.34930 > localhost.2375: Flags [.], ack 3985, win 511, options [nop,nop,TS val 1764623365 ecr 1764623365], length 0
05:38:04.920582 IP localhost.2375 > localhost.34930: Flags [P.], seq 3985:4179, ack 2091, win 512, options [nop,nop,TS val 1764623474 ecr 1764623365], length 194
{"status":"Downloading","progressDetail":{"current":1096159,"total":2799066},"progress":"[===================\u003e                               ]  1.096MB/2.799MB","id":"801bfaa63ef2"}

05:38:04.920586 IP localhost.34930 > localhost.2375: Flags [.], ack 4179, win 510, options [nop,nop,TS val 1764623474 ecr 1764623474], length 0
05:38:05.016751 IP localhost.2375 > localhost.34930: Flags [P.], seq 4179:4258, ack 2091, win 512, options [nop,nop,TS val 1764623570 ecr 1764623474], length 79
{"status":"Verifying Checksum","progressDetail":{},"id":"801bfaa63ef2"}

05:38:05.016756 IP localhost.34930 > localhost.2375: Flags [.], ack 4258, win 510, options [nop,nop,TS val 1764623570 ecr 1764623570], length 0
05:38:05.016966 IP localhost.2375 > localhost.34930: Flags [P.], seq 4258:4336, ack 2091, win 512, options [nop,nop,TS val 1764623570 ecr 1764623570], length 78
{"status":"Download complete","progressDetail":{},"id":"801bfaa63ef2"}

05:38:05.016969 IP localhost.34930 > localhost.2375: Flags [.], ack 4336, win 510, options [nop,nop,TS val 1764623570 ecr 1764623570], length 0
05:38:05.017153 IP localhost.2375 > localhost.34930: Flags [P.], seq 4336:4527, ack 2091, win 512, options [nop,nop,TS val 1764623570 ecr 1764623570], length 191
{"status":"Extracting","progressDetail":{"current":32768,"total":2799066},"progress":"[\u003e                                                  ]  32.77kB/2.799MB","id":"801bfaa63ef2"}

05:38:05.017157 IP localhost.34930 > localhost.2375: Flags [.], ack 4527, win 509, options [nop,nop,TS val 1764623570 ecr 1764623570], length 0
05:38:05.181267 IP localhost.2375 > localhost.34930: Flags [P.], seq 4527:4719, ack 2091, win 512, options [nop,nop,TS val 1764623735 ecr 1764623570], length 192
{"status":"Extracting","progressDetail":{"current":360448,"total":2799066},"progress":"[======\u003e                                            ]  360.4kB/2.799MB","id":"801bfaa63ef2"}

05:38:05.181278 IP localhost.34930 > localhost.2375: Flags [.], ack 4719, win 508, options [nop,nop,TS val 1764623735 ecr 1764623735], length 0
05:38:05.222125 IP localhost.2375 > localhost.34930: Flags [P.], seq 4719:4912, ack 2091, win 512, options [nop,nop,TS val 1764623775 ecr 1764623735], length 193
{"status":"Extracting","progressDetail":{"current":2799066,"total":2799066},"progress":"[==================================================\u003e]  2.799MB/2.799MB","id":"801bfaa63ef2"}

05:38:05.222131 IP localhost.34930 > localhost.2375: Flags [.], ack 4912, win 507, options [nop,nop,TS val 1764623775 ecr 1764623775], length 0
05:38:05.274502 IP localhost.2375 > localhost.34930: Flags [P.], seq 4912:4986, ack 2091, win 512, options [nop,nop,TS val 1764623828 ecr 1764623775], length 74
{"status":"Pull complete","progressDetail":{},"id":"801bfaa63ef2"}

05:38:05.274512 IP localhost.34930 > localhost.2375: Flags [.], ack 4986, win 507, options [nop,nop,TS val 1764623828 ecr 1764623828], length 0
05:38:05.379954 IP localhost.2375 > localhost.34930: Flags [P.], seq 4986:5086, ack 2091, win 512, options [nop,nop,TS val 1764623933 ecr 1764623828], length 100
{"status":"Digest: sha256:3c7497bf0c7af93428242d6176e8f7905f2201d8fc5861f45be7a346b5f23436"}

05:38:05.379963 IP localhost.34930 > localhost.2375: Flags [.], ack 5086, win 507, options [nop,nop,TS val 1764623933 ecr 1764623933], length 0
05:38:05.398799 IP localhost.2375 > localhost.34930: Flags [P.], seq 5086:5155, ack 2091, win 512, options [nop,nop,TS val 1764623952 ecr 1764623933], length 69
{"status":"Status: Downloaded newer image for alpine:latest"}

# POST でコンテナ作成を再リクエスト
05:38:05.420352 IP localhost.34930 > localhost.2375: Flags [.], ack 5160, win 507, options [nop,nop,TS val 1764623974 ecr 1764623974], length 0
05:38:05.420485 IP localhost.34930 > localhost.2375: Flags [P.], seq 2091:3800, ack 5160, win 512, options [nop,nop,TS val 1764623974 ecr 1764623974], length 1709
POST /v1.41/containers/create?name=alpine HTTP/1.1
Host: localhost:2375
User-Agent: Docker-Client/20.10.2 (linux)
Content-Length: 1536
Content-Type: application/json

{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":true,"OpenStdin":true,"StdinOnce":false,"Env":null,"Cmd":["/bin/sh"],"Image":"alpine","Volumes":{},"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{},"HostConfig":{"Binds":null,"ContainerIDFile":"","LogConfig":{"Type":"","Config":{}},"NetworkMode":"default","PortBindings":{},"RestartPolicy":{"Name":"no","MaximumRetryCount":0},"AutoRemove":false,"VolumeDriver":"","VolumesFrom":null,"CapAdd":null,"CapDrop":null,"CgroupnsMode":"","Dns":[],"DnsOptions":[],"DnsSearch":[],"ExtraHosts":null,"GroupAdd":null,"IpcMode":"","Cgroup":"","Links":null,"OomScoreAdj":0,"PidMode":"","Privileged":false,"PublishAllPorts":false,"ReadonlyRootfs":false,"SecurityOpt":null,"UTSMode":"","UsernsMode":"","ShmSize":0,"ConsoleSize":[0,0],"Isolation":"","CpuShares":0,"Memory":0,"NanoCpus":0,"CgroupParent":"","BlkioWeight":0,"BlkioWeightDevice":[],"BlkioDeviceReadBps":null,"BlkioDeviceWriteBps":null,"BlkioDeviceReadIOps":null,"BlkioDeviceWriteIOps":null,"CpuPeriod":0,"CpuQuota":0,"CpuRealtimePeriod":0,"CpuRealtimeRuntime":0,"CpusetCpus":"","CpusetMems":"","Devices":[],"DeviceCgroupRules":null,"DeviceRequests":null,"KernelMemory":0,"KernelMemoryTCP":0,"MemoryReservation":0,"MemorySwap":0,"MemorySwappiness":-1,"OomKillDisable":false,"PidsLimit":0,"Ulimits":null,"CpuCount":0,"CpuPercent":0,"IOMaximumIOps":0,"IOMaximumBandwidth":0,"MaskedPaths":null,"ReadonlyPaths":null},"NetworkingConfig":{"EndpointsConfig":{}},"Platform":null}

# 201 で作成した旨を受信
05:38:05.526077 IP localhost.2375 > localhost.34930: Flags [P.], seq 5160:5455, ack 3800, win 512, options [nop,nop,TS val 1764624079 ecr 1764623974], length 295
HTTP/1.1 201 Created
Api-Version: 1.41
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/20.10.2 (linux)
Date: Sat, 09 Jan 2021 05:38:05 GMT
Content-Length: 88

{"Id":"3733e8696b64ed2207d2b10ffe566dc562309a108b91a2e13278a8d749dcc98e","Warnings":[]}

# POST でコンテナの停止待ち
05:38:05.527811 IP localhost.34930 > localhost.2375: Flags [P.], seq 3800:4035, ack 5455, win 512, options [nop,nop,TS val 1764624081 ecr 1764624079], length 235
POST /v1.41/containers/3733e8696b64ed2207d2b10ffe566dc562309a108b91a2e13278a8d749dcc98e/wait?condition=next-exit HTTP/1.1
Host: localhost:2375
User-Agent: Docker-Client/20.10.2 (linux)
Content-Length: 0
Content-Type: text/plain

05:38:05.528158 IP localhost.2375 > localhost.34930: Flags [P.], seq 5455:5665, ack 4035, win 512, options [nop,nop,TS val 1764624081 ecr 1764624081], length 210
HTTP/1.1 200 OK
Api-Version: 1.41
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/20.10.2 (linux)
Date: Sat, 09 Jan 2021 05:38:05 GMT
Transfer-Encoding: chunked

# POST でコンテナを起動
05:38:05.528488 IP localhost.34950 > localhost.2375: Flags [P.], seq 1:217, ack 1, win 512, options [nop,nop,TS val 1764624082 ecr 1764624082], length 216
POST /v1.41/containers/3733e8696b64ed2207d2b10ffe566dc562309a108b91a2e13278a8d749dcc98e/start HTTP/1.1
Host: localhost:2375
User-Agent: Docker-Client/20.10.2 (linux)
Content-Length: 0
Content-Type: text/plain

# 正常に開始をレスポンス
05:38:06.047454 IP localhost.2375 > localhost.34950: Flags [P.], seq 1:159, ack 217, win 512, options [nop,nop,TS val 1764624601 ecr 1764624082], length 158
HTTP/1.1 204 No Content
Api-Version: 1.41
Docker-Experimental: false
Ostype: linux
Server: Docker/20.10.2 (linux)
Date: Sat, 09 Jan 2021 05:38:06 GMT
```

簡単にリクエストをまとめると、

1. HEAD で「/_ping」をリクエスト<br>⇒ 200 OK を受信
2. POST でコンテナ作成をリクエスト<br>⇒ 404 を受信（イメージがホストにない）
3. GET で docker の情報をリクエスト<br>⇒ 200 OK を受信（json で docker の情報を取得）
4. POST でイメージ作成（取得）をリクエスト<br>⇒ 200 OK でイメージの取得情報を受信
5. POST でコンテナ作成を再リクエスト<br>⇒ 201 で作成した旨を受信
6. POST でコンテナの停止待ち<br>
7. POST でコンテナを起動<br>⇒ 正常に開始をレスポンス

# おわりに
docker のリクエスト、レスポンスを今回は確認してみました。
docker のサブコマンド一つ取っても多くのリクエストが発行されていることが分かりました。

今回利用した docker のバージョンの API リファレンスは以下になります。ご参考までに。
https://docs.docker.com/engine/api/v1.41/