文章目录
一、Docker 的四种网络模式
网络模式 | 配置 | 说明 |
---|---|---|
host | -net=host | 容器与宿主机共享一个网络名称空间和网络协议栈 |
container | -net=container:NAME or ID | 多个容器之间共享一个网络名称空间 |
none | -net=none | 容器有独立的网络名称空间,但并没有对其进行任何网络设置,如分配veth pair和网桥连接,配置IP等。 |
bridge | -net=bridge | 默认模式 |
host模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。
container模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
bridge模式
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。
bridge模式是docker的默认网络模式,不写–net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。
二、docker 自定义网络
2.1 docker 默认的网络列表
[root@docker ~]# docker network list
NETWORK ID NAME DRIVER SCOPE
830a2384b6ef bridge bridge local
75814a6a9369 host host local
64caab163028 none null local
[root@docker ~]#
2.2 自定义网络
语法:docker network create --subnet 指定的子网网段 子网网段名称
[root@docker ~]# docker network create --subnet 172.100.0.0/16 subnet01
549f92f97df5b0ead3eddc0083e4b80fd67031d09a59ed95ede805d070bb82c4
[root@docker ~]# docker netwokr list
docker: 'netwokr' is not a docker command.
See 'docker --help'
[root@docker ~]# docker network list
NETWORK ID NAME DRIVER SCOPE
830a2384b6ef bridge bridge local
75814a6a9369 host host local
64caab163028 none null local
549f92f97df5 subnet01 bridge local
[root@docker ~]#
2.3 创建容器时指定固定的IP
语法:docker run -[ i ,t ,d] --name 容器名称 --net 指定的网络名称 --ip 指定的网络名称的子网IP 需要运行的镜像 [运行环境:/bin/bash /bin/sh /bin/init]
[root@docker ~]# docker run -itd --name centos01 --net subnet01 --ip 172.100.0.2 centos:7 /bin/bash
da6b97c02eef994139c33a77992b2770b6d9ffecabbe9ed450da089df0bf9d03
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
da6b97c02eef centos:7 "/bin/bash" 2 seconds ago Up 2 seconds centos01
[root@docker ~]# docker inspect centos01 | grep "IPAdd"
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.100.0.2",
[root@docker ~]#
2.4 暴露端口
[root@docker ~]# docker run -d --name nginx_01 -P nginx:latest // -P 表示随机暴露一个端口个宿主机(范围49153-65535)
b7e746884fd5a4dfb46403dbe094014397c0fce43f18e37af8e75dbbe661b8e2
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b7e746884fd5 nginx:latest "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp nginx_01
da6b97c02eef centos:7 "/bin/bash" 7 minutes ago Up 7 minutes centos01
[root@docker ~]# docker run -d --name nginx_02 -p 80:80 nginx:latest //-p 需要手动指定暴露给宿主机的端口
2e7fc63828f3bd551ccc6d31ed3029e0aaf754273ed890112f438553cad3ed35
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2e7fc63828f3 nginx:latest "/docker-entrypoint.…" 2 seconds ago Up 1 second 0.0.0.0:80->80/tcp, :::80->80/tcp nginx_02
b7e746884fd5 nginx:latest "/docker-entrypoint.…" 23 seconds ago Up 22 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp nginx_01
da6b97c02eef centos:7 "/bin/bash" 8 minutes ago Up 8 minutes centos01
[root@docker ~]#
2.5 容器互联
容器互联是通过容器的名称在容器间建立一条专门网络通信隧道,从而实现容器得互联。
在运行docker run 得时候使用 --link 选项可以实现容器之间得互联。
格式为 --link name:alias 其中 name 是需要连接得容器名称 alias 是这个连接得别名
注意点:容器互联是通过容器名称来实现的,–name可以给容器创建一个名称(唯一),如果已经命名了一个相同名称的容器,当要再次使用这个容器名称的时候,需要先删除之前创建的同名的容器。
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2e7fc63828f3 nginx:latest "/docker-entrypoint.…" 2 seconds ago Up 1 second 0.0.0.0:80->80/tcp, :::80->80/tcp nginx_02
b7e746884fd5 nginx:latest "/docker-entrypoint.…" 23 seconds ago Up 22 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp nginx_01
da6b97c02eef centos:7 "/bin/bash" 8 minutes ago Up 8 minutes centos01
[root@docker ~]# docker run -d --name nginx_03 -P --link nginx_02:nginx03_link_nginx02 nginx:latest
这里需要跟容器nginx_02通信
f6bd68ad95e507ae3510556e9049aef99bb53963894bd6844145c705320ab91f
[root@docker ~]# docker exec -it nginx_03 /bin/bash
root@f6bd68ad95e5:/# ping nginx_02
bash: ping: command not found //提示没有ping命令
root@f6bd68ad95e5:/# apt-get update && apt-get install iputils-ping //下载ping命令
Get:1 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB]
Get:2 http://deb.debian.org/debian buster InRelease [122 kB]
Get:3 http://security.debian.org/debian-security buster/updates/main amd64 Packages [302 kB]
Get:4 http://deb.debian.org/debian buster-updates InRelease [51.9 kB]
Get:5 http://deb.debian.org/debian buster/main amd64 Packages [7907 kB]
Get:6 http://deb.debian.org/debian buster-updates/main amd64 Packages [15.2 kB]
Fetched 8464 kB in 1min 45s (80.9 kB/s)
Reading package lists... Done
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
libcap2 libcap2-bin libpam-cap
The following NEW packages will be installed:
iputils-ping libcap2 libcap2-bin libpam-cap
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 104 kB of archives.
After this operation, 319 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
......省略部分内容
Setting up iputils-ping (3:20180629-2+deb10u2) ...
Processing triggers for libc-bin (2.28-10) ...
root@f6bd68ad95e5:/# ping nginx_02 //容器互联成功
PING nginx03_link_nginx02 (172.17.0.3) 56(84) bytes of data.
64 bytes from nginx03_link_nginx02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.229 ms
64 bytes from nginx03_link_nginx02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.096 ms
64 bytes from nginx03_link_nginx02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.111 ms
^C
--- nginx03_link_nginx02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.096/0.145/0.229/0.060 ms
root@f6bd68ad95e5:/#
三、数据卷和数据卷容器
在Docker中,为了方便管理容器中产生的数据或者是服务的配置文件,就涉及到容器的数据管理操作。
管理Docker容器中数据主要有两种方式:数据卷(Data Volume)和数据卷容器(Data Volumes Containers)
3.1 创建数据卷
语法:docker run -v [name1] -v [name2] … --name 容器名称 镜像名称:标签
-v 可以在容器中创建数据卷,多个 -v 可以创建多个
创建容器centos01 并将数据卷挂载到容器的 /data1 /data2 目录上
[root@docker ~]# docker run -itd -v /data1 -v /data2 --name centos01 centos:7 /bin/bash
addab0d2f660deed30f45cd8eb4e353491201f0dbc482973d780157c498b22de
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
addab0d2f660 centos:7 "/bin/bash" 7 seconds ago Up 7 seconds centos01
[root@docker ~]# docker exec -it centos01 /bin/bash
[root@addab0d2f660 /]# ll
total 12
-rw-r--r-- 1 root root 12114 Nov 13 2020 anaconda-post.log
lrwxrwxrwx 1 root root 7 Nov 13 2020 bin -> usr/bin
drwxr-xr-x 2 root root 6 Sep 6 16:16 data1
drwxr-xr-x 2 root root 6 Sep 6 16:16 data2
......省略部分内容
[root@addab0d2f660 /]#
3.2 挂载主机目录作为数据卷
语法:docker run -v /宿主机目录1:/容器目录1 -v /宿主机目录2:/容器目录2 … --name 容器名称 镜像名称:标签
-v 可以在容器中创建数据卷,多个 -v 可以创建多个
注意:挂载的宿主机本地目录必须是绝对路径,如果宿主机没有,会自动的创建改目录,容器中也是一样
创建容器centos02 并将宿主机的 /data1 /data2 目录挂载到容器的 /data1 /data2 的目录上
[root@docker ~]# docker run -itd -v /data1:/data1 -v /data2:/data2 --name centos02 c
e04e4f382b3ff74396ec3eb2162ca765207e0c4bac8d1f61b45f48aed3c79bb7
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAM
e04e4f382b3f centos:7 "/bin/bash" 4 seconds ago Up 3 seconds cen
addab0d2f660 centos:7 "/bin/bash" 8 minutes ago Up 8 minutes cen
[root@docker ~]#
宿主机查看是否创建了挂载目录
[root@docker ~]# cd /
[root@docker /]# ls
bin data1 dev home lib64 mnt proc run srv tmp var
boot data2 etc lib media opt root sbin sys usr
在宿主机挂载的目录中创建文件并追加内容
[root@docker /]# cd data1
[root@docker data1]# echo "hell" >> 1.txt
[root@docker data1]# cd /data2
[root@docker data2]# echo "world" >> 2.txt
[root@docker data2]#
进入容器查看是否同步
[root@docker ~]# docker exec -it centos02 /bin/bash
[root@e04e4f382b3f /]# ls
anaconda-post.log data1 dev home lib64 mnt proc run srv tmp var
bin data2 etc lib media opt root sbin sys usr
[root@e04e4f382b3f /]# cd /data1
[root@e04e4f382b3f data1]# ls
1.txt
[root@e04e4f382b3f data1]# cat 1.txt
hell
[root@e04e4f382b3f data1]# cd /data2
[root@e04e4f382b3f data2]# ls
2.txt
[root@e04e4f382b3f data2]# cat 2.txt
world
[root@e04e4f382b3f data2]#
3.3 数据卷容器
数据卷容器的作用是,让容器与容器之间实现文件共享。这里使用刚刚创建的数据卷容易 centos01 来做演示
创建容器centos02 指定数据卷来自容器centos01
[root@docker ~]# docker run -itd --volumes-from centos01 --name centos03 centos:7 /bin/bash
67968189dab74d6c6ffa1f8c39037cd582c86ac6f601de1b38cfb82ac468d451
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
67968189dab7 centos:7 "/bin/bash" 9 seconds ago Up 8 seconds centos03
e04e4f382b3f centos:7 "/bin/bash" 14 minutes ago Up 14 minutes centos02
addab0d2f660 centos:7 "/bin/bash" 23 minutes ago Up 23 minutes centos01
进入容器centos01 并在 /data1 /data2 目录下创建文件并追加内容
[root@docker ~]# docker exec -it centos01 /bin/bash
[root@addab0d2f660 /]# ls
anaconda-post.log data1 dev home lib64 mnt proc run srv tmp var
bin data2 etc lib media opt root sbin sys usr
[root@addab0d2f660 /]# echo "hello" >> /data1/1.txt
[root@addab0d2f660 /]# echo "world" >> /data2/1.txt
[root@addab0d2f660 /]#
进入容器centos03 查看文件是否同步
[root@docker ~]# docker exec -it centos03 /bin/bash
[root@67968189dab7 /]# ls
anaconda-post.log data1 dev home lib64 mnt proc run srv tmp var
bin data2 etc lib media opt root sbin sys usr
[root@67968189dab7 /]# cat /data1/1.txt
hello
[root@67968189dab7 /]# cat /data2/1.txt
world
[root@67968189dab7 /]#