目录

一.外部访问容器

默认情况下,如果在启动容器时不进行端口映射,外部是无法访问到容器内部的应用的,如:

  1. $ docker run --name web -d tomcat
  2. d3ee8f09404c0626bc18bb293368c2c171ddcae16420a16370528262e9ed7e87
  3. chench@localhost:~$ docker container ls
  4. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  5. d3ee8f09404c tomcat "catalina.sh run" 5 seconds ago Up 4 seconds 8080/tcp web

但是主机是可以访问容器的。

只有在启动容器时明确进行了端口映射,外部主机才能通过映射的端口访问到容器内部的应用,对容器端口映射有2种方式可以实现:

1.启动容器时指定参数-P(大写P)

2.启动容器时指定参数-p(小写p)

启动容器时指定参数-P(大写P)

此时Docker会随机映射一个49000~49900的主机端口到内部容器开放的网络端口。

  1. $ docker run --name web -d -P tomcat
  2. a1b6e37b751379ada8bcf9ffc044fb58eac4b0e6bbe34832a5149e8a0561f9b8
  3. $ docker container ls
  4. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  5. a1b6e37b7513 tomcat "catalina.sh run" 5 seconds ago Up 3 seconds 0.0.0.0:32769->8080/tcp web

可以看到,使用参数-P将主机的端口32769映射到容器内部的8080端口了,此时外部主机通过访问容器主机的32769端口就可以访问到容器内部的web应用。

启动容器时指定参数-p(小写p)

支持的格式有:ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort,在一个指定端口上只可以绑定一个容器,但是可以将主机的多个端口映射到相同容器的相同端口。

(1)映射主机指定接口地址的指定端口到容器指定端口

格式:-p ip:hostPort:containerPort

  1. $ docker run --name web -d -p 127.0.0.1:8080:8080 tomcat
  2. fb9531946ab22d57da7f88661cf3841a183aa84a6760f0b657106bdbd9f5d2de
  3. $ docker container ls
  4. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  5. fb9531946ab2 tomcat "catalina.sh run" 5 seconds ago Up 3 seconds 127.0.0.1:8080->8080/tcp web

映射主机的127.0.0.1上的8080端口到容器的8080端口。

因为只映射了主机的127.0.0.1接口,所以此时主机可以访问容器内部的web应用,但是外部主机却无法访问容器内部的web应用。如果希望外部主机也能访问容器内部的web应用,必须指定映射一个外部能访问的主机接口,如:

  1. $ docker run --name web2 -d -p 192.168.80.131:8081:8080 tomcat
  2. d55b5e5d39969b324d90edecf65f6a0c7d6b104fa16a147c531e832c15f48ca9
  3. $ docker container ls
  4. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  5. d55b5e5d3996 tomcat "catalina.sh run" 6 seconds ago Up 4 seconds 192.168.80.131:8081->8080/tcp web2
  6. fb9531946ab2 tomcat "catalina.sh run" 3 minutes ago Up 3 minutes 127.0.0.1:8080->8080/tcp web

因为主机的接口192.168.80.131是可以被外部主机访问的,所以上述端口映射之后,外部主机也能访问容器内部的web应用。

(2)映射主机指定接口地址的任意端口

格式:-p ip::containerPort

外部主机能访问容器内部的web应用取决于映射的主机地址是否能被外部主机访问。

(3)映射所有接口地址

格式:-p hostPort:containerPort

这是最常用的端口映射方式,采用这种方式映射了主机指定端口到容器指定端口之后,只要主机能被外部主机访问,容器内的web应用也能被外部主机访问。

(4)同时映射多个端口

-p参数可以多次使用来映射多个端口,如:

  1. $ docker run --name web3 -d -p 8082:8080 -p 8083:8080 tomcat
  2. a28613c7a7933d674689a8db72adb510deffc2e35f310d15feca4eb977776dda
  3. $ docker container ls
  4. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  5. a28613c7a793 tomcat "catalina.sh run" 7 seconds ago Up 5 seconds 0.0.0.0:8082->8080/tcp, 0.0.0.0:8083->8080/tcp web3
  6. d55b5e5d3996 tomcat "catalina.sh run" 8 minutes ago Up 8 minutes 192.168.80.131:8081->8080/tcp web2
  7. fb9531946ab2 tomcat "catalina.sh run" 12 minutes ago Up 12 minutes 127.0.0.1:8080->8080/tcp web

上述操作同时将主机的8082和8083端口同时映射到了容器的8080端口,因此外部主机可以通过容器主机的8082或8083访问到容器内部的web应用。

二.容器互联

容器互联的目的是为了使得多个容器之间能相互连通和访问,实现容器互联有2种方式:

1.使用--link参数来使容器互联

2.将容器加入自定义的Docker网络实现互联

使用--link参数使容器互联

使用"--link"参数实现容器互联是指:在启动容器时将容器连接到另一个容器。

  1. # 先运行一个名称为web1的容器
  2. $ docker run -d --name web1 tomcat
  3. # 运行名称为web2的容器时通过--link参数连接到容器web1上
  4. $ docker run -d --name web2 --link web1 tomcat
  5. # 进入到web2容器中,ping容器web1
  6. $ docker exec -it web2 bash
  7. root@a262333f2f61:/usr/local/tomcat# ping web1
  8. PING web1 (172.19.0.2) 56(84) bytes of data.
  9. 64 bytes from web1 (172.19.0.2): icmp_seq=1 ttl=64 time=0.079 ms
  10. 64 bytes from web1 (172.19.0.2): icmp_seq=2 ttl=64 time=0.121 ms
  11. 64 bytes from web1 (172.19.0.2): icmp_seq=3 ttl=64 time=0.090 ms
  12. 64 bytes from web1 (172.19.0.2): icmp_seq=4 ttl=64 time=0.094 ms
  13. 64 bytes from web1 (172.19.0.2): icmp_seq=5 ttl=64 time=0.094 ms
  14. 64 bytes from web1 (172.19.0.2): icmp_seq=6 ttl=64 time=0.144 ms
  15. ^C

显然,在启动容器web2时连接到了容器web1,进入到web2中是可以ping通web1的,那么进入到web1是否可以ping通web2呢?

  1. docker exec -it web1 bash
  2. root@a81a00962bbf:/usr/local/tomcat# ping web2
  3. PING web2.com (184.168.221.74) 56(84) bytes of data.
  4. 64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=7 ttl=40 time=216 ms
  5. 64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=8 ttl=40 time=216 ms
  6. 64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=17 ttl=40 time=216 ms
  7. 64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=27 ttl=40 time=216 ms
  8. 64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=54 ttl=40 time=218 ms
  9. 64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=62 ttl=40 time=216 ms
  10. 64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=74 ttl=40 time=216 ms

网络是通的,但是延迟特别大。

将容器加入自定义网络实现互联

默认情况下,不进行互联的容器之间不能相互连通的。将容器加入自定义的Docker网络实现互联的步骤如下:

第一步,新建一个指定名称的Docker网络

  1. $ docker network create -d bridge my-net
  2. c0e06e20f43d850ec744a495e3f3a0dbb304ab5ca53121b9b3467832859ef283
  3. $ docker network ls
  4. NETWORK ID NAME DRIVER SCOPE
  5. cb2d10962818 bridge bridge local
  6. 9c5f0af584ae host host local
  7. c0e06e20f43d my-net bridge local
  8. dd97656c3736 none null local

-d参数指定网络类型,有bridge和overlay。其中overlay网络类型用于Swarm mode。

实际上,在安装了Docker服务的主机上将会默认存在3个Docker网络:

  1. $ docker network ls
  2. NETWORK ID NAME DRIVER SCOPE
  3. cb2d10962818 bridge bridge local
  4. 9c5f0af584ae host host local
  5. dd97656c3736 none null local

第二步,在运行容器时连接到指定网络

  1. $ docker run --name web1 --network my-net -p 8080:8080 -d tomcat
  2. 667b0071ee0ba0fdd5c83743432ebf1b0a1844b0b8b5165f3b0b64c1880e102f
  3. $ docker run --name web2 --network my-net -p 8081:8080 -d tomcat
  4. 4bb0530e81058a1136307e90a0fd4431e6a9c2d5f7491c42adbf1f1625337a6a

将容器web1和web2都加入到自定义网络my-net中,进入到web1中测试是否可以连通web2:

  1. $ docker exec -it 667b0071ee0b sh
  2. #ping web2
  3. PING web2 (172.18.0.3): 56 data bytes
  4. 64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.208 ms
  5. 64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.072 ms

三.为容器配置DNS

容器有自己的内部网络和ip地址(使用docker inspect可以获取所有的变量,Docker还可以有一个可变的网络配置),对应的容器也可以配置自己的DNS。

1.配置全部容器的DNS

全局配置所有容器的DNS,可以直接在/etc/docker/daemon.json文件中增加以下内容来设置:

  1. {
  2. "dns": [
  3. "114.114.114.114",
  4. "8.8.8.8"
  5. ]
  6. }

添加全局配置之后需要重启docker服务:

  1. $ sudo systemctl restart docker

验证对容器进行全局DNS配置:

  1. $ docker run --rm -it ubuntu:16.04 cat /etc/resolv.conf
  2. search localdomain
  3. nameserver 114.114.114.114
  4. nameserver 8.8.8.8

显然,全局配置的DNS会被添加到容器的/etc/resolv.conf文件中。

2.对指定容器配置DNS

除了可以全局方式对容器DNS进行配置之外,也可在容器启动时通过参数"--dns"为容器指定DNS配置。而且还必须注意,通过参数“--dns”指定的DNS配置会覆盖全局的DNS配置。

  1. $ docker run --rm --dns=2.2.2.2 -it ubuntu:16.04 cat /etc/resolv.conf
  2. search localdomain
  3. nameserver 2.2.2.2 # 参数--dns配置的DNS覆盖了全局DNS配置,可以理解为--dns参数指定的DNS优先级比在/etc/docker/daemon.json中配置的全局DNS优先级高
  4. $ docker run --rm -it ubuntu:16.04 cat /etc/resolv.conf
  5. search localdomain
  6. nameserver 114.114.114.114
  7. nameserver 8.8.8.8

Docker实践之08-使用网络的更多相关文章

  1. Docker系列04—跨主机网络方案(overlay/weave)

    在前面详细讲解了几种网络模式:none,host,bridge,container.他们解决了单个主机间的容器的通信问题,并不能实现多个主机容器之间的通信. 跨主机网络方案包括两大类: 1,docke ...

  2. Docker实践,来自沪江、滴滴、蘑菇街架构师的交流分享

    架构师小组交流会:每期选一个时下最热门的技术话题进行实践经验分享. 第一期主题:容器实践.Docker 作为当前最具颠覆性的开源技术之一,其轻量虚拟化.可移植性是CI/CD,DevOps,微服务的重要 ...

  3. [docker]docker自带的overlay网络实战

    overlay网络实战 n3启动consul docker run -d -p 8500:8500 -h consul --name consul progrium/consul -server -b ...

  4. docker实践之docker-compose部署mysql

    文章目录 docker实践之docker-compose部署mysql 1.安装部署docker 2.编写docker-compose文件 3.编写配置文件和初始化文件 4.启动数据库 5.检查初始化 ...

  5. Docker容器基础入门认知-网络篇

    这篇文章中,会从 docker 中的单机中的 netns 到 veth,再到单机多个容器之间的 bridge 网络交互,最后到跨主机容器之间的 nat 和 vxlan 通信过程,让大家对 docker ...

  6. Docker的单主机容器网络

    作者:杨冬 欢迎转载,也请保留这段声明.谢谢! 出处: https://andyyoung01.github.io/ 或 http://andyyoung01.16mb.com/ 本篇文章主要探索Do ...

  7. 百度APP移动端网络深度优化实践分享(二):网络连接优化篇

    本文由百度技术团队“蔡锐”原创发表于“百度App技术”公众号,原题为<百度App网络深度优化系列<二>连接优化>,感谢原作者的无私分享. 一.前言 在<百度APP移动端网 ...

  8. centos7下安装docker(12.2自定义网络)

    通常默认的情况下我们使用的是docker的bridge的网络,用户也可以根据自己的业务需要,创建user-defined docker 提供三种user-defined网络驱动:bridge,over ...

  9. docker 实践

    https://doc.yonyoucloud.com/doc/docker_practice/etcd/etcdctl.html 启动http restful API docker批量映射端口 怎么 ...

  10. Docker学习(六): 网络使用与配置

    特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...

随机推荐

  1. 【转帖】AMD EPYC——CPU命名规则

    AMD的三代服务器CPU都属于7000系列大锅,那么您如何知道要购买的产品呢? 只要看一下右边的最后一个数字,数字1代表第一代那不勒斯EPYC,数字2代表罗马型号,数字3代表新米兰产品. 始终从右到左 ...

  2. [转帖]gdb调试常见命令详细总结(附示例操作)

    一.简介 通过gdb调试我们可以监控程序执行的每一个细节,包括变量的值.函数的调用过程.内存中数据.线程的调度等,从而发现隐藏的错误或者低效的代码,程序的调试过程主要有:单步执行,跳入函数,跳出函数, ...

  3. [转帖]Linux系统中的Page cache和Buffer cache

    Free命令显示内存 首先,我们来了解下内存的使用情况: Mem:表示物理内存统计 total:表示物理内存总量(total = used + free) used:表示总计分配给缓存(包含buffe ...

  4. [转帖]linux求数组的交集,shell/bash 交集、并集、差集

    方法一(直接用文件名):取两个文本文件的并集.交集.差集 并: sort -m 交: sort -m 差 file1 - file2: sort -m 方法二(用变量参数):取两个文本文件的并集.交集 ...

  5. [转帖]Ubuntu Server安装图形界面

    最早接触到的Linux系统是Ubuntu 10.04,当时在自己的一台Win7笔记本电脑上安装的Win/Ubuntu双系统,Ubuntu简洁的操作界面给我留下了深刻的印象. 后来开始做一些服务器开发, ...

  6. 程序启停分析与进程常用API的使用

    进程是程序运行的实例,操作系统为进程分配独立的资源,使之拥有独立的空间,互不干扰. 空间布局 拿c程序来说,其空间布局包括如下几个部分: 数据段(初始化的数据段):例如在函数外的声明,int a = ...

  7. 学习MySQL中DDL语句的修改字段与删除字段,删除表

    连接本地mysql语句 mysql -hlocalhost -uroot -proot 显示表结构 语法:desc 表名 查看某一个表结构以及注释 语法:show create table 表名 sh ...

  8. 【解决一个小问题】proto文件中的enum,去掉长长的重复的enum名字

    在proto中定义的enum,通常类型名字都会带上enum的前缀,很丑陋,如何去掉呢? enum DataSourceType{ NotUse = 0; MySQL = 1; ElasticSearc ...

  9. Seata分布式事务 (理论与部署相结合)

    分布式事务--Seata 分布式事务 1. 本地事务与分布式事务 1.1 本地事务 本地事务,也就是传统的单机事务.在传统数据库事务中,必须要满足四个原则: 1.2 分布式事务问题 分布式事务,就是指 ...

  10. minIO系列文章01---MinIO 简介

    MinIO.jpeg MinIO 官网 MinIO 官方GitHub MinIO 官方文档 1.什么是对象存储? 关于对象存储,我们可以看下 阿里云OSS 的解释. 对象存储服务OSS(Object ...