Как можно получить доступ к контейнеру, используя его имя?

Привет всем! 

Я столкнулся с проблемой при попытке обратиться к контейнеру по его хостнейму и внутреннему порту из другого контейнера, которые находятся в одном и том же файле docker-compose. При использовании httpClient для обращения по адресу hostname:port я получил следующую ошибку: 

`System.Net.Http.HttpRequestException: Name or service not known (keycloak:8080) ---> System.Net.Sockets.SocketException (0xFFFDFFFF): Name or service not known` 

Вот фрагмент кода, который я использовал для вызова: 

<pre><code class="cs">var metadata = _configuration["Authentication:MetadataAddress"]; // http://keycloak:8080/realms/keycloak-auth/.well-known/openid-configuration
using var response = await _httpClient.GetAsync(metadata!);
response.EnsureSuccessStatusCode();
    
var jsonResponse = await response.Content.ReadAsStringAsync();
Log.Information($"{jsonResponse}\n");
return Ok(jsonResponse);</code></pre> 

Файл docker-compose выглядит следующим образом: 

<pre><code class="yaml">keycloak:
    image: quay.io/keycloak/keycloak:26.0.0
    container_name: keycloak
    command: start-dev
    environment:
      - KC_HEALTH_ENABLE=true
      - KEYCLOAK_ADMIN=admin
      - KEYCLOAK_ADMIN_PASSWORD=passwd
    volumes:
      - ./.containers/identity:/opt/keycloak/data
    ports:
      - "10001:8080"

  post_service:
    container_name: post_service
    image: post_service
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    build:
      context: .
    ports:
      - "8082:8080"
    networks:
      - keycloak_network
      - posts_postgres_network
    depends_on:
      - keycloak
      - post_postgres</code></pre> 

Буду благодарен за любые советы по решению этой проблемы!
  • 10 октября 2024 г. 18:44
Ответы на вопрос 2
Проблема, с которой вы столкнулись, может быть связана с несколькими факторами. Давайте рассмотрим несколько аспектов, которые могут помочь решить вашу проблему:

1. **Сетевые настройки в Docker Compose**:
   Убедитесь, что контейнеры находятся в одной сети, чтобы они могли видеть друг друга по имени. В вашем примере `keycloak` и `post_service` имеют определенные сети, но вы не указали явным образом, в какой сети должен находиться `keycloak`. Добавьте их в одну сеть:

   ```yaml
   networks:
     keycloak_network:
       driver: bridge
     posts_postgres_network:
       driver: bridge

   services:
     keycloak:
       ...
       networks:
         - keycloak_network

     post_service:
       ...
       networks:
         - keycloak_network
         - posts_postgres_network
   ```

2. **Использование правильного URL**:
   Убедитесь, что в вашем конфиге вы используете правильный URL. Поскольку Keycloak работает на внутреннем порту 8080, вызывайте его с помощью `http://keycloak:8080/realms/keycloak-auth/.well-known/openid-configuration`.

3. **Проверка порядка запуска**:
   Использование `depends_on` гарантирует только порядок запуска, но не гарантирует, что сервис будет готов к приему запросов. Возможно, Keycloak просто еще не запустился, когда ваш `post_service` пытается его вызвать. Для решения этой проблемы вы можете добавить механизм ожидания (например, использовать `wait-for-it.sh` или аналогичный скрипт).

4. **Проверка наличия служебного имени**:
   Убедитесь, что внутри вашего контейнера `post_service` вы можете разрешить имя `keycloak`. Вы можете сделать это, запустив временный контейнер с `bash` и используя команду `ping` или `curl` для проверки доступности Keycloak:

   ```bash
   docker-compose run --rm post_service sh -c "ping keycloak"
   ```

5. **Логи и диагностика**:
   Проверьте логи вашего контейнера Keycloak, чтобы убедиться, что он запустился без ошибок. Это можно сделать с помощью команды:

   ```bash
   docker-compose logs keycloak
   ```

Если после всех этих проверок проблема сохраняется, предоставьте, пожалуйста, дополнительные сведения, такие как логи контейнеров или дополнительные настройки, которые могут быть полезны для диагностики.
Контейнеру keycloak нужно указать в networks хотя бы одну сеть, в которую добавлен post_service. Сейчас они у вас в разных сетях (keycloak в дефолтной для проекта, так как не указана никакая, а post_service только в тех, которые перечислены) и потому друг друга не видят.
Похожие вопросы