docker swarm集群,docker-compose部署nginx+php,nfs共享项目代码目录,
version: '3.8'
services:
php:
image: php8.0:latest # 替换为你的PHP镜像名称
networks:
- webnet
volumes:
# - /www/php8.0//www.conf:/etc/php/8.0/fpm/pool.d/www.conf
- /www/html:/var/www/html # 挂载你的应用代码
deploy:
mode: global
# endpoint_mode: vip
restart_policy:
condition: on-failure
nginx:
image: nginx:latest
networks:
- webnet
ports:
- "80:80"
volumes:
- /www/nginx/conf/nginx.conf:/etc/nginx/nginx.conf # 挂载自定义的nginx配置文件
- /www/nginx/conf/default0111:/etc/nginx/conf.d/default.conf
- /www/nginx/log:/var/log/nginx/
- /www/html:/var/www/html # 与PHP容器共享应用代码
depends_on:
- php
deploy:
mode: global
# endpoint_mode: vip
restart_policy:
condition: on-failure
networks:
webnet:
external: true
如何访问其中一个ip,其他节点nginx会有信息吗?
在你的 Docker Swarm 集群中使用 docker-compose
部署的 nginx
和 php
服务,每个服务都配置了 deploy: mode: global
,这意味着每个节点都会运行一个实例。在这种情况下,如果你访问集群中某个节点的 IP 地址,Nginx 会根据配置处理请求。
情况分析
-
访问一个节点的 IP:
- 直接访问集群中某个节点的 IP 地址时,请求将被该节点上的
nginx
实例处理。 - 由于 Nginx 和 PHP 容器共享同一个 NFS 挂载的
/www/html
目录,所以无论在哪个节点处理请求,PHP 代码都是相同的,日志文件也会写入共享的 NFS 目录中。
- 直接访问集群中某个节点的 IP 地址时,请求将被该节点上的
-
其他节点的 Nginx 信息:
- 如果你访问一个节点的 IP 地址,其他节点的
nginx
实例并不会直接处理这个请求,因此它们不会有直接的处理信息。然而,由于所有节点的nginx
都挂载了相同的日志目录(/www/nginx/log
),日志将会统一记录在这个共享目录下,因此你在一个节点上的nginx
日志中可以看到请求的信息。
- 如果你访问一个节点的 IP 地址,其他节点的
统一访问入口
- 建议使用负载均衡器:
-
如果你希望访问集群的任意一个节点时,其他节点的 Nginx 也能够参与处理请求,你可以在集群前配置一个负载均衡器,或者使用 Swarm 内置的
--endpoint-mode vip
。这样,客户端可以访问集群的虚拟 IP,Swarm 将自动把请求分发到不同的nginx
实例。 -
通过
endpoint_mode: vip
,集群内的nginx
实例可以共享一个虚拟 IP,外部请求将被均匀分发到各个节点上运行的nginx
实例,从而确保负载均衡。
-
实施
-
如果你想改为使用
--endpoint-mode vip
模式,可以按如下方式修改docker-compose.yml
:services: php: image: php8.0:latest networks: - webnet volumes: - /www/html:/var/www/html deploy: mode: global restart_policy: condition: on-failure nginx: image: nginx:latest networks: - webnet ports: - "80:80" volumes: - /www/nginx/conf/nginx.conf:/etc/nginx/nginx.conf - /www/nginx/conf/default0111:/etc/nginx/conf.d/default.conf - /www/nginx/log:/var/log/nginx/ - /www/html:/var/www/html depends_on: - php deploy: mode: global endpoint_mode: vip restart_policy: condition: on-failure networks: webnet: external: true
通过这种方式,无论你访问哪个节点,Swarm 将自动将流量分发给不同的 Nginx 实例,并确保日志和处理信息都能统一管理。
举例说明这种方法实际访问工作流程
使用 --endpoint-mode vip
模式后,Docker Swarm 会为服务创建一个虚拟 IP(VIP),该 VIP 将所有的请求根据负载均衡策略分发给服务的各个实例。让我们通过一个实际的访问流程来解释这一点。
假设的场景
- 你有一个两节点的 Docker Swarm 集群,节点 IP 分别为
192.168.1.10
和192.168.1.11
。 - 你在 Swarm 上部署了
nginx
和php
服务,每个服务都在每个节点上运行一个实例(mode: global
)。 nginx
服务的endpoint_mode
被设置为vip
,使得nginx
服务获得一个虚拟 IP(假设为10.0.0.2
)。- 客户端的请求将通过负载均衡被分发到不同的
nginx
实例。
实际访问流程
-
服务部署:
- 当你部署
nginx
服务时,Swarm 会为这个服务分配一个虚拟 IP,比如10.0.0.2
。 - 该虚拟 IP 并不绑定到某个具体的节点,而是存在于整个 Swarm 网络中。
- 当你部署
-
客户端访问:
- 客户端发送一个 HTTP 请求到集群中任意节点的 IP 地址,例如
192.168.1.10
。 - 集群中的 Docker Daemon 检查该请求目标的端口,并发现它属于
nginx
服务。 - 因为
nginx
服务在endpoint_mode: vip
下运行,Docker Swarm 会将该请求重定向到10.0.0.2
,也就是nginx
服务的虚拟 IP。
- 客户端发送一个 HTTP 请求到集群中任意节点的 IP 地址,例如
-
请求分发:
- Swarm 网络系统接收到请求后,会根据负载均衡策略,将请求分发到集群中运行
nginx
服务的某一个节点。例如,它可能会选择将请求分发到192.168.1.11
节点上的nginx
实例。
- Swarm 网络系统接收到请求后,会根据负载均衡策略,将请求分发到集群中运行
-
处理请求:
- 被选中的
nginx
实例接收请求,并通过挂载的 NFS 目录/var/www/html
访问 PHP 应用代码。 - 如果请求需要调用 PHP 后端,
nginx
会通过本地网络调用运行在同一节点上的php
实例。 php
实例处理请求,并将结果返回给nginx
,然后由nginx
返回给客户端。
- 被选中的
-
日志记录:
- 无论哪个节点上的
nginx
处理了请求,日志都会写入共享的/www/nginx/log
目录中。 - 因此,所有的请求日志都可以集中管理,方便调试和监控。
- 无论哪个节点上的
总结
- 使用
--endpoint-mode vip
后,你的服务将有一个统一的虚拟 IP,客户端请求通过负载均衡被分发到不同的节点,达到均衡流量和提升可用性的效果。 - 不需要客户端知道多个节点的 IP 地址,所有请求都可以通过一个 IP(即虚拟 IP)进行访问,Swarm 会自动处理请求的分发。
- 由于
nginx
和php
共享相同的代码和日志目录,所有节点的处理情况和日志都可以集中管理。
要验证流量是否通过 VIP (Virtual IP) 自动路由到正确的服务副本,可以按照以下步骤进行操作
:
1. 检查服务的VIP
在管理节点上,使用以下命令查看 Nginx 服务的详细信息,确认服务的 VIP 地址:
docker service inspect --format="{{json .Endpoint.VirtualIPs}}" mystack_nginx
这将返回 Nginx 服务的虚拟 IP 地址。
2. 访问服务
使用浏览器或 curl
访问 Swarm 集群中的任意节点的 IP 地址,例如:
curl http://<NODE-IP>
你应该能看到 Nginx 返回的页面。如果 Nginx 服务和 PHP 服务之间有交互,也可以通过访问相应的 URL 来验证。
3. 查看请求分发
通过登录到 Nginx 容器内部,你可以查看 Nginx 访问日志,以确认请求是否均匀分发到不同的 Nginx 容器实例中:
docker exec -it <NGINX-CONTAINER-ID> /bin/bash
tail -f /var/log/nginx/access.log
访问几次服务后,你应该能在不同的 Nginx 容器实例中看到日志输出,表明请求被均匀分发。
4. 停止其中一个服务副本
为了进一步验证,尝试停止 Nginx 服务的其中一个副本,检查剩下的副本是否继续接收请求:
docker service scale mystack_nginx=1
再次访问服务并检查日志。如果流量自动路由到剩余的服务副本,这表明 VIP 功能正常。
5. 检查 Swarm 网络
通过以下命令查看 Swarm 网络中容器的分布情况,确保容器之间的通信正常:
docker network inspect mystack_frontend
你会看到容器的网络连接信息,以及 VIP 的配置情况。
这些步骤可以帮助你验证 Swarm 集群中的流量是否通过 VIP 正确地自动路由到服务副本上。