Docker PostgreSQL服务:无法绑定IPv6套接字:无法分配请求的地址

我使用Docker运行PostgreSQL服务。 出于某种原因,PostgreSQL想绑定到IPV6 – 虽然我没有在那里指定(至less据我所知)。

由于这个原因,我无法连接到PG。 相关细节如下:

Dockerfile

FROM postgres:9.6 RUN apt-get update \ && apt-get -y install apt-utils \ && apt-get -y install python3 \ && apt-get -y install postgresql-plpython3-9.6 COPY sql /docker-entrypoint-initdb.d/ EXPOSE 5432 # Add VOLUMEs to allow backup of config, logs and databases VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"] 

PostgreSQL日志文件的内容

 LOG: received fast shutdown request LOG: aborting any active transactions waiting for server to shut down....LOG: autovacuum launcher shutting down LOG: shutting down LOG: database system is shut down done server stopped PostgreSQL init process complete; ready for start up. LOG: could not bind IPv6 socket: Cannot assign requested address HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry. LOG: database system was shut down at 2017-10-09 21:22:22 UTC LOG: MultiXact member wraparound protections are now enabled LOG: database system is ready to accept connections LOG: autovacuum launcher started 

我使用以下命令运行容器: docker run --name my_db_service_cntnr image_tag

当我运行以下命令: docker container port my_db_service_cntnr ,我什么都没有返回:

 me@yourbox:~/path/to/pgdb$ docker container port my_db_service_cntnr me@yourbox:~/path/to/pgdb$ 

我知道PostgreSQL正在容器中运行:

 me@yourbox:~/path/to/pgdb$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 824ffe17c5b9 df:pg "docker-entrypoint..." 16 hours ago Up 5 minutes 5432/tcp my_db_service_cntnr me@yourbox:/path/to/pgdb$ docker container inspect my_db_service_cntnr | grep Address "LinkLocalIPv6Address": "", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "GlobalIPv6Address": "", "IPAddress": "172.17.0.2", "MacAddress": "02:42:ac:11:00:02", "IPAddress": "172.17.0.2", "GlobalIPv6Address": "", "MacAddress": "02:42:ac:11:00:02" 

但是,当我尝试连接到PostgreSQL(使用默认端口5432)时,它无法连接到数据库:

试图通过psql进行连接

 me@yourbox:~/path/to/pgdb$ psql -h 172.17.0.2 -U postgres -p 5432 psql: could not connect to server: Connection refused Is the server running on host "172.17.0.2" and accepting TCP/IP connections on port 5432? me@yourbox:~/path/to/pgdb$ 

看来端口5432没有在我的机器上被监听 ,尽pipe我指定了PG映像EXPOSE端口5432:

 me@yourbox:~/path/to/pgdb$ sudo lsof -i -P | grep -i "listen" lighttpd 1477 www-data 4u IPv4 22342 0t0 TCP *:80 (LISTEN) dnsmasq 1645 nobody 5u IPv4 26954 0t0 TCP CEBERUS:53 (LISTEN) master 2182 root 12u IPv4 28720 0t0 TCP localhost:25 (LISTEN) master 2182 root 13u IPv6 28721 0t0 TCP ip6-localhost:25 (LISTEN) rhythmbox 3149 me 17u IPv4 33925 0t0 TCP *:3689 (LISTEN) rhythmbox 3149 me 18u IPv6 33926 0t0 TCP *:3689 (LISTEN) cupsd 8432 root 10u IPv6 87004 0t0 TCP ip6-localhost:631 (LISTEN) cupsd 8432 root 11u IPv4 87005 0t0 TCP localhost:631 (LISTEN) 

什么是造成这个错误,我该如何解决?

这不是一个完整的答案,但应该让你更接近答案。 它涵盖了问题中debugging步骤所需的dockerism。

运行一个postgres容器

 $ CID=$(docker run -d postgres) $ echo $CID 48024dc71aa446... 

获取容器的PID

 $ PID=$(docker inspect -f {{.State.Pid}} $CID) $ echo $PID 7994 

来自容器的进程列表

 $ docker exec -ti $CID ps -ef UID PID PPID C STIME TTY TIME CMD postgres 1 0 0 23:19 ? 00:00:00 postgres postgres 49 1 0 23:19 ? 00:00:00 postgres: checkpointer process postgres 50 1 0 23:19 ? 00:00:00 postgres: writer process postgres 51 1 0 23:19 ? 00:00:00 postgres: wal writer process postgres 52 1 0 23:19 ? 00:00:00 postgres: autovacuum launcher pr postgres 53 1 0 23:19 ? 00:00:00 postgres: stats collector proces postgres 54 1 0 23:19 ? 00:00:00 postgres: bgworker: logical repl root 66 0 0 23:26 ? 00:00:00 ps -ef 

在容器中运行ss寻找侦听tcp进程(如lsof

 $ docker exec -ti $CID ss -lntp State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:5432 *:* LISTEN 0 128 :::5432 :::* 

容器外部不会报告容器名称空间中的端口

 $ ss -lntp State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* users:(("sshd",pid=592,fd=3)) LISTEN 0 128 :::22 :::* users:(("sshd",pid=592,fd=4)) 

从主机,您可以使用nsenter来input容器命名空间和运行命令。

 $ nsenter -t $PID -n ss -lntp State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:5432 *:* users:(("postgres",pid=7994,fd=3)) LISTEN 0 128 :::5432 :::* users:(("postgres",pid=7994,fd=4)) $ nsenter -t $PID -n ip address show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 52: eth0@if53: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.3/16 scope global eth0 valid_lft forever preferred_lft forever 

从Docker获取容器的IP

 $ IP=$(docker inspect -f '{{.NetworkSettings.Networks.bridge.IPAddress}}' $CID) $ echo $IP 172.17.0.3 

testing连接

 $ psql -h $IP -U postgres -p 5432 

映射的端口

使用映射端口,主机上的端口略有变化

 $ CID=$(docker run -d -p 5432:5432 postgres) $ echo $CID 020f72394fcd... 

现在容器有一个configuration的端口

 $ docker container port $CID 5432/tcp -> 0.0.0.0:5432 $ docker inspect -f {{.NetworkSettings.Ports}} $CID map[5432/tcp:[{0.0.0.0 5432}]] 

端口也将在主机上侦听

 $ ss -lntp State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* users:(("sshd",pid=592,fd=3)) LISTEN 0 128 :::22 :::* users:(("sshd",pid=592,fd=4)) LISTEN 0 128 :::5432 :::* users:(("docker-proxy",pid=8571,fd=4)) 

您现在可以连接到本地主机或您的主机IP

 $ psql -h 127.0.0.1 -U postgres -p 5432