theboyaply
theboyaply
发布于 2020-03-11 / 483 阅读
0
0

Docker 网络设置

参考:

https://www.cnblogs.com/windyet/articles/10139739.html

端口映射

docker 中运行的应用可以通过外部网络来进行访问,比如我们的 web 应用使用 docker 容器运行,我们肯定需要通过外部网络来访问 web 应用提供的服务。这时候需要使用 -p-P 进行容器的端口映射。

  • -Pdocker 会随机映射一个 49000~49900 的端口对容器中开放的端口进行映射。
  • -p:我们可以指定宿主机与容器之间的端口映射。

使用 -P 来运行一个容器(其中的 demo-server 镜像可参考Dockerfile制作镜像示例):

[root@localhost dockerDir]# docker run -d -P --name demo3 demo-server
531ec87461829a23161e906ef67cc63265b4c4b70c4a2eab65eeff4fddde97d3

[root@localhost dockerDir]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                     NAMES
531ec8746182        demo-server         "/bin/sh -c 'exec ja…"   About a minute ago   Up About a minute   0.0.0.0:32769->8080/tcp   demo3

可以看到容器中开放的 8080 端口映射到了宿主机的 32769 端口。

如果容器内部开放了多个端口,-P 会全部分配一个随机的端口。

-p 则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有 ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort

其中最常用的格式为 hostPort:containerPort

docker run -d -p 80:8080 --name demo demo-server

-p 可以同时绑定多个端口,如果容器内部开放多个端口的话,可以使用以下方式绑定:

docker run -d -p 80:8080 -p 8090:8090 --name demo demo-server

容器通信及network配置

运行两个容器:

docker run -d -p 81:8080 --name demo1 demo-server
docker run -d -p 82:8080 --name demo2 demo-server

容器在启动时,都会被分配一个 IP 地址,可以通过 docker inspect "容器ID或名称" 查看。当然,这个地址仅存在 docker 应用内部。

容器之间互相通信,可以使用这个 IP 地址。

# 进入demo2容器
[root@localhost dockerDir]# docker exec -it demo2 /bin/bash

# 使用demo1的IP地址对其进行通信
root@dac8487aba99:/# ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.231 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.138 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.083 ms

但是容器每一次启动或者重启,这个 IP 地址都会改变,因此我们不建议使用 IP 地址通信。--linknetwork 可帮助我们解决这个问题。

这里只是介绍 --link 的使用方式,而不推荐使用。随着 Docker 网络的完善,强烈建议大家将容器加入自定义的 Docker 网络来连接多个容器,而不是使用 --link 参数。

我们改变 demo2demo1 的通信方式,使用容器名称对 demo1 进行通信:

[root@localhost dockerDir]# docker exec -it demo2 /bin/bash
root@dac8487aba99:/# ping demo1
ping: demo1: Name or service not known

可以看到是无法通信的,我们改变一下 demo2 的运行命令,在其后面添加一个 --link

# 当然,如果你是按照本篇文章来进行练习,需要先删除已存在demo2容器:docker rm -f demo2
docker run -d -p 82:8080 --name demo2 --link demo1 demo-server

容器启动好之后我们再次进行通信:

[root@localhost dockerDir]# docker exec -it demo2 /bin/bash
root@23076465d04e:/# ping demo1
PING demo1 (172.17.0.2) 56(84) bytes of data.
64 bytes from demo1 (172.17.0.2): icmp_seq=1 ttl=64 time=0.141 ms
64 bytes from demo1 (172.17.0.2): icmp_seq=2 ttl=64 time=0.108 ms
64 bytes from demo1 (172.17.0.2): icmp_seq=3 ttl=64 time=0.102 ms

现在已经可以正常通信了。

值得注意的是:

  • 以上操作只能使 demo2demo1 进行通信,想要 demo1demo2 进行通信,那么 demo1 也需要使用 --link 来链接 demo2
  • 使用 --link 其实就是修改了 demo2 自己的 host 文件和设置了环境变量而已。
  • 使用 --link 链接容器时,被链接的容器必须存在。

--linkyml 文件中的使用方法:

links:
 - db
 - db:database     //连接到 db 服务,并命名为 database
 - redis

使用的别名将会自动在服务容器中的 /etc/hosts 里创建。例如:

172.12.2.186  db
172.12.2.186  database
172.12.2.187  redis

network

network 是目前常用的容器间通信方式。

新建网络

# 新建一个名为 my-net 的网络
docker network create -d bridge my-net

-d 参数指定 Docker 网络类型,有 bridge overlay。其中 overlay 网络类型用于 Swarm mode,在本小节中你可以忽略它。

显示所有网络

docker network ls

执行上面命令会发现,除了我们创建的 my-net 之外,还存在三个 bridge host nono,且这三个是默认的无法删除的。

运行容器时加入网络

在运行容器时使用 --network 参数指定容器要加入的网络:

docker run -d -p 81:8080 --name demo1 --network my-net demo-server
docker run -d -p 82:8080 --name demo2 --network my-net demo-server

加入同一网络的容器可以使用容器名相互通信:

[root@localhost dockerDir]# docker exec -it demo1 /bin/bash
root@51ee50af6e16:/# ping demo2
PING demo2 (172.18.0.3) 56(84) bytes of data.
64 bytes from demo2.my-net (172.18.0.3): icmp_seq=1 ttl=64 time=0.189 ms
64 bytes from demo2.my-net (172.18.0.3): icmp_seq=2 ttl=64 time=0.099 ms
64 bytes from demo2.my-net (172.18.0.3): icmp_seq=3 ttl=64 time=0.097 ms

其他命令

# 可以查看该网络的详细信息,以及在该网络里的容器
docker inspect my-net

# 手动将某个容器加入网桥
docker network connect my-net demo3

-- end --


评论