CentOS 8环境下.Net Core Docker部署+Nginx转发

前言

.Net 开源已经很长时间了,.Net Core也发布好几年了,最近公司项目准备迁移到.Net Core平台,于是进行了一下跨平台的实操,发现还是有不少坑的,折腾了几天,终于把程序跑起来了,过程有点艰辛,查了不少资料,现在记录一下过程,以及把遇到的坑也记录一下,让后来人少走弯路。

部署环境

程序环境:.Net Core 3.1 VS2019 16.7
Docker: 19.03.7
Linux:CentOS 8.2.2004
Nginx: nginx/1.14.1

.Net Core 程序生成发布

程序就是很普通的新建.Net Core Web的官方示例。这里需要注意的要想在Docker 部署,需要在程序目录里增加Dockerfile文件,在项目右键:
在这里插入图片描述
添加完后会自动生成一个Dockerfile文件
在这里插入图片描述

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["MyDotnet/MyDotnet.csproj", "MyDotnet/"]
RUN dotnet restore "MyDotnet/MyDotnet.csproj"
COPY . .
WORKDIR "/src/MyDotnet"
RUN dotnet build "MyDotnet.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "MyDotnet.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyDotnet.dll"]

这个自动生成的Dockerfile稍微有点复杂,我们把他改造一下:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster
WORKDIR /app
EXPOSE 5000
COPY . /app
ENTRYPOINT ["dotnet", "MyDotnet.dll"]

如果这里就这么设置的话,放到CentOS里会有大问题,因为.Net Core默认通过localhost来访问的,但是在CentOS里的localhost并不是程序里的localhost,特别是在Docker里,配置Nginx转发的时候会是大坑,文章后面讲Docker部署的时候会详细说下IP地址的问题,这个问题困扰了我两天,后面才发现是这个原因导致的,所以这里我们需要把默认的localhost改成【http://*:5000】
改默认localhost网上有多种方法,可自行搜索,我说下我常用的两种,
*第一种:*改Program.cs文件:
把默认的

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

改成

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>()
                    .UseUrls("http://*:5000");
                });

*第二种:*直接在Dockerfile里指定参数:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster
WORKDIR /app
EXPOSE 5000
COPY . /app
ENTRYPOINT ["dotnet", "MyDotnet.dll","--urls","http://*:5000"]

到此我们的Dockerfile文件就算完成了。后面就是把程序打包发布的事了,可以把整个解决方案上传到CentOS里,也可以通过》项目》右键》发布》里选文件系统的方式,生成发布文件。注意,Dockerfile要放在程序目录里。
这里再顺带说下VS2019自带的Docker镜像上传到私人镜像仓库功能,本机要先安装Docker Desktop软件,这个主要用来生成镜像。生成完后可以设置仓库上传地址,以阿里云的容器镜像服务为例:
在这里插入图片描述
首先在VS2019里》项目》右键》发布》Docker容器注册表
在这里插入图片描述
在这里插入图片描述
这里选其他Docker容器注册表
在这里插入图片描述
填上阿里云镜像仓库的地址,用户名密码即可,这里有一个坑,需要注意一下:镜像地址不要把仓库名称带上,阿里云默认的就是带上仓库名,这里需要注意,因为VS2019上传的时候会自动把项目名称当作仓库名。
然后点发布就行了,系统会根据Dockerfile里的描述把程序依赖的运行环境下载,然后生成镜像,并上传到阿里云。

CentOS部署程序

由于.Net Core默认是跨平台的,在CentOS里下载对应的.Net Core程序运行环境即可,操作相当简单,这里重点推荐微软的官方文档(中文),写的非常详细了,很多人说.Net 生态不行,其实,微软已经做的非常好了。
CentOS部署.Net Core程序:https://docs.microsoft.com/zh-cn/dotnet/core/install/linux-centos
VS2019使用Docker:https://docs.microsoft.com/zh-cn/visualstudio/containers/overview?view=vs-2019
我这里就不详细描述了,发个截图吧
在这里插入图片描述
下面重点说下Docker的部署

Docker部署

先把Docker安装在CentOS里,直接下载最新的即可:

$ sudo yum install docker-ce  #由于repo中默认只开启stable仓库,故这里安装的是最新稳定版19.03.7
$ sudo yum install <FQPN>  # 例如:sudo yum install docker-ce-19.03.7.ce

安装完成:
在这里插入图片描述
几个Docker 常用的命令

$ docker images #列出所有的镜像
$ docker ps #列出所有的在运行的容器 加上 -a 列出所有的容器
$ docker start id #运行某个容器
$ docker stop id #停止某个容器
$ docker restart id #重启某个容器
$ docker rm id #删除某个容器
$ docker rmi id #删除某个镜像
$ docker exec -it id /bin/bash #进入某个容器内部
$ docker build -t counter-image -f Dockerfile . #创建镜像  注意后面的. 不要漏了
$ docker create --name core-counter counter-image #使用counter-image镜像创建容器并命名为core-counter
$ docker run --name core-counter -p 8080:80 -d counter-image #使用counter-image镜像创建容器并命名为core-counter 同时运行该容器

接下来开始部署程序,这里可以直接把上面上传到阿里云镜像仓库的镜像拉下来,直接运行,这里就不演示了,直接把编译好的程序文件上传到CentOS进行手动生成镜像。
首先进入到程序目录,目录里应该有刚才配置好的Dockerfile,运行:

$ docker build -t mydotnet-image -f Dockerfile .

这里如果是第一次部署会去下载Dockerfile里配置的程序运行环境包,时间会比较久。生成完后通过docker images 查看镜像是否创建成功
在这里插入图片描述
截图可见,包含了两个.Net Core的运行环境,这里其实只要aspnet 这一个就行,还有就是刚才创建的mydotnet-image,说明镜像已经创建成功了。
接下来创建容器:

$ docker run --name mydotnet -p 5000:5000 -d mydotnet-image

解释一下这个命令:–name 就是容器名称,
-p 将容器里的5000端口映射到CentOS的5000端口,冒号前面的为宿主机端口,后面为容器端口,切记这里的端口需要跟Dockerfile里的一致
再通过docker ps 查看容器是否正常启动了
在这里插入图片描述
可以看到mydotnet 已经运行起来了。接下来测试一下程序是否正常,在CentOS里通过

curl -I localhost:5000

可以看到程序已经运行了
在这里插入图片描述
此时通过IP地址去访问会发现访问失败,这是因为需要在防火墙里开放5000端口:

$ firewall-cmd --zone=public --add-port=5000/tcp --permanent
$ firewall-cmd --reload

再通过IP地址去访问,就可以正常了。
事情进行到这里仿佛一切都在按计划中在走,但在我的实际操作中却遇到了不少问题,先解释一下Docker在CentOS里是一个怎样的存在
在这里插入图片描述
Docker 有四种网络模式:host模式,container模式,none模式,bridge模式,默认使用的是bridge模式(如上图所示就是网桥模式),这里简单解释一下,详细的可以自行搜索一下。

host模式	–net=host	容器和宿主机共享网络空间。
container模式	–net=container:NAME_or_ID	容器和另外一个容器共享网络空间。 
none模式	–net=none	容器有独立的网络空间,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。
bridge模式	–net=bridge	(默认为该模式)

这个网络比较复杂,这也是为啥文章开头说此localhost非彼localhost,包括后面配置Nginx转发也要注意这一点。再看上面的容器运行的代码里配置的端口映射就能明白了:就是将Docker里的172.17.0.2 5000端口映射到CentOS里的5000,这就意味着每一个容器对应宿主机的端口,如果有很多容器就会造成端口的滥用。
到这里.Net Core程序就正常在CentOS里跑起来了,接下来就考虑做Nginx转发

Nginx配置

既可以直接在CentOS里安装Nginx,设置好转发端口,记得这里配置的应该是CentOS本机的地址:http://localhost:5000,
如果要在Docker里安装Nginx,则应该配置Docker内部的地址:http://172.17.0.2:5000,这一步如果没有配置正确就会导致服务无法访问。
下面重点讲Docker里安装Nginx,Nginx有官方镜像,所以这里直接拉取最新的就行:

$ docker pull nginx:latest

然后直接生成一个容器:

$ docker run --name mynginx -p 8080:80 -d nginx

查看一下
在这里插入图片描述
没有问题,
在这里插入图片描述
下面配置nginx转发,有两种方案,可以直接通过docker exec 命令进入到容器内部,再通过vim 命令去修改nginx的配置,第二种方案是通过挂载的方式,将自己写好的nginx.conf挂载到容器里,我使用的是挂载的方案,通过命令参数-v

$ docker run --name mynginx8083 -d -p 8083:8083  -v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf  -v /data/nginx/logs:/var/log/nginx -d docker.io/nginx

上述命令里两个-v 分别是将nginx.conf 和log文件挂载到nginx容器里,这里注意会重新生成一个容器,映射的宿主端口号为8083。
到此就实现了在容器里分别部署.Net Core程序和Nginx服务,并实现了Nginx的反向代理另一个容器里的.net Core功能。

结语

生命在于折腾,之前只是听别人说过.Net Core的跨平台如何如何快,.Net Core容器自适应,只有自己去实际操作一遍才能明白整个流程的逻辑,还有可以发现别人可能遇到了,但没有记录下来的一些坑。操作到这里只是实现了Docker的部署,流程还是很复杂的,接下来要实现的就是CI/CD,然后进一步实现云原生。
整体来说,.Net Core实现了真正意义的跨平台,也给更多的.Neter带来了希望,11月中旬的.Net 5正式版就要发布了,希望能带来更大的惊喜。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值