Доступ к хосту postgresql из контейнера Docker (Docker в Linux) - PullRequest
0 голосов
/ 18 марта 2019

У меня есть подпружиненное java-приложение, работающее в док-контейнере на моей машине с Linux. На хосте установлен экземпляр postgresql, к которому я хочу подключиться из запущенного контейнера.

Я пробовал несколько разных подходов (--network = "host" не то, что я хочу).

Мой Dockerfile выглядит так:

FROM openjdk:13-ea-9-jdk-alpine3.9
EXPOSE 8080
CMD mkdir /opt/StatisticalRestService
COPY target/StatisticalRestService-0.0.1-SNAPSHOT.jar         
/opt/StatisticalRestService/
COPY DockerConfig/application.yml /opt/StatisticalRestService/
RUN chmod 777 /opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar \
&& ls -l /opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar \
&& INTERNAL_HOST_IP=$(ip route show default | awk '/default/ {print $3}') \
&& echo "$INTERNAL_HOST_IP  host.docker.internal" >> /etc/hosts \
&& chmod +r /etc/hosts \
&& cat /etc/hosts 
ENTRYPOINT [ "java", "-jar", "-Dspring.config.location=/opt/StatisticalRestService/application.yml", "/opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar" ] 

application.yml:

spring:
    application:
        name: StatisticalRestService
    jpa:
        database: POSTGRESQL
        show-sql: true
        hibernate:
            ddl-auto: create-drop
    datasource:
        platform: postgres
        #url: jdbc:postgresql://host.docker.internal:5432/StatisticalRestService
        url: jdbc:postgresql://172.17.0.1:5432/StatisticalRestService
        username: statEntityUser
        password: test123
        driverClassName: org.postgresql.Driver

Я настроил параметр postresql listen_addressess = '*', и следующая запись находится в файле pg_hba.conf:

host    all     all     172.17.0.0/16       md5
host    all     all     192.168.1.0/24      md5

ifconfig docker0:

arizon@tuxpad:~/Utveckling/StatisticalRestService$ ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
    inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
    inet6 fe80::42:3bff:fe4f:ed34  prefixlen 64  scopeid 0x20<link>
    ether 02:42:3b:4f:ed:34  txqueuelen 0  (Ethernet)
    RX packets 28  bytes 1506 (1.5 KB)
    RX errors 0  dropped 0  overruns 0  frame 0
    TX packets 198  bytes 25515 (25.5 KB)
    TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Это вывод сборки:

arizon@tuxpad:~/Utveckling/StatisticalRestService$ sudo docker build . -t arizon/statisticalrestservice:1.0.0-SNAPSHOT
Sending build context to Docker daemon  223.7MB
Step 1/7 : FROM openjdk:13-ea-9-jdk-alpine3.9
---> 6a6c49978498
Step 2/7 : EXPOSE 8080
---> Running in df7ebc70e950
Removing intermediate container df7ebc70e950
---> 417e50a9f5fd
Step 3/7 : CMD mkdir /opt/StatisticalRestService
---> Running in f33ca0acddf7
Removing intermediate container f33ca0acddf7
---> 59ae394176f3
Step 4/7 : COPY target/StatisticalRestService-0.0.1-SNAPSHOT.jar /opt/StatisticalRestService/
---> 4fbcfeb039f8
Step 5/7 : COPY DockerConfig/application.yml /opt/StatisticalRestService/
---> 244d31fc4755
Step 6/7 : RUN chmod 777 /opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar && ls -l /opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar && INTERNAL_HOST_IP=$(ip route show default | awk '/default/ {print $3}') && echo "$INTERNAL_HOST_IP  host.docker.internal" >> /etc/hosts && chmod +r /etc/hosts && cat /etc/hosts
---> Running in 241f43aebbdc
-rwxrwxrwx    1 root     root      35266534 Mar 16 19:52 /opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  241f43aebbdc
172.17.0.1  host.docker.internal
Removing intermediate container 241f43aebbdc
---> 5c6c53d8011d
Step 7/7 : ENTRYPOINT [ "java", "-jar", "-Dspring.config.location=/opt/StatisticalRestService/application.yml", "/opt/StatisticalRestService/StatisticalRestService-0.0.1-SNAPSHOT.jar" ]
---> Running in 213a87164e8f
Removing intermediate container 213a87164e8f
---> 802cd987771f
Successfully built 802cd987771f
Successfully tagged arizon/statisticalrestservice:1.0.0-SNAPSHOT

Когда я запускаю это с URL источника данных, указанным на host.docker.internal, я получаю unknownHostException, несмотря на вывод из файла / etc / hosts, подтверждающий его наличие. Из того, что я понимаю, может быть проблема с /etc/nsswitch.conf в alpine. Я попытался добавить файл и вставить эту строку с моего хоста:

hosts:          files mdns4_minimal [NOTFOUND=return] dns myhostname

безрезультатно.

Когда я запускаю его с URL-адресом источника данных, указанным 172.17.0.1:5432, у меня истекает время ожидания соединения.

Я проверил доступ к psql с моего хоста, указав pgadmin на ip 192.168, чтобы убедиться, что listen_addresses = '*' работает:

host    all     all     192.168.1.0/24      md5

что и делает. Это другая запись, хотя.

Версия докера:

Client:
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        6247962
 Built:             Tue Feb 26 23:52:23 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.4
  Git commit:       6247962
  Built:            Wed Feb 13 00:24:14 2019
  OS/Arch:          linux/amd64
  Experimental:     false

Postgresql версия:

arizon@tuxpad:~/Utveckling/StatisticalRestService$ dpkg --list | grep postgresql
ii  postgresql-10                                               10.6-0ubuntu0.18.04.1               amd64        object-relational SQL database, version 10 server

Итак, TL; DR: два вопроса: 1. Как мне заставить host.docker.internal работать в Docker под Linux? 2. Как мне подключить мое контейнерное приложение к моему хосту postgresql?

1 Ответ

0 голосов
/ 26 марта 2019

Я решил это не так, как планировал, когда задал вопрос, но он решен.

Я также создал контейнер postgres с томом, чтобы сохранить постоянство сохраняемых данных.

Я создал Dockerfile для postgres, который выглядит следующим образом:

FROM postgres:10-alpine
RUN mkdir /docker-entrypoint-initdb.d/
#COPY initdb.sql /docker-entrypoint-initdb.d/
COPY my-postgres.conf /usr/local/share/postgresql/postgresql.conf
#ENV POSTGRES_USER statEntityUser
#ENV POSTGRES_PASSWORD test123
#ENV POSTGRES_DB StatisticalRestService
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 5432
CMD [ "postgres" ]

Сценарий initdb.sql просто создает то же, что и закомментированные переменные окружения, пользователя, пароль и базу данных. Sql-сценарии, помещенные в эту папку, запускаются сценарием точки входа, когда база данных запущена и готова (это встроенная функция в образе докера, из которого я получаю). Причина, по которой они закомментированы, заключается в том, что он находится в файле docker-compose (см. Ниже). Postgresql.conf - это, в основном, шаблон, который включен в контейнер, но без комментария listen_addresses = '*'.

Я также создал docker-compose.yml для хорошего запуска обоих этих контейнеров:

version: "3"
services:
  statistical-rest-service:
    build: ./StatisticalRestService
    ports: 
      - 8081:8080
    depends_on:
      - postgres
    networks:
      - statisticsNet
  postgres:
    container_name: postgres
    build: ./Postgres
    ports:
      - 5433:5432
    volumes:
      -  postgres-volume:/var/lib/postgresql/data
    command: postgres -c 'config_file=/usr/local/share/postgresql/postgresql.conf'
    networks:
      - statisticsNet
    environment:
      POSTGRES_USER: statEntityUser
      POSTGRES_PASSWORD: test123
      POSTGRES_DB: StatisticalRestService
networks:
  statisticsNet:
volumes:
  postgres-volume:

Я не уверен, нужно ли вам создавать том заранее, или он включен в docker-compose, но если вам нужно, это просто docker volume create postgres-volume.

Документация Postgres о том, как использовать изображение и / или как его получить: Postgres на концентраторе докеров ПРИМЕЧАНИЕ: Когда вы запускаете контейнер с назначенным томом, допускаете некоторую ошибку и закрываете его, при повторном запуске он не будет связываться с существующей базой данных на томе. Вы можете оказаться в ситуации, когда у вас есть «висячие тома», которые являются устаревшими версиями старых контейнеров времени выполнения, которые вы убили и удалили, но они могут привести к неожиданному поведению (для меня пользователь и база данных не были созданы из-за этот). Вы можете очистить их с помощью этой команды: docker volume rm $(docker volume ls -qf dangling=true) (или выполните команду внутри $ (), чтобы просмотреть возможные висячие тома.

Поскольку я создаю выделенную сеть докеров в файле docker-compose, контейнеры могут находить друг друга по имени (примечание container_name). Это делает URL-адрес подключения в application.yml для моего Java следующим образом: url: jdbc:postgresql://postgres:5432/StatisticalRestService

Надеюсь, кому-то это поможет:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...