【docker】Docker网络与iptables

这篇具有很好参考价值的文章主要介绍了【docker】Docker网络与iptables。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Docker能为我们提供很强大和灵活的网络能力,很大程度上要归功于与iptables的结合。在使用时,你可能没有太关注到 iptables在其中产生的作用,这是因为Docker已经帮我们自动的完成了相关的配置。

iptables在Docker中的应用主要是用于网络流量控制和安全控制。可以使用iptables规则来限制Docker容器的网络访问,以及将外部流量重定向到Docker容器。

docker的daemon进程有个--iptables的参数,可以使用它来控制是否要自动启用iptables规则的,默认已经设置成了开启(true)。所以通常我们不会过于关注到它的工作。

$ dockerd --help |grep iptables
      --iptables                                Enable addition of iptables rules (default true)

本文中,为了避免环境的干扰,我将使用DinD(docker in docker)的环境来进行介绍,可通过如下方式启动该环境:

$ sudo docker run --rm -d --privileged docker:dind

docker关闭iptables,计算机网络,CI/CD/CM,docker,网络,iptables,nat,桥接网络

关闭Docker的iptables支持

在启动一个Docker daemon时关闭iptables支持,将--iptables参数设置为false。

$ sudo docker run --rm -d --privileged docker:dind  dockerd --iptables=false
f43d990164ef66401f7424364bcf85e6506e2f1419f146b940c2cd01a6463485

$ sudo docker container exec -it f4 iptables -t filter -nvL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

$ sudo docker container exec -it f4 iptables -t nat -nvL --line-numbers
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

可以看到,当docker的daemon加了--iptables=false的参数时,默认没有任何规则的输出。

可以使用iptables-save命令将iptables的规则转储到stdout中,更方便查看:

$ iptables-save
*mangle
:PREROUTING ACCEPT [15992:2680378]
:INPUT ACCEPT [3831:436980]
:FORWARD ACCEPT [576:134155]
:OUTPUT ACCEPT [2486:235970]
:POSTROUTING ACCEPT [2931:348259]
COMMIT

*raw
:PREROUTING ACCEPT [6:348]
:OUTPUT ACCEPT [4:312]
COMMIT

*filter
:INPUT ACCEPT [82:4720]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [49:4028]
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

开启Docker的iptables支持

在启动一个Docker的daemon时不指定--iptables选项,因为默认就是true。

$ sudo docker run --rm -d --privileged docker:dind  dockerd
5a236c0f17f58e71a4ac7a073b224b1d26f29daea07508a383f0dc561cf0644f

$ sudo docker container exec -it 5a iptables -t nat -nvL --line-numbers
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 DOCKER     0    --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 DOCKER     0    --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 MASQUERADE  0    --  *      !docker0  172.18.0.0/16        0.0.0.0/0

Chain DOCKER (2 references)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 RETURN     0    --  docker0 *       0.0.0.0/0            0.0.0.0/0

$ sudo docker container exec -it 5a iptables -t filter -nvL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 DOCKER-USER  0    --  *      *       0.0.0.0/0            0.0.0.0/0
2        0     0 DOCKER-ISOLATION-STAGE-1  0    --  *      *       0.0.0.0/0            0.0.0.0/0
3        0     0 ACCEPT     0    --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
4        0     0 DOCKER     0    --  *      docker0  0.0.0.0/0            0.0.0.0/0
5        0     0 ACCEPT     0    --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0
6        0     0 ACCEPT     0    --  docker0 docker0  0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain DOCKER (1 references)
num   pkts bytes target     prot opt in     out     source               destination

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 DOCKER-ISOLATION-STAGE-2  0    --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0
2        0     0 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 DROP       0    --  *      docker0  0.0.0.0/0            0.0.0.0/0
2        0     0 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/0

Chain DOCKER-USER (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/0

可以看到,它比刚才关闭iptables支持时多了几条链:

  • DOCKER
  • DOCKER-ISOLATION-STAGE-1
  • DOCKER-ISOLATION-STAGE-2
  • DOCKER-USER

以及增加了一些转发规则,以下将具体介绍。

DOCKER-USER链

在上述新增的几条链中,我们先来看最先生效的DOCKER-USER 。

filter表中FORWARD链的第一条规则是:

-A FORWARD -j DOCKER-USER

这表示流量进入FORWARD链后,所有的流量直接进入到DOCKER-USER链。

而filter表中DOCKER-USER链中的规则是:

-A DOCKER-USER -j RETURN

这表示流量进入DOCKER-USER链处理后,(如果无其他处理)可以再RETURN回原先的链,进行后续规则的匹配。

这其实是Docker预留的一个链,供用户来自行配置的一些额外的规则的。

Docker默认的路由规则是允许所有客户端访问的,如果你的Docker服务运行在公网,或者你希望避免Docker中容器被局域网内的其他客户端访问,那么你需要在这里添加一条规则。

比如, 你仅仅允许192.168.1.100访问,但是要拒绝其他客户端访问:

$ sudo iptables -A DOCKER-USER -i eth0 ! -s 192.168.1.100 -j DROP

这个规则表示将源IP不是192.168.1.100的流量全部丢失。

此外,Docker在重启之类的操作时候,会进行iptables相关规则的清理和重建,但是DOCKER-USER链中的规则可以持久化,不受影响。

DOCKER-ISOLATION-STAGE-1/2链

filter表中的DOCKER-ISOLATION-STAGE-1DOCKER-ISOLATION-STAGE-2这两条链作用类似,这里一起进行介绍。

先来看一个例子:

// 创建一个自定义网络mynetwork
$ sudo docker network create mynetwork

// box1容器运行在默认的网络下
$ sudo docker container run --rm -d --name box1 busybox /bin/sh -c "while true; do sleep 3600; done"
// box2和box3运行在自定义的网络mynetwork下
$ sudo docker container run --rm -d --name box2 --network mynetwork busybox /bin/sh -c "while true; do sleep 3600; done"
$ sudo docker container run --rm -d --name box3 --network mynetwork busybox /bin/sh -c "while true; do sleep 3600; done"

部署示意图如下:

docker关闭iptables,计算机网络,CI/CD/CM,docker,网络,iptables,nat,桥接网络

在box2中访问box3,可以访问:

$ sudo docker container exec -it box2 ping 172.19.0.3 -c 3
PING 172.19.0.3 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.077 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.301 ms
64 bytes from 172.19.0.3: seq=2 ttl=64 time=0.196 ms

--- 172.19.0.3 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.077/0.191/0.301 ms

在box2中访问box1,不可以访问:

$ sudo docker container exec -it box2 ping 172.17.0.2 -c 3
PING 172.17.0.2 (172.17.0.2): 56 data bytes

--- 172.17.0.2 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss

可以看到,如果是相同network的容器是可以ping成功的,但如果是不同network的容器则不能ping通。

那么两个network之间不能通信是怎么进行隔离的呢?这就是filter表中的DOCKER-ISOLATION-STAGE-1DOCKER-ISOLATION-STAGE-2这两条链的功劳。

当我们创建一个新的network时,系统层面会创建一个新的bridge端口br-d4bf6d77f3cf,再加上默认创建的bridge端口docker0,系统的bridge接口列表如下:

$ ip addr show type bridge
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:15:94:c0:42 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
13: br-d4bf6d77f3cf: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:d0:f6:09:f1 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.1/16 brd 172.19.255.255 scope global br-d4bf6d77f3cf
       valid_lft forever preferred_lft forever

流量接着会进入filter表FORWARD链中的第二条规则:

-A FORWARD -j DOCKER-ISOLATION-STAGE-1

这表示流量进入FORWARD链后,所有的流量直接进入到DOCKER-ISOLATION-STAGE-1链。

再来看filter表中DOCKER-ISOLATION-STAGE-1链中的规则:

-A DOCKER-ISOLATION-STAGE-1 -i br-d4bf6d77f3cf ! -o br-d4bf6d77f3cf -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN

第一条规则表示从接口br-d4bf6d77f3cf进入但是不从接口br-d4bf6d77f3cf出去的包会进入DOCKER-ISOLATION-STAGE-2链。
第二条规则和第一条规则类似,表示从接口docker0进入但是不从接口docker0出去的包会进入DOCKER-ISOLATION-STAGE-2链。
第三条规则表示再RETURN回原先的链,进行后续规则的匹配,进入这条规则可能有三种情况:

  1. 包从br-d4bf6d77f3cf进也从br-d4bf6d77f3cf出,表示同在my-network网络中
  2. 包从docker0进也从docker0出,表示同在默认的bridge网络中
  3. 包从主机的其他接口进入,不经过docker创建的接口

接下来看filter表中DOCKER-ISOLATION-STAGE-2链中的规则:

-A DOCKER-ISOLATION-STAGE-2 -o br-d4bf6d77f3cf -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN

第一条规则表示从接口br-d4bf6d77f3cf出去的包直接丢弃,结合DOCKER-ISOLATION-STAGE-1链来看,就是让从接口docker0进入且从接口br-d4bf6d77f3cf出去的包的直接丢弃,使得docker0网络中的容器无法访问my-network网络中的容器。
第二条规则与第一条规则类似,表示从接口docker0出去的包直接丢弃,结合DOCKER-ISOLATION-STAGE-1链来看,就是让从接口br-d4bf6d77f3cf进入且从接口docker0出去的包的直接丢弃,使得br-d4bf6d77f3cf网络中的容器无法访问docker0网络中的容器。
第三条规则表示再RETURN回原先的链,进行后续规则的匹配,进入这条规则说明是docker内的容器访问外部网络(非Docker中的网络)。

Docker通过这两条链分为两个阶段对桥接网络进行了隔离,使得各个桥接网络直接无法通讯。

看到这里,你可能会问为什么要分两个阶段进行隔离?用一条链直接隔离行不行?

答案是行,一条链也能隔离,Docker很早的版本就是这样做的。

但是当时的实在超过30个network以后,就会导致Docker启动很慢。所以后来做了这个优化,将这部分的复杂度从O(N^2)降低到O(2N),Docker就不再会出现启动慢的情况了。

DOCKER链

最后我们来看看DOCKER链,这是Docker中使用最为频繁的一个链,也是规则最多的链,但它却很好理解。通常情况下,如果不小心删掉了这个链的内容,可能会导致容器的网络出现问题,手动修复下,或者重启Docker均可解决。

filter表和nat表中都存在DOCKER链。

什么样的包会进入到filter表的DOCKER链呢?

-A FORWARD -o br-d4bf6d77f3cf -j DOCKER
-A FORWARD -o docker0 -j DOCKER

FORWARD链中请求目标接口是docker0、br-d4bf6d77f3cf, 那么跳转到DOCKER链处理,也就是包转发到docker创建的bridge接口时就会进入DOCKER链。

什么样的包会进入到nat表的DOCKER链呢?

-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

第一条规则表示如果包进入时请求的目标地址是本机的地址, 那么将请求转到DOCKER链处理。
第二条规则表示如果包出去时请求的目标地址不匹配127.0.0.0/8, 并且目标地址属于本机地址, 那么将请求跳转到 DOCKER链处理。

这里我们启动一个容器,并进行端口映射,来看看会有哪些变化。

$ sudo docker container run --rm -d --name httpd -p 8080:80 httpd

之后再次执行iptables-save,对比当前的结果与上次的差别:

filter表中的DOCKER链增加如下一条规则:

-A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT

这条规则表示对目标地址是172.17.0.3/32且不是从docker0进入的但从docker0出去的,目标端口是80的TCP协议则接收。

nat表中增加如下两条规则:

-A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.3:80

第一条规则表示为172.17.0.3上目标端口为80的流量执行MASQUERADE(SNAT)动作;
第二条规则表示在自定义的DOCKER链中,如果入口不是docker0并且目标端口是8080则进行DNAT动作,将目标地址转换为172.18.0.3:80。简单点来说,这条规则就是为我们提供了Docker容器端口转发的能力,将访问主机本地8080端口流量的目标地址转换为172.18.0.3:80。文章来源地址https://www.toymoban.com/news/detail-764075.html

到了这里,关于【docker】Docker网络与iptables的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【linux docker】linux 如何关闭docker服务

    要彻底关闭Docker,可以使用以下命令: 停止所有运行中的容器 这个命令会停止所有正在运行中的Docker容器。docker ps命令用于列出所有正在运行的容器的ID,-q选项表示只显示容器ID而不显示其他信息。docker stop命令用于停止容器。 删除所有容器 这个命令会删除所有的Docker容器

    2024年02月13日
    浏览(32)
  • docker关闭所有容器的命令

    关闭所有容器的命令是docker stop $(docker ps -aq),其中: 使用docker ps -a命令列出所有的容器; 实现方法1:使用docker ps -a命令获取所有容器的ID,然后使用docker stop命令逐个停止容器。 实现方法2:使用docker ps -aq命令获取所有容器的ID,然后将其作为参数传递给docker stop命令。 最后

    2024年01月16日
    浏览(28)
  • 【Docker】开启和关闭容器自启动

    目录 一、开启自启 二、关闭自启 三、docker-compose 配置容器自启动 在docker启动容器时可以增加参数 容器已经启动,通过update命令进行修改 容器关闭自启动 : 取消所有容器自启动 配置启动容器时添加下述配置项,docker-compose 关机或者重启docker时就会生效

    2024年02月13日
    浏览(37)
  • docker容器自启与关闭自启

    大家好,我是早九晚十二,目前是做运维相关的工作。写博客是为了积累,希望大家一起进步! 我的主页:早九晚十二 在重启docker服务时,常常会拖家带口一大堆废弃的容器一起启动,如何改正这种现象呢? 要想做到docker启动,容器跟随启动可添加以下参数实现 如果容器已

    2024年02月11日
    浏览(27)
  • Centos上 关闭Linux防火墙(iptables) 及 SELinux

    一、关闭防火墙 1、重启后永久性生效: 开启: chkconfig iptables on 关闭: chkconfig iptables off 2、即时生效,重启后失效: 开启: service iptables start 关闭: service iptables stop 在开启了防火墙时,做如下设置,开启相关端口,修改 /etc/sysconfig/iptables 文件,添加以下内容: -A INPUT

    2024年02月08日
    浏览(29)
  • docker命令操作以及防火墙的开启和关闭

    1.停止运行所有的容器 docker container stop $(docker container ps -aq) 2.删除正在运行的容器 docker container rm 0c -f 3.把attached后台运行的容器转换为前台detached运行模式 docker attach +id 4. 跟踪日志 docker container logs -f +id 5. CentOS 5/CentOS 6 在CentOS 5和CentOS 6系统中,关于如何开启防火墙、关闭防

    2024年02月03日
    浏览(36)
  • 在docker中启动elasticsearch,启动后又自动关闭

    问题现象:在docker中启动elasticsearch,启动后又自动关闭。具体现象如下图。 解决方法: 1、用docker ps -a查看“容器id”,然后用docker logs -f “容器id”查看日志。 发现是elasticsearch.yml这个配置文件有问题。 我的问题是“:”后没加个空格。 3、docker rm “容器id”,然后重启ela

    2024年02月12日
    浏览(28)
  • Docker关闭不掉进程,Stopping docker.service, but it can still be activated by: docker.socket

    出现问题: Warning: Stopping docker.service, but it can still be activated by: docker.socket   Docker默认开启自动唤醒机制,即docker默认在关闭状态下被访问会自动唤醒Docker。 查看Docker是否开启自动唤醒机制: systemctl status docker 如果出现如下图的状态:即为 开启自动唤醒机制。 1. 停用Docker自

    2024年02月08日
    浏览(24)
  • RustDesk reset by peer 连接被对方关闭 Docker k8s

    最近搞物联网硬件的时候需要搭建一个 RustDesk 参考文档: https://rustdesk.com/docs/zh-cn/self-host/install/ 看到有一个 Docker Compose的部署 我们公司内部主要是腾讯云 tke k8s ,于是稍微改动了一下 在deployment里面加了一个 命令而已 按照文档, 启动了 hbbr   hbbs,并且也打开了端口,在局域网里

    2024年02月07日
    浏览(70)
  • 《Docker极简教程》--Docker网络--Docker网络的概念

    深入了解 Docker 网络对于使用 Docker 构建和管理容器化应用程序的开发人员和运维人员来说至关重要。 网络是容器化应用程序的核心组成部分 :在容器化应用程序中,网络不仅用于容器之间的通信,还用于与外部系统和服务进行交互。了解 Docker 网络如何工作可以帮助确保应

    2024年02月21日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包