懂过山 發表於 2019-6-15 18:01:00

ASP.NET Core部署系列二:发布到CentOS上

<p><span style="color: rgba(45, 148, 222, 1); font-size: 18pt">前言</span>:</p>
<p>&nbsp; 在上一节中,通过一系列的步骤,已经将项目部署到IIS上,虽然遇到了一些问题,但最终解决并成功运行了。而在这一节中,将尝试通过linux系统的环境下,部署项目,实现Net Core跨平台的亮点。</p>
<p>虽然网上已经有很多关于asp.net core在linux下的部署教程了,但我还是想写一篇,主要增强我自己的记忆,同时分享下我部署遇到的坑。</p>
<p>我在我电脑win7的操作系统中用来虚拟机建了个CentOS7,来演示,我们的项目如何发布在Linux上运行。</p>
<p><span style="color: rgba(45, 148, 222, 1); font-size: 18pt">开始</span>:</p>
<p><span style="font-family: 楷体; font-size: 14pt; color: rgba(45, 148, 222, 1)">一、安装.Dotnet Core 2.2</span></p>
<p>&nbsp; Linux上运行Dotnet Core程序的前提是安装Dotnet Core Runtime,如果想要在Linux做 .NET Core的开发和编译工作,那么需要安装 Dotnet Core SDK。Dotnet Core SDK中包括了Dotnet Core Runtime,所以这里就直接安装了<span lang="EN-US">Dotnet Core SDK</span></p>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615164520341-1759462081.png" alt=""></p>
<p><span lang="EN-US">&nbsp; Step 1:安装<span lang="EN-US">Dotnet产品的必要前提</span></span></p>
<p>&nbsp; 在安装<span lang="EN-US">Dotnet Core前,需要注册<span lang="EN-US">Microsoft签名密钥并添加<span lang="EN-US">Microsoft产品提要,每台机器只需注册一次,执行如下命令:</span></span></span></p>
<div class="cnblogs_code">
<pre>sudo rpm -Uvh https:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm</span></pre>
</div>
<p>&nbsp; Step 2:安装Dotnet Core&nbsp;SDk,执行下列命令</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">sudo yum update
y
sudo yum install dotnet</span>-sdk-<span style="color: rgba(128, 0, 128, 1)">2.2</span><span style="color: rgba(0, 0, 0, 1)">
y</span></pre>
</div>
<pre>大家注意,会有两个“<span lang="EN-US">y”的原因是,命令执行的中途停顿了,让你确认下是否进行安装,你要输入“<span lang="EN-US">y”确认安装才会执行安装<br><br></span></span>安装完后,我们输入如下命令看下是否安装成功</pre>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615164930802-494875697.png" alt=""></p>
<p><span style="font-family: 楷体; font-size: 14pt; color: rgba(45, 148, 222, 1)">二、部署Asp.net Core 应用程序</span></p>
<p><span style="font-family: 宋体">&nbsp; <strong>在CentOS系统中,新建publish文件夹</strong></span></p>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615165147367-987774383.png" alt=""></p>
<p>&nbsp; 上传上一节发布的文件到至/home/publish/。</p>
<p>&nbsp; 这边我使用了Xftp进行文件的上传。(如果是在本地虚拟机操作的话,也可以直接复制到系统对应的文件夹目录下)</p>
<p>&nbsp; <strong>进入目录:cd publish</strong></p>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615165405145-1868405077.png" alt=""></p>
<p>&nbsp; &nbsp;<strong>检查是否可以运行:dotnet LCzarCms.Admin.dll</strong></p>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615165437438-917731895.png" alt=""></p>
<p>&nbsp; 如果出现这些信息则表示成功运行</p>
<p>&nbsp;<img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615165453321-1804454540.png" alt=""></p>
<p>&nbsp; 到此,项目就运行成功了,这时候我们是无法访问到这个页面的,这时候我们需要部署一个<span lang="EN-US">web容器来进行转发,我们可能还要安装&nbsp;nginx&nbsp;、配置我们的&nbsp;FireWall&nbsp;以及配置守护服务&nbsp;Supervisor&nbsp;等等</span></p>
<p><span style="font-family: 楷体; font-size: 14pt; color: rgba(45, 148, 222, 1)" lang="EN-US">三、配置Nginx托管</span></p>
<p><span lang="EN-US">&nbsp; 微软官方提供的https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-2.2#monitor-the-app,把dotnet创建成一个服务</span></p>
<p>&nbsp;<strong> 安装nginx</strong></p>
<div class="cnblogs_code">
<pre>curl -onginx.rpm http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm</span></pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615170106969-330192408.png" alt=""></p>
<div class="cnblogs_code">
<pre> rpm -ivh nginx.rpm</pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615170144495-1390746366.png" alt=""></p>
<div class="cnblogs_code">
<pre>yum install nginx</pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615170216719-1658333328.png" alt=""></p>
<p>&nbsp; <strong>启动 </strong><span lang="EN-US"><strong>Nginx</strong>:</span></p>
<div class="cnblogs_code">
<pre>systemctl start nginx</pre>
</div>
<p>&nbsp; <strong>设置开机启动</strong>(<span lang="EN-US">linux宕机、重启会自动运行<span lang="EN-US">nginx不需要连上去输入命令):</span></span></p>
<div class="cnblogs_code">
<pre>systemctl enable nginx</pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615170321208-468281574.png" alt=""></p>
<p><span style="font-family: 楷体; font-size: 14pt; color: rgba(45, 148, 222, 1)">四、配置防火墙</span></p>
<p>&nbsp; <strong>开放80端口</strong>:</p>
<div class="cnblogs_code">
<pre>firewall-cmd --zone=<span style="color: rgba(0, 0, 255, 1)">public</span> --add-port=<span style="color: rgba(128, 0, 128, 1)">80</span>/tcp –permanent</pre>
</div>
<p>&nbsp; <strong>重启防火墙以使配置即时生效</strong>:</p>
<div class="cnblogs_code">
<pre>systemctl restart firewalld</pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615170501351-1892243798.png" alt=""></p>
<p>&nbsp; <strong>测试<span lang="EN-US">nginx是否可以访问</span></strong></p>
<p><span lang="EN-US"><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615170517984-2072450028.png" alt=""></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 楷体; font-size: 14pt; color: rgba(45, 148, 222, 1)">五、配置<span lang="EN-US">Nginx对<span lang="EN-US">ASP.net Core 应用的转发</span></span></span></p>
<p><span lang="EN-US"><span lang="EN-US">&nbsp; <strong>修改Nginx的default.conf文件</strong></span></span></p>
<p>&nbsp;<img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615170621321-2053993723.png" alt=""></p>
<p>&nbsp; 将文件内容替换为:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">server {
    listen </span><span style="color: rgba(128, 0, 128, 1)">80</span><span style="color: rgba(0, 0, 0, 1)">;
    location </span>/<span style="color: rgba(0, 0, 0, 1)"> {
      proxy_pass http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">localhost:5000;</span>
      proxy_http_version <span style="color: rgba(128, 0, 128, 1)">1.1</span><span style="color: rgba(0, 0, 0, 1)">;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection keep</span>-<span style="color: rgba(0, 0, 0, 1)">alive;
      proxy_set_header Host $host;
      proxy_cache_bypass $http_upgrade;
    }
}</span></pre>
</div>
<p>&nbsp; 进行修改覆盖</p>
<p>&nbsp; <strong>重新加载,即时生效</strong>:</p>
<div class="cnblogs_code">
<pre>nginx -s reload</pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615170820720-44536001.png" alt=""></p>
<p>&nbsp; 再次运行ASP.NET Core应用程序</p>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615170838729-516777564.png" alt=""></p>
<p>&nbsp; 但是,测试我们再次浏览运行的时候,会出现如下这种情况:</p>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615170926935-691393282.png" alt=""></p>
<p>&nbsp; 这是什么情况?经过后续了解,这个问题是由于SELinux保护机制所导致,我们需要将nginx添加至SELinux的白名单</p>
<p>&nbsp; 接下来我们通过一些命令解决这个问题</p>
<div class="cnblogs_code">
<pre>①&nbsp;&nbsp;&nbsp;yum install policycoreutils-python</pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615171012901-492396132.png" alt=""></p>
<div class="cnblogs_code">
<pre>②   sudo cat /<span style="color: rgba(0, 0, 255, 1)">var</span>/log/audit/audit.log | grep nginx | grep denied | audit2allow -M mynginx</pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615171110113-1588533631.png" alt=""></p>
<div class="cnblogs_code">
<pre>③   sudo semodule -i mynginx.pp</pre>
</div>
<p>&nbsp; 我们再次访问运行一下:</p>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615171203441-903715426.png" alt=""></p>
<p>&nbsp; 这次已经可以成功的运行起来了。</p>
<p>&nbsp; <strong>至此基本完成了部署</strong>。</p>
<p><span style="color: rgba(255, 0, 0, 1)">但是,我们还是存在着其他的问题:</span></p>
<p>&nbsp; 1.<strong><span lang="EN-US">ASP.NET Core</span></strong><strong>应用程序运行在</strong><strong><span lang="EN-US">shell</span></strong><strong>之中,如果关闭</strong><strong><span lang="EN-US">shell</span></strong><strong>则会发现</strong><strong><span lang="EN-US">ASP.NET Core</span></strong><strong>应用被关闭,从而导致应用无法访问,这种情况当然是我们不想遇到的,而且生产环境对这种情况是零容忍的。</strong></p>
<p>&nbsp; 2.<strong>如果</strong><strong><span lang="EN-US">ASP.NET Core</span></strong><strong>进程意外终止那么需要人为连进</strong><strong><span lang="EN-US">shell</span></strong><strong>进行再次启动,往往这种操作都不够及时。</strong></p>
<p>&nbsp; 3.<strong>如果服务器宕机或需要重启我们则还是需要连入</strong><strong><span lang="EN-US">shell</span></strong><strong>进行启动。</strong></p>
<p>&nbsp; 为了解决这些问题,我们需要有一个程序来监听<span lang="EN-US">ASP.NET Core 应用程序的状况。</span></p>
<p>&nbsp; 那么要解决这些问题,我们就必须要实现这么一个功能:如果ASP.NET Core 意外终止,那么我们要自动重启;如果服务器服务器重启后,我们要有个类似脚本命令一样,自动执行 dotnet 命令。现在正好有个基于&nbsp;Python&nbsp;开发的工具&nbsp;Supervisor&nbsp;可以解决我们上述问题</p>
<p><span style="font-family: 楷体; font-size: 14pt; color: rgba(45, 148, 222, 1)" lang="EN-US">六、配置Supervisor守护服务</span></p>
<p>&nbsp; 在应用程序停止运行的时候立即重新启动。这边我们用到了Supervisor这个工具,Supervisor使用Python开发的。</p>
<p>&nbsp;<span style="font-size: 16px"><strong> 安装Supervisor</strong></span>:</p>
<div class="cnblogs_code">
<pre>yum install python-setuptools</pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615171828889-638782086.png" alt=""></p>
<div class="cnblogs_code">
<pre>easy_install supervisor</pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615171855299-1195992512.png" alt=""></p>
<p>&nbsp; <span style="font-size: 16px"><strong>配置Supervisor</strong></span>:</p>
<p>①运行supervisord 服务的时候,需要指定 Supervisor 配置文件,所以,先通过如下命令创建目录,以便让 supervisor 成功加载默认配置:</p>
<div class="cnblogs_code">
<pre>mkdir /etc/supervisor</pre>
</div>
<p>②目录创建成功后, 通过 echo_supervisord_conf 程序(用来生成初始配置文件,文件名可以自定义)来初始化一个配置文件:&nbsp;</p>
<div class="cnblogs_code">
<pre>echo_supervisord_conf &gt; /etc/supervisor/supervisord.conf</pre>
</div>
<p>③通过vim命令修改创建好的supervisord.conf配置信息:</p>
<div class="cnblogs_code">
<pre>vi /etc/supervisor/supervisord.conf</pre>
</div>
<p>④最下边找到如下文本片段:</p>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615172045505-288073919.png" alt=""></p>
<p>&nbsp; 修改为:</p>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615172056907-850403774.png" alt=""></p>
<p>&nbsp;<span style="font-size: 16px"><strong> 为我们部署的.NET Core添加进程配置文件</strong></span>:</p>
<p>①创建配置文件LCzarCmsAdmin.ini(文件名自定义)</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">
command</span>=dotnet /root/publish/<span style="color: rgba(0, 0, 0, 1)">LCzarCms.Admin.dll
directory</span>=/root/publish/<span style="color: rgba(0, 0, 0, 1)">
autostart</span>=<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
autorestart</span>=<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
stderr_logfile</span>=/<span style="color: rgba(0, 0, 255, 1)">var</span>/log/<span style="color: rgba(0, 0, 0, 1)">LCzarCms.err.log
stdout_logfile</span>=/<span style="color: rgba(0, 0, 255, 1)">var</span>/log/LCzarCms.<span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)">.log
environment</span>=ASPNETCORE_ENVIRONMENT=<span style="color: rgba(0, 0, 0, 1)">Production
user</span>=<span style="color: rgba(0, 0, 0, 1)">root
stopsignal</span>=INT</pre>
</div>
<p>②在/etc/supervisor/目录下创建一个文件夹conf.d</p>
<div class="cnblogs_code">
<pre>mkdir /etc/supervisor/conf.d/</pre>
</div>
<p>&nbsp; 将刚创建的配置文件LCzarCmsAdmin.ini移到conf.d文件夹下</p>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615172339866-884463152.png" alt=""></p>
<p>&nbsp; 如果服务已经启动,则需要使用&nbsp;supervisorctl reload&nbsp;命令来使新的配置生效,当然,我们这里并没有启动,所以不需要这一步。</p>
<p>&nbsp; <strong>启动 Supervisor 服务</strong></p>
<div class="cnblogs_code">
<pre>supervisord -c /etc/supervisor/supervisord.conf</pre>
</div>
<p>&nbsp;<strong> 启动服务后,我们可以检测看一下</strong>:</p>
<div class="cnblogs_code">
<pre>ps -ef | grep LCzarCms.Admin.dll</pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615172542403-1508420852.png" alt=""></p>
<p>&nbsp; 这个时候, 我们已经不需要使用dotnet命令运行程序, 同样可以访问我们部署的.NET Core程序了。</p>
<p>&nbsp; <strong>至此关于ASP.NET Core应用程序的守护即配置完成</strong>。</p>
<p><span style="color: rgba(45, 148, 222, 1); font-family: 楷体; font-size: 14pt">七、配置Supervisor开机启动</span>:</p>
<p>①进入/usr/lib/systemd/system/目录,并创建supervisord.service文件(或者在本地写好了再通过ftp工具传输到指定目录下)</p>
<div class="cnblogs_code">
<pre>vi /usr/lib/systemd/system/supervisord.service</pre>
</div>
<p>&nbsp; 修改文件</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">
Description</span>=<span style="color: rgba(0, 0, 0, 1)">Supervisor daemon


Type</span>=<span style="color: rgba(0, 0, 0, 1)">forking
ExecStart</span>=/usr/bin/supervisord -c /etc/supervisor/<span style="color: rgba(0, 0, 0, 1)">supervisord.conf
ExecStop</span>=/usr/bin/<span style="color: rgba(0, 0, 0, 1)">supervisorctl $OPTIONS shutdown
ExecReload</span>=/usr/bin/<span style="color: rgba(0, 0, 0, 1)">supervisorctl $OPTIONS reload
KillMode</span>=<span style="color: rgba(0, 0, 0, 1)">process
Restart</span>=on-<span style="color: rgba(0, 0, 0, 1)">failure
RestartSec</span>=42s</pre>
</div>
<p>②设置开机启动</p>
<p>&nbsp; 激活开机启动:</p>
<div class="cnblogs_code">
<pre>systemctl enable supervisord.service</pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615172847010-292877124.png" alt=""></p>
<p>&nbsp; 启动supervisor进程:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">systemctl start supervisord.service

systemctl daemon</span>-reload</pre>
</div>
<p>&nbsp; 验证一下是否为开机启动:</p>
<div class="cnblogs_code">
<pre>systemctl <span style="color: rgba(0, 0, 255, 1)">is</span>-enabled supervisord</pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1576550/201906/1576550-20190615173001736-962815921.png" alt=""></p>
<p>&nbsp; 重启,测试是否可以开机自启</p>
<p>&nbsp;<strong> 好了。最终也成功的在重启之后,可以访问地址。</strong></p>
<p><span style="color: rgba(45, 148, 222, 1); font-size: 18pt">总结</span>:</p>
<p>&nbsp; 1.在虚拟机上安装CentOS7操作系统,这里就不做具体的安装内容了,可以参考VMwear安装Centos7</p>
<p>&nbsp; 2.学习了linux(CentOS) 环境下,新建、删除、移动文件夹和文件的命令。同时,Linux下路径是区分目录大小写的</p>
<p>&nbsp; 3.很多东西都是翻阅了网上大神的资料加上自己的实践理解总结记录的。如果有不对的或不理解的地方,希望大家可以指正和多多交流</p>

</div>
<div id="MySignature" role="contentinfo">
    <div>作者:艾三元</div>
<div>出处:https://www.cnblogs.com/i3yuan/</div>
<div>关注:推荐扫码关注公众号</div>
<img src="https://images.cnblogs.com/cnblogs_com/i3yuan/1381525/o_210326143458wxcode.jpg" style="width: 105px">
    <div>本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 </div><br><br>
来源:https://www.cnblogs.com/i3yuan/p/11025672.html
頁: [1]
查看完整版本: ASP.NET Core部署系列二:发布到CentOS上