容器如何与外部世界通信,这里涉及两个方向
1.容器访问外部世界
2.外部世界访问容器

当宿主机可以上网时,容器不用配置就可以访问外网

[root@su1 harbor]# ping www.baidu.com
PING www.a.shifen.com (39.156.66.14) 56(84) bytes of data.
64 bytes from 39.156.66.14 (39.156.66.14): icmp_seq=1 ttl=50 time=72.8 ms
64 bytes from 39.156.66.14 (39.156.66.14): icmp_seq=2 ttl=50 time=74.4 ms[root@su1 harbor]# docker run -it  busybox
/ # ping www.baidu.com
PING www.baidu.com (39.156.66.14): 56 data bytes
64 bytes from 39.156.66.14: seq=0 ttl=49 time=63.303 ms
64 bytes from 39.156.66.14: seq=1 ttl=49 time=46.477 ms

busybox位于docker0这个私有bridge网络中(172.17.0.0/16)
busybox从容器向外ping时,数据包是怎样到达baidu.com的呢 这里的关键就是NAT 我们查看以下docker host 上的iptables规则

查看iptables规则

[root@su1 ~]# iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N DOCKER
-N OUTPUT_direct
-N POSTROUTING_ZONES
-N POSTROUTING_ZONES_SOURCE
-N POSTROUTING_direct
-N POST_public
-N POST_public_allow
-N POST_public_deny
-N POST_public_log
-N PREROUTING_ZONES
-N PREROUTING_ZONES_SOURCE
-N PREROUTING_direct
-N PRE_public
-N PRE_public_allow
-N PRE_public_deny
-N PRE_public_log
-A PREROUTING -j PREROUTING_direct
-A PREROUTING -j PREROUTING_ZONES_SOURCE
-A PREROUTING -j PREROUTING_ZONES
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT -j OUTPUT_direct
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.22.0.0/24 ! -o br-74fb4d7b7af1 -j MASQUERADE
-A POSTROUTING -s 172.20.0.0/16 ! -o br-88c3c24e0863 -j MASQUERADE
-A POSTROUTING -s 172.19.0.0/16 ! -o br-ba6e4fa36e51 -j MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

解析:如果网桥docker0收到来自172.17.0.0/16网段的外出包,把它交给MASQUERADE处理,而MASQUERADE的处理方式是将包的源地址替换成host的地址发送出去,经过MASQUERADE进行ip地址伪装与外界通信,即做了一次网络地址转换(NAT)

下面我们通过tcpdump查看地址是如何转换的 先查看docker host路由表

[root@su1 ~]# ip r
默认路由通过eth0发出去的,所以我们要同时监控eth0 和docker0上的icpm(ping)数据包
default via 172.25.34.250 dev eth0 proto static metric 100
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
172.19.0.0/16 dev br-ba6e4fa36e51 proto kernel scope link src 172.19.0.1
172.20.0.0/16 dev br-88c3c24e0863 proto kernel scope link src 172.20.0.1
172.22.0.0/24 dev br-74fb4d7b7af1 proto kernel scope link src 172.22.0.1
172.25.34.0/24 dev eth0 proto kernel scope link src 172.25.34.8 metric 100

监控数据流向

[root@su1 ~]# yum install -y tcpdump-4.9.2-3.el7.x86_64


1.busybox发送ping包:172.17.0.2 >www.baidu.com
2.docker0收到包,发现是发送到外网站的,交给NAT处理
3.NAT将源地址转换成eth0的IP地址:172.25.0.7 >www.baidu.com
4.ping包从eth0发送出去,到达www.baidu.com

容器ip---->docker0(NAT)----->eth0(NAT)---->enp0s25(NAT)----->www.baidu.com

外部世界访问容器

外部如何访问到容器?
端口映射 docker可将容器对外提供服务的端口映射到host的某个端口,外网通过该端口访问容器

将容器的80端口映射到宿主机

[root@su1 harbor]# docker run -d -p 80 httpd
Unable to find image 'httpd:latest' locally
latest: Pulling from library/httpd
8d691f585fa8: Pull complete
8eb779d8bd44: Pull complete
574add29ec5c: Pull complete
30d7fa9ec230: Pull complete
ede292f2b031: Pull complete
Digest: sha256:35fcab73dc9ae55db5c4ac33f5e0c7e76b7735aaddb628366bab04db6f8ae96e
Status: Downloaded newer image for httpd:latest
09ca48d094a3a53af41b60dff2192b2244eefb86bfc8c8cd6cf5a2fe90800a9d
[root@su1 harbor]# docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                   NAMES
09ca48d094a3        httpd               "httpd-foreground"   22 seconds ago      Up 20 seconds       0.0.0.0:32768->80/tcp
youthful_volhard
[root@su1 harbor]# curl 172.25.34.8:32768
<html><body><h1>It works!</h1></body></html>除了映射动态端口,也可以在-p中指定映射到host某个特定端口,例如可以将80端口映射到host的8080端口
[root@su1 harbor]# docker run -d -p 8080:80 httpd
f3f0d046efbff7f4deab4ce0a05fcdd1d6c226baeabe9193320f0c3bfc539b4e
[root@su1 harbor]# docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                   NAMES
f3f0d046efbf        httpd               "httpd-foreground"   13 seconds ago      Up 10 seconds       0.0.0.0:8080->80/tcp    trusting_shtern
09ca48d094a3        httpd               "httpd-foreground"   2 minutes ago       Up 2 minutes        0.0.0.0:32768->80/tcp   youthful_volhard
[root@su1 harbor]# curl 172.25.34.8:8080
<html><body><h1>It works!</h1></body></html>

每一个映射的端口,host都会启动一个docker-proxy进程来处理访问容器的流量

[root@su1 harbor]# ps -ef | grep docker_proxy
root      2529  2122  0 23:05 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 32768 -container-ip 172.17.0.2 -container-port 80
root      2672  2122  0 23:11 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.17.0.3 -container-port 80
root      2792  2099  0 23:11 pts/0    00:00:00 grep --color=auto docker-proxy

因为端口映射,会有docker-proxy,当访问172.25.34.8:32768时会经过以下流程
172.25.34.8:32768---->docker-proxy----->容器ip:80-----httpd容器响应请求并返回结果----->docker-proxy---->172.25.34.8:32768

Docker容器——容器间的通信(端口映射,互联机制)相关推荐

  1. 【docker】修改docker容器配置,设置/修改端口映射

    目录 前言 方法1:将容器转换成镜像,用新的镜像创建新的容器 方法2:修改容器配置 方法3:创建新的容器 方法4:nginx stream代理 参考 前言 docker 创建容器时可指定端口映射.但容 ...

  2. Docker 核心概念、安装、端口映射及常用操作命令,详细到令人发指。

    Docker简介 Docker是开源应用容器引擎,轻量级容器技术. 基于Go语言,并遵循Apache2.0协议开源 Docker可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发 ...

  3. Windows版Docker(基于WSL2)增加端口映射(需重启Docker)

    1.查看容器Id. 2.关闭容器(已有映射10022->22). 3.在终端依次输入([容器Id]需修改为实际容器Id): cd \\wsl.localhost\docker-desktop-d ...

  4. Docker ❀ 容器内部/外部通信、端口映射、网络模式、自定义容器网络

    文章目录 1.网络通讯 命名空间类型 2.网络模式 Docker服务默认存在四组网络模式 3.端口映射 -p : 容器指定端口映射为本地随机端口: -p : 容器指定端口映射为本地指定端口: -p : ...

  5. centos7 docker删除端口映射_容器Docker详解

    概述 基本概念Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源.Docker可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的Li ...

  6. Docker 网络-端口映射、容器链接、Networking

    在使用Docker容器时,我们需要访问容器的内部网络,或需要在容器间相互访问.Docker 容器默认不会开放任何端口,因此需要将容器与宿主机进行端口映射,使容器可外部访问.而容器间互相访问,除了可以基 ...

  7. docker 改host_所以到底该如何修改 docker 容器的端口映射!!!

    |问题背景 docker run -d -p 9999:8080 -i --name tomcat7 tomcat:7创建容器时,指定了端口映射(-p) 如果容器运行之后发现端口需要改怎么办? 当前是 ...

  8. docker 镜像修改的配置文件自动还原_所以到底该如何修改 docker 容器的端口映射!!!...

    |问题背景 docker 创建容器时,指定了端口映射(-p) 如果容器运行之后发现端口需要改怎么办? 当前是访问 9999 端口 |删除原有容器,重新创建新的容器 |删除容器 docker |重新创建 ...

  9. Docker运行容器端口映射

    大致描述 我发现docker启动容器时(以redis为例),在已经启动了一个-p 6379:6379的redis1容器后,当我们开启第二个redis2容器时, 右边的端口映射既可以写别的我们想要映射的 ...

  10. docker中容器与宿主机之间的网络关系

    接上一篇jupter远程访问 docker中容器与宿主机之间的网络关系 一.PC上的网络关系 1.网卡的物理地址 网卡的物理地址(MAC地址):是网卡的唯一标识.由生产厂商写入网卡中.MAC地址就如同 ...

最新文章

  1. Win32 环境下的堆栈
  2. 单片机8位抢答器实训机电报告_CD4511八路抢答器实验报告-
  3. 最优布线问题(克鲁斯卡尔)
  4. JavaScript初学者必看“new”
  5. P2548 [AHOI2004]智能探险车
  6. 数据结构系列(四)栈与队列
  7. 请MVC5 WebApi2 支持OData协议查询
  8. 即将开播!联想可能成为罗永浩直播带货的首批合作者
  9. [深度学习] Python人脸识别库face_recognition使用教程
  10. librdkafka编译及简单使用过程简介
  11. ICMP协议详解和作用
  12. mapbox gl本地化部署实践
  13. 计算机组成原理__第6章之硬盘存储器
  14. 深度学习环境配置10——Ubuntu下的torch==1.7.1环境配置
  15. 字谜 大小写重复全排列问题
  16. 1rem、1em、1vh(vw)、1px各自代表的含义
  17. webhub123 前端技术社区和技术交流学习网站导航
  18. M41ST85W_3.0/3.3 V I²C组合实时时钟、NVRAM监控器和微处理器监控——科时进商城
  19. Unity3d 自发光(荧光)Bloom效果的实现
  20. net stop mysql 发生系统错误5

热门文章

  1. c# 操作服务器虚拟目录,C# 操作IIS服务器Demo
  2. 【小案例】使用CSS过渡制作手风琴
  3. vb_一个简单的小程序·1
  4. 考研过来人手把手帮你准备复试
  5. TreeMap按value排序
  6. 华为智选推出高性能电驱轿跑SUV;沃尔沃将用绿色钢铁制造概念车;大陆集团开发250米长距雷达 | 美通企业日报...
  7. 蓝牙键盘鼠标连接手提电脑无响应/罗技K380/雷柏鼠标
  8. mysql 存储过程 长字符串_mysql存储过程瓜分字符串
  9. 掌财社:八种基本K线买卖口诀
  10. BERTweet: A Pretrained Language Model for English Tweets 论文解读