一、docker网络概述
1、docker网络实现的原理
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,成为Container-IP,同时Docker’网桥是 每个容器的默认网关。
因为同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
Docker网桥是宿主机虚拟出来的,并不是真实存在网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过Container-IP访问到容器。
如果容器希望外部访问能访问到,可以通过映射容器端口到宿主主机(端口映射),即 docker run创建容器时通过-p或-P参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器 。
2、容器的端口映射
1).端口映射
- 把容器的端口映射为宿主机的一个随机或者特定端口,使用外部用户可以访问容器服务
- 端口映射本是在容器底层做了 iptables 地址转发,出去的流量做 SNAT 源地址转发,进来的流量做 DNAT 目标地址转发。
2).四种端口映射
- 随机端口映射:就是把容器的端口随机映射为宿主机的一个端口。
- 指定端口映射:就是把容器的端口映射为宿主机的指定端口。
- 指定网卡随机端口映射:就是把容器的端口映射为宿主机的指定网卡的随机端口。
- 指定网卡端口映射:就是把容器的端口映射为宿主机的指定网卡的指定端口。
3).端口映射演示
(1).随机端口映射(-P)
把 容器 8080 的端口映射到宿主机的随机端口
docker run -itd -P centos:latest
(2).指定端口映射(-p 宿主机端口:容器端口)
将 web 容器的 8080 端口指定映射到宿主机的 8000 端口
docker run -itd -p 8000:8080 --name web centos
(3).指定网卡随机端口映射(-p ::)
将 tomcat 容器的 8080 端口映射到宿主机 ens33 网卡的随机端口
docker run -itd -p 192.168.153.130::8080 --name tomcat centos
其中:192.168.153.130宿主机ip
查看映射结果,容器 8080 端口映射到了宿主机的192.168.153.130:49153 端口
(4).指定网卡指定端口映射(-p 宿主机IP:宿主机端口:容器端口)
将 mysql 容器的 3306 端口映射到宿主机 ens33 网卡的 13306 端口
docker run -itd -p 192.168.153.130:13306:3306 --name mysql centos
二、docker的网络模式
1.前言
四类网络模式:
选项 | 描述 |
---|---|
HOSt | 基础镜像(容器不会虚拟出自己的网卡,配置主机的IP等,而是使用宿主机的IP和端口; |
Container | 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP,端口范围; |
None | 该模式关闭了网络功能 |
Bridge | 默认为该模式,此模式会为每一个容器分配,设置IP等,并将容器连接到一个docker0的虚拟网桥,通过docker0网桥以及iptables nat表配置与宿主机通信。 |
2.默认网络
当你安装Docker时,它会自动创建三个网络Bridge(创建容器,默认连接到此网络)、none、host。你可以使用一下docker network ls 或者docker network list命令列出这些网络:
docker network ls
docker network llist
3.使用docker run 创建Docker容器,可以用–net或–network选项指定的网络模式
选项 | 描述 |
---|---|
host模式 | 使用--net=host指定; |
none模式 | 使用--net=hnone指定; |
container模式 | 使用--net=container:NAME_ _or_ID指定; |
bridge模式 | 使用--net=bridge指定; |
三、docker网络模式详解
1.host模式
host 模式: 使用–net=host模式指定
相当于VMware中的桥接模式,与宿主机在同一个网络中,但没有独立的IP地址。
Docker 使用了Linux的Namespace技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。一个Network Namespace提供了一份独立的网络环境,包括网卡,路由,iptables 规则等都与其他Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。
Namespace的简要说明:
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。
一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的NetworkNamespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。
但是如果启动容器的时候使用host模式,name这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口范围。此时容器不再拥有隔离的、独立的网格栈,不拥有所有的端口资源。
docker run -itd --name net-test -p 80 mycentos:1.0 /bin/bash
docker run -itd --name net-test1 -p 80 mycentos:1.0 /bin/bash
docker ps
docker attach net-test
ifconfig
2.container模式(K8S使用的模式)
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信
docker ps
#查看容器进程PID
docker inspect -f '{{.State.Pid}}' net-test
#查看容器进程、网络、文件系统等命名空间编号
ls -l /proc/容器进程PID/ns
3.none模式
使用none 模式,docker 容器有自己的network Namespace ,但是并不为Docker 容器进行任何网络配置。也就是说,这个Docker 容器没有网卡,ip, 路由等信息。
这种网络模式下,容器只有lo 回环网络,没有其他网卡。
这种类型没有办法联网,但是封闭的网络能很好的保证容器的安全性,该容器将完全独立于网络,用户可以根据需要为容器添加网卡。此模式拥有所有端口。特殊情况下才会用到,一般不用。
4.bridge模式
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。
bridge模式是docker的默认网络模式,相当于Vmware中的 nat 模式,不写–net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看
bridge模式如下图所示:
四、docker network命令详解
1.network所有的子命令
命令名称 | 说明 |
---|---|
docker network connect | 将容器连接到网络 |
docker network create | 创建一个网络 |
docker network disconnect | 断开容器的网络 |
docker network inspect | 显示一个或多个网络的详细信息 |
docker network ls | 列出所有网络 |
docker network prune | 删除所有未使用的网络 |
docker network rm | 删除一个或多个网络 |
1).语法 docker network connect命令用于将容器连接到网络。可以按名称或ID连接容器。 一旦连接,容器可以与同一网络中的其他容器通信。 用法:
docker network connect [OPTIONS] NETWORK CONTAINER
选项
名称,简写 | 默认 | 说明 |
---|---|---|
--alias | 为容器添加网络范围的别名 | |
--ip | 指定IP地址 | |
--ip6 | 指定IPv6地址 | |
--link | 添加链接到另一个容器 | |
--link-local-ip | 添加容器的链接本地地址 |
2).将正在运行的容器连接到网络
将正在运行的容器(my_container1)连接到网络(multi-host-network)
docker network connect multi-host-network my_container1
启动容器时将其连接到网络(multi-host-network)
还可以使用docker run --network=选项启动容器并立即将其连接到网络
docker run -itd --network=multi-host-network busybox-container
3).指定容器的IP地址
可以指定要分配给容器网络接口的IP地址。
docker network connect --ip 10.10.36.122 multi-host-network container2
4).使用legacy —link选项
可以使用–link选项将另一个容器与首选别名相链接
docker network connect --link container1:c1 multi-host-network container2
为容器创建一个网络别名
–alias选项可用于通过连接到的网络中的另一个名称来解析容器。
docker network connect --alias db --alias mysql multi-host-network container2
5).停止,暂停或重新启动容器的网络影响
可以暂停,重新启动并停止连接到网络的容器。容器在运行时连接到其配置的网络
docker network create --subnet 172.20.0.0/16 --ip-range 172.20.240.0/20 multi-host-network
docker network connect --ip 172.20.128.2 multi-host-network container2
2.docker network create
1).语法
docker network create命令用于创建一个新的网络连接。 DRIVER接受内置网络驱动程序的桥接或覆盖。如果安装了第三方或自己的自定义网络驱动程序,则可以在此处指定DRIVER。 如果不指定–driver选项,该命令将为您自动创建一个桥接网络。 当安装Docker Engine时,会自动创建桥接网络。 该网络对应于Engine传统依赖的docker0网桥。 当启动使用docker run运行新容器时,它将自动连接到此桥接网络。不能删除此默认网桥,但可以使用network create命令创建新的网络。
docker network create [OPTIONS] NETWORK
名称,简写 | 默认 | 说明 |
---|---|---|
--attachable | false | 启用手动容器安装 |
--aux-address | map[] | 网络驱动程序使用的辅助IPv4或IPv6地址 |
--driver, -d | bridge | 驱动程序管理网络 |
--gateway | 用于主子网的IPv4或IPv6网关 | |
--internal | false | 限制对网络的外部访问 |
--ip-range | 从子范围分配容器ip |
|
--ipam-driver | default | IP地址管理驱动程序 |
--ipam-opt | map[] | 设置IPAM驱动程序的具体选项 |
--ipv6 | false | 启用IPv6网络 |
--label | 在网络上设置元数据 | |
--opt, -o | map[] | 设置驱动程序特定选项 |
--subnet | 表示网段的CIDR格式的子网 |
2).连接容器网络
启动容器时,使用–network标志将其连接到网络。 此示例将busybox容器添加到mynet网络:
docker run -itd --network=mynet busybox
如果要在容器运行后将容器添加到网络,请使用docker network connect子命令
3).指定高级选项
创建网络时,引擎默认为网络创建一个不重叠的子网。 该子网不是现有网络的细分。 它纯粹用于IP寻址目的。可以覆盖此默认值,并使用–subnet选项直接指定子网络值。 在桥接网络上,只能创建单个子网:
docker network create --driver=bridge --subnet=192.168.0.0/16 br0
另外,还可以指定–gateway --ip-range和–aux-address选项。
docker network create \
--driver=bridge \
--subnet=172.28.0.0/16 \
--ip-range=172.28.5.0/24 \
--gateway=172.28.5.254 \
br0
如果省略–gateway标志,引擎将从首选池中选择一个。对于覆盖网络和支持它的网络驱动程序插件,可以创建多个子网络。
docker network create -d overlay \
--subnet=192.168.10.0/25 \
--subnet=192.168.20.0/25 \
--gateway=192.168.10.100 \
--gateway=192.168.20.100 \
--aux-address="my-router=192.168.10.5" --aux-address="my-switch=192.168.10.6" \
--aux-address="my-printer=192.168.20.5" --aux-address="my-nas=192.168.20.6" \
my-multihost-network
确保子网不重叠。如果重叠的话网络创建失败,并且引擎会返回错误。
4.)桥接驱动程序选项
创建自定义网络时,默认的网络驱动程序(即bridge)具有可以传递的其他选项。
例如,使用-o或–opt选项在发布端口时指定IP地址绑定
docker network create \
-o "com.docker.network.bridge.host_binding_ipv4"="172.19.0.1" \
simple-network
3、docker network disconnect
1.语法
docker network disconnect命令用于断开容器的网络。容器必须运行才能将其与网络断开连接。
用法:
docker network disconnect [OPTIONS] NETWORK CONTAINER
选项:
名称,简写 | 默认 | 说明 |
---|---|---|
--force, -f | false | 强制容器断开网络的连接 |
2.示例
docker network disconnect multi-host-network container1
4、显示一个或多个网络的详细信息(docker network inspect)
1).语法
docker network inspect命令用于显示一个或多个网络的详细信息。它返回有关一个或多个网络的信息。 默认情况下,此命令将所有结果呈现在JSON对象中。
用法
docker network inspect [OPTIONS] NETWORK [NETWORK...]
2).示例
docker network disconnect multi-host-network container1
5、列出网络(docker network ls)
1).语法
docker network ls命令用于列出网络。列出引擎守护进程知道的所有网络。 这包括跨群集中多个主机的网络。
过滤
当前支持的过滤器有:
- 1、驱动器
- 2、id(网络ID)
- 3、label(label = 或label = = )
- 4、名称(网络名称)
- 5、类型(custom | builtin)
docker network ls [OPTIONS]
选项
名称,简写 | 默认 | 说明 |
---|---|---|
--filter, -f | 提供过滤器值(例如’driver = bridge ‘) |
|
--format | 使用Go模板的美化网络 | |
--no-trunc | false | 不要截断输出 |
-quiet, -q | false | 只显示网络ID |
2)、示例
(1).列出所有网络
docker network ls
(2).使用–no-trunc选项显示完整的网络ID
docker network ls --no-trunc
(3).过滤–DRIVER
驱动程序过滤器根据驱动程序匹配网络。以下示例将网络与桥驱动程序相匹配:
docker network ls --filter driver=bridge
(4).过滤–ID
id过滤器匹配网络ID的全部或部分。以下过滤器匹配所有具有包含804f74e6eb17bcadac76f0f3…字符串的ID的网络。
docker network ls --filter id=804f74e6eb17bcadac76f0fd2fbd01ed76aa31e2e854799fb6cef2d0beb6ba33
还可以过滤ID中的子字符串,如下所示:
docker network ls --filter id=804f74e6eb17
docker network ls --filter id=80
(5).过滤–标签
标签过滤器基于单独存在标签或标签和值来匹配网络。以下过滤器将网络与使用标签进行匹配,而不管其值。
以下过滤器将网络与使用标签与prod值进行匹配。
docker network ls -f "label=usage=prod"
(6).过滤–名称
名称过滤器匹配网络名称的全部或部分。以下过滤器与包含net-test字符串的名称匹配所有网络。
也可以筛选名称中的子字符串,如下所示:
docker network ls --filter name=net-test
(7).过滤–类型
类型过滤器支持两个值; 内置显示预定义网络(桥,无,主机),而自定义显示用户定义的网络。以下过滤器与所有用户定义的网络相匹配
docker network ls --filter type=custom
有了这个标志,它允许批量清理。 例如,使用此过滤器删除所有用户定义的网络:
docker network rm 'docker network ls --filter type=custom -q'
(8).格式化
格式化选项(–format)使用Go模板打印网络输出。
以下示例使用不带标题的模板,并输出用冒号分隔所有网络的ID和驱动程序条目:
docker network ls --format "{{.ID}}: {{.Driver}}"
6.删除所有未使用的网络
1).前言
docker network prune命令用于删除所有未使用的网络。未使用的网络是不被任何容器引用的网络。
用法
docker network prune [OPTIONS]
名称,简写 | 默认 | 说明 |
---|---|---|
--force, -f | false | 不要提示确认 |
2).删除所有未连接的网络
docker network prune
7.删除一个或多个网络
1).前言
docker network rm命令用于删除一个或多个网络。按名称或标识符删除一个或多个网络。 要删除网络,必须要先断开连接到它的任何容器的网络。
docker network rm NETWORK [NETWORK...]
名称,简写 | 默认 | 说明 |
---|---|---|
--force, -f | false | 不要提示确认 |
2).要删除名为“net-test”的网络
docker network rm net-test
3).删除多个网络
要在单个docker network rm命令中删除多个网络,请提供多个网络名称或ID列表。 以下示例删除标识为3695c422697f的网络和名为my-network的网络:
docker network rm 3695c422697f my-network
指定多个网络时,该命令会依次删除每个网络。 如果删除一个网络失败,则该命令继续到列表中的下一个,并尝试删除。 该命令报告每个删除的成功或失败。
五、网桥创建示例(自定义网络)
前面的四种模式是Docker自带的网络模式,其实Docker还有一种叫自定义网络模式
语法:docker network create -d
#创建网络
[root@docker02 ~]# docker network create -d bridge --subnet 192.168.10.0/24 --gateway 192.168.10.1 net-test
ffc46a67356a9143a310eb438bd38da02f2d8569d1f41de2aaec7faa73aaed6e
#查看网络
[root@docker02 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
ac1271481467 bridge bridge local
7452d6b9af7e host host local
ffc46a67356a net-test bridge local
af803a4e6c40 none null local
# 启动容器,并指定自定义的网络
[root@docker02 ~]# docker run --network net-test -it -d busybox /bin/sh
492c49deb76986624df9aa9f0fff4d02fb6aa62c38614e931813f99f7bea0a5d
[root@docker02 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
492c49deb769 busybox "/bin/sh" 4 seconds ago Up 3 seconds wonderful_chatelet