Docker网络模式

文章目录

一、简述

二、host模式

三、none模式

四、container模式

五、bridge模式

六、自建子网


一、简述

Docker支持4种网络模式,如下所示:
1、host模式:使用 --network = host 参数;
2、container模式:使用 --network = container:NAME_or_ID 参数;
3、none模式:使用 --network = none 参数;
4、bridge模式:使用 --network = bridge 参数。缺省情况下,使用bridge模式(即,使用docker run启动一个容器时,若不指定 --network 参数,则默认使用bridge模式)。

二、host模式

在host模式下,容器和宿主机共用一个网络命名空间(Network Namespace),容器共享宿主机的网卡、IP和端口等资源。容器内的服务可以直接使用宿主机的端口,也可以直接使用宿主机的 IP 进行通信,不存在虚拟化网络带来的开销,性能上有很大的提升。但是,host模式也降低了容器与容器之间、容器与宿主机之间网络的隔离性,会引起网络资源的竞争和冲突。

缺点:隔离性差,不安全,会占用宿主机的端口。

优点:无需配置网络策略,只要能访问到宿主机,就能访问到容器。外部主机可以通过“宿主机IP:容器端口”访问容器,不用通过参数“-p 宿主机端口:容器端口”进行端口映射

三、none模式

在none模式下,Docker容器拥有自己的网络命名空间(Network Namespace),但不会进行任何网络配置。即,none模式的Docker容器没有网卡、IP、路由等信息,需要我们自己为Docker容器添加网卡、配置IP等操作。

四、container模式

在container模式下,一个Docker容器会共享其他Docker容器的网络命名空间(Network Namespace),在这两个Docker容器之间不存在网络隔离。同时,这两个Docker容器又与宿主机、其他Docker容器存在网络隔离。

共享网络命名空间的这两个容器之间可以相互通信。虽然是两个容器,但可以理解为在同一容器里面,可以用localhost访问。这两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。

K8S为Pod创建一个基础设施容器,同一Pod下的容器都以container模式共享这个基础设施容器的网络命名空间,相互之间以localhost访问,构成一个统一的整体。

五、bridge模式

缺省情况下,Docker容器就是bridge模式

在bridge模式下,Docker容器没有对外IP(只有内部IP,172.17.0.x网段)。宿主机以外的世界不能直接通过容器IP和容器进行通信,只有宿主机可以直接通过容器IP和容器进行通信。但Docker容器通过宿主机的NAT规则后可以访问外网。

外部主机可以通过“宿主机IP:宿主机端口”访问容器,但是必须通过“-p 宿主机端口:容器端口”进行端口映射

##运行MySQL容器
[root@localhost ~]# docker run --name container1 -p 3306:3306 \
                    -e MYSQL_ROOT_HOST=% -e MYSQL_ROOT_PASSWORD=123456 \
                    -v /etc/localtime:/etc/localtime \
                    -v /data/docker/mysql/conf/:/etc/mysql/conf.d \
                    -v /data/docker/mysql/logs:/var/log \
                    -v /data/docker/mysql/data:/var/lib/mysql --restart=always \
                    -d mysql:5.7

## 用docker inspect命令查看容器内部情况
[root@localhost ~]# docker inspect container1
......
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "f002912c521c5ca3bc3f......",
                    "EndpointID": "24ba5637c0b9795e868......",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
......

可以看到默认情况下(未设置--network参数)container1是bridge模式,它的IP是172.17.0.2,它的网关是172.17.0.1。

## 将容器container1删除
[root@localhost ~]# docker rm -f container1

## 删除后,docker run重新启动一个container2
[root@localhost ~]# docker run --name container2 -p 3306:3306 \
                    -e MYSQL_ROOT_HOST=% -e MYSQL_ROOT_PASSWORD=123456 \
                    -v /etc/localtime:/etc/localtime \
                    -v /data/docker/mysql/conf/:/etc/mysql/conf.d \
                    -v /data/docker/mysql/logs:/var/log \
                    -v /data/docker/mysql/data:/var/lib/mysql --restart=always \
                    -d mysql:5.7

## 用docker inspect命令查看容器内部情况
[root@localhost ~]# docker inspect container2
......
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "35837a848219fd42bfb6......",
                    "EndpointID": "33e4998ffb417ff29ef......",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
......

可见,container1被删除后,它之前所使用的IP地址被释放,然后被分配给了之后的container2。所以,随着一个Docker容器的启/停/增/删等操作,该容器的IP也可能会动态变化的。必须对Docker容器进行规划,不能通过IP地址来查找某个Docker容器。

Docker进程默认在宿主机上创建一个名叫 docker0 的网桥(其上有一个 docker0 内部接口),它在内核层连通了物理网卡和虚拟网卡,这就将所有Docker容器和宿主机都放到同一个网络。Docker默认指定了 docker0 接口 的 IP 地址和子网掩码,让宿主机和容器之间可以通过 docker0 网桥相互通信。凡是连接在 docker0 网桥上的Docker容器,就可以通过它来进行通信。

可以看一眼默认的网桥名:

[root@localhost ~]# docker network inspect bridge | grep name
            "com.docker.network.bridge.name": "docker0",

可以看到默认的网桥名字就叫docker0

Docker进程启动一个Docker容器时,会根据docker0网桥的网段分配给Docker容器一个IP地址,称为容器IP。同时,docker0网桥是每个Docker容器的默认网关。因为在同一宿主机内的Docker容器都接入同一个docker0网桥,这样Docker容器之间就能够通过容器IP直接通信。 

docker run 的时候,没有指定 --network 参数的话,默认使用bridge模式,使用的就是docker0网桥。在Linux宿主机执行 ip addr 命令,就可以看到 docker0 和自己create的Docker 子网(六、自建子网部分讲)eth0,eth1,eth2……代表网卡一,网卡二,网卡三……,lo代表127.0.0.1,即localhost,inet addr用来表示网卡的IP地址

网桥docker0创建一对 对等的虚拟设备接口,一个叫veth,另一个叫eth0,成对匹配。整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth。在宿主机和容器内分别创建一个虚拟接口,并让他们彼此连通(这样一对接口叫veth pair)。
1)每个Docker容器内部也有一块网卡,网卡接口叫eth0;
2)docker0上面的每个veth匹配某个Docker容器内部的eth0,两两配对,一一匹配。

通过上述,将宿主机上的所有Docker容器都连接到这个内部网络上。两个Docker容器在同一个网络下,会从这个网桥docker0下各自拿到分配的IP,此时两个容器的网络就互通了。

Docker默认的bridge网络模式

如上图,docker0 网桥相当于一个交换机,它用于把宿主机的物理网卡和上面的Docker容器的虚拟网卡进行连接,让其可以进行联网通信。而docker0的IP地址就是Docker容器的网关。上图中红框所标出的就类似于进行连接的RJ45水晶头。eth0就相当于是Docker容器中虚拟出的网卡接口,veth相当于交换机上的接口。

六、自建子网

在宿主机上通过“docker network create --subnet 子网IP/掩码 子网名”创建子网,然后docker run时,使用“--network 子网名 --ip 所属子网的IP”

只有宿主机可以通过“容器IP:容器端口”访问容器,外部主机不能访问容器

示例:

## 创建子网
docker network create --subnet 192.168.100.0/24 --gateway=192.168.100.1 my-net

## 使用创建的子网来运行容器
docker run -d \
-p 8111:8111 \
-p 8112:8112 \
--name my-nginx \
--restart=always \
-v /etc/localtime:/etc/localtime \
-v ~/data/docker/nginx/static:/etc/nginx/html \
-v ~/data/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v ~/data/docker/nginx/log:/var/log/nginx \
-v ~/data/docker/nginx/conf.d:/etc/nginx/conf.d \
--network my-net --ip 192.168.100.2 \
nginx:1.18.0
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乌托邦的逃亡者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值