1. Linux安装Docker教程

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
# 确定你是CentOS7及以上版本
cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

# yum安装gcc相关
yum -y install gcc
yum -y install gcc-c++
Complete!

# 安装需要的软件包
yum install -y yum-utils
Complete!
# 设置stable镜像仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo

# 更新yum软件包索引
yum makecache fast
Metadata Cache Created

# 安装DOCKER CE
yum -y install docker-ce docker-ce-cli containerd.io
Complete!

## 启动docker
systemctl start docker

# 测试
docker version
docker run hello-world
Hello from Docker!

# 卸载
systemctl stop docker
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
rm -rf /var/lib/containerd

# 阿里云镜像加速
mkdir -p /etc/docker
vi /etc/docker/daemon.json

{
"registry-mirrors": ["https://7167asyf.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.100.38:8081"]
}

# 重启服务器
systemctl daemon-reload
systemctl restart docker

2. Docker常见命令

2.1 帮助启动类命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 启动docker: 
systemctl start docker

# 停止docker:
systemctl stop docker

# 重启docker:
systemctl restart docker

# 查看docker状态:
systemctl status docker

# 开机启动:
systemctl enable docker

# 查看docker概要信息:
docker info

# 查看docker总体帮助文档:
docker --help

# 查看docker命令帮助文档:
docker 具体命令 --help

2.2 镜像命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 列出本机上的镜像
# -a 列出本地所有的镜像
# -q 只显示镜像id
docker images

# 查找镜像
# --limit 只列出N个镜像,默认25个
docker search [OPTIONS] 某个镜像名字
docker search redis --limit 3

# 下载镜像
docker pull 某个镜像名字[:TAG]
docker pull redis

# 查看镜像、容器、数据卷所占的空间
docker system df

# 删除镜像
docker rmi 某个镜像名字、id
docker rmi -f 镜像id ## 删除单个镜像
docker rmi -f 镜像名:TAG 镜像名:TAG ## 删除多个镜像

docker rmi -f 7614ae9453d1

2.3 容器命令

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
docker pull redis:6.0.8
# 新建+启动容器
# --name="容器新名字"
# -d 后台运行并返回容器ID
# -i 以交互模式运行容器 -t 为容器重新分配一个伪终端
# -P 随机端口映射 -p 指定端口映射
# docker run -it redis:6.0.8 前台交互式启动
# docker run -d redis:6.0.8 后台守护式启动
docker run [OPTIONS] IMAGE [COMMAND] [ARG]

# 列出当前所有正在运行的容器
# -a 列出当前所有正在运行的容器+运势上运行过的
# -l 显示最近创建的容器
# -n 显示最近n个创建的容器
# -q 静默模式 只显示容器编号
docker ps [OPTIONS]

# 退出容器,容器停止
exit
# 退出容器,容器不停止
ctrl+p+q

# 启动已经停止运行的容器
docker start 容器id或者容器名

# 重启容器
docker restart 容器id或者容器名

# 停止容器
docker stop 容器id或者容器名

# 强制停止容器
docker kill 容器id或者容器名

# 删除以停止容器
docker rm 容器id

# 一次性删除多个容器示例
docker rm -f $(docker ps -a -q) docker ps -a -q |xargs docker rm

# 查询容器日志
docker logs 容器id

# 查看容器内运行的进程
docker top 容器id

# 查看容器内部细节
docker inspect 容器id

# 进入正在运行的容器命令行交互
docker exec -it 容器id /bin/bash # exit退出,不会导致容器停止
docker exec -it aae5fe60b063 /bin/bash
docker attach 容器id # exit退出,会导致容器停止
会卡死

3. 本地镜像发布到镜像仓库

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
# 登录私有镜像仓库
[root@dockertest ~]# docker login http://192.168.100.38:8081
Username: admin
Password: 123456
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
# 下载ubuntu
[root@dockertest ~]# docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
7b1a6ab2e44d: Pull complete
Digest: sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
[root@dockertest ~]#
# 运行ubuntu
[root@dockertest ~]# docker run --name myubuntu01 -d -it ubuntu /bin/bash
945369699fd4a6efd1858db726423a758f57518479fdc98788386a974f6c1331
[root@dockertest ~]#
[root@dockertest ~]#
[root@dockertest ~]#
[root@dockertest ~]# docker run --name myubuntu02 -d -it ubuntu /bin/bash
057c19a28a22864e42479ec132cdc18f7da7ccd05e7a1494a0f24880248d221a
[root@dockertest ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
057c19a28a22 ubuntu "/bin/bash" 29 seconds ago Up 28 seconds myubuntu02
945369699fd4 ubuntu "/bin/bash" 35 seconds ago Up 34 seconds myubuntu01
# docker镜像commit制作新的镜像
[root@dockertest ~]# docker commit -m="test commit" -a="kakalong" 945369699fd4 myubuntu01_commit:1.0
sha256:ec181a2972a8ea7a4af953571a5f895a19a7a8d9de79c133ab1b4483613199fb
# docker修改符合私服规范的tag
[root@dockertest ~]# docker tag myubuntu01_commit:1.0 192.168.100.38:8081/kakalong/myubuntu01_commit:1.0

[root@dockertest ~]#
[root@dockertest ~]# docker push 192.168.100.38:8081/kakalong/myubuntu01_commit:1.0
The push refers to repository [192.168.100.38:8081/kakalong/myubuntu01_commit]
24799adcb504: Pushed
9f54eef41275: Pushed
1.0: digest: sha256:e7a13de8470f976b29bcf27981beb6172762e4cc16fb18f2f9ef7e1f8794cf70 size: 736

[root@dockertest ~]#
[root@dockertest ~]# docker pull 192.168.100.38:8081/kakalong/myubuntu01_commit:1.0
1.0: Pulling from kakalong/myubuntu01_commit
7b1a6ab2e44d: Already exists
f7786e239110: Pull complete
Digest: sha256:e7a13de8470f976b29bcf27981beb6172762e4cc16fb18f2f9ef7e1f8794cf70
Status: Downloaded newer image for 192.168.100.38:8081/kakalong/myubuntu01_commit:1.0
192.168.100.38:8081/kakalong/myubuntu01_commit:1.0

----------------推送镜像到阿里云------------------

[root@dockertest ~]# docker login --username=卡卡帅哥承担 registry.cn-shenzhen.aliyuncs.com
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

[root@dockertest ~]# docker commit -m="test commit alibaba" -a="kakalong" 057c19a28a22 mynginx_commit:1.0
sha256:0c123c39ab59b7fc56b11bd0bc67f8bac4284ed8450039079f7ae23e0522427b


[root@dockertest ~]# docker tag mynginx_commit:1.0 registry.cn-shenzhen.aliyuncs.com/kakalong/mynginx_commit:1.0

[root@dockertest ~]# docker push registry.cn-shenzhen.aliyuncs.com/kakalong/mynginx_commit:1.0
The push refers to repository [registry.cn-shenzhen.aliyuncs.com/kakalong/mynginx_commit]
9f54eef41275: Pushed
1.0: digest: sha256:e4ab88bdd973b760961f84341ff772cf87b0dced9a686517aeb8af9916ee3b28 size: 529



4. 容器数据卷

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 宿主机和容器之间映射添加容器卷
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名

# 查看数据卷是否挂载成功
docker inspect 容器ID
# 宿主机和容器之前数据共享
docker修改,主机同步获得
主机修改,docker同步获得
docker容器stop,主机修改,docker容器重启看数据是否同步。

# 默认rw 读写,只读 ro
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:rw 镜像名

# 只读
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro 镜像名

# 卷的继承和共享
# 容器1完成和宿主机的映射
docker run -it --privileged=true -v /mydocker/u:/tmp --name u1 ubuntu
# 容器2继承容器1的卷规则
docker run -it --privileged=true --volumes-from 父类 --name u2 ubuntu

5. DockerFile解析

Dockerfile 指令 说明
FROM 指定基础镜像,用于后续的指令构建。
MAINTAINER 指定Dockerfile的作者/维护者。
LABEL 添加镜像的元数据,使用键值对的形式。
RUN 在构建过程中在镜像中执行命令。
CMD 指定容器创建时的默认命令。(可以被覆盖)
ENTRYPOINT 设置容器创建时的主要命令。(不可被覆盖)
EXPOSE 声明容器运行时监听的特定网络端口。
ENV 在容器内部设置环境变量。
ADD 将文件、目录或远程URL复制到镜像中。
COPY 将文件或目录复制到镜像中。
VOLUME 为容器创建挂载点或声明卷。
WORKDIR 设置后续指令的工作目录。
USER 指定后续指令的用户上下文。
ARG 定义在构建过程中传递给构建器的变量,可使用 “docker build” 命令设置。
ONBUILD 当该镜像被用作另一个构建过程的基础时,添加触发器。
STOPSIGNAL 设置发送给容器以退出的系统调用信号。
HEALTHCHECK 定义周期性检查容器健康状态的命令。
SHELL 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。

6. Docker网络

Host 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
Bridge 此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。
None 该模式关闭了容器的网络功能。
Container 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。

当你安装Docker时,它会自动创建三个网络。你可以使用以下docker network ls命令列出这些网络:

1
2
3
4
5
[root@server1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
0147b8d16c64 bridge bridge local
2da931af3f0b host host local
63d31338bcd9 none null local

Docker内置这三个网络,运行容器时,你可以使用该--network标志来指定容器应连接到哪些网络。

该bridge网络代表docker0所有Docker安装中存在的网络。除非你使用该docker run --network=选项指定,否则Docker守护程序默认将容器连接到此网络。

我们在使用docker run创建Docker容器时,可以用 --net 选项指定容器的网络模式,Docker可以有以下4种网络模式:

  • host模式:使用 –net=host 指定。
  • none模式:使用 –net=none 指定。
  • bridge模式:使用 –net=bridge 指定,默认设置。
  • container模式:使用 –net=container:NAME_or_ID 指定。

6.1 host模式

如果启动容器时使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

6.2 container模式

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信

6.3 none模式

使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过–network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

6.4 bridge模式

相当于Vmware中的Nat模式,容器使用独立network Namespace,并连接到docker0虚拟网卡。bridge模式是docker的默认网络模式,不写–net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器都会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。

Docker容器完成bridge网络配置的过程如下:
  1. 在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
   2. Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以vethb22db1b4这样类似的名字命名,并将这个网络设备加入到docker0网桥中。
   3. 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。

   宿主机和Docker容器之间是可以进行网络连接的,同样的,Docker容器和容器之间也可以直接进行网络连接。

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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
# docker启动后linux主机多了一个docker0虚拟网桥
[root@dockertest ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:ef:4a:95 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.89/24 brd 192.168.100.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::d8f1:535c:bcb5:b20f/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 02:42:41:b0:80:d0 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:41ff:feb0:80d0/64 scope link
valid_lft forever preferred_lft forever

# 启动两个ng
[root@dockertest ~]# docker run --name=nginx_bridge --net=bridge -p 80:80 -d nginx
6fb4ce745f776b9b5b75472648df13eb769625b2333546eebf2e6f5129855d67

[root@dockertest ~]# docker run --name=nginx_bridge_2 --net=bridge -p 81:80 -d nginx
93d4f49f2ea03fceb6cf7347147ff35f8f561362a96634f244d01f999e381d3f

# 再看主机网络配置;veth701440b、vethadbdef3是主机中的veth设备
[root@dockertest ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:ef:4a:95 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.89/24 brd 192.168.100.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::d8f1:535c:bcb5:b20f/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:41:b0:80:d0 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:41ff:feb0:80d0/64 scope link
valid_lft forever preferred_lft forever
13: veth701440b@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP
link/ether 72:5a:af:a8:bf:0e brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::705a:afff:fea8:bf0e/64 scope link
valid_lft forever preferred_lft forever
15: vethadbdef3@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP
link/ether 5a:4d:85:c4:a5:ff brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::584d:85ff:fec4:a5ff/64 scope link
valid_lft forever preferred_lft forever

# docker0的两个veth的设备
[root@dockertest ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.024241b080d0 no veth701440b
vethadbdef3
# 查询容器
[root@dockertest ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
93d4f49f2ea0 nginx "/docker-entrypoint.…" 6 minutes ago Up 6 minutes 0.0.0.0:81->80/tcp, :::81->80/tcp nginx_bridge_2
6fb4ce745f77 nginx "/docker-entrypoint.…" 8 minutes ago Up 8 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp nginx_bridge

# 查看容器详情
[root@dockertest ~]# docker inspect 93d4f49f2ea0
[
{
"Id": "93d4f49f2ea03fceb6cf7347147ff35f8f561362a96634f244d01f999e381d3f",
"Created": "2024-04-05T14:57:31.311461325Z",
"Path": "/docker-entrypoint.sh",
"Args": [
"nginx",
"-g",
"daemon off;"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 11450,
"ExitCode": 0,
"Error": "",
"StartedAt": "2024-04-05T14:57:31.52201822Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85",
"ResolvConfPath": "/var/lib/docker/containers/93d4f49f2ea03fceb6cf7347147ff35f8f561362a96634f244d01f999e381d3f/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/93d4f49f2ea03fceb6cf7347147ff35f8f561362a96634f244d01f999e381d3f/hostname",
"HostsPath": "/var/lib/docker/containers/93d4f49f2ea03fceb6cf7347147ff35f8f561362a96634f244d01f999e381d3f/hosts",
"LogPath": "/var/lib/docker/containers/93d4f49f2ea03fceb6cf7347147ff35f8f561362a96634f244d01f999e381d3f/93d4f49f2ea03fceb6cf7347147ff35f8f561362a96634f244d01f999e381d3f-json.log",
"Name": "/nginx_bridge_2",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "bridge",
"PortBindings": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "81"
}
]
},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
40,
209
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": [],
"BlkioDeviceWriteBps": [],
"BlkioDeviceReadIOps": [],
"BlkioDeviceWriteIOps": [],
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": [],
"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",
"/sys/devices/virtual/powercap"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/a2af914147ff1474a876f18d7b7808b95aeb043552787fc52028dde879b1442a-init/diff:/var/lib/docker/overlay2/0be3b772b630031b66349f9d688db74c353803f7c59c5c84e506c8f391f052b4/diff:/var/lib/docker/overlay2/54ec853940602ba0b2bb56e734314e1574521a782523912f838525c912ac30fd/diff:/var/lib/docker/overlay2/7f68adad17b9a020bd004b88cb7f657a15c5a0fdafc0358380fa35571a7dc9af/diff:/var/lib/docker/overlay2/d2e577e06f1bef508ab637680c0f484e441e29803af6ee17bb3e34e1301a2390/diff:/var/lib/docker/overlay2/e61cf1d804ebac7310e390da7fea9a39c66b81a60293b003c0fa453eaf24a9ba/diff:/var/lib/docker/overlay2/7d1fb9e6438f5d29b8ea909c42db4efb2b4e6304f59a80404bdc3065a931d94b/diff",
"MergedDir": "/var/lib/docker/overlay2/a2af914147ff1474a876f18d7b7808b95aeb043552787fc52028dde879b1442a/merged",
"UpperDir": "/var/lib/docker/overlay2/a2af914147ff1474a876f18d7b7808b95aeb043552787fc52028dde879b1442a/diff",
"WorkDir": "/var/lib/docker/overlay2/a2af914147ff1474a876f18d7b7808b95aeb043552787fc52028dde879b1442a/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "93d4f49f2ea0",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.21.5",
"NJS_VERSION=0.7.1",
"PKG_RELEASE=1~bullseye"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"Image": "nginx",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGQUIT"
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "3d164125bf57274a545c577611c4c920d443fbe4ec1d15d05bca926224e1186e",
"SandboxKey": "/var/run/docker/netns/3d164125bf57",
"Ports": {
"80/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "81"
},
{
"HostIp": "::",
"HostPort": "81"
}
]
},
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "6f20721bf27247fa1e11dd6b47db664a895f761e71d4e75207b2880fcf38d814",
"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,
"MacAddress": "02:42:ac:11:00:03",
"NetworkID": "c619f5015f4c8f2ca6b08bdc9ec3d1d377a14447593b645402783cea5d8f67c6",
"EndpointID": "6f20721bf27247fa1e11dd6b47db664a895f761e71d4e75207b2880fcf38d814",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DriverOpts": null,
"DNSNames": null
}
}
}
}
]

# 查看网桥信息
[root@dockertest ~]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "c619f5015f4c8f2ca6b08bdc9ec3d1d377a14447593b645402783cea5d8f67c6",
"Created": "2024-04-03T22:53:02.78681339+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"6fb4ce745f776b9b5b75472648df13eb769625b2333546eebf2e6f5129855d67": {
"Name": "nginx_bridge",
"EndpointID": "8a61ed6ed4b6471425ff78b1b3d864c33ee8f4c9c1a769efc97ab26e0c3943d0",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"93d4f49f2ea03fceb6cf7347147ff35f8f561362a96634f244d01f999e381d3f": {
"Name": "nginx_bridge_2",
"EndpointID": "6f20721bf27247fa1e11dd6b47db664a895f761e71d4e75207b2880fcf38d814",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]

6.5 容器互联

在微服务部署的场景下,注册中心是使用服务名来唯一识别微服务的,而我们上线部署的时候微服务对应的IP地址可能会改动,所以我们需要使用容器名来配置容器间的网络连接。使–link可以完成这个功能。

首先不设置–link的情况下,是无法通过容器名来进行连接的。centos_02容器是可以直接ping通centos_01的容器ip,但是无法ping通centos_01的容器name:

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
# 启动两个centos容器
[root@dockertest ~]# docker run --name centos_01 -d -i -t centos /bin/bash
2f8bd3075d2171f722793e71403a3d6e4e9efee74c200b2f882e3c403de74d37
[root@dockertest ~]#
[root@dockertest ~]#
[root@dockertest ~]#
[root@dockertest ~]# docker run --name centos_02 -d -i -t centos /bin/bash
2f19f8a807b3bea96244656722748260f8ab856642703f21dd49ca5d01bf0a29
# 查看ip
[root@dockertest ~]# docker exec -it centos_01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
20: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:4/64 scope link
valid_lft forever preferred_lft forever

[root@dockertest ~]# docker exec -it centos_02 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:5/64 scope link
valid_lft forever preferred_lft forever
# 互相ping ip,是可以联通的
[root@dockertest ~]# docker exec -it centos_02 ping 172.17.0.4
PING 172.17.0.4 (172.17.0.4) 56(84) bytes of data.
64 bytes from 172.17.0.4: icmp_seq=1 ttl=64 time=0.097 ms
64 bytes from 172.17.0.4: icmp_seq=2 ttl=64 time=0.160 ms
64 bytes from 172.17.0.4: icmp_seq=3 ttl=64 time=0.107 ms
64 bytes from 172.17.0.4: icmp_seq=4 ttl=64 time=0.099 ms
64 bytes from 172.17.0.4: icmp_seq=5 ttl=64 time=0.099 ms
64 bytes from 172.17.0.4: icmp_seq=6 ttl=64 time=0.100 ms
64 bytes from 172.17.0.4: icmp_seq=7 ttl=64 time=0.101 ms
[root@dockertest ~]#
[root@dockertest ~]#
[root@dockertest ~]# docker exec -it centos_01 ping 172.17.0.5
PING 172.17.0.5 (172.17.0.5) 56(84) bytes of data.
64 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.100 ms
64 bytes from 172.17.0.5: icmp_seq=3 ttl=64 time=0.039 ms
64 bytes from 172.17.0.5: icmp_seq=4 ttl=64 time=0.238 ms

添加参数 –link,可以通过容器name进行连接。centos_03容器link到centos_01,所以centos_03可以直接通过ping centos_01的容器名去ping通,但是反过来centos_01去ping centos_03的容器名是ping不通的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@dockertest ~]#  docker run -d -P -it --name centos_03 --link centos_01 5d0da3dc9764
f3b90891a5d07172d1eca8f13799e38129c5073725f3c095db83cbf49a39bfde
[root@dockertest ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3b90891a5d0 5d0da3dc9764 "/bin/bash" 2 minutes ago Up 2 minutes centos_03
2f19f8a807b3 centos "/bin/bash" 10 minutes ago Up 10 minutes centos_02
2f8bd3075d21 centos "/bin/bash" 10 minutes ago Up 10 minutes centos_01

[root@dockertest ~]# docker exec -it centos_03 ping centos_01
PING centos_01 (172.17.0.4) 56(84) bytes of data.
64 bytes from centos_01 (172.17.0.4): icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from centos_01 (172.17.0.4): icmp_seq=2 ttl=64 time=0.102 ms
64 bytes from centos_01 (172.17.0.4): icmp_seq=3 ttl=64 time=0.159 ms
64 bytes from centos_01 (172.17.0.4): icmp_seq=4 ttl=64 time=0.101 ms
64 bytes from centos_01 (172.17.0.4): icmp_seq=5 ttl=64 time=0.101 ms
[root@dockertest ~]#
[root@dockertest ~]# docker exec -it centos_01 ping centos_03
ping: centos_03: Name or service not known

–link的原理就是在centos_03容器的hosts文件中添加了要去link的centos_01容器的容器名和ip地址映射。但是因为docker0不支持容器名访问,所以–link设置容器互连的方式也不再推荐使用了,更多地选择自定义网络。

6.6 自定义网络(推荐使用)

1
2
3
4
5
6
7
8
9
10
11
12
[root@dockertest ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
5b8aa81df8754f97ee09f483b4932c18970ff1ada5192891f1742d410260076b
[root@dockertest ~]#
[root@dockertest ~]#
[root@dockertest ~]#
[root@dockertest ~]#
[root@dockertest ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
c619f5015f4c bridge bridge local
ee2d66fdc77d host host local
5b8aa81df875 mynet bridge local
9c1bf95ba7de none null local

查看新创键的mynet详细信息:

使用自定义网络创建容器后,相同网络name下的容器,不管是通过容器IP还是容器name,都可以进行网络通信:

创建两个使用相同自定义网络的容器:

1
2
3
4
5
6
7
8
[root@dockertest ~]# 
[root@dockertest ~]#
[root@dockertest ~]# docker run -d -P --name centos-net-01 --net mynet -it 5d0da3dc9764 /bin/bash
6afbd85ce5887f1031488dfa7e0b2a18d1cb62e5b25ef3ce4e41825f1b1ce395
[root@dockertest ~]#
[root@dockertest ~]#
[root@dockertest ~]# docker run -d -P --name centos-net-02 --net mynet -it 5d0da3dc9764 /bin/bash
03daa0c2b87c1201a0fd4edbc2dbad401a7936fd4d0787605200b6e4b8d9386c

测试容器互连:

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
[root@dockertest ~]# 
[root@dockertest ~]# docker exec -it centos-net-01 ping centos-net-02
PING centos-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from centos-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.049 ms
64 bytes from centos-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.101 ms
64 bytes from centos-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.099 ms
64 bytes from centos-net-02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.176 ms
64 bytes from centos-net-02.mynet (192.168.0.3): icmp_seq=5 ttl=64 time=0.037 ms
[root@dockertest ~]#
[root@dockertest ~]#
[root@dockertest ~]#
[root@dockertest ~]# docker exec -it centos-net-02 ping centos-net-01
PING centos-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.023 ms
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.166 ms
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.236 ms
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=4 ttl=64 time=0.097 ms
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=5 ttl=64 time=0.098 ms
[root@dockertest ~]#
[root@dockertest ~]# docker exec -it centos-net-02 ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.073 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.154 ms
64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.098 ms
64 bytes from 192.168.0.2: icmp_seq=4 ttl=64 time=0.098 ms
64 bytes from 192.168.0.2: icmp_seq=5 ttl=64 time=0.099 ms


6.7 网络连通

在没有使用connect命令的情况下,不同网络间的容器是无法进行网络连接的。

不同Docker网络之间的容器想要连接的话,需要把该容器注册到另一个容器所在的网络上,使用docker connect命令。

docker network connect mynet centos_01

connect设置成功后,我们可以看到新注册进来的容器信息:

接下来进行容器双向连接测试:

centos-net-01 ping centos_01,连接成功

1
2
3
4
5
6
[root@dockertest ~]# docker exec -it centos-net-01 ping centos_01
PING centos_01 (192.168.0.4) 56(84) bytes of data.
64 bytes from centos_01.mynet (192.168.0.4): icmp_seq=1 ttl=64 time=0.059 ms
64 bytes from centos_01.mynet (192.168.0.4): icmp_seq=2 ttl=64 time=0.115 ms
64 bytes from centos_01.mynet (192.168.0.4): icmp_seq=3 ttl=64 time=0.096 ms
64 bytes from centos_01.mynet (192.168.0.4): icmp_seq=4 ttl=64 time=0.096 ms

centos_01 ping centos-net-01,连接成功

1
2
3
4
5
6
7
8
9
[root@dockertest ~]# docker exec -it centos_01 ping centos-net-01
PING centos-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.046 ms
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.197 ms
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.233 ms
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=4 ttl=64 time=0.156 ms
[root@dockertest ~]# 未连接到mynet的容器还是无法访问
[root@dockertest ~]# docker exec -it centos-net-01 ping centos_02
ping: centos_02: Name or service not known

7. Docker安装案例


本站由 卡卡龙 使用 Stellar 1.27.0 主题创建

本站访问量 次. 本文阅读量 次.