Docker群未暴露端口

rkue9o1l  于 2022-11-28  发布在  Docker
关注(0)|答案(6)|浏览(225)

我尝试在单个节点上运行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运行时代码正常工作

以下命令启动映像并显示如何验证端口是否已公开。
docker run -p 8123:8123 --name myapp myapp
curl 然后工作。
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 psPORT字段的输出相匹配。

Docker堆栈部署不公开端口

在开始使用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,local不同。我尝试使用现有的bridge网络,但当我在堆栈/编写文件中参考bridge网络时,我发现创建了网络myapp_bridge
所以我读了关于Docker Networking的文章https://blog.alexellis.io/docker-stacks-attachable-networks/是一篇很好的文章。
到目前为止,我还没有得到它的工作,所以我起草了这一点,以寻求建议/帮助。
注意:This aricle (dated Feb 2017)说它应该可以工作,但没有解决我的问题。
我想我快到了。

资源和其他相关问题

https://docs.docker.com/v17.12/get-started/part5/-是Docker堆栈技术的Docker主要文档。但是在该页面上搜索网络没有显示任何有用的内容。
https://blog.alexellis.io/docker-stacks-attachable-networks/-写得很好。
Docker swarm service port not exposed-与我提出的问题类似。
https://runnable.com/docker/basic-docker-networking-编写Docker网络。当创建覆盖网络时(使用Docker堆栈部署时,这是默认设置),它会说以下内容。
这些网络需要有效的键-值存储服务,如Consul、Etcd或ZooKeeper。在创建网络之前,必须安装并配置键-值存储服务。
是的

c7rzv4ha

c7rzv4ha1#

蜂群

ports:
  - "8123:8123"

我将公开所有群节点上的端口,如果其他服务使用某些节点上的端口,您可能会遇到问题
您只能在具有带有next docker-compose.yml config容器的主机上公开端口

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

jqjz2hbq2#

你应该为你的服务定义一个网络.在Docker Swarm模式下,Docker容器变成'Service',要访问它的端口,你需要调用服务的名称我给你提供了一个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

0lvr5msh

0lvr5msh3#

我有一个端口,正在使用的两个SWARM和本地Linux操作系统,两个应用程序都运行,但只有一个收到传入的连接。
奇怪的是,当我本以为其中一个试图使用该端口的应用程序会发生错误时,却没有出现EADDRINSE错误。
例如,在端口8080上运行本地应用程序,并在使用端口8080的主机上使用SWARM。
一个传入的连接来到端口8080,该连接被发送到其中一个(我不记得是哪个)。

cwdobuhd

cwdobuhd4#

我也遇到过同样的问题--在我的ubuntu机器上它能正常工作--在我的debian服务器上不能。最后我把问题缩小到debian上使用的内核版本。升级到5.11.22-5为我解决了这个问题。
有一些关于缺少内核模块的帖子(没有提到是哪个)--也许这是相关的。

hivapdat

hivapdat5#

我有同样的问题。通过改变IP解决。首先,获得当前Docker群节点的IP地址。

docker info

找到你的IP Manager Addresses行。例如,我的IP是192.168.0.13。现在你可以通过这个地址192.168.0.13:8123打开你的应用程序。

fnx2tebb

fnx2tebb6#

由于IPv6的存在,这种情况经常发生。在主机上,localhost被定义为::1,而不是/etc/hosts . Ingress networking in swarm does not support IPv6中的127.0.0.1。因此,有两种可能的解决方案:
1.使用IPv4连接:curl -v http://127.0.0.1:8123/myapp .
1.使用主机模式而不是入口网络发布端口。这将仅在运行容器的主机上发布端口。这对于部署在每个节点(deploy: mode: global)上的服务删除节点之间的额外网络跃点非常有用。要切换到已发布端口的主机模式,请在发布端口时通过切换到长语法来遵循Ryabchenko Alexander's advice

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

有关详细信息,请参阅合成文件v3参考:https://docs.docker.com/compose/compose-file/compose-file-v3/#long-syntax-1。请注意,这里以主机模式发布端口不同于主机联网,主机联网运行没有网络沙箱的容器,遗憾的是,“主机”在这里用于两种不同的事情,一种是在swarm之外,另一种是在docker隔离之外。

相关问题