TestContainers:容器之间的通信+映射在港口外
我有这样的测试设置:
myService
连接到postgtresql
myService
endpoint从test Suite中调用了
myService
and 和<代码> PostgreSQL 正在使用TestContainers运行。
这是我要实现的网络模式。
起初,我试图通过暴露端口来安排通信。
static final PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>(DockerImageName.parse(POSTGRES_VERSION));
static final GenericContainer<?> myService = new GenericContainer<>(DockerImageName.parse(MY_SERVICE_IMAGE))
.withEnv(
Map.of(
"SPRING_DATASOURCE_URL", postgres.getJdbcUrl(),
"SPRING_DATASOURCE_USERNAME", postgres.getUsername(),
"SPRING_DATASOURCE_PASSWORD", postgres.getPassword()
)
)
.withExposedPorts(8080)
.withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("MyService")))
根据logs myService
无法建立与PostgreSQL
的连接。
Caused by: java.net.ConnectException: Connection refused
然后,我配置了两种服务以共享同一网络。
static final Network SHARED_NETWORK = Network.newNetwork();
static final PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>(DockerImageName.parse(POSTGRES_VERSION))
.withNetwork(SHARED_NETWORK)
.withNetworkAliases("postgres");
static final GenericContainer<?> myService = new GenericContainer<>(DockerImageName.parse(MY_SERVICE_IMAGE))
.withEnv(
Map.of(
"SPRING_DATASOURCE_URL", "jdbc:postgresql://postgres:5432/" + postgres.getDatabaseName(),
"SPRING_DATASOURCE_USERNAME", postgres.getUsername(),
"SPRING_DATASOURCE_PASSWORD", postgres.getPassword()
)
)
.withExposedPorts(8080)
.withNetwork(SHARED_NETWORK)
.withNetworkAliases("MyService")
.withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("MyService")))
现在MyService
成功地与PostgreSQL 建立了连接。但是,当我从测试套件中执行myService
的http请求时,我会遇到相同的错误。
restTemplate.getForObject("http://" + myService.getHost() + ":" + myService.getMappedPort(8080) +"/api/endpoint", Void.class)
Caused by: java.net.ConnectException: Connection refused
我的问题是如何设置容器网络以使该体系结构起作用?
I have such test setup:
MyService
connects toPostgtreSQL
MyService
endpoint is being called from test suite
Both MyService
and PostgreSQL
are being run with Testcontainers.
Here is the network schema I want to achieve.
At first I tried to arrange communication by exposing ports.
static final PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>(DockerImageName.parse(POSTGRES_VERSION));
static final GenericContainer<?> myService = new GenericContainer<>(DockerImageName.parse(MY_SERVICE_IMAGE))
.withEnv(
Map.of(
"SPRING_DATASOURCE_URL", postgres.getJdbcUrl(),
"SPRING_DATASOURCE_USERNAME", postgres.getUsername(),
"SPRING_DATASOURCE_PASSWORD", postgres.getPassword()
)
)
.withExposedPorts(8080)
.withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("MyService")))
According to logs MyService
couldn't establish connection to PostgreSQL
.
Caused by: java.net.ConnectException: Connection refused
Then I configured both services to share the same network.
static final Network SHARED_NETWORK = Network.newNetwork();
static final PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>(DockerImageName.parse(POSTGRES_VERSION))
.withNetwork(SHARED_NETWORK)
.withNetworkAliases("postgres");
static final GenericContainer<?> myService = new GenericContainer<>(DockerImageName.parse(MY_SERVICE_IMAGE))
.withEnv(
Map.of(
"SPRING_DATASOURCE_URL", "jdbc:postgresql://postgres:5432/" + postgres.getDatabaseName(),
"SPRING_DATASOURCE_USERNAME", postgres.getUsername(),
"SPRING_DATASOURCE_PASSWORD", postgres.getPassword()
)
)
.withExposedPorts(8080)
.withNetwork(SHARED_NETWORK)
.withNetworkAliases("MyService")
.withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("MyService")))
Now MyService
has established connection with PostgreSQL
successfully. But when I perform HTTP request to MyService
from the test suite, I get the same error.
restTemplate.getForObject("http://" + myService.getHost() + ":" + myService.getMappedPort(8080) +"/api/endpoint", Void.class)
Caused by: java.net.ConnectException: Connection refused
My question is how can I setup the containers network to make this architecture work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要指定端口绑定以将端口暴露于“外部世界”。
与您想要的类似的示例:
两个容器使用“内部”端口与容器一通信。
容器One将20306(重定向到3306)端口公开到“外界”。
You need to specify port bindings to expose a port to the "outside world".
Example similar to what you want:
Container two communicates with container one using "internal" port.
Container one exposes 20306 (that redirects to 3306) port to the "outside world".
Docker自定义网络具有自己的DNS,您无法使用外部网络的DNS。默认的主机网络共享外部和内部网络的DNS,但有一些缺点。要将数据库容器连接到服务容器,您可以使用
- 网络-Alias
将Docker转换为IP( https://docs.docker.com/get-started/07_multi_container/ )。例如:where:
application.yml
The docker custom network has its own DNS and you cannot use DNS of the outer network. The default host network shares DNS of the outer and inner networks, but has some disadvantages. To connect a database container to a service container you can use
--network-alias
that docker converts to ip (https://docs.docker.com/get-started/07_multi_container/ ). For example:where:
application.yml