Docker kapsayıcısının yerel / ana bilgisayar postgres veritabanına bağlanmasına izin ver


143

Son zamanlarda Docker ve QGIS ile oynuyorum ve bu eğitimdeki talimatları izleyerek bir kap yükledim .

Her şey harika çalışıyor, ancak tüm GIS verilerimi içeren bir localhost postgres veritabanına bağlanamıyorum. Bunun nedeni, postgres veritabanımın uzak bağlantıları kabul edecek şekilde yapılandırılmamış olması ve bu makaledeki talimatları kullanarak uzak bağlantılara izin vermek için postgres conf dosyalarını düzenlemesidir .

Docker'da QGIS çalıştıran veritabanımı bağlamaya çalıştığımda hala bir hata iletisi alıyorum: sunucuya bağlanamadı: Connection refused Is the server running on host "localhost" (::1) and accepting TCP/IP connections to port 5433? Postgres sunucusu çalışıyor ve bir dizi bağlantıya izin vermek için pg_hba.conf dosyamı düzenledim IP adresleri (172.17.0.0/32). Daha önce kullanarak docker konteynerinin IP adresini sorgulamıştım ve IP adresi docker psdeğişse de, şimdiye kadar her zaman 172.17.0.x aralığındaydı

Neden bu veritabanına bağlanamıyorum? Muhtemelen çok basit bir şey hayal ediyorum!

Ubuntu 14.04 kullanıyorum; Postgres 9.3

Yanıtlar:


149

TL; DR

  1. 172.17.0.0/16IP adresi aralığı olarak kullanın , değil 172.17.0.0/32.
  2. Kullanmayın localhostBarındırıcınıza PostgreSQL veritabanına bağlanmak için, ancak ana bilgisayarın IP yerine. Kapsayıcıyı taşınabilir tutmak için kapsayıcıyı --add-host=database:<host-ip>bayrakla başlatın ve databasePostgreSQL'e bağlanmak için ana bilgisayar adı olarak kullanın .
  3. PostreSQL'in sadece açık değil tüm IP adreslerindeki bağlantıları dinleyecek şekilde yapılandırıldığından emin olun localhost. listen_addressesPostgreSQL'in yapılandırma dosyasında (genellikle /etc/postgresql/9.3/main/postgresql.conf@DazmoNorton'a kredi) bulunan ayarı arayın .

Uzun versiyon

172.17.0.0/32bir IP adresi aralığı değil, tek bir adrestir (yani 172.17.0.0). Hiçbir Docker kapsayıcısı bu adresi alamaz, çünkü Docker bridge ( docker0) arayüzünün ağ adresidir .

Docker başladığında, arama yaparken kolayca görebileceğiniz yeni bir köprü ağı arayüzü oluşturur ip a:

$ ip a
...
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever

Gördüğünüz gibi, benim durumumda, docker0arayüzün (veya ) 172.17.42.1bir ağ maskesi olan IP adresi var . Bu, ağ adresinin olduğu anlamına gelir ./16255.255.0.0172.17.0.0/16

IP adresi rastgele atanır, ancak herhangi bir ek yapılandırma olmadan her zaman 172.17.0.0/16ağda olur. Her Docker kapsayıcısı için, bu aralıktan rastgele bir adres atanacaktır.

Bu araçlar, size veritabanı, kullanımı mümkün olan tüm kaplardan erişim izni vermek istiyorsanız 172.17.0.0/16.


1
hey yorumlarınız için teşekkürler. pg_hba.confÖnerdiğim adresimi değiştirdim , ancak postgres hizmetini durdurup yeniden başlattıktan sonra da aynı bağlantı hata mesajını alıyorum. IPv4 bağlantılarımın altına satırı ekledim - önerdiğiniz adresi eklemem gereken başka bir yer var mı? Alternatif olarak Docker'da çalışan QGIS uygulamamda postgres bağlantı bilgilerini değiştirmem gerekir mi? Örneğin, bir docker kapsayıcısından bağlanıyorsam, ana bilgisayar hala 'localhost'?
marty_c

Ah, bu önemli bir nokta. Hayır, localhostDocker kabınızın içindeki ana bilgisayar sistemi değil. Ana bilgisayar sisteminin genel IP adresine bağlanmayı deneyin. Kapsayıcıyı taşınabilir tutmak için, kapsayıcıyı ile başlatabilir ve PostgreSQL ana makinenize Docker kapsayıcısından bağlanmak için ana bilgisayar adı olarak --add-host=database:<host-ip>kullanabilirsiniz database.
helmbert

6
Bir parça daha lazım. Ayrıca /etc/postgresql/9.3/main/postgresql.confsunucumun eth0IP adresini de düzenlemek ve eklemek zorunda kaldım listen_addresses. Varsayılan listen_addressesolarak postgres localhostyalnızca bağlanacaktır .
Dzamo Norton

@DzamoNorton, ipucu için teşekkürler! Cevabımı buna göre güncelledim.
helmbert

@helmbert host-ipsanal makine veya liman işçisi konteynerinin ip adresidir?
Mr.D

56

Mac için Docker çözümü

17.06 sonrası

@Birchlabs'ın yorumu sayesinde, artık yalnızca Mac için kullanılabilen bu özel DNS adıyla tonlarca daha kolay :

docker run -e DB_PORT=5432 -e DB_HOST=docker.for.mac.host.internal

17.12.0-cd-mac46 docker.for.mac.host.internalyerine, yerine kullanılmalıdır docker.for.mac.localhost. Ayrıntılar için sürüm notuna bakın.

Eski versiyon

@ helmbert'in cevabı konuyu iyi açıklıyor. Ancak Mac için Docker köprü ağını açığa çıkarmaz , bu yüzden sınırlamayı çözmek için bu hile yapmak zorunda kaldım:

$ sudo ifconfig lo0 alias 10.200.10.1/24

/usr/local/var/postgres/pg_hba.confBu satırı açın ve ekleyin:

host    all             all             10.200.10.1/24            trust

/usr/local/var/postgres/postgresql.confDeğişikliği açma ve düzenleme listen_addresses:

listen_addresses = '*'

Hizmeti yeniden yükleyin ve kapsayıcınızı başlatın:

$ PGDATA=/usr/local/var/postgres pg_ctl reload
$ docker run -e DB_PORT=5432 -e DB_HOST=10.200.10.1 my_app 

Bu geçici çözümün yaptığı temelde @ helmbert'in cevabı ile aynıdır, ancak ağ arabirimi lo0yerine eklenmiş bir IP adresi kullanır docker0.


3
Bu hala 4 Nisan 2017 itibariyle geçerli mi?
Petrus Theron

Ben veritabanı maruz kalmaz bu şekilde seviyorum. BTW, bunu CentOS'ta kullanabilir miyim? Hatayı aldım: alias: Sağladığınız diğer ad komutunu kullanmaya çalıştığımda bilinmeyen ana bilgisayar.
Tsung Goh

6
Docker 17.06.0-rc1-ce-mac13 (1 Haziran 2017) itibarıyla macOS'ta daha iyi bir yol var. kaplar ana bilgisayarı tanır docker.for.mac.localhost. bu, ana makinenizin IP'sidir. kabın ana bilgisayar veritabanındaki girişini docker run alpine /bin/sh -c 'getent hosts docker.for.mac.localhost'
şöyle arayın

@Birchlabs Bu harika!
qqilihq

5
host.docker.internal18.03'ten beri değişmiş gibi görünüyor , diğer seçenekler hala kullanılabilir, ancak kullanımdan kaldırıldı ( Kaynak ).
gseva

44

Mac için Basit Çözüm:

Docker'ın en yeni sürümü (18.03) yerleşik bir port yönlendirme çözümü sunar. Docker konteynerinizin içinde db ana bilgisayarını ayarlamanız yeterlidir host.docker.internal. Bu, docker konteynerinin üzerinde çalıştığı ana bilgisayara iletilecektir.

Bunun için belgeler burada: https://docs.docker.com/docker-for-mac/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host


3
Bu şimdiye kadarki en iyi cevap! çok daha kolay ve nasıl olması gerektiği.
bjm88

2
olduğu host.docker.internalsadece Mac'ler ile sınırlı?
Dragas

@ Docs belgelerine göre "Mac dışında çalışmaz", ancak aynı DNS adı Docker for Windows için belgelerinde belirtilmiştir, bu yüzden "Docker for ..." ile sınırlı olduğunu düşünüyorum. Her iki durumda da yalnızca geliştirme amaçlıdır: bunu kullanan bir liman işçisi resmi göndermeniz amaçlanmamıştır.
Ravent

Sadece Windows ve Mac ile çalışmak. Benim durumumda ubuntu çalışmıyor
Azri Zakaria

17

Basit çözüm

Sadece eklemek --network=hostiçin docker run. Bu kadar!

Bu şekilde konteyner konağın ağını kullanacak, böylece localhostve 127.0.0.1ana bilgisayar (varsayılan olarak bir kapta işaret) işaret eder. Misal:

docker run -d --network=host \
  -e "DB_DBNAME=your_db" \
  -e "DB_PORT=5432" \
  -e "DB_USER=your_db_user" \
  -e "DB_PASS=your_db_password" \
  -e "DB_HOST=127.0.0.1" \
  --name foobar foo/bar

1
Dikkatli ol! Bence doğru olan bu çözüm macOS için işe yaramıyor. Neden işe yaramadığını anlamaya çalışmak için zaman kaybetmeyin. Şuna bir göz atın: github.com/docker/for-mac/issues/2716
jfcorugedo

1
Debian üzerinde çalışır. Postgresql.conf ve pg_hba.conf değiştirmeyi denedim, ancak bu daha basit ve daha hızlı.
frmbelz

2

Ubuntu'da:

İlk önce aşağıdaki komutu kullanarak Docker Veritabanı bağlantı noktasının sisteminizde kullanılabilir olduğunu kontrol etmelisiniz.

sudo iptables -L -n

Örnek ÇIKTI:

Chain DOCKER (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:3306
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.3           tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.3           tcp dpt:22

İşte 3306bu liman aşağıdaki komutu kullanılabilir çalıştırın değilse, 172.17.0.2 IP Docker Veritabanı Limanı olarak kullanılan -

sudo iptables -A INPUT -p tcp --dport 3306 -j ACCEPT

Artık yapılandırmayı izleyerek Docker Veritabanına yerel sisteminizden kolayca erişebilirsiniz

  host: 172.17.0.2 
  adapter: mysql
  database: DATABASE_NAME
  port: 3307
  username: DATABASE_USER
  password: DATABASE_PASSWORD
  encoding: utf8

CentOS'ta:

Önce aşağıdaki komutu kullanarak güvenlik duvarınızda Docker Veritabanı bağlantı noktasının kullanılabilir olduğunu kontrol etmeniz gerekir.

sudo firewall-cmd --list-all

Örnek ÇIKTI:

  target: default
  icmp-block-inversion: no
  interfaces: eno79841677
  sources: 
  services: dhcpv6-client ssh
  **ports: 3307/tcp**
  protocols: 
  masquerade: no
  forward-ports: 
  sourceports: 
  icmp-blocks: 
  rich rules:

İşte 3307bu liman aşağıdaki komutu kullanılabilir çalıştırın değilse, 172.17.0.2 IP Docker Veritabanı Limanı olarak kullanılan -

sudo firewall-cmd --zone=public --add-port=3307/tcp

Sunucuda, bağlantı noktasını kalıcı olarak ekleyebilirsiniz

sudo firewall-cmd --permanent --add-port=3307/tcp
sudo firewall-cmd --reload

Şimdi, yukarıdaki yapılandırma ile Docker Veritabanına yerel sisteminizden kolayca erişebilirsiniz.


Bunun eski olduğunu biliyorum, ancak Şimdi, yapılandırmayı izleyerek Docker Veritabanına yerel sisteminizden kolayca erişebilirsiniz - bunun yanlış bir yolu var. Yerel bir veri tabanı ve bu yerel
db'ye

2

Burada yayınlanan çözüm benim için çalışmıyor. Bu nedenle, benzer bir sorunla karşılaşan birine yardımcı olmak için bu cevabı gönderiyorum.

İşletim Sistemi: Ubuntu 18
PostgreSQL: 9.5 (Ubuntu'da barındırılıyor)
Docker: Sunucu Uygulaması (PostgreSQL'e bağlanır)

Uygulama oluşturmak için docker-compose.yml kullanıyorum.

ADIM 1: Lütfen ekleyinhost.docker.internal:<docker0 IP>

version: '3'
services:
  bank-server:
    ...
    depends_on:
      ....
    restart: on-failure
    ports:
      - 9090:9090
    extra_hosts:
      - "host.docker.internal:172.17.0.1"

Docker'ın IP'sini bulmak için şunları i.e. 172.17.0.1 (in my case)kullanabilirsiniz:

$> ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255

VEYA

$> ip a
1: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

2. ADIM: postgresql.conf dosyasında listen_addresses öğesinilisten_addresses = '*'

ADIM 3: pg_hba.conf dosyasına bu satırı ekleyin

host    all             all             0.0.0.0/0               md5

ADIM 4: Şimdi postgresql servisini kullanarak yeniden başlatın,sudo service postgresql restart

ADIM 5:host.docker.internal Veritabanını Sunucu Uygulamasından bağlamak için lütfen hostname kullanın.
Ör:jdbc:postgresql://host.docker.internal:5432/bankDB

Zevk almak!!



1

Bir Postgresql bağlantı sağlayan şey basit kurmak için gelen ben postgresql.conf bu kullanılan benim localhost için liman işçisi kap:

listen_addresses = '*'

Ve bu pg_hba.conf ekledi:

host    all             all             172.17.0.0/16           password

Sonra yeniden başlatın. Müvekkilim gelen şifre, veritabanı, kullanıcı adı ve parola: (172.17.0.2 idi) liman işçisi konteyner sonra ev sahibi kullanarak localhost üzerinde çalışan Postgresql bağlanabilir.


0

Kurulumum için gerekli olan bir şey daha

172.17.0.1  localhost

için /etc/hosts

böylece Docker işaret edeceğini 172.17.0.1DB ana makine adını ve DB bulmak için bir değişen dış ip güvenmeyin. Umarım bu konuda başka birine yardımcı olur!


14
Bu kötü bir çözüm. Localhost tipik olarak 127.0.0.1'i göstermelidir. Bu özel durumda işe yarasa bile, değiştirilmesinin istenmeyen sonuçları olabilir.
Alex

2
Kapsayıcıyı çalıştırırken databasebirlikte bir ana bilgisayar kurmak daha iyi bir yoldur --add-host=database:172.17.0.1. Ardından uygulamanızı bu ana bilgisayara yönlendirin. Bu, bir kap içindeki bir IP adresinin kodlanmasını önler.
jaredsk

1
--add-host=database:172.17.0.1tercih edilir
Luis Martins

-3

Başka bir çözüm hizmet birimidir, bir hizmet birimi tanımlayabilir ve ana makinenin PostgreSQL Veri dizinini bu birime bağlayabilirsiniz. Ayrıntılar için verilen oluşturma dosyasına bakın.

version: '2'
services:
  db:   
    image: postgres:9.6.1
    volumes:
      - "/var/lib/postgresql/data:/var/lib/postgresql/data" 
    ports:
      - "5432:5432"

Bunu yaparak, başka bir PostgreSQL hizmeti kap altında çalışacak, ancak PostgreSQL hizmetini barındıran aynı veri dizinini kullanacaktır.


1
Bu muhtemelen çalışan bir ana bilgisayar PostgreSQL servisi ile yazma çakışmalarına neden olacaktır
Petrus Theron

Bence bu durumda ana bilgisayar servisini durdurmak sorunu çözecektir.
Hrishi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.