Haproxy

haproxy 負載均衡器無法訪問 Podman rootful 容器

  • July 10, 2020

我在 podman 中創建了兩個網路,“後端”和“前端”。

NAME      VERSION  PLUGINS
podman    0.4.0    bridge,portmap,firewall,tuning
backend   0.4.0    bridge,portmap,firewall,dnsname
frontend  0.4.0    bridge,portmap,firewall,dnsname

我有一個使用以下命令在“後端”網路中執行的 MS Sql Server 容器:

podman run -d -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=TestS01Pass' --name mssqlserver -v sqlvolume:/var/opt/mssql --network backend mcr.microsoft.com/mssql/server:2019-latest

我還有三個 .netcore Web 應用程序(productapp1、productapp2、productapp3),它們分配給“後端”和“前端”網路。請參閱下面的 dockerfile 內容:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
COPY dist /app
WORKDIR /app
EXPOSE 80/tcp
ENTRYPOINT [ "dotnet", "DockerSample.dll" ]

這些是我用來創建它們的命令:

podman create --name productapp1 --network backend,frontend docker-sample
podman create --name productapp2 --network backend,frontend docker-sample
podman create --name productapp3 --network backend,frontend docker-sample

我還有一個使用以下命令分配給“前端”網路的 haproxy 容器:

podman run -d --name loadbalancer --network frontend --volume $(pwd)/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg -p 3000:80 --privileged haproxy:latest

haproxy的配置如下:

defaults
       timeout connect 5000
       timeout client 50000
       timeout server 50000
frontend localnodes
       bind *:80
       mode http
       default_backend mvc
       stats enable
       stats uri /stats
       stats refresh 1s

backend mvc
       mode http
       balance roundrobin
       server mvc1 productapp1:80
       server mvc2 productapp2:80
       server mvc3 productapp3:80

通過查看 Web 應用程序的日誌,我可以確認它們按預期工作,沒有任何問題。請參閱以下其中一個 Web 應用程序容器的日誌:

warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
     Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
Applying Migrations...
Seed Data Not Required...
info: Microsoft.Hosting.Lifetime[0]
     Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
     Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
     Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
     Content root path: /app

問題是當我導航到 http://localhost:3000 時,我收到 503 Service Unavailable 消息。(沒有可用的伺服器來處理這個請求。)

我在其中一個 webapps 上執行了以下命令,並驗證了 mssqlserver 的埠是可訪問的:

podman exec -it productapp1 /bin/nc -zvw3 mssqlserver 1433

結果是:

DNS fwd/rev mismatch: mssqlserver != mssqlserver.dns.podman
mssqlserver [10.89.1.55] 1433 (?) open

但是,如果我為其中一個 Web 應用程序執行相同的命令:

podman exec -it productapp1 /bin/nc -zvw3 productapp2 80
podman exec -it productapp1 /bin/nc -zvw3 productapp2 5000

兩者都返回連接被拒絕消息:

DNS fwd/rev mismatch: productapp2 != productapp2.dns.podman
productapp2 [10.89.1.57] 80 (?) : Connection refused

DNS fwd/rev mismatch: productapp2 != productapp2.dns.podman
productapp2 [10.89.1.57] 5000 (?) : Connection refused

我想知道是否有人可以對此有所了解,因為我一直在搜尋和閱讀很多內容,但無法弄清楚為什麼這麼簡單的事情不應該起作用。

非常感謝。

謝謝。

更新 1:我忘了提到我也嘗試過使用以下配置的 haproxy:

defaults
  timeout connect 5000
  timeout client 50000
  timeout server 50000
frontend localnodes
  bind *:80
  mode http
  default_backend mvc
  stats enable
  stats uri /stats
  stats refresh 1s
   
backend mvc
  mode http
  balance roundrobin
  server mvc1 productapp1:5000
  server mvc2 productapp2:5000
  server mvc3 productapp3:5000

更新 2:以下是我的 launchSettings.json 的內容

{
 "iisSettings": {
   "windowsAuthentication": false,
   "anonymousAuthentication": true,
   "iisExpress": {
     "applicationUrl": "http://localhost:30113",
     "sslPort": 44371
   }
 },
 "profiles": {
   "IIS Express": {
     "commandName": "IISExpress",
     "launchBrowser": true,
     "environmentVariables": {
       "ASPNETCORE_ENVIRONMENT": "Development"
     }
   },
   "DockerSample": {
     "commandName": "Project",
     "launchBrowser": true,
     "applicationUrl": "https://localhost:5001;http://localhost:5000",
     "environmentVariables": {
       "ASPNETCORE_ENVIRONMENT": "Development"
     }
   }
 }
}

我還嘗試使用 -e ASPNETCORE_URLS=http://+:5000 創建容器,但仍然遇到相同的錯誤。

更新 3:將 launchSettings.json 更新為:

{
 "iisSettings": {
   "windowsAuthentication": false,
   "anonymousAuthentication": true,
   "iisExpress": {
     "applicationUrl": "http://localhost:30113",
     "sslPort": 44371
   }
 },
 "profiles": {
   "IIS Express": {
     "commandName": "IISExpress",
     "launchBrowser": true,
     "environmentVariables": {
       "ASPNETCORE_ENVIRONMENT": "Development"
     }
   },
   "DockerSample": {
     "commandName": "Project",
     "launchBrowser": true,
     "applicationUrl": "https://+:5001;http://+:5000",
     "environmentVariables": {
       "ASPNETCORE_ENVIRONMENT": "Development"
     }
   }
 }
}

更新 4:在 Michael Hampton 的幫助下,我設法為我的 Web 應用程序容器打開了 5000 埠。我的 Web 應用程序容器的日誌現在如下所示:

warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
     Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
info: Microsoft.Hosting.Lifetime[0]
     Now listening on: http://[::]:5000
info: Microsoft.Hosting.Lifetime[0]
     Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
     Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
     Content root path: /app

我也可以從其他容器 netcat 這個埠:

DNS fwd/rev mismatch: productapp2 != productapp2.dns.podman
productapp2 [10.89.1.82] 5000 (?) open

我現在可以按預期導航到我的網路應用程序。

您的日誌顯示該應用正在偵聽埠 5000,但您已將 haproxy 配置為嘗試在埠 80 上連接它!這是行不通的。重新配置 haproxy 以連接到正確的埠。

       server mvc1 productapp1:5000
       server mvc2 productapp2:5000
       server mvc3 productapp3:5000

您的日誌還說 Web 應用程序僅在偵聽 localhost,因此它只會接受來自其自己容器的連接,而不接受來自 pod 中的其他容器的連接。如何解決此問題取決於應用程序的具體情況。我想你應該看看Properties/launchSettings.json你是否正在使用 ASP.NET Core 範例應用程序。

引用自:https://serverfault.com/questions/1024587