Linux中以单容器部署Nginx+ASP.NET Core

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: Linux中以单容器部署Nginx+ASP.NET Core引言  正如前文提到的,强烈推荐在生产环境中使用反向代理服务器转发请求到Kestrel Http服务器,本文将会实践将Nginx --->ASP.NET Core 部署架构容器化的过程。

Linux中以单容器部署Nginx+ASP.NET Core
引言
  正如前文提到的,强烈推荐在生产环境中使用反向代理服务器转发请求到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应用
1
2
3
4
5
mkdir app
cd app
dotnet new web
dotnet restore
dotnet build
  之后将项目发布到指定目录(dotnet publish), 发布产生的文件将会用于镜像打包。

构建镜像
  本次将以 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.

因为该基础镜像不包含ASP.NET Core框架组件。
  
  本次Dokefile的定义将会包含nginx,在容器内启用Nginx标准配置代理请求到Kestrel:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 设置工作目录,放置ASP.NET Core WebApp部署包

  Line 9-10 设置启动脚本

  Line 12-13 设置nginx配置文件

  Line 15-16 设置ASP.NETCore Kestrel在5000端口上监听, 暴露5000,80 端口给容器外部

  Line 18 稍后给出启动脚本

tip: 需要理解容器内是一个独立的linux环境,Dockfile中EXPOSE用于指示容器打算暴露的端口。

    这里可只暴露80端口给外部,但是必须给ASPNETCORE_URLS定义一个非80端口,作为容器内kestrel监听端口。

最终(tree -L 1)输出的app目录结构如下

1
2
3
4
5
6
7
8
9
10
11
12
.
├── 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 创建文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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

  总之,这个文件定义了Nginx在80端口监听外部请求,并将请求转发给同一容器的5000端口。

启动脚本
  对于Docker容器,只能使用一个CMD(或ENTRYPOINT定义),但是这种反向代理配置需要启动Nginx和Kestrel, 所以我们定义一个脚本去完成这两个任务

1
2
3

!/bin/bash

service nginx start
dotnet /app/app.dll

构建镜像
  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

1
2
3
4
5
6
7
8
9
10
11
12
13

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部分配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
---- 截取自 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。

作者:Julian_酱

相关文章
|
10天前
|
弹性计算 运维 监控
快速部署 Nginx 社区版
Nginx是一个高性能的HTTP和反向代理服务器。Nginx在计算巢上提供了社区版服务,您无需自行配置云主机,即可在计算巢上快速部署Nginx服务、实现运维监控,从而方便地基于Nginx搭建您自己的应用。本文介绍使用如何通过计算巢快速部署Nginx社区版。
快速部署 Nginx 社区版
|
8天前
|
应用服务中间件 nginx Docker
docker应用部署---nginx部署的配置
这篇文章介绍了如何使用Docker部署Nginx服务器,包括搜索和拉取Nginx镜像、创建容器并设置端口映射和目录映射,以及如何创建一个测试页面并使用外部机器访问Nginx服务器。
|
1月前
|
NoSQL 关系型数据库 Redis
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
mall在linux环境下的部署(基于Docker容器),docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongodb、minio详细教程,拉取镜像、运行容器
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
|
8天前
|
安全 Linux 虚拟化
10-26|我现在加了,在容器内也可以改时间了,但是我在容器内改了,为什么会影响到linux机子啊
10-26|我现在加了,在容器内也可以改时间了,但是我在容器内改了,为什么会影响到linux机子啊
|
1月前
|
负载均衡 网络协议 应用服务中间件
web群集--rocky9.2源码部署nginx1.24的详细过程
Nginx 是一款由 Igor Sysoev 开发的开源高性能 HTTP 服务器和反向代理服务器,自 2004 年发布以来,以其高效、稳定和灵活的特点迅速成为许多网站和应用的首选。本文详细介绍了 Nginx 的核心概念、工作原理及常见使用场景,涵盖高并发处理、反向代理、负载均衡、低内存占用等特点,并提供了安装配置教程,适合开发者参考学习。
|
2月前
|
Java 应用服务中间件 nginx
【Azure Spring Apps】Spring App部署上云遇见 502 Bad Gateway nginx
【Azure Spring Apps】Spring App部署上云遇见 502 Bad Gateway nginx
|
2月前
|
应用服务中间件 Linux PHP
【Azure 应用服务】App Service For Linux 环境中,如何修改 Nginx 配置中 server_name的默认值 example.com
【Azure 应用服务】App Service For Linux 环境中,如何修改 Nginx 配置中 server_name的默认值 example.com
|
2月前
|
Linux C# C++
【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务
|
2月前
|
负载均衡 应用服务中间件 Linux
在Linux中,Nginx如何实现负载均衡分发策略?
在Linux中,Nginx如何实现负载均衡分发策略?
|
2月前
|
缓存 负载均衡 应用服务中间件
在Linux中,LVS与nginx有何区别?
在Linux中,LVS与nginx有何区别?
下一篇
无影云桌面