【问题标题】:Passing docker container IP address to container将 docker 容器 IP 地址传递给容器
【发布时间】:2016-04-13 08:38:32
【问题描述】:

我想获取容器的 IP 地址,以便可以将该 IP 地址设置为环境变量。

docker-compose.yml

django:
  build: .
  command: python /app/project/manage.py test --liveserver=172.18.0.4:8081  //hard coded - trying to avoid this
  ports:
    - "8000:8000"
    - "8081:8081"

selenium:
  container_name: selenium
  image: selenium/standalone-firefox-debug:2.52.0
  ports:
    - "4444:4444"
    - "5900:5900"

问题在于,为了正确运行 django 需要:

A.设置 --liveserver

python /app/manage.py test --liveserver=django-appnet-ip:port

B.或者我设置环境变量:

  DJANGO_LIVE_TEST_SERVER_ADDRESS=django-appnet-ip:port

问题是在创建容器之前没有设置 docker 容器的 IP 地址。那么如何将IP地址传递给django呢?

到目前为止我所尝试的...

A.创建调用脚本的 django 管理命令,然后调用管理命令:

class Command(BaseCommand):
    def add_arguments(self, parser):
        // I would have to redefine all the arguments because
        //I can't call super on django/core/management/commands/test.py
    ...

B.在 DJANGO_LIVE_TEST_SERVER_ADDRESS 'django:8081' 中引用应用程序本身仅在使用此配置的 docker-compose 中有效:

django:
  build: .
  net: appnet
  command: python /app/project/manage.py test
  ports:
    - "8000:8000"
    - "8081:8081"
  environment:
    - DJANGO_LIVE_TEST_SERVER_ADDRESS=django:8081  # where django is the name of the app

如果我将命令设置为空白,则从命令行运行: docker-compose run django python /app/project/manage.py test我明白了

======================================================================
ERROR: setUpClass (django_behave.runner.DjangoBehaveTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/django/test/testcases.py", line 1354, in setUpClass
    raise cls.server_thread.error
error: [Errno 99] Cannot assign requested address

----------------------------------------------------------------------

问题

如何将容器的 IP 地址通过网络传递给容器,以便容器运行的命令获取 IP 地址?

或者也许有一个完全不同的方法来解决这个问题?

【问题讨论】:

  • 如何创建一个可以在容器中运行的 shell 脚本包装器。它将有 2 个步骤。第 1 步:获取容器 ip 地址(类似于 ip addr 或 ifconfig 并从输出中解析 ip) 第 2 步:运行 django(以 ip 地址作为参数)。然后在启动容器时只需运行该外壳包装器..
  • @calvix 成功! - 我会写下来。谢谢:)

标签: django docker


【解决方案1】:

我制作了一个 bash 脚本来获取 docker 容器 id,然后使用该 id 从容器的 /etc/hosts 中获取该容器 id 的 IP 地址。

解决方案

在 django Dockerfile 中

ENTRYPOINT ["/entrypoint.sh"]

入口点.sh

#!/bin/bash
set -e
# Now we need to get the ip address of this container so we can supply it as an environmental
# variable for django so that selenium knows what url the test server is on

# only add if 'manage.py test' in the args
if [[ "'$*'" == *"manage.py test"* ]]
then
  # get the container id
  THIS_CONTAINER_ID_LONG=`cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1`
  # take the first 12 characters - that is the format used in /etc/hosts
  THIS_CONTAINER_ID_SHORT=${THIS_CONTAINER_ID_LONG:0:12}
  # search /etc/hosts for the line with the ip address which will look like this:
  #     172.18.0.4    8886629d38e6
  THIS_DOCKER_CONTAINER_IP_LINE=`cat /etc/hosts | grep $THIS_CONTAINER_ID_SHORT`
  # take the ip address from this
  THIS_DOCKER_CONTAINER_IP=`(echo $THIS_DOCKER_CONTAINER_IP_LINE | grep -o '[0-9]\+[.][0-9]\+[.][0-9]\+[.][0-9]\+')`
  # add the port you want on the end
  # Issues here include: django changing port if in use (I think)
  # and parallel tests needing multiple ports etc.
  THIS_DOCKER_CONTAINER_TEST_SERVER="$THIS_DOCKER_CONTAINER_IP:8081"
  export DJANGO_LIVE_TEST_SERVER_ADDRESS=$THIS_DOCKER_CONTAINER_TEST_SERVER
fi

eval "$@"

或者你可以使用类似的东西

 "$@ --liveserver=$THIS_DOCKER_CONTAINER_TEST_SERVER"

最好设置环境变量,以便在其他地方使用它。

【讨论】:

  • 非常感谢。这对我很有帮助。
【解决方案2】:

这是一个容器依赖问题吗?您是否在容器中运行硒? docker-compose 建议使用 2 个或更多 docker 容器,但您只提到了 Django 容器。如果这是一个容器依赖问题,那么遗憾的是目前无法使用docker-compose 先启动一个容器再启动另一个容器。但是,您可以使用...

docker wait

...bash 脚本中的命令,然后使用...

docker inspect containerName

...获取 IP 地址并将该 IP 传递给 docker compose。

docker-compose 支持使用变量。

【讨论】:

  • 对造成的混乱表示歉意。它与 docker-compose 中的多个容器无关。我只是在谈论一个容器依赖于自己来提供它自己的 IP 地址作为命令行参数给它自己的容器(或它自己的容器的环境变量)的命令。
  • 我知道 docker-compose 确实支持使用变量,我只是很难将自己的 IP 地址作为变量放入其中
  • 依赖于自我疯狂:) - 命令是在容器中执行还是在主机上执行?该命令何时执行,在 docker run 之前还是之后?你能不使用端口转发 - 将域设置为 localhost:your_containers_port (而不是使用 ip)?然后在 docker run 语句中使用 -p 标志将端口公开给主机操作系统?
  • 我用更新的 docker-compose.yml 文件更新了我的问题。这是否回答了您的前 2 个问题?
  • 我尝试在 docker-compose.yml 中为 django 设置此设置:domainname: localhost:8081 command: python /app/project/manage.py test --testrunner=testing.runner.BehaveTestRunner --liveserver=localhost:8081 但随后 selenium 无法连接 - 请参阅此问题:stackoverflow.com/questions/35143927/…
猜你喜欢
  • 1970-01-01
  • 2018-11-13
  • 2019-04-14
  • 1970-01-01
  • 1970-01-01
  • 2016-04-15
  • 2013-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多