我试图在docker容器中运行使用带有EC2的RDS数据库的Web服务器。
我已经设置了安全组,因此允许EC2主机角色访问RDS,如果我尝试直接从主机访问它,一切正常。
但是,当我在主机上运行一个简单容器并尝试访问RDS时,它会被阻止,就好像安全组没有通过它一样。在经过一系列的反复试验之后,似乎确实容器请求似乎并非来自EC2主机,因此防火墙说没有。
通过在docker容器上设置--net = host,我能够在短期内解决这个问题,但这会破坏很多很棒的docker网络功能,比如能够映射端口(即,现在我需要确保容器的每个实例都手动侦听不同的端口。
有没有人找到解决方法?如果您实际使用任何AWS资源,那么在AWS中运行容器似乎是一个非常大的限制。
答案 0 :(得分:17)
是的,容器确实击中了RDS的公共IP。但是您不需要调整低级Docker选项以允许容器与RDS通信。 ECS群集和RDS实例必须位于同一个VPC 中,然后才能通过安全组配置访问权限。最简单的方法是:
This tutorial has screenshots说明了去哪里。
完全披露:本教程介绍了Bitnami的容器,我为Bitnami工作。然而,这里表达的想法是我自己的,而不是Bitnami的意见。
答案 1 :(得分:7)
弄清楚发生了什么,发布在这里,万一它可以帮助其他人。
来自容器内的请求是攻击RDS的公共IP而不是私有(这是安全组的工作方式)。看起来Docker容器中的DNS正在使用8.8.8.8 google dns,并且不会将AWS的rds端点转换为私有IP。
例如:
DOCKER_OPTS="--dns 10.0.0.2 -H tcp://127.0.0.1:4243 -H unix:///var/run/docker.sock -g /mnt/docker"
答案 2 :(得分:1)
正如@adamneilson所提到的,设置Docker选项是你最好的选择。以下是discover your Amazon DNS server on the VPC的方法。此外,Amazon EC2容器服务开发人员指南中的Enabling Docker Debug Output部分还提到了Docker选项文件的位置。
假设您正在运行10.0.0.0/24的VPC块,则DNS将为10.0.0.2。
对于CentOS,Red Hat和亚马逊:
sed -i -r 's/(^OPTIONS=\")/\1--dns 10.0.0.2 /g' /etc/sysconfig/docker
对于Ubuntu和Debian:
sed -i -r 's/(^OPTIONS=\")/\1--dns 10.0.0.2 /g' /etc/default/docker
答案 3 :(得分:0)
RDS的入站规则应设置为EC2实例的私有IP,而不是公共IPv4。
答案 4 :(得分:0)
当我尝试在docker容器内部连接到AWS RDS时,出现"Access denied for user 'username'@'xxx.xx.xxx.x' (using password: YES)"
错误。
为了解决这个问题,我做了以下两种方法:
我创建了新用户并分配了赠款。
$ CREATE USER 'newuser'@'%' IDENTIFIED BY 'password';
$ GRANT ALL ON newuser@'%' IDENTIFIED BY 'password';
$ FLUSH PRIVILEGES;
在运行docker时将全局DNS地址8.8.8.8
添加到docker容器中,以便docker容器可以从域名解析AWS RDS的IP地址。
$ docker run --name backend-app --dns=8.8.8.8 -p 8000:8000 -d backend-app
然后我从docker容器内部成功连接到AWS RDS。