从另一个容器访问Docker容器


80

我基于两个不同的图像创建了两个docker容器。一个数据库,另一个用于网络服务器。这两个容器都在我的Mac OS X上运行。

我可以从主机访问数据库容器,也可以从主机访问Web服务器。

但是,如何从Web服务器访问数据库连接?

我启动数据库容器的方式是

docker run --name oracle-db -p 1521:1521 -p 5501:5500 oracle/database:12.1.0.2-ee

我开始了wls容器作为

docker run --name oracle-wls -p 7001:7001 wls-image:latest

我可以通过连接到主机上的数据库

sqlplus scott/welcome1@//localhost:1521/ORCLCDB

我可以以以下身份访问主机上的wls:

http://localhost:7001/console

那么Web容器和db容器都在主机上吗?如果是这样,您正在使用哪个版本的Docker?因为旧版本的docker有一种实现方式,而新版本的docker具有另一种方式。您还可以使用docker-compose吗?这样会更容易,但是我不想使用无法使用的方法给出答案。
Caperneoignis

这个答案可能会有所帮助,如何访问本地主机从一个容器在Mac OS
超骏钟

对于外部网络,此解决方案对我
有用

Answers:


44

最简单的方法是使用--link,但是较新版本的docker正在远离它,实际上,开关很快就会被删除。

下面的链接也很好地连接了两个容器。您可以跳过附加部分,因为这只是在向图像添加项目时非常有用的方法。

https://deis.com/blog/2016/connecting-docker-containers-1/

您感兴趣的部分是两个容器之间的通信。最简单的方法是从Web服务器容器中按名称引用数据库容器。

例:

您将数据库容器DB1和Web服务器容器WEB0命名为。容器都应该在桥接网络上,这意味着Web容器应该能够通过引用其名称连接到DB容器。

因此,如果您有用于应用程序的Web配置文件,则对于数据库主机,您将使用名称DB1。

如果您使用的是较旧版本的docker,则应使用--link。

例:

步骤1: docker run --name db1 oracle/database:12.1.0.2-ee

然后,当您启动网络应用程序时。使用:

第2步: docker run --name web0 --link db1 webapp/webapp:3.0

然后该Web应用将链接到数据库。但是,正如我所说的--link开关将很快被删除。

我会改用docker compose,它将为您建立一个网络。然而; 您将需要为您的系统下载docker compose。https://docs.docker.com/compose/install/#prerequisites

一个示例设置如下所示:

文件名是 base.yml

version: "2"
services:
  webserver:
    image: "moodlehq/moodle-php-apache:7.1
    depends_on:
      - db
    volumes:
      - "/var/www/html:/var/www/html"
      - "/home/some_user/web/apache2_faildumps.conf:/etc/apache2/conf-enabled/apache2_faildumps.conf"
    environment:
      MOODLE_DOCKER_DBTYPE: pgsql
      MOODLE_DOCKER_DBNAME: moodle
      MOODLE_DOCKER_DBUSER: moodle
      MOODLE_DOCKER_DBPASS: "m@0dl3ing"
      HTTP_PROXY: "${HTTP_PROXY}"
      HTTPS_PROXY: "${HTTPS_PROXY}"
      NO_PROXY: "${NO_PROXY}"
  db:
    image: postgres:9
    environment:
      POSTGRES_USER: moodle
      POSTGRES_PASSWORD: "m@0dl3ing"
      POSTGRES_DB: moodle
      HTTP_PROXY: "${HTTP_PROXY}"
      HTTPS_PROXY: "${HTTPS_PROXY}"
      NO_PROXY: "${NO_PROXY}"

这将为网络命名一个通用名称,除非您使用--name开关,否则我不记得该名称是什么。

IE浏览器 docker-compose --name setup1 up base.yml

注意:如果使用--name开关,则在调用docker compose时将需要使用它,因此,docker-compose --name setup1 down这样一来,您可以拥有一个以上的webserver和db实例,在这种情况下,因此docker compose知道哪个实例您要针对其运行命令;这样一来,您可以一次运行多个。如果要在同一服务器上并行运行测试,则非常适合CI / CD。

Docker compose也具有与docker相同的命令,因此 docker-compose --name setup1 exec webserver do_some_command

最好的部分是,如果您想更改数据库或类似的用于单元测试的文件,则可以在up命令中包含一个附加的.yml文件,它将覆盖具有相似名称的所有项目,我认为它是键=>值替换。

例:

db.yml

version: "2"
services:
  webserver:
    environment:
      MOODLE_DOCKER_DBTYPE: oci
      MOODLE_DOCKER_DBNAME: XE
  db:
    image: moodlehq/moodle-db-oracle

然后打电话 docker-compose --name setup1 up base.yml db.yml

这将覆盖数据库。使用不同的设置。当需要从每个容器连接到这些服务时,可以使用在服务下设置的名称,在本例中为webserver和db。

我认为这实际上可能是您所用的更有用的设置。由于您可以在yml文件中设置所需的所有变量,并在需要启动时为docker compose运行命令。因此,多启动它,然后忘记它的设置。

注意:我没有使用 --port命令,因为容器->容器通信不需要公开端口。仅当您希望主机从主机外部连接到容器或应用程序时才需要它。如果公开端口,则该端口对主机允许的所有通信开放。因此,在端口80上公开Web与在物理主机上启动Web服务器相同,并且如果主机允许,则将允许外部连接。另外,如果您出于某种原因想要一次运行一个Web应用程序,则无论出于何种原因,如果您也尝试在该端口上进行公开,则暴露端口80将阻止您运行其他Web应用程序。因此,对于CI / CD,最好根本不公开端口,如果将docker compose与--name开关配合使用,则所有容器都将位于其自己的网络上,因此它们不会发生冲突。因此,您几乎会有一个容器容器。

更新:在进一步使用功能并了解其他人如何对诸如詹金斯(Jenkins)这样的CICD程序进行了这项工作之后。网络也是可行的解决方案。

例:

docker network create test_network

上面的命令将创建一个“ test_network”,您也可以附加其他容器。使用--network开关操作器可以轻松实现。

例:

docker run \
    --detach \
    --name DB1 \
    --network test_network \
    -e MYSQL_ROOT_PASSWORD="${DBPASS}" \
    -e MYSQL_DATABASE="${DBNAME}" \
    -e MYSQL_USER="${DBUSER}" \
    -e MYSQL_PASSWORD="${DBPASS}" \
    --tmpfs /var/lib/mysql:rw \
    mysql:5

当然,如果您具有代理网络设置,则仍应使用“ -e”或“ --env-file”开关语句将这些设置传递到容器中。因此,容器可以与Internet通信。Docker表示代理设置应由较新版本的Docker容器吸收;但是,我还是把它们当作习惯来传递。这是即将消失的“ --link”开关的替代品。将容器连接到您创建的网络后,您仍然可以使用容器的“名称”引用其他容器中的那些容器。根据上面的示例,它将是DB1。您只需要确保所有容器都连接到同一网络,就可以了。

有关在cicd管道中使用网络的详细示例,请参考以下链接:https ://git.in.moodle.com/integration/nightlyscripts/blob/master/runner/master/run.sh

这是Jenkins中针对Moodle进行的大规模集成测试中运行的脚本,但是该想法/示例可以在任何地方使用。我希望这对其他人有帮助。


如果第一个链接不起作用,则可以使用此链接。linode.com/docs/applications/containers/…–
Caperneoignis

对于做Docker作文还是做网络,网络服务器将如何引用数据库?它会使用容器的名称吗?在第二个链接中看起来是这样:因此,如果您定义一个数据库和一个APP,则在这种情况下,该应用将必须进行引用:psql -U {USER} -h database -p 5432 {DATABASE}如果我被带壳,
则从

1
@Fallenreaper(如果您在容器中,并且由docker撰写),如果您未明确为其指定名称,则将使用“服务:”下使用的名称。因此,在示例中,如果您尝试从外壳程序中的“ db”容器进行连接,则将使用“ webserver”。查看db.yml的示例,您将使用名称webserver和db。对不起,延迟延迟了,忘记了通知。
Caperneoignis

44

这很简单。如果您有两个或多个正在运行的容器,请完成以下步骤:

docker network create myNetwork
docker network connect myNetwork web1
docker network connect myNetwork web2

现在,您可以从web1连接到web2容器,或者反过来。

使用可以通过运行以下命令找到的内部网络IP地址:

docker network inspect myNetwork

请注意,网桥连接的容器只能访问内部IP地址和端口。

因此,例如,假设web1容器以:开头docker run -p 80:8888 web1(这意味着其服务器内部在端口8888上运行),并且检查myNetwork显示web1的IP为172.0.0.2,则可以使用进行从web2到web1的连接curl 172.0.0.2:8888


1
嗨,我如何从web1连接到web2?通过IP,主机名?从哪里获得此信息?
亨利·阿维拉

在文件docker-compose.yml中创建网络:myNetwork。
MxWild

11
@HenryÁvila您只需使用容器的名称(例如web1)作为主机名。
Pascal

最好使用--net = host,如#hitter所述,它将能够通过localhost:port内部连接
Arch

17

您将必须通过主机的ip来访问db,或者如果您想通过localhost:1521访问它,则可以像下面那样运行webserver:

docker run --net=host --name oracle-wls wls-image:latest

看这里


1
主机的ip将根据运行的机器容器的不同而在现实生活中如何工作。
维克

1
仅当计算机具有静态ip或DNS时才有效,否则请采用第二种方法。
xitter's

我似乎对此有疑问。我确切的运行命令是:docker run --name ora-tools-wls -it -p 7001:7001 orawls这行得通,让我以本地主机:7001 / console访问在此容器上运行的服务器 但是,从服务器进行数据库访问需要精确的ip到达运行数据库的另一个容器。如果我使用docker run --name ora-tools-wls -it -p 7001:7001 --network =“ host” orawls,则服务器可以使用localhost作为ip来访问db,但是可以在主机浏览器中访问服务器失败。
维克

3
您无需定义-p 7001:7001,因为所有容器都在使用主机的网络堆栈本身。
xitter

@Vik,我遇到了同样的麻烦,发现Mac不支持它。也许那就是你在做的。>主机网络驱动程序仅适用于Linux主机,而Mac的Docker桌面,Windows的Docker桌面或Windows Server的Docker EE不支持该主机网络驱动程序。 docs.docker.com/network/host
Brent Fisher

7

使用docker-compose,默认情况下,服务会按名称公开。文件
您还可以指定一个别名,例如;

version: '2.1'
services:
  mongo:
    image: mongo:3.2.11
  redis:
    image: redis:3.2.10
  api:
    image: some-image
    depends_on:
      - mongo
      - solr
    links:
      - "mongo:mongo.openconceptlab.org"
      - "solr:solr.openconceptlab.org"
      - "some-service:some-alias"

然后使用指定的别名作为主机名称,例如访问服务mongo.openconceptlab.org对于mongo在这种情况下。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.