我们在企业的实际的生产环境中经常会遇到要求客户进行软件的版本升级操作,如果升级新版本失败也能进行回滚到旧版本。今天主要来做一下如何对Nginx做版本升级与回滚的实验操作。
实验环境介绍:
系统版本:CentOS 7.5.1804
Nginx版本:nginx-1.12.2.tar.gz
nginx-1.14.2.tar.gz
1)编译安装旧版本的Nginx
[root@nginx application]# tar -xf nginx-1.12.2.tar.gz
[root@nginx application]# cd nginx-1.12.2
[root@nginx nginx-1.12.2]# ./configure --prefix=/usr/local/nginx-1.12.2 --user=nginx --group=nginx --with-http_ssl_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_secure_link_module --with-http_stub_status_module --with-http_perl_module --with-pcre
[root@nginx nginx-1.12.2]# echo $?
0
[root@nginx nginx-1.12.2]# make && make install
[root@nginx nginx-1.12.2]# echo $?
0
[root@nginx nginx-1.12.2]# ls /usr/local/nginx-1.12.2/
conf html logs sbin
2)编译安装nginx新版本
[root@nginx nginx-1.12.2]# cd /application/
[root@nginx application]# tar -xf nginx-1.14.2.tar.gz
[root@nginx application]# cd nginx-1.14.2
[root@nginx nginx-1.14.2]#
[root@nginx nginx-1.14.2]# ./configure --prefix=/usr/local/nginx-1.14.2 --user=nginx --group=nginx --with-http_ssl_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_secure_link_module --with-http_stub_status_module --with-http_perl_module --with-pcre --with-perl_modules_path=/home/webserver/nginx3/perl
#编译新版本最后--with要指明相关perl程序/模块 安装到具体目录里;
[root@nginx nginx-1.14.2]# echo $?
0
[root@nginx nginx-1.14.2]# make && make install
[root@nginx nginx-1.14.2]# echo $?
0
[root@nginx nginx-1.14.2]# ls /usr/local/nginx-1.14.2/
conf html logs sbin
[root@nginx nginx-1.14.2]#
3)启动旧版本Nginx并测试访问
[root@nginx ~]# useradd -s /sbin/nologin -M nginx
[root@nginx ~]# /usr/local/nginx-1.12.2/sbin/nginx -t
nginx: the configuration file /usr/local/nginx-1.12.2/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx-1.12.2/conf/nginx.conf test is successful
[root@nginx ~]#
[root@nginx ~]# /usr/local/nginx-1.12.2/sbin/nginx
[root@nginx ~]# ps -aux | grep "nginx"
root 20741 0.0 0.0 59396 1808 ? Ss 17:37 0:00 nginx: master process /usr/local/nginx-1.12.2/sbin/nginx
nginx 20742 0.0 0.1 59804 2596 ? S 17:37 0:00 nginx: worker process
root 20744 0.0 0.0 112708 980 pts/0 R+ 17:37 0:00 grep --color=auto nginx
[root@nginx ~]# ss -tunl | grep "80"
tcp LISTEN 0 128 *:80 *:*
[root@nginx ~]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Sun, 11 Aug 2019 09:37:51 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Sun, 11 Aug 2019 09:35:22 GMT
Connection: keep-alive
ETag: "5d4fe15a-264"
Accept-Ranges: bytes
4)升级到新的版本
Nginx的升级主要就是对sbin里的二进制执行文件的升级
[root@nginx ~]# cd /usr/local/nginx-1.12.2/sbin/
[root@nginx sbin]# /usr/local/nginx-1.12.2/sbin/nginx -v
nginx version: nginx/1.12.2
[root@nginx sbin]# ls
nginx
[root@nginx sbin]# mv nginx nginx-1.12.2
#首先对原来的旧版本nginx文件进行备份
[root@nginx sbin]# cp /usr/local/nginx-1.14.2/sbin/nginx ./
#拷贝新版本的二进制文件到当前目录
[root@nginx sbin]# ls
nginx nginx-1.12.2
[root@nginx sbin]#
#接着开始进行平滑升级操作
[root@nginx sbin]# ps -ef | grep nginx
root 20741 1 0 17:37 ? 00:00:00 nginx: master process /usr/local/nginx-1.12.2/sbin/nginx
nginx 20742 20741 0 17:37 ? 00:00:00 nginx: worker process
root 20784 2889 0 17:41 pts/0 00:00:00 grep --color=auto nginx
[root@nginx sbin]# kill -USR2 20741
[root@nginx sbin]# ps -ef | grep nginx
root 20741 1 0 17:37 ? 00:00:00 nginx: master process /usr/local/nginx-1.12.2/sbin/nginx
nginx 20742 20741 0 17:37 ? 00:00:00 nginx: worker process
root 20785 20741 0 17:42 ? 00:00:00 nginx: master process /usr/local/nginx-1.12.2/sbin/nginx
nginx 20786 20785 0 17:42 ? 00:00:00 nginx: worker process
root 20788 2889 0 17:42 pts/0 00:00:00 grep --color=auto nginx
#此时新的master进程已经正常的启动了,但是老的worker进程也存在,我们可以使用下面的命令,将老的worker进程发出平滑停止的信号。
[root@nginx sbin]# kill -WINCH 20741
[root@nginx sbin]# ps -ef | grep nginx
root 20741 1 0 17:37 ? 00:00:00 nginx: master process /usr/local/nginx-1.12.2/sbin/nginx
root 20785 20741 0 17:42 ? 00:00:00 nginx: master process /usr/local/nginx-1.12.2/sbin/nginx
nginx 20786 20785 0 17:42 ? 00:00:00 nginx: worker process
root 20790 2889 0 17:45 pts/0 00:00:00 grep --color=auto nginx
此时,老的worker进程已经停止了,我们在浏览器上测试是否还可以正常访问页面
网站仍然可以正常访问,其实这一平滑升级操作,对用户来说是完全是感受不到的,所以nginx的热部署就完成了
[root@nginx sbin]# /usr/local/nginx-1.12.2/sbin/nginx -v
nginx version: nginx/1.14.2
#查看版本也是最新的版本,升级完成
如果在版本升级完成之后,没有任何的问题,需要关闭老的master进程的话,只需要发出QUIT信号即可
kill -QUIT old_master_PID
5)版本回滚
对于升级来说,最难的不是升级,而是回滚,因为在实际生产环境回滚的机率是存在,比如:新版本由于某些未知bug导致与现有应用不兼容、或出现运行不稳定的情况等等。
所以,对运维工程师来说,故障回滚是重点。
在上面的结果中,我们也能看到老的master进程是一直存在,在没有手工关闭前,它是不会自已关闭的,这种设计是有好处的,好处就是为了升级新版本后,如果出现问题能及时快速的回滚到上一个稳定版本。
[root@nginx sbin]# ps -ef | grep nginx
root 20741 1 0 17:37 ? 00:00:00 nginx: master process /usr/local/nginx-1.12.2/sbin/nginx
root 20785 20741 0 17:42 ? 00:00:00 nginx: master process /usr/local/nginx-1.12.2/sbin/nginx
nginx 20786 20785 0 17:42 ? 00:00:00 nginx: worker process
root 20800 2889 0 17:52 pts/0 00:00:00 grep --color=auto nginx
[root@nginx sbin]# cd /usr/local/nginx-1.12.2/sbin/
[root@nginx sbin]# ls
nginx nginx-1.12.2
[root@nginx sbin]# mv nginx nginx-1.14.2
[root@nginx sbin]# mv nginx-1.12.2 nginx
[root@nginx sbin]# ls
nginx nginx-1.14.2
[root@nginx sbin]# kill -USR1 20741
[root@nginx sbin]# ps -ef | grep nginx
root 20741 1 0 17:37 ? 00:00:00 nginx: master process /usr/local/nginx-1.12.2/sbin/nginx
root 20785 20741 0 17:42 ? 00:00:00 nginx: master process /usr/local/nginx-1.12.2/sbin/nginx
nginx 20786 20785 0 17:42 ? 00:00:00 nginx: worker process
root 20831 2889 0 17:54 pts/0 00:00:00 grep --color=auto nginx
[root@nginx sbin]#
[root@nginx sbin]# ./nginx -v
nginx version: nginx/1.12.2
[root@nginx sbin]#
此时我们可以看到nginx的版本已经回到了旧版本,那么我们继续查看是否可以访问页面
同样可以正常的访问,所以,回滚操作也对用户来说是察觉不到的。