3.1 确保 Docker 已经就绪

  1. $ sudo docker info

3.2 运行我们的第一个容器

  1. $ sudo docker run -i -t ubuntu /bin/bash
  • -i: 保证容器中 STDIN 是开启的
  • -t: 为要创建的容器分配一个伪 tty 终端

新创建的容器拥有自己的:

  1. 网络
  2. ip
  3. 和宿主机通信的桥接网络接口

3.3 使用第一个容器

  1. root@a3fc4d76c6e9:/# hostname
  2. a3fc4d76c6e9
  1. root@a3fc4d76c6e9:/# cat /etc/hosts
  2. 127.0.0.1 localhost
  3. ::1 localhost ip6-localhost ip6-loopback
  4. fe00::0 ip6-localnet
  5. ff00::0 ip6-mcastprefix
  6. ff02::1 ip6-allnodes
  7. ff02::2 ip6-allrouters
  8. 172.17.0.2 a3fc4d76c6e9

我的实验环境中没有 ip 命令.

image.png
image.png

  1. root@a3fc4d76c6e9:/# ps -aux
  2. USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
  3. root 1 0.0 0.0 4232 3468 pts/0 Ss 02:44 0:00 /bin/bash
  4. root 17 0.0 0.0 5880 2776 pts/0 R+ 02:58 0:00 ps -aux
  1. root@a3fc4d76c6e9:/# apt-get update && apt-get install vim
  1. root@a3fc4d76c6e9:/# exit
  2. exit
  3. # jdxj @ jdxj-manjaro in ~ [11:00:00]
  4. $ sudo docker ps -a
  5. [sudo] jdxj 的密码:
  6. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  7. a3fc4d76c6e9 ubuntu "/bin/bash" 16 minutes ago Exited (0) 53 seconds ago flamboyant_moser
  8. 88132fe6a04b consul:1.4.4 "docker-entrypoint.s…" 6 days ago Exited (1) 5 days ago consul
  9. 351269acdacf rabbitmq:3.8.9-management "docker-entrypoint.s…" 2 weeks ago Exited (0) 2 weeks ago myrabbit3
  10. 1c6772e4177c rabbitmq:3.8.9-management "docker-entrypoint.s…" 2 weeks ago Exited (0) 2 weeks ago myrabbit2
  11. ce58ec2d0602 rabbitmq:3.8.9-management "docker-entrypoint.s…" 2 weeks ago Exited (0) 2 weeks ago myrabbit1
  12. 614ad03e945c swaggerapi/swagger-editor "/docker-entrypoint.…" 7 weeks ago Exited (0) 7 weeks ago focused_lichterman
  13. 9e85bd65e188 mysql:5.7 "docker-entrypoint.s…" 4 months ago Exited (0) 2 days ago mysql
  14. f483173b2aeb 587380cbba10 "docker-entrypoint.s…" 4 months ago Exited (0) 2 days ago rabbitmq
  15. 22d487c89ec6 redis:6 "docker-entrypoint.s…" 4 months ago Exited (0) 3 days ago redis

3.4 容器命名

  1. $ sudo docker run --name bob_the_container -i -t ubuntu /bin/bash
  2. root@ef61fcc1f09c:/# exit
  3. exit

合法的命名:

  • a~z
  • A~Z
  • 0~9
  • _
  • .
  • -

3.5 重新启动已经停止的容器

  1. $ sudo docker start bob_the_container
  2. bob_the_container
  1. $ sudo docker start ef61fcc1f09c
  2. ef61fcc1f09c
  1. $ sudo docker restart ...
  1. $ sudo docker create ...

3.6 附着到容器上

  1. $ sudo docker attach bob_the_container
  2. root@ef61fcc1f09c:/#
  1. $ sudo docker attach ef61fcc1f09c
  2. root@ef61fcc1f09c:/#

3.7 创建守护式容器

  • 交互式容器 (interactive container)
  • 守护式容器 (daemonized container)
  1. $ sudo docker run --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
  2. 5b01d58127a7799b028714e73f0e40bef58afb8fbb1a638f25c4a0d8f9a2c8be
  • -d
  1. $ sudo docker ps
  2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  3. 5b01d58127a7 ubuntu "/bin/sh -c 'while t…" About a minute ago Up About a minute daemon_dave

3.8 容器内部都在干些什么

  1. $ sudo docker logs daemon_dave
  2. hello world
  3. hello world
  4. hello world
  5. ...

跟踪 -f :

  1. $ sudo docker logs -f daemon_dave
  2. hello world
  3. hello world
  4. hello world
  5. ...
  6. ^C
  1. docker logs --tail 10 daemon_dave # 获取最后10行
  2. docker logs --tail 0 -f daemon_dave # 跟踪最新日志而不是整个日志文件

时间戳 -t :

  1. $ sudo docker logs -ft daemon_dave
  2. 2021-01-12T03:15:47.131583739Z hello world
  3. 2021-01-12T03:15:48.133284530Z hello world
  4. 2021-01-12T03:15:49.135542050Z hello world
  5. ...
  6. ^C

3.9 Docker 日志驱动

—log-driver:

  • json-file
  • syslog
  • none

syslog:

image.png

none:

  • 禁用所有容器中的日志
  • docker logs 命名被禁用

其它日志驱动:

  • Graylog GELF 协议
  • Fluentd
  • 日志轮转

3.10 查看容器内的进程

  1. $ sudo docker top daemon_dave
  2. UID PID PPID C STIME TTY TIME CMD
  3. root 14807 14787 0 11:15 ? 00:00:03 /bin/sh -c while true; do echo hello world; sleep 1; done
  4. root 25954 14807 0 13:31 ? 00:00:00 sleep 1

3.11 Docker 统计信息

  1. $ sudo docker stats daemon_dave
  2. CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
  3. 5b01d58127a7 daemon_dave 0.20% 2.664MiB / 7.564GiB 0.03% 63.2kB / 0B 348kB / 0B 2
  4. ^C

3.12 在容器内部运行进程

启动后台任务:

  1. $ sudo docker exec -d daemon_dave touch /etc/new_config_file

启动交互式任务:

  1. $ sudo docker exec -it daemon_dave /bin/bash

3.13 停止守护式容器

  1. $ sudo docker stop daemon_dave
  2. daemon_dave
  1. docker ps -n x # 显示最后 x 个容器

3.14 自动重启容器

—restart:

  • always
  • on-failure
  1. $ sudo docker run --restart=always --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
  2. e4be0a1dc144e5993d1d5ca56e8d9f2faf36918b9d37c3f13e3bc8dc48fa9e6a
  1. --restart=on-failure:5 # 指定次数

3.15 深入容器

  1. $ sudo docker inspect daemon_dave
  2. [
  3. {
  4. "Id": "e4be0a1dc144e5993d1d5ca56e8d9f2faf36918b9d37c3f13e3bc8dc48fa9e6a",
  5. "Created": "2021-01-12T05:45:58.997841821Z",
  6. "Path": "/bin/sh",
  7. "Args": [
  8. "-c",
  9. "while true; do echo hello world; sleep 1; done"
  10. ],
  11. "State": {
  12. "Status": "exited",
  13. "Running": false,
  14. "Paused": false,
  15. "Restarting": false,
  16. "OOMKilled": false,
  17. "Dead": false,
  18. "Pid": 0,
  19. "ExitCode": 137,
  20. "Error": "",
  21. "StartedAt": "2021-01-12T05:45:59.378960863Z",
  22. "FinishedAt": "2021-01-12T05:48:03.603102775Z"
  23. },
  24. "Image": "sha256:4e2eef94cd6b93dd4d794c18b45c763f72edc22858e0da5b6e63a4566a54c03c",
  25. "ResolvConfPath": "/var/lib/docker/containers/e4be0a1dc144e5993d1d5ca56e8d9f2faf36918b9d37c3f13e3bc8dc48fa9e6a/resolv.conf",
  26. "HostnamePath": "/var/lib/docker/containers/e4be0a1dc144e5993d1d5ca56e8d9f2faf36918b9d37c3f13e3bc8dc48fa9e6a/hostname",
  27. "HostsPath": "/var/lib/docker/containers/e4be0a1dc144e5993d1d5ca56e8d9f2faf36918b9d37c3f13e3bc8dc48fa9e6a/hosts",
  28. "LogPath": "/var/lib/docker/containers/e4be0a1dc144e5993d1d5ca56e8d9f2faf36918b9d37c3f13e3bc8dc48fa9e6a/e4be0a1dc144e5993d1d5ca56e8d9f2faf36918b9d37c3f13e3bc8dc48fa9e6a-json.log",
  29. "Name": "/daemon_dave",
  30. "RestartCount": 0,
  31. "Driver": "overlay2",
  32. "Platform": "linux",
  33. "MountLabel": "",
  34. "ProcessLabel": "",
  35. "AppArmorProfile": "docker-default",
  36. "ExecIDs": null,
  37. "HostConfig": {
  38. "Binds": null,
  39. "ContainerIDFile": "",
  40. "LogConfig": {
  41. "Type": "json-file",
  42. "Config": {}
  43. },
  44. "NetworkMode": "default",
  45. "PortBindings": {},
  46. "RestartPolicy": {
  47. "Name": "always",
  48. "MaximumRetryCount": 0
  49. },
  50. "AutoRemove": false,
  51. "VolumeDriver": "",
  52. "VolumesFrom": null,
  53. "CapAdd": null,
  54. "CapDrop": null,
  55. "CgroupnsMode": "host",
  56. "Dns": [],
  57. "DnsOptions": [],
  58. "DnsSearch": [],
  59. "ExtraHosts": null,
  60. "GroupAdd": null,
  61. "IpcMode": "private",
  62. "Cgroup": "",
  63. "Links": null,
  64. "OomScoreAdj": 0,
  65. "PidMode": "",
  66. "Privileged": false,
  67. "PublishAllPorts": false,
  68. "ReadonlyRootfs": false,
  69. "SecurityOpt": null,
  70. "UTSMode": "",
  71. "UsernsMode": "",
  72. "ShmSize": 67108864,
  73. "Runtime": "runc",
  74. "ConsoleSize": [
  75. 0,
  76. 0
  77. ],
  78. "Isolation": "",
  79. "CpuShares": 0,
  80. "Memory": 0,
  81. "NanoCpus": 0,
  82. "CgroupParent": "",
  83. "BlkioWeight": 0,
  84. "BlkioWeightDevice": [],
  85. "BlkioDeviceReadBps": null,
  86. "BlkioDeviceWriteBps": null,
  87. "BlkioDeviceReadIOps": null,
  88. "BlkioDeviceWriteIOps": null,
  89. "CpuPeriod": 0,
  90. "CpuQuota": 0,
  91. "CpuRealtimePeriod": 0,
  92. "CpuRealtimeRuntime": 0,
  93. "CpusetCpus": "",
  94. "CpusetMems": "",
  95. "Devices": [],
  96. "DeviceCgroupRules": null,
  97. "DeviceRequests": null,
  98. "KernelMemory": 0,
  99. "KernelMemoryTCP": 0,
  100. "MemoryReservation": 0,
  101. "MemorySwap": 0,
  102. "MemorySwappiness": null,
  103. "OomKillDisable": false,
  104. "PidsLimit": null,
  105. "Ulimits": null,
  106. "CpuCount": 0,
  107. "CpuPercent": 0,
  108. "IOMaximumIOps": 0,
  109. "IOMaximumBandwidth": 0,
  110. "MaskedPaths": [
  111. "/proc/asound",
  112. "/proc/acpi",
  113. "/proc/kcore",
  114. "/proc/keys",
  115. "/proc/latency_stats",
  116. "/proc/timer_list",
  117. "/proc/timer_stats",
  118. "/proc/sched_debug",
  119. "/proc/scsi",
  120. "/sys/firmware"
  121. ],
  122. "ReadonlyPaths": [
  123. "/proc/bus",
  124. "/proc/fs",
  125. "/proc/irq",
  126. "/proc/sys",
  127. "/proc/sysrq-trigger"
  128. ]
  129. },
  130. "GraphDriver": {
  131. "Data": {
  132. "LowerDir": "/var/lib/docker/overlay2/c0a02e5389777c9503b706c4d47610b1fc63305315f1794e28daa5a1ca2c0092-init/diff:/var/lib/docker/overlay2/ac744ee943866cd0be76ee79f366fd892afdc4088ddf37a77453dc3336e9aaf5/diff:/var/lib/docker/overlay2/3d9270cbd9affd9d7802c5ea3064aaf94f65698dfdc9d1e78b265d7ab5886334/diff:/var/lib/docker/overlay2/2e4be4e4aa62ab5dede3ed77261a6a2d9490df614a3fb748f448f38028d27e7e/diff:/var/lib/docker/overlay2/78ac84782a0c925d8e62ae32ab677268ea7055e81844805bee9974a2486b3039/diff",
  133. "MergedDir": "/var/lib/docker/overlay2/c0a02e5389777c9503b706c4d47610b1fc63305315f1794e28daa5a1ca2c0092/merged",
  134. "UpperDir": "/var/lib/docker/overlay2/c0a02e5389777c9503b706c4d47610b1fc63305315f1794e28daa5a1ca2c0092/diff",
  135. "WorkDir": "/var/lib/docker/overlay2/c0a02e5389777c9503b706c4d47610b1fc63305315f1794e28daa5a1ca2c0092/work"
  136. },
  137. "Name": "overlay2"
  138. },
  139. "Mounts": [],
  140. "Config": {
  141. "Hostname": "e4be0a1dc144",
  142. "Domainname": "",
  143. "User": "",
  144. "AttachStdin": false,
  145. "AttachStdout": false,
  146. "AttachStderr": false,
  147. "Tty": false,
  148. "OpenStdin": false,
  149. "StdinOnce": false,
  150. "Env": [
  151. "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  152. ],
  153. "Cmd": [
  154. "/bin/sh",
  155. "-c",
  156. "while true; do echo hello world; sleep 1; done"
  157. ],
  158. "Image": "ubuntu",
  159. "Volumes": null,
  160. "WorkingDir": "",
  161. "Entrypoint": null,
  162. "OnBuild": null,
  163. "Labels": {}
  164. },
  165. "NetworkSettings": {
  166. "Bridge": "",
  167. "SandboxID": "dfdb27203f768d4614e0b8a1c4b8fc5fda34fb820dc03d01ad1dbddb3631f994",
  168. "HairpinMode": false,
  169. "LinkLocalIPv6Address": "",
  170. "LinkLocalIPv6PrefixLen": 0,
  171. "Ports": {},
  172. "SandboxKey": "/var/run/docker/netns/dfdb27203f76",
  173. "SecondaryIPAddresses": null,
  174. "SecondaryIPv6Addresses": null,
  175. "EndpointID": "",
  176. "Gateway": "",
  177. "GlobalIPv6Address": "",
  178. "GlobalIPv6PrefixLen": 0,
  179. "IPAddress": "",
  180. "IPPrefixLen": 0,
  181. "IPv6Gateway": "",
  182. "MacAddress": "",
  183. "Networks": {
  184. "bridge": {
  185. "IPAMConfig": null,
  186. "Links": null,
  187. "Aliases": null,
  188. "NetworkID": "f5b93ac2e1eec82ca7f04a1b000ae39dd8c97929301bb544c0ed18baa0f91ffb",
  189. "EndpointID": "",
  190. "Gateway": "",
  191. "IPAddress": "",
  192. "IPPrefixLen": 0,
  193. "IPv6Gateway": "",
  194. "GlobalIPv6Address": "",
  195. "GlobalIPv6PrefixLen": 0,
  196. "MacAddress": "",
  197. "DriverOpts": null
  198. }
  199. }
  200. }
  201. }
  202. ]

格式化选项:

$ sudo docker inspect --format='{{ .State.Running }}' daemon_dave
false

存放容器的目录:

/var/lib/docker/containers

3.16 删除容器

sudo docker rm ...
sudo docker rm -f ... # 删除运行中的容器

删除全部容器:

  • -q: 只需返回容器 ID
    $ sudo docker rm `sudo docker ps -a -q`
    

3.17 小结