从Docker容器中访问RDS而不通过安全组?

时间:2015-10-01 17:55:16

标签: amazon-web-services amazon-ec2 docker

我试图在docker容器中运行使用带有EC2的RDS数据库的Web服务器。

我已经设置了安全组,因此允许EC2主机角色访问RDS,如果我尝试直接从主机访问它,一切正常。

但是,当我在主机上运行一个简单容器并尝试访问RDS时,它会被阻止,就好像安全组没有通过它一样。在经过一系列的反复试验之后,似乎确实容器请求似乎并非来自EC2主机,因此防火墙说没有。

通过在docker容器上设置--net = host,我能够在短期内解决这个问题,但这会破坏很多很棒的docker网络功能,比如能够映射端口(即,现在我需要确保容器的每个实例都手动侦听不同的端口。

有没有人找到解决方法?如果您实际使用任何AWS资源,那么在AWS中运行容器似乎是一个非常大的限制。

5 个答案:

答案 0 :(得分:17)

是的,容器确实击中了RDS的公共IP。但是您不需要调整低级Docker选项以允许容器与RDS通信。 ECS群集和RDS实例必须位于同一个VPC 中,然后才能通过安全组配置访问权限。最简单的方法是:

  1. 导航到RDS实例页面
  2. 选择数据库实例并深入查看详细信息
  3. 单击安全组ID
  4. 导航至“入站”选项卡,然后选择“编辑”
  5. 并确保有源自定义
  6. 的MySQL / Aurora类型规则
  7. 输入自定义来源时,只需输入ECS群集名称,即可自动完成安全组名称
  8. 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)"错误。 为了解决这个问题,我做了以下两种方法:

  1. 我创建了新用户并分配了赠款。

    $ CREATE USER 'newuser'@'%' IDENTIFIED BY 'password';
    $ GRANT ALL ON newuser@'%' IDENTIFIED BY  'password';
    $ FLUSH PRIVILEGES;
    
  2. 在运行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。

  • 注意:首先,我尝试了第二种方法。但是我没有解决连接问题。当我尝试两种方式时,我都是成功的。