【问题标题】:Vagrant + Docker + Postgresql - Cannot connect from hostVagrant + Docker + Postgresql - 无法从主机连接
【发布时间】:2015-05-15 14:01:56
【问题描述】:

我正在尝试使用 Vagrant 在本地模拟我们的生产设置。在生产中,我们为我们的 postgresql 数据库使用 docker 容器,在 centos6.5/redhat 上运行(不是选择)。

所以,我在本地安装了 Vagrant,创建了一台机器,在该机器上启动并运行了 postgresql docker 容器,通过从 VM 连接确保它正在运行。但是我不知道如何从主机(或从另一个虚拟机)连接到 postgresql。

这是我的 Vagrant 文件:

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|  

  config.vm.box = "chef/centos-6.5"

  config.vm.provision "shell" do |s|
    s.inline = "ps aux | grep 'sshd:' | awk '{print $2}' | xargs kill"
  end

  config.vm.define "db" do |db|
    db.vm.synced_folder "../db", "/vagrant/db"
    db.vm.synced_folder "../deploy", "/vagrant/deploy"
    db.vm.hostname = "dbserver"
    db.vm.network :private_network, ip: "192.168.50.4"
    db.vm.network :forwarded_port, guest: 5432, host: 6543 
  end

end

请注意,我将访客端口 5432 转发到主机端口 6543。

在VM上,你可以看到docker运行postgresql容器:

[vagrant@dbserver vagrant]$ sudo docker ps
CONTAINER ID        IMAGE                                     COMMAND             CREATED             STATUS              PORTS                    NAMES
075f71e9f8de        quay.io/aptible/postgresql:standardized   "run-database.sh"   12 hours ago        Up 12 hours         0.0.0.0:5432->5432/tcp   hungry_morse  

在虚拟机上,我必须使用如下命令进行连接:

psql -h 0.0.0.0 -U <username> -d db

从宿主看来,我应该使用:

psql -h 192.168.50.4 -p 6543 -U <username> -d db

但这给了我:

psql: could not connect to server: Connection refused
    Is the server running on host "192.168.50.4" and accepting
    TCP/IP connections on port 6543?

请注意,这并不特定于 postgresql。我有一个 redis 容器设置,以同样的方式给出同样的问题。

我不确定这是我的 Vagrant 设置、Centos 上的防火墙还是什么问题。关于如何完成这项工作的任何想法?

更新 1

我们的 docker 容器中的 pg_hba.conf 文件如下所示:

local     all   all                        peer
hostssl   all   all        0.0.0.0/0       md5

我们的 docker 容器中的 postgresql.conf 文件如下所示:

#------------------------------------------------------------------------------
# FILE LOCATIONS
#------------------------------------------------------------------------------

data_directory = '/var/lib/postgresql/9.3/main'
hba_file = '/etc/postgresql/9.3/main/pg_hba.conf'
ident_file = '/etc/postgresql/9.3/main/pg_ident.conf'
external_pid_file = '/var/run/postgresql/9.3-main.pid'

#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------

listen_addresses = '*'
port = 5432
max_connections = 250
unix_socket_directories = '/var/run/postgresql'
ssl = on
ssl_ciphers = 'DEFAULT:!LOW:!EXP:!MD5:@STRENGTH'
ssl_cert_file = '/etc/postgresql/9.3/ssl/server.crt'
ssl_key_file = '/etc/postgresql/9.3/ssl/server.key'

#------------------------------------------------------------------------------
# RESOURCE USAGE (except WAL)
#------------------------------------------------------------------------------

shared_buffers = 128MB


#------------------------------------------------------------------------------
# QUERY TUNING
#------------------------------------------------------------------------------

log_line_prefix = '%t '
log_timezone = 'UTC'
client_min_messages = ERROR
log_min_messages = FATAL
log_min_error_statement = FATAL

#------------------------------------------------------------------------------
# CLIENT CONNECTION DEFAULTS
#------------------------------------------------------------------------------

datestyle = 'iso, mdy'
timezone = 'UTC'
lc_messages = 'C'
lc_monetary = 'C'
lc_numeric = 'C'
lc_time = 'C'
default_text_search_config = 'pg_catalog.english'

tcp_keepalives_idle = 30
tcp_keepalives_interval = 30

更新 2

VM 的 iptables 规则:

[vagrant@dbserver vagrant]$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:http 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:postgres 

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            ctstate RELATED,ESTABLISHED 
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             172.17.0.3          tcp dpt:postgres 

【问题讨论】:

    标签: postgresql docker vagrant


    【解决方案1】:

    您似乎误解了如何访问 Vagrant 实例上的服务。您可以作为服务的主机和服务端口连接到 VM,也可以使用 port forwarding 将流量从本地端口转发到 VM 的端口。

    从宿主看来,我应该使用:

    psql -h 192.168.50.4 -p 6543 -U &lt;username&gt; -d db

    使用 Vagrant,如果您转发端口,则可以像在 localhost 上一样访问它。

    在你的情况下,你应该使用:

    psql -h 192.168.50.4 -p 5432 -U &lt;username&gt; -d db

    psql -h 127.0.0.1 -p 6543 -U &lt;username&gt; -d db

    而不是&lt;VM ip&gt;:&lt;forwarded port&gt;

    除此之外,您还需要确保将 Postgres 实例配置为允许远程访问 asmPostgres,开箱即用,只接受来自 localhost 的连接。

    要打开远程访问,您必须先修改pg_hba.conflisten_addresspostresql.conf

    pg_hba.conf 需要有一行允许你的 Vagrant 主机连接到它。这通常被 VM 视为 10.0.2.2,因此您需要添加的行如下所示:

    # Allow connections from Vagrant host on 10.0.2.2 to all datababases for all users using an md5 hashed password
    host    all         all         10.0.2.2/32    md5
    

    您的 postgresql.conf 更改很简单,您只需要替换:

    listen_addresses='localhost'
    

    与:

    listen_addresses='*'
    

    对于典型的 VM,我建议使用配置器进行更改,但对于 Docker,您应该通过 Dockerfile 进行设置。有用的是,Docker 在他们的文档中提供了一个useful example

    【讨论】:

    • 所以,我可以深入了解我们用于 postgresql 的 Dockerfile 的详细信息,但我认为这已经设置好了。我拿了这个完全相同的 Docker 容器,把它扔到 AWS 上,并且能够毫无问题地从外部主机连接。我将在对我的问题的更新中发布 pg_hba.confg 和 postgresql.conf 的详细信息。
    • 看来我的 postgresql 内容中需要设置。我正在监听所有地址,并允许所有连接。因此,问题似乎更多地出现在 Centos 级别或 Vagrant 级别(或两者的某种组合)。
    • 你能在 Centos 虚拟机上显示iptables -L 吗?顺便说一句,您最好使用 Vagrant 直接配置您的 Docker 映像,或者如果您在 Windows/Mac 上,则使用 boot2docker。
    • 这里的整个想法是模仿生产,所以我们在 Centos 上安装了 docker,就像我们在生产中一样。据我所知,boot2docker 根本没有被使用。
    • 看起来您的 CentOS VM 正在接受 5432 上的连接,而不是转发的 6543。您可以在 VM 上尝试iptables -A INPUT -p tcp --dport 6543 -j ACCEPT 吗?
    猜你喜欢
    • 1970-01-01
    • 2013-11-24
    • 2021-06-20
    • 2014-06-23
    • 1970-01-01
    • 2015-05-03
    • 2019-10-30
    • 2018-12-19
    • 1970-01-01
    相关资源
    最近更新 更多