摘要 考慮我們為什麼要選擇.NET Core? 因為它面向的是高性能伺服器開發,拋卻了 AspNet 的臃腫組件,非常輕量,加上微軟的跨平臺戰略,對 Docker 的親和性,對於開發人員也非常友好,所以整體環境來說是健康發展的,未來技術決策時 .Net Core 也有很大的優勢。那既然.NET Co ...
摘要
考慮我們為什麼要選擇.NET Core?
因為它面向的是高性能伺服器開發,拋卻了 AspNet 的臃腫組件,非常輕量,加上微軟的跨平臺戰略,對 Docker 的親和性,對於開發人員也非常友好,所以整體環境來說是健康發展的,未來技術決策時 .Net Core 也有很大的優勢。那既然.NET Core 本身具有跨平臺 (Windows、Mac OSX、Linux) 特性,而之前我們的網站一直是部署在 Windows Server 伺服器上,這個章節我們不妨學習在生產環境下,怎麼將我們的網站應用程式切換部署在Linux系統上。
環境說明
- CentOS / 7.1 (64bit) (Linux操作系統)
- MySQL5.7(網站應用資料庫)
- .NET Core SDK 2.0.0(網站應用環境)
- Nginx(反向代理伺服器)
- Supervisor(管理網站應用守護進程)
- Symantec SSL(功能變數名稱型證書,提供https協議服務)
這裡資料庫由SQL Server改為MySQL,因為SQL Server 2017對運行環境要求的配置比較高,我這1G記憶體的低端雲伺服器傷不起,o(╥﹏╥)o
工具介紹
- Xshell 5(終端模擬軟體)
- WinSCP(圖形化SFTP客戶端)
安裝 CentOS
首先將雲伺服器,重新安裝操作系統,選擇CentOS / 7.1 x86_64 (64bit)版本的鏡像,並設置訪問用戶名和密碼,系統會幫我們自動安裝好CentOS系統。接下來我們配置一下Xshell和WinSCP,使得這2個工具能正常訪問並管理操作系統,相關的配置和使用方法,請大家自行百度。
完成上述操作後,首先查看一下硬碟情況:
fdisk -l
發現我們的第二塊磁碟雲磁碟(/dev/vdb)並沒有被載入。
在掛載之前,首先要格式化這塊硬碟。我們選擇的是ext4格式:
mkfs.ext4 /dev/vdb
硬碟格式化後,創建一個掛載目標目錄,並將磁碟掛載該目錄上:
mkdir /data
mount /dev/vdb /data
這時候,我們再查看下系統磁碟情況:
df -h
可以看到,雲磁碟可以正常的被掛載了。但是如果重啟系統的話,磁碟仍舊會丟失,我們還必須在每次啟動的時候將磁碟掛載。
修改/etc/fstab文件,需要在該文件的最後添加一行,具體如下:
至此,我們重啟系統,發現磁碟可以正常掛載使用了。
安裝 .NET Core
參考官方文檔:Prerequisites for .NET Core on Linux
第1步,註冊Microsoft簽名密鑰,然後添加Microsoft產品Feed:
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo sh -c 'echo -e "[packages-microsoft-com-prod]\nname=packages-microsoft-com-prod \nbaseurl=https://packages.microsoft.com/yumrepos/microsoft-rhel7.3-prod\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/dotnetdev.repo'
第2步,更新可用於安裝的產品列表,安裝.NET Core所需的組件,然後安裝.NET Core SDK:
sudo yum update
sudo yum install libunwind libicu
sudo yum install dotnet-sdk-2.0.0
第3步,設置環境變數:
export PATH=$PATH:$HOME/dotnet
以上,.NET Core環境已配置完成,可以新建一個項目HelloWorld,執行命令:dotnet run,正常運行,並使用localhost:5000正常訪問,這裡就不再多述。
安裝 MySQL
第1步,下載MySQL Yum倉庫的RPM安裝包:
在MySQL官網中下載YUM源rpm安裝包:http://dev.mysql.com/downloads/repo/yum/
第2步,安裝MySQL RPM安裝包:
yum localinstall mysql57-community-release-el7-11.noarch.rpm
第3步,安裝MySQL伺服器:
yum install mysql-community-server
安裝完畢後,我們啟動MySQL,並查看運行狀態,並設置開機啟動:
service mysqld start
service mysqld status
systemctl enable mysqld
mysql安裝完成之後,在/var/log/mysqld.log文件中給root生成了一個預設密碼。通過下麵的方式找到root預設密碼:
grep 'temporary password' /var/log/mysqld.log
我們獲取了預設密碼,就可以進行一些安全設置,輸入命令:
mysql_secure_installation
最後設置遠程訪問許可權:
mysql -u root -p mysql
mysql> grant all privileges on *.* to 'root'@'%' identified by 'password' with grant option;
預設情況,MySQL的字元集為lanti,考慮我們使用中文的習慣,修改mysql配置文件/etc/my.cnf,增加如下一行,把預設的字元集改成utf8:
[mysqld]
character-set-server=utf8
程式移植
因為.NET Core本身就是支持跨平臺,所以程式邏輯不用進行任何調整,但是我們已將資料庫切換成MySQL,所以針對這塊,稍微調整下。
首先,將appsettings.json中的資料庫連接字元串修改為新的連接;
然後,Startup.cs文件啟動配置修改如下:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySQL(Configuration.GetConnectionString("DefaultConnection")));
重新編譯發佈到目錄:/data/wwwroot/MyWebSite
進入該目錄,執行:
dotnet MyWebSite.dll
現在我們的項目就正常的部署並運行在localhost:5000上了。
安裝 Nginx
Nginx是一個高性能的HTTP和反向代理伺服器,在CentOS中很容易安裝和配置,接下來進行如下操作:
yum install nginx
安裝完成後,我們啟動Nginx,並將它設置為開機啟動:
service nginx start
systemctl enable nginx.service
要使得Nginx代理外網80埠,訪問我們內部5000埠監聽的網站程式,需要修改Nginx配置文件/etc/nginx/nginx.conf:
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
最後,我們重新啟動restart nginx.service,並通過外網鏈接,發現可以正常訪問我們的網站了。
安裝 Supervisor
其實,經過以上的步驟,已經完成基本的移植和部署,網站訪問也沒有問題了。但是,.NET Core應用程式運行在shell之中,如果shell關閉,.NET Core應用程式也隨之關閉,導致應用無法訪問。而且.NET Core進程意外終止或者伺服器宕機或重啟,都會導致服務不可用,這是我們不想看到的。
為瞭解決這個問題,我們需要有一個守護進程來監聽ASP.NET Core 應用程式的狀況,在應用程式停止運行的時候立即重新啟動。
這裡利用Supervisor工具幫我們創建這樣的守護進程,先安裝:
easy_install supervisor
安裝完畢後,如下操作
mkdir /etc/supervisor
echo_supervisord_conf > /etc/supervisor/supervisord.conf
修改supervisord.conf文件,將文件尾部的配置修改:
[include]
files = conf.d/*.conf
再創建一個/etc/supervisor/conf.d/ MyWebSite.conf文件,內容大致如下:
[program:MyWebSite]
command=dotnet .dll ; 運行程式的命令
directory=/data/wwwroot/MyWebSite/ ; 命令執行的目錄
autorestart=true ; 程式意外退出是否自動重啟
stderr_logfile=/var/log/MyWebSite.err.log ; 錯誤日誌文件
stdout_logfile=/var/log/MyWebSite.out.log ; 輸出日誌文件
environment=ASPNETCORE_ENVIRONMENT=Production ; 進程環境變數
user=root ; 進程執行的用戶身份
stopsignal=INT
運行supervisord,查看是否生效:
supervisord -c /etc/supervisor/supervisord.conf
ps -ef | grep MyWebSite
最後,我們要配置Supervisor開機啟動,新建一個“/usr/lib/systemd/system/supervisord.service”文件
# dservice for systemd (CentOS 7.0+)
# by ET-CS (https://github.com/ET-CS)
[Unit]
Description=Supervisor daemon
[Service]
Type=forking
ExecStart=/usr/bin/supervisord -c /etc/supervisor/supervisord.conf
ExecStop=/usr/bin/supervisorctl shutdown
ExecReload=/usr/bin/supervisorctl reload
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
執行命令,使得服務開機啟動:
systemctl enable supervisord
開啟防火牆
CentOS中防火牆程式主要是firewall和iptables,CentOS7中firewall服務已經預設安裝好了。所以,這裡介紹一下firewall相關配置。
預設防火牆是關閉的,為了訪問的安全性,我們首先將防火牆開啟,並設置開啟啟動:
systemctl start firewalld.service
systemctl enable firewalld.service
這時候,我們訪問網站鏈接,發現已經埠屏蔽無法正常訪問。所以接下來,我們要開放http(80埠)、https(443埠)、MySQL(3306埠):
firewall-cmd --zone=public --add-port=80/tcp --permanen
firewall-cmd --zone=public --add-port=443/tcp --permanen
firewall-cmd --zone=public --add-port=3306/tcp --permanen
重啟伺服器,重新打開網站鏈接,可以正常訪問。
FTP 一鍵部署
在之前Windows Server伺服器上,已經配置過FTP伺服器,項目部署時,通過VS可以很方便的一鍵部署,那CentOS上該如何配置呢?
第1步,安裝一下ftp服務:
yum -y install vsftpd
第2步,打開/etc/vsftpd/vsftpd.conf配置文件,修改如下2處:
anonymous_enable=NO
chroot_local_user=YES
第3步,打開ftp服務,並設置開機啟動,並開放遠程訪問埠:
systemctl restart vsftpd.service
systemctl enable vsftpd.service
firewall-cmd --permanent --add-service=ftp
firewall-cmd --reload
setsebool -P ftp_home_dir on
最後,增加一個ftp訪問用戶,配置發佈目錄,並提供寫許可權和設置密碼:
useradd -d /data/wwwroot -m ftpuser -s /sbin/nologin
cd /data/wwwroot/
chmod -R 777 *
passwd ftpuser
VS2017中,修改ftp部署配置如下圖:
配置 https 協議
為了實現數據信息在客戶端和伺服器之間的加密傳輸,防止數據信息的泄露,保證雙方傳遞信息的安全性,我們需要HTTP下加入SSL層,我之前已經申請過Symantec免費的SSL證書,所以就簡單說明一下怎麼配置。
前面我們的網站應用程式,已經通過Nginx反向代理來訪問,那其實只用通過配置Nginx來管理我們申請的證書文件。首先下載證書文件,包括.crt和.key兩個文件,然後拷貝到目錄:/etc/nginx/ssl下,接著編輯Nginx配置文件,找到相關地方做如下修改:
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl; #如果硬性要求全部走https協議,這裡去除ssl
server_name _;
root /usr/share/nginx/html;
#ssl on; #如果硬性要求全部走https協議,這裡開啟ssl on
ssl_certificate /etc/nginx/ssl/www.lancel0t.cn.crt;
ssl_certificate_key /etc/nginx/ssl/www.lancel0t.cn.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
最後,我們重啟一下Nginx,輸入我們的網站地址:https://www.lancel0t.cn/ ,看到能夠正常訪問。
至此,網站應用程式移植到Linux環境中完美完成!當然,實施的過程中筆者也踩過不少的坑,這裡希望能拋磚引玉,有什麼問題歡迎給我博客留言,一起討論。