声明:这是我在大学毕业后进入第一家互联网公司学习的内容
深入浅出Docker原理及实战系列第五篇,我主要分享Docker的网络概念及如何合理的使用Docker网络。
Docker容器和服务如此强大的原因之一是您可以将它们连接在一起,或将它们连接到非Docker环境中。
Docker容器和服务甚至不需要知道它们已部署在Docker上,也不必知道它们的对等对象是否也是Docker中运行。
无论您的Docker主机运行Linux,Windows还是两者结合,您都可以使用Docker以与平台无关的方式管理它们。
Docker的网络子系统可使用驱动程序插入。默认情况下,存在几个驱动程序,它们提供核心联网功能:
默认的网络驱动程序。如果未指定驱动程序,则这是您正在创建的网络类型。当您的应用程序在需要通信的独立容器中运行时,通常会使用网桥网络。
对于独立容器,请删除容器与Docker主机之间的网络隔离,然后直接使用主机的网络。
覆盖网络将多个Docker守护程序连接在一起,并使群集服务能够相互通信。您还可以使用覆盖网络来促进群集服务和独立容器之间或不同Docker守护程序上的两个独立容器之间的通信。这种策略消除了在这些容器之间进行操作系统级路由的需要。
Macvlan网络允许您将MAC地址分配给容器,使其在网络上显示为物理设备。Docker守护程序通过其MAC地址将流量路由到容器。macvlan 在处理希望直接连接到物理网络而不是通过Docker主机的网络堆栈进行路由的旧应用程序时,使用驱动程序有时是最佳选择。
对于此容器,请禁用所有联网。通常与自定义网络驱动程序一起使用。none不适用于群体服务。
在网络方面,网桥是在网段之间转发流量的链路层设备。桥可以是在主机内核中运行的硬件设备或软件设备。
就Docker而言,网桥网络使用软件网桥,该软件网桥允许连接到同一网桥网络的容器进行通信,同时与未连接到该网桥网络的容器隔离。Docker网桥驱动程序会自动在主机中安装规则,以使不同网桥网络上的容器无法直接相互通信。
桥接网络适用于在同一 Docker守护程序主机上运行的容器。
启动Docker时,会自动创建一个默认的桥接网络(也称为bridge),并且除非另有说明,否则新启动的容器将连接到它。您还可以创建用户定义的自定义网桥网络。用户定义的网桥网络优于默认bridge 网络。
下面是一个默认网桥的例子
[root@localhost ~]# ip add
3: docker0: mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:ec:96:8d:3a 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:ecff:fe96:8d3a/64 scope link
valid_lft forever preferred_lft forever
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
45c686d33317 bridge bridge local
默认网桥上的容器只能通过IP地址相互访问,除非您使用–link选项。在用户定义的网桥网络上,容器可以通过名称或别名相互解析。
如果在默认网桥上运行相同的应用程序,则需要在容器之间手动创建链接(使用–link)。这些链接需要双向创建,因此您可以看到,要进行通信的容器超过两个,这将变得很复杂。或者,您可以修改/etc/hosts容器中的文件,但这会导致难以调试的问题。
想象一个具有Web前端和db后端的应用程序同时放在一个用户定义好的网桥上。如果容器web调用db,则db无论应用程序在哪个Docker主机上运行,Web容器都可以通过连接到db容器。
所有没有通过–network指定的容器都将连接到默认网桥网络。这可能是一种风险,因为不相关的应用/服务/容器随后能够进行通信。
自定义的网桥可提供局域网,其中只有连接到该网络的容器才能通信。
在容器的生命周期内,您可以即时将其与自定义的网桥连接或断开连接。要从默认网桥网络中删除容器,您需要停止容器并使用其他网络选项重新创建它。
如果您的容器使用默认的网桥,则可以对其进行配置,但是所有容器都使用相同的设置,例如MTU和iptables规则。此外,配置默认桥接网络发生在Docker本身之外,并且需要重新启动Docker。
自定义的网桥是通过 docker network create创建和配置的。如果不同的应用程序组具有不同的网络要求,则可以在创建时分别配置每个自定义的网桥。
最初,在两个容器之间共享环境变量的唯一方法是使用–link链接它们。自定义网络无法进行这种类型的变量共享。但是,存在共享环境变量的高级方法。
连接到同一自定义网桥的容器可以有效地将所有端口彼此公开。为了使容器或不同网络上的非Docker主机可以访问该端口,必须使用-p或–publish来发布该端口。
使用docker network create命令创建自定义网桥,在不选择任何配置的情况创建的就是网桥模式,您还可以指定子网,IP地址范围,网关和其他选项。
docker network create my-net
使用docker network rm命令删除用户定义的网桥网络。如果容器当前已连接到网络,请先断开它们的连接。
docker network rm my-net
创建新容器时,可以指定一个或多个–network参数。此示例将Nginx容器连接到my-net网络。它还将容器中的端口80发布到Docker主机上的端口8080,
因此外部客户端可以访问该端口。连接到my-net网络的任何其他容器都可以访问my-nginx容器上的所有端口,反之亦然。
docker create --name my-nginx \
--network my-net \
--publish 8080:80 \
nginx:latest
要将运行中的容器连接到现有的用户定义的网桥,请使用docker network connect命令。以下命令将一个已经在运行的my-nginx容器连接到一个已经存在的my-net网络:
docker network connect my-net my-nginx
要将运行中的容器与用户定义的网桥断开连接,请使用docker network断开命令。以下命令将my-nginx容器与my-net网络断开连接。
docker network disconnect my-net my-nginx
默认网桥被认为是Docker的遗留细节,不建议用于生产环境。对其进行配置需要手动操作,存在技术缺陷。
如果您未使用–network标志指定网络,而是指定了网络驱动程序,则默认情况下,您的容器将连接到默认网桥网络。除非使用旧版–link标志进行链接,否则连接到默认网桥网络的容器只能通过IP地址进行通信。
要配置默认的桥接网络,请在daemon.json中指定选项。这是一个daemon.json示例,其中指定了多个选项。仅指定您需要自定义的设置。
{
"bip": "192.168.1.5/24",
"fixed-cidr": "192.168.1.5/25",
"fixed-cidr-v6": "2001:db8::/64",
"mtu": 1500,
"default-gateway": "10.20.1.1",
"default-gateway-v6": "2001:db8:abcd::89",
"dns": ["10.20.1.2","10.20.1.3"]
}
重新启动Docker以使更改生效。
创建或删除用户定义的网桥或将容器与用户定义的网桥连接或断开连接时,docker使用指定操作系统的工具来管理基础网络基础结构(例如,在Linux上添加或删除桥接设备或配置iptables规则)。这些细节应视为实施细节。让Docker为您管理用户定义的网络。
默认情况下,来自连接到默认网桥网络的容器的流量不会转发到外界。要启用转发,您需要更改两个设置。这些不是Docker命令,它们会影响Docker主机的内核。
sysctl net.ipv4.conf.all.forwarding=1
iptables -P FORWARD ACCEPT
这些设置不会在重新启动后持续存在,因此您可能需要将它们添加到启动脚本中。
覆盖网络驱动程序会在多个Docker守护程序主机之间创建一个分布式网络。该网络位于特定于主机的网络之上(覆盖主机网络),启用加密后,允许与其连接的容器(包括群集服务容器)进行安全通信。
Docker透明地处理每个数据包与正确的Docker守护程序主机和正确的目标容器之间的路由。
初始化群集或将Docker主机加入现有群集时,将在该Docker主机上创建两个新网络:
使用覆盖网络的Docker守护程序的防火墙规则
您需要打开以下端口,以往返于参与覆盖网络的每个Docker主机的流量:
在创建覆盖网络之前,您需要使用初始化Docker守护程序作为swarm管理器,docker swarm init或者使用将该Docker守护程序加入现有的swarm docker swarm join。这两个都将创建默认的ingress覆盖网络,默认情况下,群集服务会使用该 覆盖网络。即使您从未计划使用群体服务,也需要这样做。之后,您可以创建其他用户定义的覆盖网络。
官方文档讲了一个通俗易懂的例子:
需要三台物理或虚拟Docker主机,它们可以相互通信,并且都运行Docker 17.03或更高版本的新安装。本教程假定这三台主机在同一网络上运行,并且不涉及防火墙。
这些主机将被称为manager,worker-1和worker-2。该 manager主机将作为既是经理和工人,这意味着它可以运行服务任务和管理群。worker-1并且worker-2将作为唯一的工人
然后通过一系列命令,创建集群,加入集群,创建服务,连接服务即可。
看到这,如果你了解过kubernetes,是不是会发现Docker的覆盖网络和Kubernetes有异曲同工之妙,(虽然我还没仔细了解kubernetes的网络,但是我已经明显感觉到kubernetes就是加强版这种覆盖网络的使用,后期继续深挖主机之间的网络通信原理)
具体实现可以查看
覆盖网络官方教程
如果您对容器使用主机网络模式,则该容器的网络堆栈不会与Docker主机隔离(该容器共享主机的网络名称空间),并且该容器不会分配自己的IP地址。例如,如果您运行一个绑定到端口80 host 的容器并使用网络,则该容器的应用程序在主机IP地址上的端口80上可用。
注意!!!
由于使用时容器不拥有自己的IP地址 host模式的网络,端口映射不生效,并且-p,–publish,-P,和–publish-all选项都将被忽略,并且产生一个警告:
WARNING: Published ports are discarded when using host network mode
主机模式网络对于优化性能以及在容器需要处理大量端口的情况下很有用,因为它不需要网络地址转换(NAT),并且不会为每个端口创建"userland-proxy"。
通过将–network host传递给docker service create命令,您还可以将主机网络用于群集服务。在这种情况下,控制流量(与管理群集和服务有关的流量)仍会通过覆盖网络发送,但是单个群集服务容器会使用Docker守护程序的主机网络和端口发送数据。这带来了一些额外的限制。例如,如果服务容器绑定到端口80,则在给定的群集节点上只能运行一个服务容器。
主机网络官方教程
某些应用程序,尤其是旧版应用程序或监视网络流量的应用程序,期望直接连接到物理网络。在这种情况下,可以使用macvlan网络驱动程序为每个容器的虚拟网络接口分配MAC地址,使其看起来像是直接连接到物理网络的物理网络接口。在这种情况下,您需要在Docker主机上指定用于macvlan的物理接口,以及的子网和网关。
您甚至可以macvlan使用不同的物理网络接口隔离网络。请记住以下几点:
由于IP地址耗尽或“ VLAN扩散”,很容易无意间损坏您的网络,在这种情况下,您的网络中有大量不正确的唯一MAC地址。
您的网络设备需要能够处理“混杂模式”,在该模式下,可以为一个物理接口分配多个MAC地址。
如果您的应用程序可以使用网桥(在单个Docker主机上)或覆盖(跨多个Docker主机进行通信)工作,那么从长远来看,这些解决方案可能会更好。
具体实现可以看
macvlan网络官方教程
对于Docker来说,掌握好网桥模式足够,覆盖网络会有更好的替代容器编排工具(k8s),mac网络和主机网络用的也较少。
管理网络。您可以使用子命令来创建,检查,列出,删除,修剪,连接和断开网络连接。
用法:
docker network COMMAND
COMMAND子命令
COMMAND | 描述 |
---|---|
docker network connect | 将容器连接到网络 |
docker network create | 建立网络 |
docker network disconnect | 断开容器与网络的连接 |
docker network inspect | 显示网络的详细信息 |
docker network ls | 列出网络 |
docker network rm | 删除网络 |
将容器连接到网络
docker network connect [OPTIONS] NETWORK CONTAINER
OPTIONS | 描述 |
---|---|
–alias | 为容器添加网络的别名 |
–driver-opt | 网络的驱动程序选项 |
–ip | 指定要分配给容器接口的IP地址 |
–link | 将链接添加到另一个容器 |
例子:
docker network connect redis-network redis
docker run -itd --network=redis-network redis
docker network connect --ip 172.18.1.2 redis-network redis
–alias 选项可用于通过所连接网络中的另一个名称来解析容器。
docker network connect --alias redis6379 redis-network redis
处在redis-network这个网络中的容器可以通过redis6379去连接redis
您可以使用–link链接另一个具有首选别名的容器
docker network connect --link redis:redis6379 redis-network test
创建一个新的网络。在DRIVER默认的网络驱动程序是bridge或者overlay。如果您安装了第三方或自己的自定义网络驱动程序,则也可以DRIVER在此处指定。如果未指定该 --driver选项,该命令将自动为您创建一个网桥。当您安装Docker Engine时,它会自动创建一个网桥。该网络对应于Docker Engine传统上依赖的网桥。当您启动一个新容器时, docker run它会自动连接到该网桥网络。您不能删除此默认网桥,但可以使用以下network create命令创建新的网桥。
docker network create [OPTIONS] NETWORK
OPTIONS | 描述 |
---|---|
–aux-address | 网络驱动程序使用的辅助IPv4或IPv6地址 |
–driver , -d 默认是bridge | 网络的驱动程序选项 |
–gateway | 主子网的IPv4或IPv6网关 |
–internal | 限制外部访问网络 |
–ip-range | 从子范围分配容器ip |
–subnet | 代表网段的CIDR格式的子网 |
网桥是单个引擎安装上的隔离网络。如果要创建一个跨越多个运行主机的Docker主机的overlay网络,则必须创建一个网络。与网桥不同,覆盖网络需要先存在一些先决条件才能创建一个。这些条件已经在上文讲过,不再重复,这里主要讲创建网桥的具体内容。
创建网络时,默认情况下,引擎会为该网络创建一个不重叠的子网。该子网不是现有网络的细分。它仅用于ip寻址目的。您可以覆盖此默认值,并使用该–subnet选项直接指定子网值。
docker network create --driver=bridge --subnet=192.168.0.0/16 redis-network
docker network create \
--driver=bridge \
--subnet=172.28.0.0/16 \
--ip-range=172.28.5.0/24 \
--gateway=172.28.5.254 \
redis-network
断开容器与网络的连接,断开容器与网络的连接。容器必须正在运行才能将其与网络断开连接。
docker network disconnect [OPTIONS] NETWORK CONTAINER
--force , -f 强制容器断开网络连接
eg: docker network disconnect multi-host-network container1
显示一个或多个网络详细信息,默认情况下,此命令将所有结果呈现在JSON对象中。
docker network inspect [OPTIONS] NETWORK [NETWORK...]
--format , -f 使用给定的Go模板格式化输出
--verbose , -v 详细输出以进行诊断
列出daemon引擎知道的所有网络。这包括跨群集中多个主机的网络。
docker network ls [OPTIONS]
OPTIONS | 描述 |
---|---|
–filter , -f | 提供过滤器值(例如“ driver = bridge”) |
–format | 使用Go模板的打印网络 |
–no-trunc | 不要截断输出 |
–quiet , -q | 仅显示网络ID |
例子:
列出所有网络:
docker network ls
NETWORK ID NAME DRIVER SCOPE
7fca4eb8c647 bridge bridge local
9f904ee27bf5 none null local
cf03ee007fb4 host host local
78b03ee04fc4 multi-host overlay swarm
使用--no-trunc选项显示完整的网络ID:
docker network ls --no-trunc
NETWORK ID NAME DRIVER SCOPE
18a2866682b85619a026c81b98a5e375bd33e1b0936a26cc497c283d27bae9b3 none null local
c288470c46f6c8949c5f7e5099b5b7947b07eabe8d9a27d79a9cbf111adcbf47 host host local
7b369448dccbf865d397c8d2be0cda7cf7edc6b0945f77d2529912ae917a0185 bridge bridge local
95e74588f40db048e86320c6526440c504650a1ff3e9f7d60a497c4d2163e5bd foo bridge local
63d1ff1f77b07ca51070a8c227e962238358bd310bde1529cf62e6c307ade161 dev bridge local
过滤器匹配基于其驱动程序的网络。
docker network ls --filter driver=bridge
NETWORK ID NAME DRIVER SCOPE
db9db329f835 test1 bridge local
f6e212da9dfd test2 bridge local
按名称或标识符删除一个或多个网络。要删除网络,必须首先断开连接到它的所有容器。
docker network rm NETWORK [NETWORK...]
例子:
docker network rm my-network
在Linux上,Docker操纵iptables规则以提供网络隔离。尽管这是实现的详细信息,并且您不应修改Docker在iptables策略中插入的规则,但是如果您想要拥有自己的策略(而不是由Docker管理的策略),它确实会对您需要执行的操作产生一些影响。
如果您在已暴露网络的主机上运行Docker,则可能需要采用iptables策略,以防止未经授权访问您主机上运行的容器或其他服务。下面主要描述如何实现此目标以及需要注意的注意事项。
Docker安装了两个iptables链,名叫DOCKER-USER 和DOCKER,它确保传入的数据包始终首先由这两个链进行检查。
手动或通过其他基于iptables的防火墙添加到FORWARD链中的规则在这些链之后进行评估。这意味着,如果您通过Docker公开端口,则无论防火墙配置了什么规则,该端口都会公开。如果您希望即使在通过Docker公开端口时也要应用这些规则,则必须将这些规则添加到DOCKER-USER链中。
默认情况,允许所有外部IP连接到Docker主机。
要仅允许特定的IP或网络访问容器,请在DOCKER-USER过滤器链的顶部插入一个否定的规则。例如,下面一个规则限制了除192.168.1.1之外的所有IP地址的外部访问,也就是说只能有192.168.1.1才能访问这个容器内部
iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.1 -j DROP
请注意,您将需要更改ext_if以与主机的实际外部接口相对应。您可以改为允许来源子网的连接。以下规则仅允许从子网192.168.1.0/24访问容器内部:
iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.0/24 -j DROP
iptables是复杂的,更复杂的规则不在此主题范围内。有关它的更多信息,请参见Netfilter.org HOWTO。
还有几种策略具体请看 Docker和iptables
正好前几天出现了一个Docker的网络问题,无法启动容器,现在来回顾一下
为了证明启动Docker之前添加iptables策略这点非常重要,我做了以下实验。
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (2 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.17.0.2 tcp dpt:6379
ACCEPT tcp -- anywhere 172.18.0.2 tcp dpt:17010
ACCEPT tcp -- anywhere 172.18.0.2 tcp dpt:ups-onlinet
ACCEPT tcp -- anywhere 172.18.0.3 tcp dpt:17011
ACCEPT tcp -- anywhere 172.18.0.3 tcp dpt:talon-disc
ACCEPT tcp -- anywhere 172.18.0.4 tcp dpt:17012
ACCEPT tcp -- anywhere 172.18.0.4 tcp dpt:talon-engine
ACCEPT tcp -- anywhere 172.18.0.5 tcp dpt:17013
ACCEPT tcp -- anywhere 172.18.0.5 tcp dpt:microtalon-dis
ACCEPT tcp -- anywhere 172.18.0.6 tcp dpt:17014
ACCEPT tcp -- anywhere 172.18.0.6 tcp dpt:microtalon-com
ACCEPT tcp -- anywhere 172.18.0.7 tcp dpt:17015
ACCEPT tcp -- anywhere 172.18.0.7 tcp dpt:talon-webserver
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
[root@localhost ~]# systemctl start firewalld
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
INPUT_direct all -- anywhere anywhere
INPUT_ZONES_SOURCE all -- anywhere anywhere
INPUT_ZONES all -- anywhere anywhere
DROP all -- anywhere anywhere ctstate INVALID
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
FORWARD_direct all -- anywhere anywhere
FORWARD_IN_ZONES_SOURCE all -- anywhere anywhere
FORWARD_IN_ZONES all -- anywhere anywhere
FORWARD_OUT_ZONES_SOURCE all -- anywhere anywhere
FORWARD_OUT_ZONES all -- anywhere anywhere
DROP all -- anywhere anywhere ctstate INVALID
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
OUTPUT_direct all -- anywhere anywhere
Chain FORWARD_IN_ZONES (1 references)
target prot opt source destination
FWDI_public all -- anywhere anywhere [goto]
FWDI_public all -- anywhere anywhere [goto]
Chain FORWARD_IN_ZONES_SOURCE (1 references)
target prot opt source destination
Chain FORWARD_OUT_ZONES (1 references)
target prot opt source destination
FWDO_public all -- anywhere anywhere [goto]
FWDO_public all -- anywhere anywhere [goto]
Chain FORWARD_OUT_ZONES_SOURCE (1 references)
target prot opt source destination
Chain FORWARD_direct (1 references)
target prot opt source destination
Chain FWDI_public (2 references)
target prot opt source destination
FWDI_public_log all -- anywhere anywhere
FWDI_public_deny all -- anywhere anywhere
FWDI_public_allow all -- anywhere anywhere
ACCEPT icmp -- anywhere anywhere
Chain FWDI_public_allow (1 references)
target prot opt source destination
Chain FWDI_public_deny (1 references)
target prot opt source destination
Chain FWDI_public_log (1 references)
target prot opt source destination
Chain FWDO_public (2 references)
target prot opt source destination
FWDO_public_log all -- anywhere anywhere
FWDO_public_deny all -- anywhere anywhere
FWDO_public_allow all -- anywhere anywhere
Chain FWDO_public_allow (1 references)
target prot opt source destination
Chain FWDO_public_deny (1 references)
target prot opt source destination
Chain FWDO_public_log (1 references)
target prot opt source destination
Chain INPUT_ZONES (1 references)
target prot opt source destination
IN_public all -- anywhere anywhere [goto]
IN_public all -- anywhere anywhere [goto]
Chain INPUT_ZONES_SOURCE (1 references)
target prot opt source destination
Chain INPUT_direct (1 references)
target prot opt source destination
Chain IN_public (2 references)
target prot opt source destination
IN_public_log all -- anywhere anywhere
IN_public_deny all -- anywhere anywhere
IN_public_allow all -- anywhere anywhere
ACCEPT icmp -- anywhere anywhere
Chain IN_public_allow (1 references)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh ctstate NEW
Chain IN_public_deny (1 references)
target prot opt source destination
Chain IN_public_log (1 references)
target prot opt source destination
Chain OUTPUT_direct (1 references)
target prot opt source destination
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@localhost ~]# docker run -d -p 80:80 --volumes-from pmm-data --name pmm-server --restart always percona/pmm-server:latest
f86d559846840468a45ec4b69b3cd4458854b2e9392e4e47b84430e420c59f7c
docker: Error response from daemon: driver failed programming external connectivity on endpoint pmm-server (b5e49ead04279b9c1ab16609ed3fcb78d309fb2fcab001adda57a9bd45dc23d0): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 80 -j DNAT --to-destination 172.17.0.3:80 ! -i docker0: iptables: No chain/target/match by that name.
(exit status 1)).
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (2 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.18.0.2 tcp dpt:17014
ACCEPT tcp -- anywhere 172.18.0.2 tcp dpt:microtalon-com
ACCEPT tcp -- anywhere 172.18.0.3 tcp dpt:17015
ACCEPT tcp -- anywhere 172.18.0.4 tcp dpt:17010
ACCEPT tcp -- anywhere 172.18.0.5 tcp dpt:17012
ACCEPT tcp -- anywhere 172.18.0.3 tcp dpt:talon-webserver
ACCEPT tcp -- anywhere 172.18.0.4 tcp dpt:ups-onlinet
ACCEPT tcp -- anywhere 172.18.0.5 tcp dpt:talon-engine
ACCEPT tcp -- anywhere 172.18.0.6 tcp dpt:17013
ACCEPT tcp -- anywhere 172.18.0.7 tcp dpt:17011
ACCEPT tcp -- anywhere 172.18.0.6 tcp dpt:microtalon-dis
ACCEPT tcp -- anywhere 172.18.0.7 tcp dpt:talon-disc
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
你一定要在启动Docker之前关闭防火墙,否则重新启动防火墙再关闭也不会让iptables加入Docker链,唯一的解决办法就是重启Docker,这对于生产环境来说是极为危险的(你这台机器上的所有容器都得重启)
容器使用的网络类型,无论是网桥,主机网络, 覆盖网络,macvlan网络还是自定义网络插件,在容器内部都是透明的。从容器的角度来看,它具有一个带有IP地址,网关,路由表,DNS服务和其他网络详细信息的网络接口(假定容器未使用none网络驱动程序)。
默认情况下,创建容器时,它不会将其任何端口发布到外界。要使端口可用于Docker外部的服务或未连接到容器网络的Docker容器,请使用 --publish或-p标志。这将创建一个防火墙规则,该规则将容器端口映射到Docker主机上的端口。这里有些例子。
标志值 | 描述 |
---|---|
-p 8080:80 | 将容器中的TCP端口80映射到Docker主机上的端口8080。 |
-p 192.168.1.100:8080:80 | 将容器中的TCP端口80映射到Docker主机上的端口8080,以连接到主机IP 192.168.1.100。 |
-p 8080:80/udp | 将容器中的UDP端口80映射到Docker主机上的端口8080。 |
-p 8080:80/tcp -p 8080:80/udp | 将容器中的TCP端口80映射到Docker主机上的TCP端口8080,并将容器中的UDP端口80映射到Docker主机上的UDP端口8080。 |
默认情况下,为容器连接到的每个Docker网络分配一个IP地址。IP地址是在网络池中分配的,因此Docker守护程序实际上充当了每个容器的DHCP服务器。每个网络还具有默认的子网掩码和网关。
容器启动时,只能使用将该容器连接到单个网络 --network。但是,您可以使用将运行中的容器连接到多个网络docker network connect。使用–network标志启动容器时 ,可以使用–ip或–ip6标志指定分配给该网络上的容器的IP地址。
使用将现有容器连接到其他网络时 docker network connect,可以在该命令上使用–ip或–ip6标志来指定其他网络上容器的IP地址。
同样,容器的主机名默认为Docker中容器的ID。您可以使用覆盖主机名–hostname。使用来连接到现有网络时docker network connect,可以使用该–alias 标志为该网络上的容器指定其他网络别名。
默认情况下,容器会继承/etc/resolv.conf配置文件中定义的主机的DNS设置 。使用默认网桥的容器将获得此文件的副本,而使用自定义网桥的容器将使用 Docker的嵌入式DNS服务器,该服务器会将外部DNS查找转发到主机上配置的DNS服务器。
自定义主机中定义的/etc/hosts不会继承。要将其他主机传递到您的容器中,请参考docker run 的参数设置。
重要的事情说三次,你一定要在启动Docker之前关闭防火墙,你一定要在启动Docker之前关闭防火墙,你一定要在启动Docker之前关闭防火墙。
Docker Network CLI
Docker Networking overview
版权声明:
原创不易,洗文可耻。除非注明,本博文章均为原创,转载请以链接形式标明本文地址。