Docker – 分别缩放nginx和php-fpm

我一直在玩docker和docker写作,并有一个问题。

目前我的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 

应用程序包含端口9000上的php-fpm和我的应用程序代码。 Web是带有几个configuration的nginx。

这个函数我期望它然而为了连接nginx到php-fpm我有这样的一行:

 fastcgi_pass app:9000; 

我怎样才能有效地扩大这个? 例如,如果我想让一个nginx容器运行,但运行三个应用程序容器,那么我肯定会有三个php-fpm实例都试图在端口9000上进行监听。

我怎样才能有不同的端口上的每个php-fpm实例,但在任何给定的时间仍然知道他们在我的nginxconfiguration?

我采取了错误的做法?

谢谢!

一个解决scheme是将其他php-fpm实例添加到您的docker-compose文件中,然后使用其他答案中提到的nginx上游来在它们之间进行负载平衡。 这是在这个例子docker-compose回购: 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; } 

这是不是很理想,因为它需要改变nginxconfiguration和docker-compose.yml,当你想要扩大或缩小。

请注意,9000端口是容器的内部,而不是您的实际主机,所以在端口9000上有多个php-fpm容器并不重要。

Docker今年秋天收购了Tutum。 他们有一个解决scheme,将HAProxy容器和他们的api结合起来,自动调整负载平衡器configuration到正在进行负载平衡的正在运行的容器。 这是一个很好的解决scheme。 然后nginx指向分配给负载平衡器的主机名。 也许Docker会在收购Tutum之后将这种types的解决scheme进一步整合到他们的工具中。 有一篇关于它的文章: https : //web.archive.org/web/20160628133445/https : //support.tutum.co/support/solutions/articles/5000050235-load-balancing-a-web-service

Tutum目前是付费服务。 Rancher是一个开源项目,提供类似的负载平衡function。 他们也有一个“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一起工作,自动更新nginxconfiguration并重新启动它。 另请参阅@ iwaseatenbyagrue的答案有其他方法。

您可以使用上游来定义多个后端,如下所述:

https://stackoverflow.com/questions/5467921/how-to-use-fastcgi-next-upstream-in-nginx

你也希望有新的后端死亡/服务时,configuration更新如下:

https://github.com/kelseyhightower/confd

在你的Nginx和php-fpm容器在同一个主机上的情况下,你可以在Nginx容器使用的主机上configuration一个小的dnsmasq实例,并且运行一个脚本来在容器的IP地址有自动更新的DNSlogging改变。

我已经写了一个小脚本来执行此操作(粘贴在下面),它会自动更新与容器名称相同的DNSlogging,并将它们指向容器的IP地址:

 #!/bin/bash # 10 seconds interval time by default INTERVAL=${INTERVAL:-10} # dnsmasq config directory DNSMASQ_CONFIG=${DNSMASQ_CONFIG:-.} # commands used in this script DOCKER=${DOCKER:-docker} SLEEP=${SLEEP:-sleep} TAIL=${TAIL:-tail} declare -A service_map while true do changed=false while read line do name=${line##* } ip=$(${DOCKER} inspect --format '{{.NetworkSettings.IPAddress}}' $name) if [ -z ${service_map[$name]} ] || [ ${service_map[$name]} != $ip ] # IP addr changed then service_map[$name]=$ip # write to file echo $name has a new IP Address $ip >&2 echo "host-record=$name,$ip" > "${DNSMASQ_CONFIG}/docker-$name" changed=true fi done < <(${DOCKER} ps | ${TAIL} -n +2) # a change of IP address occured, restart dnsmasq if [ $changed = true ] then systemctl restart dnsmasq fi ${SLEEP} $INTERVAL done 

然后,使用--dns host-ip-address启动您的nginx容器,其中host-ip-address是接口docker0上主机的IP地址。

你的Nginxconfiguration应该dynamic地parsing名字:

 server { resolver host-ip-address; listen 80; server_name @server_name@; root /var/www/@root@; index index.html index.htm index.php; location ~ ^(.+?\.php)(/.*)?$ { try_files $uri =404; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$1; set $backend "@fastcgi_server@"; fastcgi_pass $backend; } } 

参考文献:

如果你的nginx和php-fpm在不同的主机上,你可以试试@ smaj的答案。

另一种方法可能是查看诸如领事模板之类的东西。

当然,在某些时候, Kubernetes可能需要被提及 。

但是,通过查看哪些消耗式docker事件可以为您执行(运行docker events --since 0的快速示例),您可以考虑稍微多点“string和胶带”方法。

有一个脚本可以查看这些事件(考虑到有几个可用的客户端软件包,包括python,go等等),修改configuration文件并重新加载nginx(即使用consul-template方法,但不需要领事)。

回到你的原始前提,只要你的php-fpm容器是用自己的networking启动的(即不能共享另一个容器,比如nginx的容器),那么你可以有多less容​​器在端口上监听9000,因为他们有每个容器的IP,所以没有任何问题与港口的冲突。

你如何扩展这个可能取决于你的最终目标/用例是什么,但是你可能会考虑的一件事是在nginx和你的php-fpm节点之间放置HAproxy。 有一件事情可以让你做的只是为你的php-fpm服务器(即172.18.0.0/24)指定一个范围(并可能创build一个dockernetworking),并configurationHAproxy来尝试使用该范围内的任何IP一个后端。 由于HAproxy具有健康检查function,因此可以快速识别哪些地址是活的,并使用它们。

请参阅https://stackoverflow.com/questions/1358198/nginx-removing-upstream-servers-from-pool关于nginx与haproxy如何处理上游的讨论&#x3002;

除非您为此使用专用的dockernetworking,否则您可能需要为您的php-fpm节点执行一些手动IPpipe理。