在Docker Swarm中访问容器/服务端口而不将端口发布到外部网络

152次阅读
没有评论

问题描述

在使用docker-compose时,可以通过在docker-compose.yml中设置ports配置,例如127.0.0.1:8080:80,将端口仅转发到容器内部的localhost。然而,在Docker Swarm中,这种方式不适用,因为发布的端口会对外界可见。用户想知道在不将端口对外开放的情况下,如何仅从localhost访问容器端口。尝试使用iptables配置拒绝连接到特定端口,但由于Docker的iptables设置,该方法无效。

解决方案

以下解决方案中的操作需要注意版本差异,可能需要备份数据。请在操作前谨慎阅读并确保理解。

使用docker_gwbridge接口访问容器

在Docker Swarm中,可以通过容器所属的docker_gwbridge接口访问容器。通过在容器内部运行ifconfig命令,可以获取容器在docker_gwbridge接口上的IP地址。以下是具体步骤:

  1. 进入需要访问的容器:
    bash
    docker exec -it <container-id> sh
  2. 在容器内部运行ifconfig命令来查找docker_gwbridge接口的IP地址:
    bash
    ifconfig

    记下该IP地址,假设为172.18.0.2

这样,在主机上可以使用容器的docker_gwbridge接口IP地址和端口号进行访问,例如172.18.0.2:5432,从而实现仅从localhost访问容器端口,而无需将端口对外开放。

请注意,在Docker Swarm服务中,使用docker inspect <container-id>docker inspect <service-name>docker inspect <network-id>来查找IP地址可能不会显示出docker_gwbridge接口的IP地址。因此,建议在容器内部使用ifconfig来获取IP地址。

使用内部网络设置

另一种方法是使用内部网络设置来实现容器端口的访问,而无需将端口发布到外部网络。以下是具体步骤:

  1. 在Docker Compose或Docker Swarm的服务配置中,定义一个自定义网络:
    yaml
    version: '3'
    services:
    service_a:
    image: your_image_for_service_a:latest
    networks:
    - internal_network
    # 其他配置项
    service_b:
    image: your_image_for_service_b:latest
    networks:
    - internal_network
    # 其他配置项
    networks:
    internal_network:

  2. 这样,service_aservice_b将加入到名为internal_network的自定义网络中。

  3. 在容器内部,可以使用服务名称来访问其他服务的端口。例如,在service_b中可以通过service_a的服务名和端口号来访问service_a的端口:
    bash
    http://service_a:port_number

这种方式可以在Docker Swarm中实现容器之间的内部通信,而不需要将端口发布到外部网络,从而实现只从localhost访问容器端口的需求。

使用脚本进行访问

如果以上方法不适用,你还可以考虑编写脚本来实现容器的访问控制。例如,你可以编写一个bash脚本,在容器A启动后等待其完全启动,然后再启动容器B。

以下是一个示例bash脚本,用于在容器A启动后等待并启动容器B:

#!/bin/bash
# 启动容器A
docker run -d --name container_a your_image_a
# 等待容器A完全启动
while ! docker exec container_a echo "Container A is ready"; do
  sleep 1
done
# 启动容器B
docker run -d --name container_b your_image_b

在这个示例中,我们首先使用docker run命令启动容器A,并将其命名为container_a。然后,使用一个循环来等待容器A完全启动。一旦容器A就绪,我们再使用docker run命令启动容器B,并将其命名为container_b

请注意,这种方法可能会增加复杂性,并且需要确保容器A和容器B之间的依赖关系正确设置。

总结

在Docker Swarm中访问容器/服务端口,而不将端口发布到外部网络,可以通过使用容器的docker_gwbridge接口IP地址、内部网络设置或编写脚本来实现。根据实际情况,选择合适的方法来满足你的需求。

正文完