我在Debian 8.3节点上有两个Docker容器。 一个是官方postgres图像,一个是基本的凤凰/灵药应用程序。 我正在连接一个docker堆栈文件。 但凤凰是无法连接到postgres,除非我发布端口。 这让我觉得有些内部dockernetworking是错误的,因为这个节点是新的Debian安装,它可能是iptables。 这也不包括密码或主机名是错误的。
我在做什么错了什么是正确的方法来设置iptables规则,以允许两个容器进行通信?
在凤凰应用程序中的错误消息:
app-1 | 2016-03-15T16:15:18.019402549Z ** (Mix) The database for App.Repo couldn't be created, reason given: psql: could not connect to server: Connection refused app-1 | 2016-03-15T16:15:18.019456447Z Is the server running on host "postgres" (10.7.0.1) and accepting app-1 | 2016-03-15T16:15:18.019468609Z TCP/IP connections on port 5432?
在postgres容器中输出日志文件
postgres-1 | 2016-03-15T16:46:32.457844697Z LOG: MultiXact member wraparound protections are now enabled postgres-1 | 2016-03-15T16:46:32.464806051Z LOG: database system is ready to accept connections postgres-1 | 2016-03-15T16:46:32.465087076Z LOG: autovacuum launcher started
我的Docker堆栈文件
app: image: myrepo/app environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgrespassword PORT: 4000 links: - postgres ports: - 80:4000 postgres: image: postgres:9.5 environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgrespassword volumes: - /var/dbdata:/var/lib/postgresql/data
Phoenix App中的数据库configuration(prod.secret.exs)
config :data_bucket, DataBucket.Repo, adapter: Ecto.Adapters.Postgres, username: System.get_env("POSTGRES_USER"), password: System.get_env("POSTGRES_PASSWORD"), database: "app_prod", hostname: "postgres", pool_size: 20
$ sudo iptables -L结果
Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere REJECT all -- anywhere loopback/8 reject-with icmp-port-unreachable ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED ACCEPT tcp -- anywhere anywhere tcp dpt:http ACCEPT tcp -- anywhere anywhere tcp dpt:https ACCEPT tcp -- anywhere anywhere tcp dpt:2375 ACCEPT tcp -- anywhere anywhere tcp dpt:6783 ACCEPT udp -- anywhere anywhere udp dpt:6783 ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh ACCEPT icmp -- anywhere anywhere icmp echo-request LOG all -- anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix "iptables denied: " REJECT all -- anywhere anywhere reject-with icmp-port-unreachable DROP tcp -- anywhere 172.17.0.1 tcp dpt:6783 DROP udp -- anywhere 172.17.0.1 udp dpt:6783 DROP udp -- anywhere 172.17.0.1 udp dpt:6784 ACCEPT udp -- anywhere anywhere udp dpt:domain ACCEPT tcp -- anywhere anywhere tcp dpt:domain Chain FORWARD (policy ACCEPT) target prot opt source destination DROP all -- anywhere anywhere DROP all -- anywhere anywhere DOCKER all -- anywhere anywhere ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED ACCEPT all -- anywhere anywhere ACCEPT all -- anywhere anywhere REJECT all -- anywhere anywhere reject-with icmp-port-unreachable ACCEPT all -- anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere Chain DOCKER (1 references) target prot opt source destination
$ sudo docker version结果
Client: Version: 1.9.1-cs2 API version: 1.21 Go version: go1.4.3 Git commit: 4ade326 Built: Mon Nov 30 21:56:07 UTC 2015 OS/Arch: linux/amd64 Server: Version: 1.9.1-cs2 API version: 1.21 Go version: go1.4.3 Git commit: 4ade326 Built: Mon Nov 30 21:56:07 UTC 2015 OS/Arch: linux/amd64
sudo docker ps结果:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f113435b781b myrepo/app:latest "elixir --erl '-smp d" 35 seconds ago Up 34 seconds 0.0.0.0:80->4000/tcp app-1.App.15ffa2c2 6e2879fd9f2c postgres:9.5 "/docker-entrypoint.s" 37 minutes ago Up 5 minutes 5432/tcp postgres-1.App.cbe400ac
对于最后的输出:当然只有当我不运行迁移时,凤凰App才会启动。 通常这是在我的Dockerfile的末尾:
CMD ["elixir", "--erl", "-smp disable", "/usr/local/bin/mix", "do", "compile", ",", "ecto.create", ",", "ecto.migrate", ",", "phoenix.server"]
我改变了以下来获得这个输出
CMD ["elixir", "--erl", "-smp disable", "/usr/local/bin/mix", "do", "compile", ",", "phoenix.server"]
我find了解决办法:问题是iptables设置。 除非另有定义,我有一个规则在那里放弃所有的转发:
-A FORWARD -j REJECT
摆脱这个规则是解决scheme。
编辑:
正如@ Zoredache指出,删除规则显然是一个坏主意,我是一个白痴。 正确的方法是把它放在规则链的最后,在docker创build的规则之后。 所以,如果你有同样的问题,这对我有用:
摆脱规则
$ sudo iptables -D FORWARD -j REJECT
再次添加它将其移动到集合的末尾
$ sudo iptables -A FORWARD -j REJECT
确保他们是在正确的顺序。 所以拒绝所有其他规则应该是最后的。
$ sudo iptables -v -L FORWARD
在Debian上,您可以在重新启动服务器时确保规则仍然适用 :
一旦你快乐,把新的规则保存到主iptables文件:
$ iptables-save > /etc/iptables.up.rules
为了确保iptables规则在重启时启动,我们将创build一个新文件:
$ editor /etc/network/if-pre-up.d/iptables
将这些行添加到它:
#!/bin/sh /sbin/iptables-restore < /etc/iptables.up.rules
该文件需要是可执行的,所以更改权限:
$ sudo chmod +x /etc/network/if-pre-up.d/iptables