我正在尝试使不同的Python脚本运行在不同的容器上,配置为docker,能够侦听相同的端口。每个容器( 9)都应该监听端口1883和8086。这样做的目的是编写一个坞-撰写文件,其中每个服务都具有以下特征:
sensor1:
build: ./sensor1
image: sensor1:latest
ports:
- "8086:80"
- "1883:80"
....
....
sensor9:
build: ./sensor9
image: sensor9:latest
ports:
- "8086:80"
- "1883:80"
我知道,对于普通的码头组合文件,它不工作,我需要一个反向代理,但我被困在这个反向代理(即Traefik)配置。实际上,这些脚本应该侦听从外部代理接收的端口1883,并在位于同一主机上的数据库上写入,该数据库可以使用端口8086进行访问。
发布于 2022-06-07 12:07:50
绑定到多个地址
当侦听同一个主机地址时,不能将多个容器的端口绑定到同一个主机端口。做这样的配置的唯一方法是将端口绑定到主机上的不同地址。例如,如果我的主机上有多个与eth0
相关的地址:
$ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 192.168.1.175/24 brd 192.168.1.255 scope global dynamic noprefixroute eth0
valid_lft 49625sec preferred_lft 49625sec
inet 192.168.1.200/24 scope global secondary eth0
valid_lft forever preferred_lft forever
inet 192.168.1.201/24 scope global secondary eth0
valid_lft forever preferred_lft forever
然后,我可以将每个容器绑定到特定的地址,如下所示:
sensor1:
build: ./sensor1
image: sensor1:latest
ports:
- "192.168.1.175:8086:80"
- "192.168.1.175:1883:80"
[...]
sensor2:
build: ./sensor2
image: sensor2:latest
ports:
- "192.168.1.200:8086:80"
- "192.168.1.200:1883:80"
[...]
然后,到http://192.168.1.175:8086
的连接将转到sensor1
容器,而到http://192.168.1.200:8086
的连接将转到sensor2
容器。
基于主机名和路径的路由
如果您希望将所有内容都托管在同一个地址,那么您需要另一种策略来区分容器。你的选择是有效的:
http://myhost/sensor1
到sensor1,http://myhost/sensor2
到sensor2,等等)。负载平衡器使用传入请求中包含的路径来路由通信量。路径示例
我将从路径示例开始,因为这通常是最简单的。它不需要在多台机器上设置DNS条目或使用/etc/hosts
。
以下docker-compose.yaml
演示了基于路径的路由配置:
version: '3'
services:
# This is the load balancer. To match the configuration you show in
# your question, I have it listening on ports 8086 and 1883 in
# addition to port 80.
#
# The default configuration of Traefik is to expose a management
# interface on port 8080; if you don't want that, you can remove
# the corresponding `ports` entry.
reverse-proxy:
image: traefik:v2.7
command: --api.insecure=true --providers.docker
ports:
- "80:80"
- "8086:80"
- "1883:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# In our container configuration, we use labels to configure
# Traefik. Here, we're declaring that requests prefixed by `/sensor1`
# will be routed to this container, and then we strip the `/sensor1`
# prefix from the request (so that the service running inside the
# container doesn't see the prefix).
#
# Note that we're not publishing any ports here: only the load
# balancer has ports published on the host.
sensor1:
hostname: sensor1
labels:
- traefik.enable=true
- traefik.http.routers.sensor1.rule=PathPrefix(`/sensor1`)
- traefik.http.services.sensor1.loadbalancer.server.port=80
- traefik.http.middlewares.strip-sensor1.stripprefix.prefixes=/sensor1
- traefik.http.routers.sensor1.middlewares=strip-sensor1
build: ./sensor1
sensor2:
hostname: sensor2
labels:
- traefik.enable=true
- traefik.http.routers.sensor2.rule=PathPrefix(`/sensor2`)
- traefik.http.services.sensor2.loadbalancer.server.port=80
- traefik.http.middlewares.strip-sensor2.stripprefix.prefixes=/sensor2
- traefik.http.routers.sensor2.middlewares=strip-sensor2
build: ./sensor2
如果每个容器都运行一个在/hostname.txt
中包含主机名的服务,我将看到以下行为:
$ curl myhost/sensor1/hostname.txt
sensor1
$ curl myhost/sensor2/hostname.txt
sensor2
主机名示例
基于主机的配置看起来基本相同,但rule
使用的是Host
匹配而不是PathPrefix
匹配(我们不再需要前缀剥离逻辑):
version: '3'
services:
reverse-proxy:
image: traefik:v2.7
command: --api.insecure=true --providers.docker
ports:
- "80:80"
- "8086:80"
- "1883:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
sensor1:
hostname: sensor1
labels:
- traefik.enable=true
- traefik.http.routers.sensor1.rule=Host(`sensor1`)
- traefik.http.services.sensor1.loadbalancer.server.port=8080
build:
context: web
sensor2:
hostname: sensor2
labels:
- traefik.enable=true
- traefik.http.routers.sensor2.rule=Host(`sensor2`)
- traefik.http.services.sensor2.loadbalancer.server.port=8080
build:
context: web
sensor3:
hostname: sensor3
labels:
- traefik.enable=true
- traefik.http.routers.sensor3.rule=Host(`sensor3`)
- traefik.http.services.sensor3.loadbalancer.server.port=8080
build:
context: web
为此,需要将多个主机名映射到docker主机。您可以通过设置适当的DNS条目,或者在任何需要联系这些服务的机器上向/etc/hosts
添加适当的条目来实现这一点。
我们可以通过在请求中设置显式Host
头来演示配置:
$ curl -H 'Host: sensor1' myhost/hostname.txt
sensor1
$ curl -H 'Host: sensor2' myhost/hostname.txt
sensor2
https://stackoverflow.com/questions/72529750
复制相似问题