我有一个配方,使用我为我的应用程序制作的特定 mysql 映像设置一个 docker 实例。作为该配方的一部分,我希望在容器启动并运行 mysql 后,从备份恢复数据的过程将自动开始。
为此,我需要有容器的 IP(或者从 DNS 获取 IP)。但是,由于我根据配方自动启动容器,因此我无法知道该 IP 是什么,因此我尝试让 docker 为其设置一个稍后可以解析的主机名。
奇怪的是,如果我将一个容器链接到另一个容器,我将能够从链接到它的容器中解析另一个容器的主机。但是,我发现没有办法从主机解析该主机名。
这是我用来调出容器的食谱(厨师)的一部分:
docker_container 'imhere-mysql' do
hostname mysqlHost
repo 'lutraman/imhere'
tag 'mysql'
env ["MYSQL_ROOT_PASSWORD=#{mysql_password}"]
volumes [ '/var/imhere/mysql:/var/lib/mysql' ]
action :run
end
我想要用来恢复数据的命令是这样的(根据配方构建):
"gunzip -c #{parent_data_dir}/#{db_restore_filename} | mysql -h #{mysqlHost} -u root -p'#{mysql_password}'"
仅从主机运行,中的名称mysqlHost
(在当前情况下 - imhere-mysql
)未从主机解析。
底部有一条注释这文章说应该有一个在 127.0.0.11 上运行的 docker dns 服务器 - 但我担心这是容器内部的。
我希望能够做的是查询 docker(在理想情况下,作为 DNS,但任何方式都可以)以获取名为“imhere-mysql”的容器的 ip。 最好的方法是什么,希望能够适用于 docker 的未来版本,并且无论主机操作系统如何?
答案1
您可以使用带有过滤器的 docker inspect 命令获取容器的 IP 地址:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container name>
你的命令是:
"gunzip -c #{parent_data_dir}/#{db_restore_filename} | mysql -h $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' #{mysqlHost}) -u root -p'#{mysql_password}'"
您还可以为容器使用静态 IP 地址,声明自己的网络。
答案2
我的解决方案是在同一网络的容器中(或使用链接)运行恢复命令。听起来您已经拥有可用的文件夹信息,因此可以将它们作为卷传递到临时容器中。
使用传统的 Docker 链接它看起来像这样:
docker run --link #{mysqlHost} --rm -v #{parent_data_dir}/#{db_restore_filename}:/tmp/dbrestore.sql lutraman/imhere bash -c "gunzip -c /tmp/dbrestore.sql | mysql -h #{mysqlHost} -u root -p'#{mysql_password}'"
这将使用相同的图像(假设mysql
和gunzip
二进制文件可用并且没有ENTRYPOINT
)将主机卷安装到容器中的临时位置,然后从该临时位置解压缩到mysql
连接到链接的二进制文件。
您可以通过创建自定义 Docker 网络桥来避免使用旧链接。在这种情况下,该自定义网络中的容器名称应该可以通过 DNS 获得,而无需链接。但这会为您的配方添加额外的部分,可能得不偿失。