Я пишу интеграционные тесты для микросервиса на основе Open Liberty с использованием Testcontainers (Java). Приложение предназначено для запуска в Kubernetes с набором реплик MongoDB (3 узла).
При локальном запуске тестов приложению не удается запуститься или подключиться к базе данных, поскольку оно настаивает на разрешении рабочих полных доменных имен Kubernetes (например, mongodb-0.mongodb-headless...) вместо использования предоставленного мной локального псевдонима Testcontainers.
Установка: Я вручную управляю жизненным циклом контейнера в @BeforeAll, чтобы гарантировать, что контейнер MongoDB запускается первым, что позволяет мне получить его внутренний IP-адрес и попытаться сопоставить DNS.
Тестовый код (ServiceEndpointIT.java):
Java
публичный класс ServiceEndpointIT {
Код: Выделить всё
public static Network network = Network.newNetwork();
public static MongoDBContainer mongoDbContainer;
public static GenericContainer openLibertyContainer;
@BeforeAll
public static void setup() {
// 1. Start MongoDB
mongoDbContainer = new MongoDBContainer("mongo:6.0")
.withNetwork(network)
.withNetworkAliases("testmongo")
.withExposedPorts(27017);
mongoDbContainer.start();
// 2. Get Internal IP for DNS mapping
String mongoIp = mongoDbContainer.getContainerInfo()
.getNetworkSettings().getNetworks().values().iterator().next().getIpAddress();
// 3. Start Open Liberty
openLibertyContainer = new GenericContainer("icr.io/my-repo/my-app:latest")
.withNetwork(network)
.withExposedPorts(9080)
// Attempting to override connection details via Env Vars
.withEnv("MONGO_HOSTS", "testmongo:27017")
.withEnv("MONGO_REPLICASET", "rs0")
.withEnv("MONGO_REPLICAS", "0") // Trying to force single node mode
// Attempting to map the K8s Hostnames to the local Mongo IP
.withExtraHost("mongodb-0.mongodb-headless.ibm-storage-defender-dev.svc.cluster.local", mongoIp)
.withExtraHost("mongodb-1.mongodb-headless.ibm-storage-defender-dev.svc.cluster.local", mongoIp)
.withExtraHost("mongodb-2.mongodb-headless.ibm-storage-defender-dev.svc.cluster.local", mongoIp)
.withStartupTimeout(Duration.ofMinutes(3))
.waitingFor(Wait.forHttp("/health").forStatusCode(200));
openLibertyContainer.start();
}
Ошибка: несмотря на использование .withExtraHost() для сопоставления полных доменных имен с IP-адресом контейнера и попытку переопределить конфигурацию через переменные среды, приложение завершает работу с тайм-аутом, вызванным исключением UnknownHostException. Похоже, драйвер обнаруживает топологию кластера и не может достичь узлов.
Plaintext
com.mongodb.MongoTimeoutException: истекло время ожидания сервера, соответствующего WritableServerSelector.
Клиентское представление состояния кластера: {type=REPLICA_SET, server=[
{address=mongodb-0.mongodb-headless.ibm-storage-defender-dev.svc.cluster.local:27017, type=UNKNOWN, state=CONNECTING,
Exception={com.mongodb.MongoSocketException: mongodb-0.mongodb-headless.ibm-storage-defender-dev.svc.cluster.local},
вызвано {java.net.UnknownHostException: mongodb-0.mongodb-headless.ibm-storage-defender-dev.svc.cluster.local}},
...
]at com.mongodb.internal.connection.BaseCluster.logAndThrowTimeoutException(BaseCluster.java:431)
...
в com.ibm.storage.defender.service.mongodb.ClusterManagerImpl.createIndex(ClusterManagerImpl.java:94)
Что я пробовал:
Переменные среды: Set MONGO_REPLICAS="0" и MONGO_HOSTS="testmongo:27017", чтобы попытаться принудительно выполнить одноузловую конфигурацию, но журналы показывают, что представление клиента все еще ожидает REPLICA_SET с адресами K8s.
Сопоставление DNS: используется .withExtraHost() для сопоставления конкретных полных доменных имен K8s с внутренним IP-адресом Docker контейнера MongoDB.
Сетевые псевдонимы: попробовал добавить полные доменные имена как .withNetworkAliases() на стороне контейнера MongoDB.
Среда:
Java 17 / Jakarta EE
Open Liberty (MicroProfile)
Драйвер MongoDB (синхронизация)
Тестовые контейнеры 1.19.x
Вопрос: Как заставить приложение Open Liberty (или базовый драйвер Mongo) игнорировать топологию набора реплик K8s и подключаться к одному контейнеру testmongo? Или почему withExtraHost не может разрешить UnknownHostException в этом сценарии Docker-in-Docker?
(Примечание. Для формулировки вопроса использовался ChatGPT)
Подробнее здесь: https://stackoverflow.com/questions/798 ... y-app-atte
Мобильная версия