我想在docker swarm中部署具有故障转移Patroni和HAProxy(如单个入口点)的HA Postgresql。
我有docker-compose.yml-
version: "3.7"
services:
etcd1:
image: patroni
networks:
- test
env_file:
- docker/etcd.env
container_name: test-etcd1
hostname: etcd1
command: etcd -name etcd1 -initial-advertise-peer-urls http://etcd1:2380
etcd2:
image: patroni
networks:
- test
env_file:
- docker/etcd.env
container_name: test-etcd2
hostname: etcd2
command: etcd -name etcd2 -initial-advertise-peer-urls http://etcd2:2380
etcd3:
image: patroni
networks:
- test
env_file:
- docker/etcd.env
container_name: test-etcd3
hostname: etcd3
command: etcd -name etcd3 -initial-advertise-peer-urls http://etcd3:2380
patroni1:
image: patroni
networks:
- test
env_file:
- docker/patroni.env
hostname: patroni1
container_name: test-patroni1
environment:
PATRONI_NAME: patroni1
deploy:
placement:
constraints: [node.role == manager]
# - node.labels.type == primary
# - node.role == manager
patroni2:
image: patroni
networks:
- test
env_file:
- docker/patroni.env
hostname: patroni2
container_name: test-patroni2
environment:
PATRONI_NAME: patroni2
deploy:
placement:
constraints: [node.role == worker]
# - node.labels.type != primary
# - node.role == worker
patroni3:
image: patroni
networks:
- test
env_file:
- docker/patroni.env
hostname: patroni3
container_name: test-patroni3
environment:
PATRONI_NAME: patroni3
deploy:
placement:
constraints: [node.role == worker]
# - node.labels.type != primary
# - node.role == worker
haproxy:
image: patroni
networks:
- test
env_file:
- docker/patroni.env
hostname: haproxy
container_name: test-haproxy
ports:
- "5000:5000"
- "5001:5001"
command: haproxy
networks:
test:
driver: overlay
attachable: true
并使用以下命令将此服务部署在docker swarm中:
docker stack deploy --compose-file docker-compose.yml test
当我使用此命令时,我的服务正在创建,但是服务 patroni2 和 patroni3 不会在其他角色上启动,而其他节点是 worker 强>。他们根本没有开始!
我想看到我的服务部署在docker swarm中存在的所有节点(3个管理器和2个工作器)上 但是,如果我删除约束,当我在Swarm中部署docker-compose.yml时,我的所有服务都将在一个节点上启动。
尽管我使用docker官方文档进行了部署,但该服务可能看不到我的网络。
答案 0 :(得分:0)
使用不同的服务名称,docker不会尝试将容器分布在多个节点上,而是将退回到满足需求的使用最少的节点上,其中使用最少的节点是按计划的容器数量来衡量的。
您可以尝试使用相同的服务名称和3个副本来解决此问题。这将要求它们定义相同。为了使这项工作有效,您可以利用一些功能,第一个功能是etcd.tasks
将解析为每个etcd
服务容器的各个ip地址。第二个是service templates,可用于将{{.Task.Slot}}
之类的值注入到主机名,卷装载和env变量的设置中。挑战在于,最后的列表可能不会提供您想要的内容,这是从其他副本中唯一寻址每个副本的一种方法。主机名似乎可以工作,但是不幸的是,它不能在docker的DNS实现中解析(并且不容易实现,因为可以创建一个具有在Docker部署后更改主机名的功能的容器)。
剩下的选项是configuring constraints on each service,可在特定节点上运行。这不理想,并且降低了这些服务的容错能力。如果您有很多节点可以分为3组,那么使用node labels就可以解决问题。