Docker容器之间访问策略

前言

最近在做项目的时候,许多中间件和软件的下载与配置都是在本机WSL2下完成的,十分的繁琐。在使用InfluxDB持久化Prometheus数据时,始终无法连接本机的InfluxDB,卸载重新安装后还出现了一堆其他错误,终于这成为了压死我的最后一根稻草。因此,我选择用半天多的时间将项目所用到的软件与中间件迁移至Docker,以绝后患。在迁移至Docker后,容器之间的互相访问是一个需要解决的问题,本文将对Docker的容器之间访问策略进行记录。

策略一:默认桥接网络

当启动Docker容器时,如果命令中不指定容器所使用的网络,那么Docker会为容器提供一个默认桥接网络docker0,我们通过docker inspect指令查看容器元数据可以看到以下内容

容器元数据

如果在一个容器中使用localhost:端口号是访问本容器的端口,而不是访问其他容器的端口。在元数据中我们可以看到默认分配的IPAddress,其他容器可以使用该IP地址访问本容器。

但是如果容器重启,Docker会根据启动顺序分配IPAddress,也就是说IPAddress会动态变化,这导致容器配置需要在每次重启时修改(除非你保证每次启动容器时的顺序都一样)。因此这种方法并不实用。

策略二:--link参数

在容器启动时,我们可以添加--link <容器名>参数的方法来连接两个容器,这种方法要求容器之间有先后启动的顺序之分,如果容器数量过多,那么使用--link工作量极大。并且Docker官方已经将--link标记为弃用,说不定在哪个版本就会删除--link参数,所以这种方法并不建议。

官方警告

策略三:用户自定义网络

我们可以使用以下指令创建自定义网络,然后在启动容器时使用--network参数指定自定义网络

docker network create -d bridge my-net
docker run --network=my-net -itd --name=container3 busybox

我们可以使用docker network ls指令展示docker现有的网络。。

其中bridge就是策略一中讲到的默认桥接网络。

host则是不给容器分配Network Namespace,也就是说容器不会自己模拟网卡、ip地址等信息,而是跟宿主机共同使用ip地址和端口,但是这种方式会导致无法区分宿主机和容器。

mynet是我自定义的网络。

none是不使用网络,即外部不可以访问容器内部。

可以看到用户自定义网络和默认桥接网络都是用brdige这种网络驱动,那么它们的区别是什么呢?

  1. 用户自定义网络提供容器之间的自动 DNS 解析,也就是说可以通过容器名:端口号的方式访问其他容器
  2. 用户自定义网络提供更好的隔离,默认网络会让所有的容器连接,这会带来一定的风险
  3. 用户自定义网络容器可以动态地与自定义网络连接和分离,即容器和网络是独立的,容器可以连接其他网络
  4. 用户自定义网络都是可配置的网桥,默认网络中所有的容器使用一个网络配置,而自定义网络可以再对网络内容器进行更细粒度的配置划分
  5. 默认桥接网络上的容器共享环境变量,而用户自定义网络不可以

以下是官方文档的原文

Differences between user-defined bridges and the default bridge
User-defined bridges provide automatic DNS resolution between containers.
Containers on the default bridge network can only access each other by IP addresses, unless you use the f ="https:// Legacy container links | Docker Docs">--link option, which is considered legacy. On a user-defined bridge network, containers can resolve each other by name or alias.
Imagine an application with a web front-end and a database back-end. If you call your containers  web and  db, the web container can connect to the db container at  db, no matter which Docker host the application stack is running on.
If you run the same application stack on the default bridge network, you need to manually create links between the containers (using the legacy  --link flag). These links need to be created in both directions, so you can see this gets complex with more than two containers which need to communicate. Alternatively, you can manipulate the  /etc/hosts files within the containers, but this creates problems that are difficult to debug.
User-defined bridges provide better isolation.
All containers without a  --network specified, are attached to the default bridge network. This can be a risk, as unrelated stacks/services/containers are then able to communicate.
Using a user-defined network provides a scoped network in which only containers attached to that network are able to communicate.
Containers can be attached and detached from user-defined networks on the fly.
During a container's lifetime, you can connect or disconnect it from user-defined networks on the fly. To remove a container from the default bridge network, you need to stop the container and recreate it with different network options.
Each user-defined network creates a configurable bridge.
If your containers use the default bridge network, you can configure it, but all the containers use the same settings, such as MTU and  iptables rules. In addition, configuring the default bridge network happens outside of Docker itself, and requires a restart of Docker.
User-defined bridge networks are created and configured using  docker network create. If different groups of applications have different network requirements, you can configure each user-defined bridge separately, as you create it.
Linked containers on the default bridge network share environment variables.
Originally, the only way to share environment variables between two containers was to link them using the f ="https:// Legacy container links | Docker Docs">--link flag. This type of variable sharing isn't possible with user-defined networks. However, there are superior ways to share environment variables. A few ideas:

Multiple containers can mount a file or directory containing the shared information, using a Docker volume.
Multiple containers can be started together using  docker-compose and the compose file can define the shared variables.
You can use swarm services instead of standalone containers, and take advantage of shared  secrets and  configs.
Containers connected to the same user-defined bridge network effectively expose all ports to each other. For a port to be accessible to containers or non-Docker hosts on different networks, that port must be  published using the  -p or  --publish flag.
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小事不要慌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值