Docker容器之间的通信

一些问题

  1. docker每次启动,ip地址会变更吗?
    Docker容器的IP地址是在容器启动时由Docker守护进程分配的,默认情况下,容器内部的IP地址可能会在每次容器启动时发生变化。容器获得的IP地址是从宿主机上预配置的网络桥接接口的子网池中分配的。当容器停止并重新启动时,它通常会得到一个新的IP地址,因为Docker会将先前的IP地址放回到地址池中供未来容器使用。
    如果你重新创建了一个容器(例如,使用docker rm删除了旧容器并用docker run启动了一个新容器),新容器也会获得一个新的IP地址,因为每次docker run基本上都是创建了一个全新的容器实例。

  2. 怎样保证容器IP的一致性?
    默认情况下,Docker容器是连接到一个名为bridge的默认网络。你可以创建一个用户定义的网络,并将容器连接到这个网络。在用户定义的网络中,容器的IP地址在启动和停止容器时具有更强的一致性。

    • 创建一个新的网络:docker network create my-custom-network
    • 启动容器时指定网络:docker run --net=my-custom-network --name=my-container my-image
    • 当你在用户定义的网络中启动容器时,你可以手动指定容器的IP地址: docker run --net=my-custom-network --ip=172.28.0.10 --name=my-container my-image,这个IP地址必须在网络的子网内,并且未被其他容器占用。

保持IP地址不变通常对于容器间的网络通信来说不是必要的,因为Docker提供了其他发现机制,如链接和DNS解析(通过容器名)。最好的做法通常是通过容器名进行网络通信,而不是依赖于IP地址,这可以让你的Docker架构更灵活且易于维护。

容器名进行通信的方式

Docker 使用内部的DNS服务来支持通过容器名进行通信。当你创建一个用户定义的网络时,Docker会自动为网络中的每个容器配置DNS解析,使得容器可以通过容器名进行互相访问。

下面是一个利用容器名进行通信的简单案例:

创建一个新的 Docker 网络:
docker network create my-network
在这个网络中启动两个容器,它们分别运行不同的服务:
docker run --name=container1 --net=my-network my-app-image
docker run --name=container2 --net=my-network my-db-image
在这个例子中,container1 可能是一个Web应用程序,而 container2 是相关的数据库服务。

在 container1 中,你想要连接到 container2 上的数据库服务,可以使用 container2 作为主机名来进行连接,例如:
db.connect("container2:3306")
在这儿,"3306"是MySQL默认的端口号。“container2”在DNS解析中指向了该容器的内部IP地址。

在Docker环境中,使用container2作为连接字符串的一部分类似于在传统的单机设置中使用localhost。但是,它们背后的解析逻辑是有区别的。
当你在一个单机环境(不使用Docker)中使用localhost,它代表的是本地机器的回环地址(127.0.0.1)。所以,如果一个应用程序尝试连接到localhost:3306,它实际上是尝试连接到本地机器上正在监听端口3306的服务。
而在Docker环境中,每个容器都被分配了一个唯一的IP地址,并被Docker内部DNS服务识别。当你在一个容器中使用另一个容器的名称(如container2)作为主机名时,Docker的内部DNS服务会将这个名称解析为所对应的容器的私有IP地址。因此,在container1中使用db.connect(“container2:3306”),实际上是让container1连接到与之关联的Docker网络中名为container2的容器实例。

Docker Compose 简例

如果您使用 Docker Compose,可以在 docker-compose.yml 文件中定义服务及网络。Docker Compose也会自动处理服务之间的网络连接,并且服务名可以用作主机名进行通信。

docker-compose.yml 的示例内容:

version: '3'
services:
  webapp:
    image: my-app-image
    networks:
      - my-network

  database:
    image: my-db-image
    networks:
      - my-network

networks:
  my-network:
    driver: bridge

在这种配置下,webapp 服务可以通过 database 作为主机名连接到数据库服务,反之亦然。

Docker 的这种基于DNS的服务发现模式提供了一种简单,而且富有弹性的方式来管理容器内部的通信,而不必担心IP地址在容器重新启动或者重新创建时会改变的问题。

容器跨主机访问

容器在跨主机访问时依赖于Docker网络模式的配置。Docker提供了多种网络模式来满足不同的网络和跨主机通信需求。以下是一些常见的Docker跨主机通信解决方案及其使用的协议:

  1. Docker Swarm Mode
    Docker Swarm Mode 提供了一套原生的集群管理和编排功能。它利用了Overlay网络,这是一种封装了一个分布式的网络跨多个Docker主机的网络类型。
    协议:Overlay网络使用VXLAN协议(Virtual Extensible LAN)来封装跨主机间的通信。VXLAN在第3层路由(即IP路由)上工作,并允许容器直接通过封装在UDP数据包中的VXLAN包进行通信。
  2. Docker Bridge Networking with External Tools
    通常,Docker容器会使用Docker主机的默认bridge网络,它是本地网络,无法跨主机通信。要使跨主机通信成为可能,可以使用第三方工具,如Weave、Calico或Flannel,它们在主机之上提供了一个覆盖网络层。
    协议:这些工具使用各种协议。比如,Weave使用自己的封装格式在主机之间传输数据包。Calico使用IP路由(BGP协议),而Flannel使用UDP或VXLAN。
  3. Docker Multi-Host Networking
    在Docker Engine 1.9版本中引入了本地的多主机网络支持,允许创建一个跨多个主机的Overlay网络。
    协议:就像Swarm Mode,它使用VXLAN协议。
  4. Host Networking
    该模式下容器共享主机的网络命名空间。如果你有一组通过其他手段(例如物理网络或者虚拟私有网络)连接在一起的Docker主机,那么容器可以使用主机网络模式直接暴露在物理网络中。
    协议:这种情况下,容器直接使用主机的网络堆栈,因此可以使用任何在主机网络上运行的协议。
  5. Port Mapping
    容器内的服务可以通过将容器端口映射到主机端口来从外部网络访问,这使用了NAT(Network Address Translation)技术。
    协议:容器服务使用它们自己的协议,如HTTP或TCP,而Docker主机则将外部请求的端口转发到容器的端口上。

容器的跨主机通信协议取决于所使用的网络模式和工具。在Docker的Overlay网络中,通常使用VXLAN封装IP数据包并通过UDP传输。如果使用第三方网络插件,可能会使用不同的协议,如BGP、IPSec或它们自己的传输机制。在主机网络模式下,容器则直接使用主机支持的网络协议进行通信。

  • 38
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值