本文以jeager官网提供的jeager以及运行样例程序hotrod的docker运行命令为例,对镜像下服务间的通信进行总结。
首先了解一下docker网络中的基础概念。
Docker 网络的基本原理
网络命名空间(Network Namespaces):
每个容器运行在自己的网络命名空间中,这为容器提供了独立的网络堆栈,包括独立的 IP 地址、路由表、防火墙规则等。
虚拟以太网对(Veth Pairs):
Veth pair 是一对虚拟网络接口,它们是成对出现的,其中一个接口连接到容器的网络命名空间,另一个接口连接到主机或其他容器。
通过这种方式,容器可以通过 Veth pairs 实现网络通信。
网桥(Bridge):
Docker 默认创建一个名为 bridge 的虚拟网桥。所有未指定自定义网络的容器都会连接到这个默认网桥上。
网桥可以看作是一个虚拟交换机,它将连接到它的所有容器的流量转发给其他连接到它的容器。
自定义网桥网络:
使用 Docker Compose 或者直接用 Docker CLI 创建的自定义网络,通常是基于网桥(bridge driver)的。
自定义网络的好处是,它们提供了更好的隔离性和控制,并允许容器通过名称进行服务发现。
Docker Compose 网络配置的工作原理
创建自定义网络:
在启动 Docker Compose 时,会根据 networks 配置创建指定的自定义网络。
例如:在你的 Compose 文件中,定义了一个 jaeger-example 网络。Docker Compose 会自动创建一个名为 projectname_jaeger-example 的网络(其中 projectname 是你的项目名称)。
服务连接到网络:
在启动服务时,Docker 会将服务容器连接到指定的自定义网络。
连接到同一自定义网络的容器可以通过彼此的容器名称进行通信,而不需要知道具体的 IP 地址。
DNS 服务:
Docker 内置的 DNS 服务会自动为连接到同一网络的容器提供名称解析功能。
例如:在 jaeger-example 网络中的 hotrod 容器可以通过 jaeger:4318 访问 jaeger 容器,而不需要知道 jaeger 容器的 IP 地址。
连接协议和方法
Docker 使用以下协议和方法来实现容器之间的网络连接:
虚拟以太网对(Veth Pairs):
Veth pairs 实现了容器与主机以及容器与容器之间的网络连接。
网桥(Bridge):
自定义桥接网络通过虚拟网桥连接多个容器,类似于一个虚拟交换机。
IPTables:
Docker 使用 IPTables 来管理网络地址转换(NAT)和端口转发,以确保容器之间以及容器与外部世界之间的通信。
DNS:
Docker 内置的 DNS 解析器为连接到同一网络的容器提供名称解析服务,这使得容器可以通过名称互相访问。
实现服务间通信的方法:
1. Docker Compose 自定义网络
在 Docker Compose 中,networks 用于定义并管理容器之间的网络连接。在 Docker 中,每个容器默认都会连接到一个名为 bridge 的默认网络。然而,为了更好地管理容器之间的网络连接,尤其是在复杂应用中,我们通常会定义自定义网络,这样可以确保容器之间能够通过容器名称互相通信。
docker-compose.yml
version: '3.7'
services:
jaeger:
image: jaegertracing/all-in-one:${JAEGER_VERSION:-latest}
ports:
- "16686:16686"
- "4318:4318"
environment:
- LOG_LEVEL=debug
networks:
- jaeger-example # 指定该服务连接到 'jaeger-example' 网络
hotrod:
image: jaegertracing/example-hotrod:${JAEGER_VERSION:-latest}
ports:
- "8080:8080"
- "8083:8083"
command: ["all"]
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4318
networks:
- jaeger-example # 指定该服务连接到 'jaeger-example' 网络
depends_on:
- jaeger
networks:
jaeger-example: # 定义一个名为 'jaeger-example' 的自定义网络
此时,jaeger 和 hotrod 服务将连接到同一个名为 jaeger-example 的网络。hotrod 服务可以通过 jaeger 这个名称来访问 Jaeger 服务,因为它们都在同一个网络中。
2.–link 参数 创建私有网络
docker run -d --name=jaeger -p6831:6831/udp -p16686:16686 jaegertracing/all-in-one:latest
docker run \
--rm \
--link jaeger \
--env OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4318 \
-p8080-8083:8080-8083 \
jaegertracing/example-hotrod:latest \
all
–link 参数:
–link jaeger: 这个选项将当前容器与名为 jaeger 的容器链接在一起。
容器 jaeger 的网络信息(IP 地址和别名)将被添加到 example-hotrod 容器的 /etc/hosts 文件中,并且一些环境变量也会被设置。
当 example-hotrod 容器内部的应用程序尝试连接到 http://jaeger:4318 时,DNS 解析会将 jaeger 解析为实际的 IP 地址。
3.Kubernetes 的服务发现机制
待更新