首頁  >  文章  >  運維  >  怎麼在Linux系統中以單容器安裝Nginx+ASP.NET Core

怎麼在Linux系統中以單容器安裝Nginx+ASP.NET Core

little bottle
little bottle轉載
2019-04-30 11:39:493081瀏覽

建議在生產環境中使用反向代理伺服器轉送請求到Kestrel Http伺服器,本文將會實踐將Nginx --->ASP.NET Core 部署架構容器化的流程。

Nginx->ASP.NET Coe部署架構容器化

  在Docker部署Nginx--->ASP.NETCore 有兩種選擇, 第一種是在單容器內部署Nginx ASP.NET Core, 這是本文著重要講述的,另一種是以獨立容器分別部署Nginx和ASP.NET Core,容器之間透過Docker內建的network bridge完成通訊(請關注後續博文)。

 本次實作將會使用.NET Core CLI 建立預設的web應用程式

mkdir app
cd app
dotnet new web
dotnet restore
dotnet build

  之後將專案發佈到指定目錄(dotnet publish), 發佈產生的檔案將會用於鏡像打包。

相關教學:Linux影片教學

 建構鏡像

  本次將以ASP.NETCore Runtime Image【mcr. microsoft.com/dotnet/core/aspnet:2.2】 作為基礎鏡像, 鏡像包含.NET Core Runtime、ASP.NET Core框架元件、依賴項,鏡像為生產部署做了一些最佳化。

坑1:本次部署的是web app,不要使用【mcr.microsoft.com/dotnet/core/runtime:2.2】作為基礎鏡像,啟動容器會報錯:

It was not possible to find any compatible framework version

The specified framework 'Microsoft.AspNetCore.App', version '2.2.0' was not found.

#- Check application dependencies and dependencies and target a framework version installed at:

/usr/share/dotnet/

- Installing .NET Core prerequisites might help resolve this problem:

https://go.

https://go. microsoft.com/fwlink/?LinkID=798306&clcid=0x409

- The .NET Core framework and SDK can be installed from:

https://aka.ms/dotnet-download


#因為該基礎映像不包含ASP.NET Core框架元件。

  本次Dokefile的定義將會包含nginx,在容器內啟用Nginx標準配置代理請求到Kestrel:

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
RUN apt-get update
RUN apt-get install -y nginx
WORKDIR /app
COPY bin/Debug/netcoreapp2.2/publish .
COPY ./startup.sh .
RUN chmod 755 /app/startup.sh
RUN rm /etc/nginx/nginx.conf
COPY nginx.conf /etc/nginx
 ENV ASPNETCORE_URLS http://+:5000
EXPOSE 5000 80
 CMD ["sh", "/app/startup.sh"]

  Line 1        指定基礎鏡像

#  Line 3-4     從Debian package management store安裝Nginx

  Line 6-7     設定工作目錄,並放置套件

#  Line 12-13 設定nginx設定檔

  Line 15-16 設定ASP.NETCore Kestrel在5000埠上監聽, 暴露5000,80 埠給容器外部

 後面給出啟動腳本

tip: 需要理解容器內是一個獨立的linux環境,Dockfile中EXPOSE用於指示容器打算暴露的連接埠。 

       

這裡可只暴露80埠給外部,但是必須為ASPNETCORE_URLS定義一個非80埠,作為容器內kestrel監聽埠。

    最終(tree -L 1)輸出的app目錄結構如下
.
├── app.csproj
├── appsettings.Development.json
├── appsettings.json
├── bin
├── Dockerfile
├── nginx.conf
├── obj
├── Program.cs
├── Properties
├── Startup.cs
└── startup.sh

 Nginx設定

  建立上述Dockerfile中所需的nginx設定檔,在同一目錄,vim nginx.conf 建立檔案:

worker_processes 4;
events { worker_connections 1024; }
 http {
    sendfile on;
    upstream app_servers {
        server 127.0.0.1:5000;
    }
    server {
        listen 80;
        location / {
            proxy_pass         http://app_servers;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        }
    }
}

  Line 8-10    定義一組伺服器(這裡只有webapp),資源名稱(app_servers)可用在本檔案任意位置。

  Line 13       通知Nginx在80埠監聽

  Line 15-22  指示所有的請求都需要被代理到app_servers#gin

#  總埠在這個檔案定義了Nx監聽外部請求,並將請求轉送給同一容器的5000連接埠。

 啟動腳本

  對於Docker容器,只能使用一個CMD(或ENTRYPOINT定義),但是這種反向代理配置需要啟動Nginx和Kestrel, 所以我們定義一個腳本去完成這兩個任務    
#!/bin/bash
service nginx start
dotnet /app/app.dll

相關教學:

docker影片教學

 建置映像

  docker build -t example/hello- nginx .

  該映像名稱為example/hello-nginx  觀察輸出,會看到Dockerfile 中定義的每一步輸出。

  此映像建構Dockerfile與vs docker tool產生的dockerfile進行對比,該檔案產生的映像更小,充分利用了鏡像分層的概念。

 運行映像

  docker run --name test -it -d -p 8080:80 example/test

  该容器名称为test, 现在可从 http://localhost:8080 端口访问webapp, 通过curl -s -D - localhost:8080 -o /dev/null 验证

  通过shell终端进入容器内部, 可进一步分别探究Nginx和Kestrel服务:

  docker exec -it test bash

# curl -s -D - localhost:80 -o /dev/null
HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Fri, 24 Feb 2017 14:45:03 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked

# curl -s -D - localhost:5000 -o /dev/null
HTTP/1.1 200 OK
Date: Fri, 24 Feb 2017 14:45:53 GMT
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Server: Kestrel

tip:对于正在运行的容器,可使用docker exec -it  [container_id] [command]  进入容器内部探究容器

  对于启动失败的容器,可使用docker logs [container_id]  查看容器输出日志

了解一下docker的网络基础知识:

  当Docker守护进程以其默认的配置参数在宿主机启动时,会创建一个名为docker0的Linux网桥设备, 该网桥会自动分配满足标准的私有IP段的随机IP直至和子网, 该子网决定了所有新创建容器将被分配的容器IP地址所属网段。

可使用 docker inspect [container_id] 查看network部分配置:

---- 截取自 docker inspect [container_id]的输出---

"Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "a74331df40dc8c94483115256538304f1cbefe9f65034f20780a27271e6db606",
                    "EndpointID": "4f35ea62c1715bd9f6855bc82ada06e1bf5e58291dabb42e92ebc9552c6f017b",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null
                }
            }

  其中列出的NetworkID 正是 docker network ls 名为bridge的网桥, 这便是默认建立的docker0 网桥(docker inspect networkid 可继续探究)。

正如上面所说,ASP.NET Core有两种容器化反向代理部署架构,后续将会实践以独立容器分别部署Nginx、ASP.NET Core。 

以上是怎麼在Linux系統中以單容器安裝Nginx+ASP.NET Core的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:cnblogs.com。如有侵權,請聯絡admin@php.cn刪除