Docker实验二:Docker容器
1 实验内容
- 学习
Docker
容器的常用命令。
2 实验要点
- 掌握
Docker
容器的常用命令。
3 实验环境
- Windows 7 Docker环境
4 注意事项
Docker官方对docker pull
指令进行了限制,同一个IP每6小时最多使用100次,如果pull上限后,可以尝试下载相应的images
,然后使用docker load
命令直接加载相应的镜像。
例如:
1
docker load < images/ubuntu_latest.tar.gz
5 实验步骤
5.1 Docker 客户端
docker 客户端非常简单 ,可以直接输入 docker
命令或docker --help
来查看到 Docker 客户端的所有命令选项。
可通过命令docker command --help
深入了解某个Docker命令使用方法。
5.2 容器的使用
5.2.1 获取镜像
如果本地没有ubuntu镜像,可使用docker pull ubuntu
下载:
5.2.2 启动容器
以下命令使用 ubuntu 镜像启动一个容器,参数表示以命令行模式进入该容器:
1
docker run -it ubuntu /bin/bash
参数说明:
- -i: 交互式操作。
- -t: 终端。
- ubuntu: ubuntu 镜像。
- /bin/bash:放在镜像名后的是命令,这里需要使用交互式方式Shell访问容器,因此用的是 /bin/bash。
要退出终端,直接输入 exit
或使用快捷键Ctrl + D
:
5.2.3 启动已停止运行的容器
查看所有的容器命令如下:
1
docker ps -a
注意:docker ps
命令只显示当前正在运行的容器,-a选项表示显示所有容器,包括停止运行的容器。
从 Status 一列中可以看出容器 c0030ca3df6b已处于停止运行状态。
使用 docker start 启动一个已停止的容器:
1
docker start c0030ca3df6b
可以看出,容器 c0030ca3df6b已顺利启动。
5.2.4 后台运行
在大部分的场景下,docker 的服务是在后台运行的,可以通过 -d 指定容器的运行模式。
1
docker run -itd --name ubuntu_test ubuntu /bin/bash
注意:加了 -d 参数默认不会进入容器,可通过 docker exec
命令进入容器(后续详细介绍)。
5.2.5 停止和重启一个容器
停止容器的命令为:docker stop <容器 ID>
重启容器的命令为:docker restart <容器 ID>
示例如下:
1
2
docker stop c0030ca3df6b
docker restart c0030ca3df6b
除了docker start
外,停止的容器也可以通过命令docker restart <容器 ID>
重启。
5.2.6 进入容器
在使用 -d 参数时,容器启动后会在后台运行。此时想要进入容器,可通过以下命令进入:
1
2
docker attach
docker exec
推荐使用 docker exec
命令,因为使用该命令退出容器终端后,不会导致容器停止运行。
attach 命令
下面演示了
docker attach
命令的使用。1
docker attach 8708d8e65f03
exec 命令
下面演示了
docker exec
命令的使用。1
docker exec -it 8708d8e65f03 /bin/bash
可以看出,使用
docker exec
命令进入容器后,从容器退出不会导致容器停止运行。因此,推荐使用docker exec
命令。请使用
docker exec --help
命令查看docker exec
命令的更多参数说明。
5.2.7 导出和导入容器
导出容器
如果要导出本地某个容器,可以使用 docker export 命令。
1 2
docker export 8708d8e65f03 -o ubuntu_test.tar ls -l ubuntu_test.tar
导出容器 8708d8e65f03快照到本地文件 ubuntu_test.tar ,从上图中可以看出生成了文件 ubuntu_test.tar 。
导入容器
可以使用 docker import 从容器快照文件中再导入为镜像,以下命令将快照文件 ubuntu_test.tar 导入为镜像 cg/my_ubuntu:v1:
1
docker import ubuntu_test.tar cg/my_ubuntu:v1.0
1
docker import http://example.com/exampleimage.tar example/imagerepo
5.2.8 删除容器
删除容器使用 docker rm 命令:
1
docker rm 8708d8e65f03
可见通过 docker rm 删除容器8708d8e65f03后,在容器列表中已经移除了该容器。
通过 docker container prune
命令可将处于终止状态的容器全部删除。
以下操作演示了该命令的使用,首先使用 ubuntu 镜像创建三个容器,并将其终止, 然后使用docker container prune
删除停止的容器,操作如下:
1
2
3
docker ps -a
docker container prune
docker ps -a
首先使用 docker ps -a
查看所有容器状态,可以看到ubuntu_test1、ubuntu_test2、ubuntu_test3这三个容器都已经处于终止状态。
docker container prune
命令执行后,再使用 docker ps -a
查看,可以发现ubuntu_test1、ubuntu_test2、ubuntu_test3这三个容器都已删除。
注意:实验环境中还存在一个已经停止运行的hello-world容器,该容器也被 docker container prune
命令删除。这个hello-world容器是运行其他实验时遗留的容器,如果你的环境中不存在该容器也不用担心。
5.3 运行Web应用
前面运行的容器并没有特别的用处。
接下来尝试使用 docker 构建一个 web 应用程序。
5.3.1 实战环境准备
本次实战中,将在 docker 容器中基于 Python Flask 运行一个简单的web应用。
本实验项目的目录为: D:\Users\JOJO\Desktop\Docker实验报告\webapp
,所需运行的程序的目录为D:\Users\JOJO\Desktop\Docker实验报告\webapp\webapp
。因此,首先将工作目录切换为该目录,
1
2
3
cd /d/users/JOJO/Desktop/Docker实验报告/webapp/webapp/
pwd
ls
使用 docker pull
命令下载webapp镜像,webapp镜像中封装了Python Flask环境,
1
docker pull training/webapp
本应用的逻辑实现位于app.py文件中,本应用的目的是在浏览器的页面上输出:Hello World,app.py的代码内容如下: 使用webapp容器运行应用, 参数说明:
- -d:让容器在后台运行。
- -P:将容器内部使用的网络端口映射到宿主机上。
5.3.2 查看WEB应用容器
使用 docker ps 来查看正在运行的容器:
1
docker ps
1
2
PORTS
0.0.0.0:32768->5000/tcp
Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 32768 上。
这时可以通过浏览器访问WEB应用,在地址栏输入:localhost:32768,可以看到如下图所示的页面,
也可以在docker环境的终端内输入`curl localhost:32768`获取网页源码也可以通过 -p 参数指定所要映射的端口,
1
docker run -d -p 5000:5000 training/webapp python app.py
docker ps
查看正在运行的容器 可以看到,容器内部的 5000 端口映射到本地主机的 5000 端口上。
5.3.3 网络端口的快捷方式
通过 docker ps 命令可以查看到容器的端口映射,docker 还提供了另一个快捷方式 docker port,使用 docker port 可以查看指定 (ID 或者名字)容器的某个确定端口映射到宿主机的端口号。
上面创建的 web 应用容器 ID 为 e0c8a4a24e7e 名字为 musing_meninsky。
可以使用 docker port e0c8a4a24e7e
或 docker port musing_meninsky
来查看容器端口的映射情况。
5.3.4 查看WEB应用程序日志
docker logs [ID或者名字]
可以查看容器内部的标准输出。
1
2
docker logs e0c8a4a24e7e
docker logs musing_meninsky
可以使用 -f 选项,这样 docker logs 会像 tail -f 一样来输出容器内部的标准输出。
1
2
docker logs -f e0c8a4a24e7e
docker logs -f musing_meninsky
从上面,可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志。
5.3.5 查看WEB应用程序容器的进程
使用 docker top
查看容器内部运行的进程
1
docker top e0c8a4a24e7e
5.3.6 检查WEB应用程序
使用 docker inspect 查看 Docker 的底层信息,该命令会返回一个记录了 Docker 容器配置和状态信息的JSON 文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
JOJO@DESKTOP-LG5R18D MINGW64 /d/users/JOJO/Desktop/Docker实验报告/webapp/webapp
$ docker inspect e0c8a4a24e7e
[
{
"Id": "e0c8a4a24e7e6b65c1c440520e49505dbe6df7fc70ada0a599e7f94280a569e9",
"Created": "2021-09-23T12:30:47.84475838Z",
"Path": "python",
"Args": [
"app.py"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 11388,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-09-23T12:30:48.014015659Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:6fae60ef344644649a39240b94d73b8ba9c67f898ede85cf8e947a887b3e6557",
"ResolvConfPath": "/mnt/sda1/var/lib/docker/containers/e0c8a4a24e7e6b65c1c440520e49505dbe6df7fc70ada0a599e7f94280a569e9/resolv.conf",
"HostnamePath": "/mnt/sda1/var/lib/docker/containers/e0c8a4a24e7e6b65c1c440520e49505dbe6df7fc70ada0a599e7f94280a569e9/hostname",
"HostsPath": "/mnt/sda1/var/lib/docker/containers/e0c8a4a24e7e6b65c1c440520e49505dbe6df7fc70ada0a599e7f94280a569e9/hosts",
"LogPath": "/mnt/sda1/var/lib/docker/containers/e0c8a4a24e7e6b65c1c440520e49505dbe6df7fc70ada0a599e7f94280a569e9/e0c8a4a24e7e6b65c1c440520e49505dbe6df7fc70ada0a599e7f94280a569e9-json.log",
"Name": "/musing_meninsky",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {
"5000/tcp": [
{
"HostIp": "",
"HostPort": "5000"
}
]
},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Capabilities": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "shareable",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
23,
96
],
"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": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/mnt/sda1/var/lib/docker/overlay2/972dfe028e55bd1376246a20a9482bc770110f1bfd5b8973a5c827140d86802c-init/diff:/mnt/sda1/var/lib/docker/overlay2/b255bb29042700e8d435dbb1f22d38da1e1abb5c47511689101d1f68f0fbd53d/diff:/mnt/sda1/var/lib/docker/overlay2/0df1f40ab5098ca51f98059e1cfad94b929c2d4cbded7f608ffc69572696622b/diff:/mnt/sda1/var/lib/docker/overlay2/e64a810f17657ae460453a6fcdd83d8774df17c1448ad9c66b7dc73df727ebde/diff:/mnt/sda1/var/lib/docker/overlay2/b3a8dd02542a23d08b30d185713f878ee32ec1916529affc0a5143e6d8cbaf1d/diff:/mnt/sda1/var/lib/docker/overlay2/795f0a493cb34a8272c81ba76dcbb0ae363ca7bea37c12503b7e630790eb38b9/diff:/mnt/sda1/var/lib/docker/overlay2/c9b5c8cc15c32e2dade7c934473ec334be4f026c2e263cade46872fcfc1fedcb/diff:/mnt/sda1/var/lib/docker/overlay2/90f62154c24acbb8c522025b703135de9b1a5d0545c22a3264846b42319287b8/diff:/mnt/sda1/var/lib/docker/overlay2/283683f52c3b31af68a0b04d24e8f82717471e7b33121df5046b9d8b72b0c5e6/diff:/mnt/sda1/var/lib/docker/overlay2/95f5c4414e13e6d7748649f1f208d16dad067f22e519a378e2028efb4d6d34b4/diff:/mnt/sda1/var/lib/docker/overlay2/2323ad95c0fe0a348196de058751db41b7ad901f47f709dc099631f50b33cdf1/diff:/mnt/sda1/var/lib/docker/overlay2/7de49640d3651d0f4c336dbd4d133e3612e6ad405223bd8c82f7b80eceb04e87/diff:/mnt/sda1/var/lib/docker/overlay2/1a55a67dc9f63fbb00e3943be30a42724437c9982377f65df821f67b3c6f8f93/diff:/mnt/sda1/var/lib/docker/overlay2/4ffcb6d0da325d8dddd818d76e1155e891d1a0577cfe13fd987eab089643a856/diff",
"MergedDir": "/mnt/sda1/var/lib/docker/overlay2/972dfe028e55bd1376246a20a9482bc770110f1bfd5b8973a5c827140d86802c/merged",
"UpperDir": "/mnt/sda1/var/lib/docker/overlay2/972dfe028e55bd1376246a20a9482bc770110f1bfd5b8973a5c827140d86802c/diff",
"WorkDir": "/mnt/sda1/var/lib/docker/overlay2/972dfe028e55bd1376246a20a9482bc770110f1bfd5b8973a5c827140d86802c/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "e0c8a4a24e7e",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"5000/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"python",
"app.py"
],
"Image": "training/webapp",
"Volumes": null,
"WorkingDir": "/opt/webapp",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "d6d5a236e2a3ec3a2e2008fb2d1b2d1f35118700d52e3f95a1b7cc5c4d92960b",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"5000/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "5000"
}
]
},
"SandboxKey": "/var/run/docker/netns/d6d5a236e2a3",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "ae4b5cd5a75d8da238d11b88170502cfe470c8e94c7e43fd579d511fda5f7bc7",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "cb9d9c850475238f06e71782b77510ae854f27c26da12f562622fb6a0d1f61d0",
"EndpointID": "ae4b5cd5a75d8da238d11b88170502cfe470c8e94c7e43fd579d511fda5f7bc7",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
5.3.7 停止WEB应用容器
使用docker stop停止应用,
1
2
docker stop e0c8a4a24e7e
docker ps
5.3.8 重启WEB应用容器
可通过docker start <容器ID>
或者 docker restart <容器ID>
启动停止运行的容器,已经停止的容器,可以使用命令 docker start
来启动。 容器启动后,再次使用浏览器访问Web服务: 可见,服务已经可以正常访问。
可以使用命令 docker ps -l
查询最后一次创建的容器:
5.3.9 移出WEB应用容器
可使用 docker rm 命令删除容器,例如对于容器e0c8a4a24e7e,
1
2
3
docker rm e0c8a4a24e7e
docker stop e0c8a4a24e7e
docker rm e0c8a4a24e7e