我一直在研究 docker 和 docker-compose 并且有一个问题。
目前我的 docker-compose.yml 如下所示:
app:
image: myname/php-app
volumes:
- /var/www
environment:
<SYMFONY_ENVIRONMENT>: dev
web:
image: myname/nginx
ports:
- 80
links:
- app
volumes_from:
- app
App 包含端口 9000 上的 php-fpm 和我的应用程序代码。Web 是带有一些配置的 nginx。
它的功能与我预期的一样,但是为了将 nginx 连接到 php-fpm,我有以下几行:
fastcgi_pass app:9000;
我如何才能有效地扩展它?例如,如果我想运行一个 nginx 容器,但运行三个应用程序容器,那么我肯定会有三个 php-fpm 实例都尝试监听端口 9000。
我怎样才能将每个 php-fpm 实例放在不同的端口上,但仍然知道它们在任何给定时间在我的 nginx 配置中的位置?
我是否采取了错误的方法?
谢谢!
答案1
一种解决方案是将其他 php-fpm 实例添加到 docker-compose 文件,然后使用其他答案中提到的 nginx 上游在它们之间进行负载平衡。此示例 docker-compose repo 中已完成此操作:https://github.com/iamyojimbo/docker-nginx-php-fpm/blob/master/nginx/nginx.conf#L137
upstream php {
#If there's no directive here, then use round_robin.
#least_conn;
server dockernginxphpfpm_php1_1:9000;
server dockernginxphpfpm_php2_1:9000;
server dockernginxphpfpm_php3_1:9000;
}
这其实并不理想,因为当您想要扩大或缩小规模时,需要更改 nginx 配置和 docker-compose.yml。
请注意,9000 端口是容器内部的,而不是实际主机的,因此在端口 9000 上拥有多个 php-fpm 容器并不重要。
Docker 今年秋天收购了 Tutum。他们有一个解决方案,将 HAProxy 容器与其 API 相结合,以自动调整负载均衡器配置以适应正在负载平衡的运行容器。这是一个不错的解决方案。然后 nginx 指向分配给负载均衡器的主机名。也许 Docker 会在收购 Tutum 后进一步将此类解决方案集成到他们的工具中。这里有一篇关于它的文章:https://web.archive.org/web/20160628133445/https://support.tutum.co/support/solutions/articles/5000050235-load-balancing-a-web-service
Tutum 目前是一项付费服务。Rancher 是一个开源项目,提供类似的负载平衡功能。他们还有一个“rancher-compose.yml”,可以定义 docker-compose.yml 中设置的服务的负载平衡和扩展。 http://rancher.com/the-magical-moment-when-container-load-balancing-meets-service-discovery/ http://docs.rancher.com/rancher/concepts/#load-balancer
更新 2017/03/06:我使用了一个名为联锁它与 Docker 配合使用,自动更新 nginx 配置并重新启动它。另请参阅 @iwaseatenbyagrue 的回答它有附加方法。
答案2
虽然这篇文章是 2015 年的,而且我感觉我已经过时了(对不起社区),但我觉得在这个时候补充一些内容还是很有价值:
如今(自从提到 Kubernetes 以来),当您使用 Docker 时,您可以非常轻松地使用 Kubernetes 或 Docker Swarm 来解决这个问题。 这两个编排器都会接收您的 Docker 节点(一个节点 = 一台装有 Docker 的服务器),您可以将服务部署到它们,它们将使用覆盖网络为您管理端口挑战。
由于我更熟悉 Docker Swarm,因此您可以按照以下方法解决此问题(假设您有一个 Docker 节点):
初始化群体:
docker swarm init
cd 进入你的项目根目录
cd some/project/root
从你的 docker-compose.yml 创建一个 swarm 堆栈(而不是使用 docker-compose):
docker stack deploy -c docker-compose.yml myApp
这将创建一个名为“myApp”的 docker swarm 服务堆栈,并为您管理端口。这意味着:您只需在 docker-compose 文件中为 php-fpm 服务添加一个“port: 9000:9000”定义,然后就可以扩展 php-fpm 服务,比如扩展到 3 个实例,而 swarm 将自动在三个实例之间对请求进行负载平衡,而无需进一步工作。
答案3
您可以使用上游来定义多个后端,如下所述:
https://stackoverflow.com/questions/5467921/how-to-use-fastcgi-next-upstream-in-nginx
您还希望在新的后端死亡/投入使用时更新配置,例如:
答案4
另一种方法可能是研究类似consul-模板。
当然,在某个时候,Kubernetes可能需要提一下。
但是,您可以考虑采用稍微更像“绳子和胶带”的方法,看看使用 docker 事件可以为您做什么(运行docker events --since 0
快速示例)。
用一个脚本来查看这些事件(记住有几个可用的客户端包,包括 python、go 等)、修改配置文件并重新加载 nginx(即使用 consul-template 方法,但不需要 consul)是相当简单的。
不过,回到你最初的前提:只要你的 php-fpm 容器使用自己的网络启动(即不与另一个容器共享网络,比如 nginx),那么你就可以让任意数量的容器在端口 9000 上监听 - 因为它们有每个容器的 IP,所以不会出现端口“冲突”的问题。
如何扩展它很可能取决于您的最终目标/用例,但您可能考虑将 HAproxy 放置在 nginx 和 php-fpm 节点之间。这可以让您做的一件事就是docker network
为您的 php-fpm 服务器(即 172.18.0.0/24)指定一个范围(并可能创建一个),并将 HAproxy 配置为尝试使用该范围内的任何 IP 作为后端。由于 HAproxy 具有健康检查功能,它可以快速识别哪些地址是活动的,并利用它们。
看https://stackoverflow.com/questions/1358198/nginx-removing-upstream-servers-from-pool讨论 nginx 与 haproxy 如何处理上游。
除非你为此使用了专用的 docker 网络,否则可能需要对您的 php-fpm 节点进行一些手动 IP 管理。