Docker群容器连接问题

时间:2018-06-22 12:13:03

标签: docker docker-compose docker-swarm

我正在尝试使用docker swarm创建位于Haproxy之后的简单nodejs服务并连接到mysql。因此,我创建了这个docker compose文件:

我有几个问题:

  1. 后端服务无法使用localhost或127.0.0.1连接到数据库,因此,我设法使用数据库容器的私有ip(10.0.1.4)连接到数据库。
  2. 后端依赖数据库尝试过早尝试连接数据库。
  3. 无法从外部访问该应用程序。

    version: '3'

    services:
      db:
        image: test_db:01
        ports:
          - 3306
        networks:
          - db

    test:
        image: test-back:01
        ports:
          - 3000
        environment:
          - SERVICE_PORTS=3000
          - DATABASE_HOST=localhost
          - NODE_ENV=development
        deploy:
          replicas: 1
          update_config:
              parallelism: 1
              delay: 5s
          restart_policy:
              condition: on-failure
              max_attempts: 3
              window: 60s
        networks:
          - web
          - db
        depends_on:
          - db
        extra_hosts:
          - db:10.0.1.4

    proxy:
        image: dockercloud/haproxy
        depends_on:
          - test
        environment:
          - BALANCE=leastconn
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
        ports:
          - 80:80
        networks:
          - web
        deploy:
          placement:
            constraints: [node.role == manager]

networks:
    web:
      driver: overlay
    db:
      driver: bridge

我正在运行以下内容:

docker stack deploy --compose-file=docker-compose.yml prod

所有服务都在运行。

curl http://localhost/api/test <-- Not working

但是,正如我上面提到的,我遇到的问题。

Docker version 18.03.1-ce, build 9ee9f40
docker-compose version 1.18.0, build 8dd22a9

我想念什么?

3 个答案:

答案 0 :(得分:0)

  

后端服务无法使用localhost或127.0.0.1连接到数据库,因此,我设法使用数据库容器的私有ip(10.0.1.4)连接到数据库。

请勿使用IP地址进行连接。仅使用DNS名称。
因此,您必须将连接更改为l <- list(`20014409-EA` = list(WEEK = structure(c(NA, 17448, 17455, 17462, 17469, 17476, 17483, 17490, 17497, 17504, 17511, 17518, 17546, 17553, 17560, 17567, 17574, 17581, 17588, 17595, 17602, 17609, 17616, 17623, 17630, 17637, 17644, 17651, 17658, 17665, 17672, 17679, 17686, 17693), class = "Date"), INTpercent = c(NA, 0, 0, 0, 0, 0, 0, 0, 0, -42.809364548495, 0, 0, 29.9765807962529, 0, 0, -42.809364548495, 0, 0, 0, 29.9765807962529, 2.28832951945081, 0, 0, 0, 2.34192037470727, 0, 0, 0, 0, 0, 0, 0, 0, 0), EXTpercent = c(NA, 0, -0.510204081632654, 0.50761421319797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), `20015041-EA` = list(WEEK = structure(c(NA, 17448, 17455, 17462, 17469, 17476, 17483, 17490, 17497, 17504, 17511, 17518, 17546, 17553, 17560, 17567, 17574, 17581, 17588, 17595, 17602, 17609, 17616, 17623, 17630, 17637, 17644, 17651, 17658, 17665, 17672, 17679, 17686, 17693), class = "Date"), INTpercent = c(NA, 30.4609218436874, 0, 0, -0.402414486921538, 0, 0, 0, 0, 0, 0, 0, -24.25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19.5171026156942, 0, 0, 0, 0, -24.25, 0, 0, 0, 19.5171026156942, 0), EXTpercent = c(NA, 0, 0, 0, 0, 0, -0.404858299595133, 0.403225806451604, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -42.9394812680115, 0, 0, 30.0403225806452, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), `20016844-EA` = list(WEEK = structure(c(NA, 17448, 17455, 17462, 17469, 17476, 17483, 17490, 17497, 17504, 17511, 17518, 17546, 17553, 17560, 17567, 17574, 17581, 17588, 17595, 17602, 17609, 17616, 17623, 17630, 17637, 17644, 17651, 17658, 17665, 17672, 17679, 17686, 17693), class = "Date"), INTpercent = c(NA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.78468899521531, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), EXTpercent = c(NA, 0, -19.9195171026157, 16.3299663299663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.507614213197974, 0.505050505050509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), `20044140-EA` = list(WEEK = structure(c(NA, 17448, 17455, 17462, 17469, 17476, 17483, 17490, 17497, 17504, 17511, 17518, 17546, 17553, 17560, 17567, 17574, 17581, 17588, 17595, 17602, 17609, 17616, 17623, 17630, 17637, 17644, 17651, 17658, 17665, 17672, 17679, 17686, 17693), class = "Date"), INTpercent = c(NA, 0, 0, 0, 0, 0, 0, 0, 0, -59.5317725752508, 0, 0, -59.0425531914894, 0, 60.5870020964361, 0, 0, 0, 0, 0, 2.05338809034909, 0, -151.030927835052, 60.1642710472279, 0, 0, 0, 0, -143.5, 0, 58.9322381930185, -63.973063973064, 0, 0), EXTpercent = c(NA, 0, -17.632241813602, 14.9892933618844, 0, 0, -137.055837563452, 0, 57.8158458244111, -137.055837563452, 57.8158458244111, 0, 0, 0, 0, 0, 0, -91.3934426229508, 0, 47.7516059957173, 0, 0, -89.0688259109312, 0, 47.1092077087794, 0, 0, 0, 0, -153.804347826087, 60.5995717344754, 0, 0, 0)), `20067427-EA` = list(WEEK = structure(c(NA, 17448, 17455, 17462, 17469, 17476, 17483, 17490, 17497, 17504, 17511, 17518, 17546, 17553, 17560, 17567, 17574, 17581, 17588, 17595, 17602, 17609, 17616, 17623, 17630, 17637, 17644, 17651, 17658, 17665, 17672, 17679, 17686, 17693), class = "Date"), INTpercent = c(NA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34.3544857768053, 0, 0, 0, 2.14132762312633, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23.8726790450928, 19.271948608137, -57.2390572390572), EXTpercent = c(NA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -87.7049180327869, 17.8451178451179, 0, -21.7213114754098, 0, 46.4912280701754, 0, 0, 0, -58.3333333333333, 0, 0, 0, 0, 0, 0, 4)), `20071339-EA` = list(WEEK = structure(c(NA, 17448, 17455, 17462, 17469, 17476, 17483, 17490, 17497, 17504, 17511, 17518, 17546, 17553, 17560, 17567, 17574, 17581, 17588, 17595, 17602, 17609, 17616, 17623, 17630, 17637, 17644, 17651, 17658, 17665, 17672, 17679, 17686, 17693), class = "Date"), INTpercent = c(NA, 0, 25.5639097744361, 0, 0, 0, 0, -61.5384615384615, 0, 0, 0, 0, 0, 38.0952380952381, -34.3434343434343, 0, -3.48432055749129, 0, 28.0701754385965, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -99.5, 49.874686716792, -34.3434343434343, 25.5639097744361, 0), EXTpercent = c(NA, 10.1010101010101, 0, 25.3768844221105, 0, -40.1408450704225, 0, 0, 0, 0, 28.643216080402, 0, -61.1336032388664, 14.2361111111111, -16.5991902834008, 14.2361111111111, 0, 0, 27.6381909547739, -34.006734006734, -11.2359550561798, 32.9145728643216, 0, -38.1944444444444, 0, 27.6381909547739, 0, 0, 0, 0, 0, -38.1944444444444, 0, 0))) ,因为这是您定义的服务名称。
Localhost是错误的,因为该服务与DATABASE_HOST=db服务在不同的容器中运行。

  

即使后端依赖数据库,后端也会尝试过早连接到数据库。

test不能按预期工作。请阅读https://docs.docker.com/compose/compose-file/#depends_on和信息框depends_on
TL; DR:在群集模式下使用版本3 Compose文件部署堆栈时,将忽略"There are several things to be aware of when using depends_on:"选项。

  

无法从外部访问该应用程序。

当某人在depends_on上请求haproxy时,必须为http://test:3000请求的haproxy配置在哪里?

答案 1 :(得分:0)

对于DATABASE_HOST=localhost-localhost表示我的本地容器。您需要使用托管db的服务名称。 localhost是一个特殊的DNS名称,始终指向应用程序主机。使用容器时-将是容器。在云开发中,您需要忘记使用localhost(将指向容器)或IP(每次运行容器时它们可能会更改,并且您将无法使用负载平衡)或IP,而只需使用服务名称。 / p>

关于准备情况-docker无法知道您在容器中启动的应用程序是否准备就绪。您需要使服务意识到数据库的不可用性,并让代码/脚本具有一些轮询/容错机制。

答案 2 :(得分:0)

马库斯是正确的,所以请听从他的建议。

这是一个组成/堆栈文件,假设您的应用在容器中的端口3000上侦听并且使用正确的密码,数据库等设置了db,该文件应该可以工作(您通常根据Docker将这些设置为compose中的环境变量)集线器自述文件)。

您的应用应设计为在无法正常使用数据库的情况下崩溃/重新启动/等待。这就是所有分布式计算的本质……任何“远程”(另一个容器,主机等)都不能被假定为始终可用。如果您的应用程序崩溃了,那么这对Docker来说是正常的过程,它将每次都重新创建Swarm Service任务。

如果您可以尝试使用公共Docker Hub映像进行此操作,那么我可以尝试为您进行测试。

请注意,在Swarm中,使用Traefik作为代理(Traefik on Swarm Mode Guide)可能会更容易,该代理将根据您给标签提供的主机名自动更新传入的请求并将其路由到正确的容器...但是注意您应该首先仅测试应用程序和数据库,然后在知道它们可行之后,尝试添加代理层。

此外,在Swarm中,您的所有网络都应该重叠,并且您无需指定,因为这是堆栈中的默认设置。

以下是使用traefik进行上述设置的示例。我没有给test服务指定特定的traefik主机名,因此它应该接受所有来自80并进入测试服务3000的流量。

version: '3'

services:
  db:
    image: test_db:01
    networks:
      - db
  test:
    image: test-back:01
    environment:
      - SERVICE_PORTS=3000
      - DATABASE_HOST=db
      - NODE_ENV=development
    networks:
      - web
      - db
    deploy:
      labels:
        - traefik.port=3000
        - traefik.docker.network=web
  proxy:
    image: traefik
    networks:
      - web
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - "80:80"
      - "8080:8080" # traefik dashboard
    command:
      - --docker
      - --docker.swarmMode
      - --docker.domain=traefik
      - --docker.watch
      - --api
    deploy:
      placement:
        constraints: [node.role == manager]

networks:
  web:
  db: