【问题标题】:Docker swarm not exposing portDocker swarm 不暴露端口
【发布时间】:2019-06-22 01:22:57
【问题描述】:

我正在尝试在单个节点上运行 docker swarm,但无法将 docker 应用程序端口暴露给主机。

这与Docker swarm service port not exposed 类似,但我在单个节点中运行,并提供有关我的问题和研究的更多详细信息。

例如,给定以下 myapp.yml 文件:

version: "3"
services:
  app:
    image: myapp
    ports: 
      - "8123:8123"

堆栈是通过

docker stack deploy -c myapp.yml myapp

堆栈启动后,当我尝试访问端口(通过 curl)时失败。例如,

curl -v http://localhost:8123/myapp

显示连接被拒绝(该端口上没有任何监听)。

代码在使用 docker run 时有效

以下命令启动映像并显示如何验证端口是否暴露。

docker run -p 8123:8123 --name myapp myapp

卷曲然后工作。

curl -v http://localhost:8123/myapp

提供在 docker 中运行的应用程序的输出。

当我运行docker ps 时,PORTS 部分的输出显示:0.0.0.0:8123:8123/tcp。

docker network inspect bridge - 显示 docker 容器已分配给 bridge 网络。 docker 桥接网络默认与 docker run 命令一起使用。

命令docker port myapp显示:

8123/tcp -> 0.0.0.0:8123

与docker ps PORT 字段的输出相匹配。

docker stack deploy 不暴露端口

开始使用docker stack deploy -c myapp.yml myapp 后,我运行docker ps 命令,在输出的PORTS 字段中只看到8123/tcp。

docker port myapp 命令没有输出(表示 docker 主机没有可用的端口。

当我运行docker network ls 时,我看到了:

NETWORK ID       NAME            DRIVER     SCOPE
1234567890      bridge           bridge     local
9999999999      myapp_default   overlay    swarm

所以我注意到网络 myapp_default 与本地网桥的模式不同。我尝试使用现有的 bridge 网络,但是当我在我的堆栈/撰写文件中引用 bridge 网络时,我观察到网络 myapp_bridge 已创建。

所以我阅读了 docker network https://blog.alexellis.io/docker-stacks-attachable-networks/ 是一篇很好的文章。

到目前为止,我还没有让它工作,所以我起草了这个来寻求建议/帮助。

注意:This aricle (dated Feb 2017) 说它应该可以工作,但没有解决我的问题。

我想我很接近了。

资源和其他相关问题

https://docs.docker.com/v17.12/get-started/part5/ - 是 docker stack 技术的主要文档。但是在该页面上搜索网络显示没有任何用处。

https://blog.alexellis.io/docker-stacks-attachable-networks/ - 写得很好。

Docker swarm service port not exposed - 类似于我要问的问题。

https://runnable.com/docker/basic-docker-networking - 写在 docker 网络上。它在创建覆盖网络时显示以下内容(这是使用 docker stack deploy 时的默认设置)。

这些网络需要有效的键值对存储服务,例如 Consul、Etcd 或 ZooKeeper。您必须安装和配置您的 创建网络之前的键值存储服务。

Can not use user-defined bridge in swarm compose yaml file.

【问题讨论】:

  • 这是一个很长的尝试,但是您是否尝试在堆栈文件中明确定义网络并让 docker 在启动堆栈时创建您的应用程序的网络?
  • @YamaçKurtuluş,是的,我也尝试过,但没有奏效。我认为问题在于创建的网络处于覆盖模式。这篇文章runnable.com/docker/basic-docker-networking 说,当使用覆盖网络时,您需要拥有其他服务,例如 Consul、Etcd 或 ZooKeeper。请参阅创建覆盖网络,我没有设置这些服务之一(因为我在单个节点上运行)。
  • 这很奇怪,你不应该需要 Consul 或其他任何东西,swarm 应该开箱即用。您是否尝试过使用docker service create 命令?
  • 您的 app.yml 中的键“端口”应采用列表格式。如果您将 'nginx' 替换为 'myapp' 并在 yml 文件中公开端口 8123:80 只是为了测试端口是否已公开,该怎么办?
  • 我有点不好意思说问题出在错误的启动脚本(在 docker 容器中)。当我修复它时,我可以curl 并且它按照 YamacKurtulus 所说的那样工作。我还了解到docker ps 输出的是 Dockerfile EXPOSE 中的内容,而不是实际映射的内容。我认为docker inspect myapp 并显示了映射的端口,但我并不积极。

标签: docker docker-compose


【解决方案1】:

成群结队

ports:
  - "8123:8123"

将在所有 swarm 节点上公开端口,如果其他服务使用某些节点上的端口,您可能会遇到问题

您只能在带有容器的主机上使用下一个 docker-compose.yml 配置公开端口

services:
  app:
    ports:
      - target: 8123
        published: 8123
        mode: host

【讨论】:

    【解决方案2】:

    您应该为您的服务定义一个网络。在 Docker Swarm 模式下,docker 容器变为“服务”,要访问其端口,您可以调用服务的名称 我给你一个docker-compose文件的例子,如何连接nginx和php-fpm

    version: '3.2'
      services:
        nginx:
          image: nginx
          links:
          - php
          - mariadb:mysql
          ports:
          - "8880:80"
          networks:
          - frontend
          deploy:
            #mode: replicated
            replicas: 1
            placement:
              constraints: [node.role == manager]
        php:
           image: php
           deploy:
             #mode: replicated
             replicas: 1
             placement:
               constraints: [node.role == manager]
               #endpoint_mode: dnsrr
           links:
             - mariadb:mysql
        mariadb:
           image: mariadb:10.4.1
           #restart: always
           deploy:
             mode: replicated
             replicas: 1
             #placement:
             #constraints: [node.role == manage]
             environment:
               MYSQL_ROOT_PASSWORD: SECRET          
             volumes:
               - type: volume
                  source: mydatabase
                  target: /var/lib/mysql/data
                  volume:
                    nocopy: true # do not copy data from container when a volume is created?
        networks:
          frontend  
        volumes:
          mydatabase:
    

    部署 (docker stack deploy -c docker-compose.yaml) 后,查看服务列表:

    docker service ls 
    

    要公会 nginx 如何访问你的 php-fpm 后端,编辑你的 nginx 配置文件:

    location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass **NAME_OF_PHP_SERVICE_IN SWARM**:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    

    您将 php 服务的名称放在 Swarm 集群中,而不是放置容器的 IP 地址 (IP:9000)

    【讨论】:

      猜你喜欢
      • 2019-06-04
      • 2018-09-03
      • 1970-01-01
      • 2020-11-13
      • 2019-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多