docker一台服务器部署多容器,容器a无法通过宿主机外网ip访问另外一个容器b分析

姜大伟QQ:41612453 姜大伟QQ:41612453     2022-12-25     139

关键词:

首先出现这个问题,都是iptables ---input chain 设置了默认Policy 为 Drop导致的(如果默认全都是 accept或者没有其他拒绝策略,肯定是没问题的。)

这是我服务器上的INPUT规则如下:

 

 3306 ,6379那几个, 分别是mysql容器和 redis容器对应的端口号,第一行表示,input默认策略是 Drop。

这台服务器的结构很简单,就是一张外网网卡, 直接接外网,eth0 ,  ip=101.*。*。*,   然后docker0网桥,  172.17.0.1  

此时,我新建了一个nginx容器, 做了端口映射, 9999--》 容器里的80,

 

容器启动后, docker会自动在 Iptable添加相应的转发规则的,如果从别的服务器上, 访问   该容器服务器外网ip 101 : 9999, 其实是可以访问成功的。

我们可以拿iptabels 分析一下。

从外面进来的数据包, 会首先走iptables的prerouting链, 但是在这里, nat表里是有一条规则的,

 

可以看到第一个粗红框中 ,in out src dest 不是*就是0, 后面跟了一个 addrtype的模块,match dest = local,

首先前面四个,肯定命中,剩下的,就是匹配目标ip是不是本机了, 既然是直接访问宿主机的Ip,那就肯定 = local了,所以这条规则会命中, 从 prerouting链,jump到  docker链,即第二个粗红框

这里,我们依然要挨个检查,是否能命中规则(这里不太清楚,应该是执行完了,依然要返回调用方,即 prerouting) 

第一条,in = docker0,肯定不对, 我们只有一个外网网卡接口 eth0, 所以忽略,第二条, in 命中, 不是docker0, src和 dest不管了, 命中, dport就不对了, 是6379, 我们访问的是9999,

一看, 最后一条命中了, targe是 dnat,即目标地址转换, 转换成  172.17.0.6,端口由 9999转成80.

然后返回到 prerouting里, 这里贴一张图,就很清晰的看到iptables都干了什么了。

 

 

刚才 ,从docker链判断完了, 做了目标地址转换后, 返回了 上面的那个紫框,  nat-prerouting, 然后要继续往下执行, 判断是否是本机IP(这里本机ip有连个,1.外网ip101****, 第二个是 docker0网桥上的ip  172.17.0。1,由于刚才把ip换成了172.17.0.6了,所以判断是fale, 只能走forward链了, 不能走input了。(这也是为什么,最早的时候, 安装docker,一定要提前把Ip_foward打开   = 1),foward链中也有几个规则, 不过不影响大局,就不分析了。

这是一个正常的使用流程。

问题是, 我们再使用过程中 ,偶尔会出现,一个容器要访问另一个容器,如果直接使用容器ip,会不太方便,而公网ip大家都知道,一般人肯定会用公网ip去访问另一个容器, 这时候,如果Iptables不做更改,我们这里就出现了一个异常,

容器a访问   101.*。*。*:9999, 居然连接超时,无响应。

我们仔细想一下,容器a的包,正常出去, 通过容器a的路由表, 肯定只能发送给网桥那个172.17.0.1的ip, 通过tcpdump抓包,我们可以看到  宿主机 docker0网卡有数据进来(废话,容器的出包,也只能走这个网卡了)

 

 这就很简单了,既然知道了是从docker0进来的,那就继续走一边iptables,就知道包到底被谁干掉了。

1. prerouting链, 是发给LOCAL的数据,命中,跳转到 docker链, 这个时候, 跟从外面来的包就不一样了,因为会命中  docker链 nat表的第一个规则 ,In 的确是  docker0, target = return,什么都没干,就返回到了prerouting, 然后判断host,发现是本机,不能欧foward链了,要走input,这个时候, input里的各种规则就起作用了, 咱们根本就没有添加相应的rule,(只有原来的那些22啊, 3306之类的,9999是没有的,所以就被默认drop了,导致无响应), 这么一分析,其实就清晰了, 所以如果要想让9999对本机的容器(记住一定是本机的容器(因为容器的src ip无法匹配local的,不然  本机给本机发包, 感觉input没拦截,这里没太弄懂,不知道到底本机ip1to本机ip2到底忽略了什么))也能联通, 只需要在input里增加一条 --dport 9999 -j accept的规则就好了 (而且source ip 可以为 172.17.0.0/24)这个段,不一定非要开全网的,因为  tcpdump抓的包明显能看出来,不可能是非容器段的Ip的。

 

无法将多容器 docker 部署到 ElasticBeanstalk

】无法将多容器docker部署到ElasticBeanstalk【英文标题】:Failedtodeploymulti-containersdockertoElasticBeanstalk【发布时间】:2021-10-2602:04:14【问题描述】:我试图将多容器docker部署到ElasticBeanstalk中。但它不起作用。我尝试使用正在运行的dock... 查看详情

一台物理机器部署多个docker

参考技术A部署多个docker有两种方式,一种是让容器映射端口到宿主机,然后可以直接从外部访问到该端口,一种是利用nginx做转发,容器端口不对外暴露。这种是容器在建立的时候,使用-p参数来将容器的端口绑定到宿主机的端... 查看详情

通过 Beanstalk 部署的 Docker 容器无法连接到 RDS 上的数据库

】通过Beanstalk部署的Docker容器无法连接到RDS上的数据库【英文标题】:DockercontainerdeployedviaBeanstalkcannotconnecttothedatabaseonRDS【发布时间】:2018-11-2509:10:01【问题描述】:我是docker和AWS的新手。我刚刚创建了我的第一个docker镜像。该... 查看详情

多容器 Docker 应用程序部署失败

...我的应用程序是一个多容器Docker应用程序,其中包括节点服务器和mongoDB。不知何故,应用程序每次都会崩溃,我从mongoDB得到这个奇怪的错误。错误 查看详情

docker容器内无法访问其他服务器(代码片段)

问题:A,B两台服务器,都是docker部署的程序,A服务器的b1服务无法访问B服务器的c1服务(c1服务部署到A服务器的话可以访问),问题,docker容器内无法访问除宿主机外的局域网里的服务器?解决办... 查看详情

docker容器内无法访问其他服务器(代码片段)

问题:A,B两台服务器,都是docker部署的程序,A服务器的b1服务无法访问B服务器的c1服务(c1服务部署到A服务器的话可以访问),问题,docker容器内无法访问除宿主机外的局域网里的服务器?解决办... 查看详情

docker容器内无法访问其他服务器(代码片段)

问题:A,B两台服务器,都是docker部署的程序,A服务器的b1服务无法访问B服务器的c1服务(c1服务部署到A服务器的话可以访问),问题,docker容器内无法访问除宿主机外的局域网里的服务器?解决办... 查看详情

docker容器网络绑定端口部署

...sp;            docker网络基础一.1.默认情况下容器可以建立到外网网络的链接但是外网网络无法连接到容器   docker允许通过外部访问容器或容器互联的方式来提供网络服务 ... 查看详情

Angular docker 无法访问后端服务容器

】Angulardocker无法访问后端服务容器【英文标题】:Angulardockercannotreachbackendservicecontainer【发布时间】:2020-09-1900:44:15【问题描述】:我有一个AngularSPA和一个后端服务,两者都是通过docker容器部署的。我似乎无法让Angular应用程序... 查看详情

部署到 Google Cloud Run 时 Docker 容器无法启动

】部署到GoogleCloudRun时Docker容器无法启动【英文标题】:DockercontainerfailedtostartwhendeployingtoGoogleCloudRun【发布时间】:2020-11-2002:13:31【问题描述】:我是GCP的新手,我正在尝试通过在连接到BigQuery并写入系统时间的Docker容器中部署... 查看详情

通过docker部署odoo14

参考技术A为了保存数据,在容器关闭或者删除后仍然可以使用数据,可以添加数据路径这样就建立一个名称为db的容器,在PostgreSQLserver重启后,连接到db容器的Odoo同时也需要重新启动。-指定存储文件的卷,这样容器被删除后数... 查看详情

docker容器自动启动run

参考技术A部署项目服务器时,为了应对停电等情况影响正常web项目的访问,会把Docker容器设置为开机自动启动。如果创建时未指定--restart=always,可通过update命令设置Docker容器的重启策略是面向生产环境的一个启动策略,在开发过... 查看详情

无法通过 Docker 容器运行 NodeJS 微服务

】无法通过Docker容器运行NodeJS微服务【英文标题】:UnabletorunNodeJSmicroservicesthroughDockercontainers【发布时间】:2020-09-1409:48:04【问题描述】:我刚开始使用Docker,创建了几个小型Express(NodeJS)服务。计划是在Docker容器中运行微服务,... 查看详情

docker nodejs容器无法连接mysql容器

...:2017-08-1006:43:40【问题描述】:我在DigitalOcean中运行Docker服务器。我有两个容器Nodejs和Mysql。Mysql容器开放了3306端口。当尝试通过Docker服务器ip+端口通过nodejs访问mysql时。我收到错误:连接ET 查看详情

多 Docker 容器的 AWS Route53 设置问题

】多Docker容器的AWSRoute53设置问题【英文标题】:IssueswithAWSRoute53setupforMultiDockerContainer【发布时间】:2017-03-3103:16:12【问题描述】:我通过ElasticBeanstalk部署了两个不同的应用程序:单实例tomcat预构建单实例多docker对于App#1,我以ww... 查看详情

思源笔记docker容器化部署

...全离线使用,支持Docker部署,通过Docker镜像将思源部署在服务器上来搭建自己的云端笔记,通过授权码控制访问权限,方便多人协作。但是官方的Docker部署教程需在安装完成后才能查看[捂脸],网上现有Docker部署资料亦有错误及... 查看详情

无法从远程 docker 容器监听 docker 容器内运行的服务

】无法从远程docker容器监听docker容器内运行的服务【英文标题】:Unabletolistentoaservicerunninginsideadockercontainerfromremotedockercontainer【发布时间】:2019-10-1022:45:13【问题描述】:我有两台机器:机器A和机器B。两者都在不同的网络上。... 查看详情

python学习之美多商城:商品部分:docker使用(安装与操作)(代码片段)

...以在Ubuntu服务中运行RedhatEnterpriseLinux,但无法再Ubuntu服务器上运行MicrosoftWindows。相对于彻底隔离的管理程序虚拟化,容器被认为是不安全的。而反对这一观点的人则认为,由于虚拟容器所虚拟的是一个完整的操作系... 查看详情