前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Docker实践之07-使用网络

Docker实践之07-使用网络

作者头像
编程随笔
发布2022-09-08 20:31:41
3890
发布2022-09-08 20:31:41
举报
文章被收录于专栏:后端开发随笔后端开发随笔

目录

一.外部访问容器

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

代码语言:javascript
复制
$ docker run --name web -d tomcat
d3ee8f09404c0626bc18bb293368c2c171ddcae16420a16370528262e9ed7e87
chench@localhost:~$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
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的主机端口到内部容器开放的网络端口。

代码语言:javascript
复制
$ docker run --name web -d -P tomcat
a1b6e37b751379ada8bcf9ffc044fb58eac4b0e6bbe34832a5149e8a0561f9b8
$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
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

代码语言:javascript
复制
$ docker run --name web -d -p 127.0.0.1:8080:8080 tomcat
fb9531946ab22d57da7f88661cf3841a183aa84a6760f0b657106bdbd9f5d2de
$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                      NAMES
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应用,必须指定映射一个外部能访问的主机接口,如:

代码语言:javascript
复制
$ docker run --name web2 -d -p 192.168.80.131:8081:8080 tomcat
d55b5e5d39969b324d90edecf65f6a0c7d6b104fa16a147c531e832c15f48ca9
$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                           NAMES
d55b5e5d3996        tomcat              "catalina.sh run"   6 seconds ago       Up 4 seconds        192.168.80.131:8081->8080/tcp   web2
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参数可以多次使用来映射多个端口,如:

代码语言:javascript
复制
$ docker run --name web3 -d -p 8082:8080 -p 8083:8080 tomcat
a28613c7a7933d674689a8db72adb510deffc2e35f310d15feca4eb977776dda
$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                            NAMES
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
d55b5e5d3996        tomcat              "catalina.sh run"   8 minutes ago       Up 8 minutes        192.168.80.131:8081->8080/tcp                    web2
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参数实现容器互联
使用--link参数实现容器互联

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

代码语言:javascript
复制
# 先运行一个名称为web1的容器
$ docker run -d --name web1 tomcat

# 运行名称为web2的容器时通过--link参数连接到容器web1上
$ docker run -d --name web2 --link web1 tomcat

# 进入到web2容器中,ping容器web1
$ docker exec -it web2 bash
root@a262333f2f61:/usr/local/tomcat# ping web1
PING web1 (172.19.0.2) 56(84) bytes of data.
64 bytes from web1 (172.19.0.2): icmp_seq=1 ttl=64 time=0.079 ms
64 bytes from web1 (172.19.0.2): icmp_seq=2 ttl=64 time=0.121 ms
64 bytes from web1 (172.19.0.2): icmp_seq=3 ttl=64 time=0.090 ms
64 bytes from web1 (172.19.0.2): icmp_seq=4 ttl=64 time=0.094 ms
64 bytes from web1 (172.19.0.2): icmp_seq=5 ttl=64 time=0.094 ms
64 bytes from web1 (172.19.0.2): icmp_seq=6 ttl=64 time=0.144 ms
^C

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

代码语言:javascript
复制
docker exec -it web1 bash
root@a81a00962bbf:/usr/local/tomcat# ping web2
PING web2.com (184.168.221.74) 56(84) bytes of data.
64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=7 ttl=40 time=216 ms
64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=8 ttl=40 time=216 ms
64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=17 ttl=40 time=216 ms
64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=27 ttl=40 time=216 ms
64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=54 ttl=40 time=218 ms
64 bytes from ip-184-168-221-74.ip.secureserver.net (184.168.221.74): icmp_seq=62 ttl=40 time=216 ms
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网络

代码语言:javascript
复制
$ docker network create -d bridge my-net
c0e06e20f43d850ec744a495e3f3a0dbb304ab5ca53121b9b3467832859ef283
$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
cb2d10962818        bridge              bridge              local
9c5f0af584ae        host                host                local
c0e06e20f43d        my-net              bridge              local
dd97656c3736        none                null                local

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

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

代码语言:javascript
复制
$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
cb2d10962818        bridge              bridge              local
9c5f0af584ae        host                host                local
dd97656c3736        none                null                local

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

代码语言:javascript
复制
$ docker run --name web1 --network my-net -p 8080:8080 -d tomcat
667b0071ee0ba0fdd5c83743432ebf1b0a1844b0b8b5165f3b0b64c1880e102f
$ docker run --name web2 --network my-net -p 8081:8080 -d tomcat
4bb0530e81058a1136307e90a0fd4431e6a9c2d5f7491c42adbf1f1625337a6a

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

代码语言:javascript
复制
$ docker exec -it 667b0071ee0b sh
#ping web2
PING web2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.208 ms
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文件中增加以下内容来设置:

代码语言:javascript
复制
{
	"dns": [
		"114.114.114.114",
		"8.8.8.8"
	]
}

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

代码语言:javascript
复制
$ sudo systemctl restart docker

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

代码语言:javascript
复制
$ docker run --rm -it ubuntu:16.04 cat /etc/resolv.conf
search localdomain
nameserver 114.114.114.114
nameserver 8.8.8.8

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

2.对指定容器配置DNS

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

代码语言:javascript
复制
$ docker run --rm --dns=2.2.2.2 -it ubuntu:16.04 cat /etc/resolv.conf
search localdomain
nameserver 2.2.2.2   # 参数--dns配置的DNS覆盖了全局DNS配置,可以理解为--dns参数指定的DNS优先级比在/etc/docker/daemon.json中配置的全局DNS优先级高
$ docker run --rm -it ubuntu:16.04 cat /etc/resolv.conf
search localdomain
nameserver 114.114.114.114
nameserver 8.8.8.8
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 一.外部访问容器
    • 启动容器时指定参数-P(大写P)
      • 启动容器时指定参数-p(小写p)
      • 二.容器互联
        • 使用--link参数使容器互联
          • 将容器加入自定义网络实现互联
          • 三.为容器配置DNS
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档