Docker - 分別擴充 nginx 和 php-fpm

Docker - 分別擴充 nginx 和 php-fpm

我一直在使用 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

應用程式包含連接埠 9000 上的 php-fpm 和我的應用程式程式碼。 Web 是帶有一些設定的 nginx。

這個功能正如我所期望的那樣,但是為了將 nginx 連接到 php-fpm 我有這一行:

fastcgi_pass    app:9000;

我怎樣才能有效地擴展這個規模?例如,如果我想要運行一個 nginx 容器,但運行三個應用程式容器,那麼我肯定會擁有三個 php-fpm 實例,它們都試圖監聽連接埠 9000。

如何讓每個 php-fpm 實例位於不同的連接埠上,但在任何給定時間仍然知道它們在我的 nginx 配置中的位置?

我採取了錯誤的方法嗎?

謝謝!

答案1

一種解決方案是為 docker-compose 檔案添加額外的 php-fpm 實例,然後使用其他答案中提到的 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 指向分配給負載平衡器的主機名稱。也許在收購 Tutum 之後,Docker 會進一步將這種類型的解決方案整合到他們的工具中。這裡有一篇關於它的文章: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

您也希望在新後端死亡/投入使用時更新配置,例如:

https://github.com/kelseyhightower/confd

答案4

另一種方法可能是研究類似的東西領事模板

當然,在某個時候,庫伯內斯可能需要提及。

但是,您可以透過查看消費性 docker 事件可以為您做的事情來考慮稍微多一點的「字串和膠帶」方法(運行docker events --since 0以獲取快速範例)。

讓一個腳本查看這些事件(記住有幾個可用的客戶端包,包括 python、go 等)、修改設定檔並重新載入 nginx(即使用 consul-template 方法,但不需要領事)。

不過,回到最初的前提:只要您的 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 管理。

相關內容