4- shell部署和大型脚本框架
关闭应用
开启什么应用,就关闭什么应用
关闭顺序: A B
开启顺序: B A
检查
查看浏览器效果
ok
解压代码:
tar xf ...
放置代码
在把新的代码放置到服务器之前,要把服务器的旧的代码做一个备份
备份的形式最好用时间戳的形式混合在一起,首先下面来介绍liux关于事件date的命令如下:
date
时间戳效果:
年月日:
date +%Y%m%d
时分秒:
date +%H%M%S
年月日时分秒:
date +%Y%m%d%H%M%S
时间戳生成示例:
生成年月日
date +%Y-%m-%d
生成时分秒
date +%H-%M-%S
生成年月日时分秒
date +%Y-%m-%d-%H-%M-%S
那么下面来演示以时间的格式来备份代码
先创建一个文件file
touch file mv file file-`date +%y%m%d%H%M%S` ls
主机间免秘钥认证
1、生成秘钥对(在本机上完成)
-t 指定秘钥的类型
rsa 秘钥类型
ssh-keygen -t rsa
2、编辑认证文件(在远程主机上完成)
把本机上的公匙复制进来
cd .ssh/ vim authorized_keys
3、编辑ssh配置文件(在远程主机上完成)
sudo vim /etc/ssh/sshd_config
把这一行的注释打开就好
AuthorizedKeysFile %h/.ssh/authorized_keys
4、配置文件生效(在远程主机上启动)
重启ssh服务
/etc/init.d/ssh restart
5、验证操作(在本机上操作)
就第一次让输入密码,往后就直接连接就行
ssh root@47.95.8.70
环境部署
准备工作
创建基本目录
# 在一个不存在的目录下,创建目录 mkdir /data/{server,logs,backup,soft,virtual,codes,scripts} -p ls /data/
mkdir /data/codes
├── backup 备份
├── codes 代码
├── logs 日志
├── scripts 脚本
├── server 服务
├── soft 软件
└── virtual 虚拟环境
项目分析
需求:
部署一个环境,支持我们的django项目正常运行
分析:
2、python环境 ---> 3、python虚拟环境 1、django环境部署 4、django软件安装 5、项目基本操作 6、应用基本操作 7、view和url配置 8、问题:只有本机能访问 9、方案代理---- 10、nginx 11、nginx实现代理 13、pcre软件安装 12、nginx软件安装 14、nginx基本操作 15、nginx代理的配置 16、目录结构 17、查看配置文件 18、找到对应的代理配置项 19、启动django 20、启动nginx 21、整个项目调试
python虚拟环境
软件安装
apt-get install python-virtualenv -y
虚拟环境基本操作
创建
virtualenv -p /usr/bin/python2.7 venv
进入
source venv/bin/activate
退出
deactivate
删除
rm -rf venv
django环境部署
django软件安装
解压
cd /data/soft tar xf Django。。。
查看
cd Django... cat INSTALL or README
安装
python setup.py install
python类型软件的安装流程
普通: 解压 安装 特殊: 解压 编译 安装 编译:python setup.py build
django项目操作
创建
django-admin startproject itcast
django应用操作
创建应用
python manager.py startapp test1
注册应用
itcast/settings.py INSTALL_APP = [ 。。。 'test1', ]
view和url配置
view 配置文件生效
cat /data/server/itcast/test1/views.py from django.shortcuts import render from django.http import HttpResponse # Create your views here. def hello(resquest): return HttpResponse("itcast V1.0")
url文件配置
cat /data/server/itcast/itcast/urls.py
from django.conf.urls import url from django.contrib import admin from test1.views import * urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^hello/$', hello), ]
启动服务:
cd /data/server/itcast python manager.py runserver
启动django
python manage.py runserver >> /dev/null 2>&1 &
关闭:
ps aux | grep python kill 56491
问题:
django项目只能在本机查看
方案:
nginx、haproxy
优中选优
简单
nginx环境部署
pcre软件安装
解压
tar xf pcre...
查看帮助
cd pcre。。。 INSTALL 或者 README
配置
./configure
编译
make
安装
make install
linux中软件安装的一般流程
解压
tar 解压文件,获取真正的配置文件
配置
configure 根据默认的配置项或者更改配置项,生成编译配置文件(Makefile)
编译
make 根据 Makefile 内容,编译生成指定的软件所需要的所有文件
安装
make install 将编译生成的所有文件,转移到软件指定安装的目录下面 prefix
nginx软件安装
解压
cd /data/soft/ tar xf nginx-1.10.2.tar.gz
配置
cd nginx-1.10.2/ ./configure --prefix=/data/server/nginx --without-http_gzip_module
编译
make
安装
make install
nginx简单操作
检查
./sbin/nginx -t
开启
./sbin/nginx
关闭
./sbin/nginx -s stop
重载
./sbin/nginx -s reload
突发问题:
root@admina-virtual-machine:/data/server/nginx# ./sbin/nginx -t ./sbin/nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
分析:
1、先看报错
2、思考,是否报错真实有效
分析: 谁错了
3、查找文件
全名找不到,我们使用正则
4、找到文件,我没有问题
nginx默认找库文件的路径有问题
5、解决
nginx代理django项目
nginx的目录结构
root@admina-virtual-machine:/data/server/nginx# tree -L 2 /data/server/nginx/
/data/server/nginx/
├── ...
├── conf 配置文件目录
│ ...
│ ├── nginx.conf 默认的配置文件
│ ...
├── ...
├── html 网页文件
│ ├── 50x.html
│ └── index.html
├── logs 日志目录
│ ├── access.log
│ └── error.log
├── ...
├── sbin 执行文件目录
│ └── nginx
├── ...
nginx配置文件介绍
全局配置段
http配置段
server配置段 项目或者应用
location配置段 url配置
需求:
127.0.0.1:8000/hello/
代理配置项 #location ~ \.php$ { # proxy_pass http://127.0.0.1; #}
编辑配置文件实现代理功能
配置内容
62: location /hello/ { 63: proxy_pass http://127.0.0.1:8000; 64: }
标准配置文件
root@admina-virtual-machine:/data/server/nginx# egrep -vn '#|^$' conf/nginx.conf 3:worker_processes 1; 12:events { 13: worker_connections 1024; 14:} 17:http { 18: include mime.types; 19: default_type application/octet-stream; 27: sendfile on; 31: keepalive_timeout 65; 35: server { 36: listen 80; 37: server_name localhost; 43: location / { 44: root html; 45: index index.html index.htm; 46: } 52: error_page 500 502 503 504 /50x.html; 53: location = /50x.html { 54: root html; 55: } 62: location /hello/ { 63: proxy_pass http://127.0.0.1:8000; 64: } 81: } 119:}
配置文件生效
调试
手工发布代码
需求:
手工方式部署代码
线上主机:56.11
代码仓库:56.12
方案:
获取代码
打包代码
传输代码
关闭应用
解压代码
放置代码
备份老文件
放置新文件
开启应用
检查
实践
获取代码
sed -i 's#1.0#1.1#' django/views.py sed -i 's#原内容#替换后内容#g' 文件 分隔符:# / @
打包代码
tar zcf django.tar.gz django
传输代码
scp root@192.168.56.12:/data/code/django.tar.gz ./
关闭应用
关闭nginx应用
/data/server/nginx/sbin/nginx -s stop
关闭django应用
根据端口查看进程号,
lsof -Pti :8000
杀死进程号
kill 56502
解压代码
cd /data/codes tar xf django.tar.gz
放置代码
备份老文件
需求:备份的格式:
文件名-时间戳
时间戳:年月日时分秒
date +%Y%m%d%H%M%S
mv /data/server/itcast/test1/views.py /data/backup/views.py-`date +%Y%m%d%H%M%S`
放置新文件
cd /data/codes mv django/views.py /data/server/itcast/test1/
开启应用
开启django应用
source /data/virtual/venv/bin/activate cd /data/server/itcast/ python manage.py runserver >> /dev/null 2>&1 & deactivate
开启nginx应用
/data/server/nginx/sbin/nginx
检查
netstat -tnulp | grep :80
脚本发布代码
5.1 远程脚本编写
5.1.1 远程命令执行
56.11 让 56.12 执行命令
示例:
5.1.2 远程脚本编写
1、实现简单的功能--- 简单的命令罗列
cat tar_code.sh
代码如下:
#!/bin/bash # 功能:打包代码 # 脚本名:tar_code.sh # 作者:python 13期全体 # 版本:V 0.1 # 联系方式:长安街1号 太和殿旁边 中南海1号厅 cd /data/code [ -f django.tar.gz ] && rm -f django.tar.gz tar zcf django.tar.gz django
脚本优化之 固定内容变量化
cat tar_code.sh
代码如下:
#!/bin/bash # 功能:打包代码 # 脚本名:tar_code.sh # 作者:python 13期全体 # 版本:V 0.2 # 联系方式:长安街1号 太和殿旁边 中南海1号厅 FILE='django.tar.gz' CODE_DIR='/data/code' CODE_PRO='django' cd "${CODE_DIR}" [ -f "${FILE}" ] && rm -f "${FILE}" tar zcf "${FILE}" "${CODE_PRO}"
脚本优化之 功能函数化
cat tar_code.sh
代码如下:
#!/bin/bash # 功能:打包代码 # 脚本名:tar_code.sh # 作者:python 13期全体 # 版本:V 0.3 # 联系方式:长安街1号 太和殿旁边 中南海2号厅 FILE='django.tar.gz' CODE_DIR='/data/code' CODE_PRO='django' code_tar(){ cd "${CODE_DIR}" [ -f "${FILE}" ] && rm -f "${FILE}" tar zcf "${FILE}" "${CODE_PRO}" } code_tar
5.2 部署脚本编写
5.2.1 脚本框架
需求:先将脚本所设计的所有业务流程跑通
方案:
使用函数来体现
#!/bin/bash # 功能:打包代码 # 脚本名:deploy.sh # 作者:python 13期全体 # 版本:V 0.1 # 联系方式:长安街1号 太和殿旁边 国务院1号厅 # 打包代码 tar_code(){ echo "打包代码" } # 传输代码 scp_code(){ echo "传输代码" } # 关闭应用 serv_stop(){ echo "关闭nginx应用" echo "关闭django应用" } # 解压代码 untar_code(){ echo "解压代码" } # 放置代码 fangzhi_code(){ echo "放置代码" } # 开启应用 serv_star(){ echo "开启django应用" echo "开启nginx应用" } # 检查 check(){ echo "检查" } main(){ tar_code scp_code serv_stop untar_code fangzhi_code serv_star check } main
5.2.2 命令填空
需求:
在流程跑通的情况下,执行完整的代码部署过程
方案:
在流程框架中,填写执行没有任何问题的命令
脚本实施:
#!/bin/bash # 功能:打包代码 # 脚本名:deploy.sh # 作者:python 13期全体 # 版本:V 0.2 # 联系方式:长安街1号 太和殿旁边 国务院2号厅 # 打包代码 tar_code(){ echo "打包代码" ssh root@192.168.8.15 "/bin/bash /data/scripts/tar_code.sh" } # 传输代码 scp_code(){ echo "传输代码" cd /data/codes/ [ -f django.tar.gz ] && rm -f django.tar.gz [ -d django ] && rm -rf django scp root@192.168.8.15:/data/codes/django.tar.gz ./ } # 关闭应用 serv_stop(){ echo "关闭nginx应用" /data/server/nginx/sbin/nginx -s stop echo "关闭django应用" kill `lsof -Pti :8000` } # 解压代码 untar_code(){ echo "解压代码" cd /data/codes tar xf django.tar.gz } # 放置代码 fangzhi_code(){ echo "备份原文件" mv /data/server/itcast/test1/views.py /data/backup/views.py-`date +%Y%m%d%H%M%S` echo "放置新文件" mv /data/codes/django/views.py /data/server/itcast/test1/ } # 开启应用 serv_star(){ echo "开启django应用" source /data/virtual/venv/bin/activate cd /data/server/itcast/ python manage.py runserver >> /dev/null 2>&1 & deactivate echo "开启nginx应用" /data/server/nginx/sbin/nginx } # 检查 check(){ echo "检查" netstat -tnulp | grep nginx } main(){ tar_code scp_code serv_stop untar_code fangzhi_code serv_star check } main
5.2.3 增加日志功能
需求:
1、追踪记录
2、数据说话
方案:
增加日志功能
1、日志文件
/data/logs/deploy.log
2、日志格式
日期 时间 脚本名称 步骤
日期:date +%F
时间:date +%T
脚本:$0
脚本实施:
#!/bin/bash # 功能:打包代码 # 脚本名:deploy.sh # 作者:python 13期全体 # 版本:V 0.3 # 联系方式:长安街1号 太和殿旁边 国务院3号厅 LOG_FILE='/data/logs/deploy.log' # 增加日志功能 write_log(){ log_date=`date +%F` log_time=`date +%T` buzhou="$1" echo "${log_date} ${log_time} $0 ${buzhou}" >> "${LOG_FILE}" } # 打包代码 tar_code(){ echo "打包代码" ssh root@192.168.8.15 "/bin/bash /data/scripts/tar_code.sh" write_log "打包代码" } # 传输代码 scp_code(){ echo "传输代码" cd /data/codes/ [ -f django.tar.gz ] && rm -f django.tar.gz [ -d django ] && rm -rf django scp root@192.168.8.15:/data/codes/django.tar.gz ./ write_log "传输代码" } # 关闭应用 serv_stop(){ echo "关闭nginx应用" /data/server/nginx/sbin/nginx -s stop write_log "关闭nginx应用" echo "关闭django应用" kill `lsof -Pti :8000` write_log "关闭django应用" } # 解压代码 untar_code(){ echo "解压代码" cd /data/codes tar xf django.tar.gz write_log "解压代码" } # 放置代码 fangzhi_code(){ echo "备份原文件" mv /data/server/itcast/test1/views.py /data/backup/views.py-`date +%Y%m%d%H%M%S` write_log "备份原文件" echo "放置新文件" mv /data/codes/django/views.py /data/server/itcast/test1/ write_log "放置新文件" } # 开启应用 serv_star(){ echo "开启django应用" source /data/virtual/venv/bin/activate cd /data/server/itcast/ python manage.py runserver >> /dev/null 2>&1 & deactivate write_log "开启django应用" echo "开启nginx应用" /data/server/nginx/sbin/nginx write_log "开启nginx应用" } # 检查 check(){ echo "检查" netstat -tnulp | grep :80 write_log "检查" } main(){ tar_code scp_code serv_stop untar_code fangzhi_code serv_star check } main
5.2.4 增加锁文件功能
需求:
同一时间段内,只允许有一个用户来执行这个脚本
如果脚本执行的时候,有人在执行,那么输入报错:该脚本正在运行......
设计:
锁文件 /tmp/deploy.pid
脚本执行的时候,需要创建锁文件
脚本执行结束的时候,需要删除锁文件
脚本实施
#!/bin/bash # 功能:打包代码 # 脚本名:deploy.sh # 作者:python 13期全体 # 版本:V 0.4 # 联系方式:长安街1号 太和殿旁边 国务院4号厅 LOG_FILE='/data/logs/deploy.log' # 增加锁文件 add_lock(){ echo "增加锁文件" touch /tmp/deploy.pid write_log "增加锁文件" } # 删除锁文件 del_lock(){ echo "删除锁文件" rm -f /tmp/deploy.pid write_log "删除锁文件" } # 增加日志功能 write_log(){ log_date='date +%F' log_time='date +%T' buzhou="$1" echo "${log_date} ${log_time} $0 ${buzhou}" >> "${LOG_FILE}" } # 打包代码 tar_code(){ echo "打包代码" ssh root@192.168.56.12 "/bin/bash /data/scripts/tar_code.sh" write_log "打包代码" } # 传输代码 scp_code(){ echo "传输代码" cd /data/codes/ [ -f django.tar.gz ] && rm -f django.tar.gz [ -d django ] && rm -rf django scp root@192.168.56.12:/data/code/django.tar.gz ./ write_log "传输代码" } # 关闭应用 serv_stop(){ echo "关闭nginx应用" /data/server/nginx/sbin/nginx -s stop write_log "关闭nginx应用" echo "关闭django应用" kill `lsof -Pti :8000` write_log "关闭django应用" } # 解压代码 untar_code(){ echo "解压代码" cd /data/codes tar xf django.tar.gz write_log "解压代码" } # 放置代码 fangzhi_code(){ echo "备份原文件" mv /data/server/itcast/test1/views.py /data/backup/views.py-`date +%Y%m%d%H%M%S` write_log "备份原文件" echo "放置新文件" mv /data/codes/django/views.py /data/server/itcast/test1/ write_log "放置新文件" } # 开启应用 serv_star(){ echo "开启django应用" source /data/virtual/venv/bin/activate cd /data/server/itcast/ python manage.py runserver >> /dev/null 2>&1 & deactivate write_log "开启django应用" echo "开启nginx应用" /data/server/nginx/sbin/nginx write_log "开启nginx应用" } # 检查 check(){ echo "检查" netstat -tnulp | grep :80 write_log "检查" } main(){ if [ -f /tmp/deploy.pid ] then echo "脚本 $0 正在运行中....." exit else add_lock tar_code scp_code serv_stop untar_code fangzhi_code serv_star check del_lock fi } main
5.2.5 脚本流程知识点填充
需求:
如果我给脚本出入的参数是deploy,那么我才执行
方案;
1、脚本的传参
2、位置参数的调用
3、case流程语句的使用
输出帮助信息:
脚本 $0 的使用方式: $0 [ deploy ]
#!/bin/bash # 功能:打包代码 # 脚本名:deploy.sh # 作者:python 13期全体 # 版本:V 0.5 # 联系方式:长安街1号 太和殿旁边 国务院5号厅 LOG_FILE='/data/logs/deploy.log' # 脚本使用帮助 usage(){ echo "脚本 $0 的使用方式: $0 [ deploy ]" exit } # 增加锁文件 add_lock(){ echo "增加锁文件" touch /tmp/deploy.pid write_log "增加锁文件" } # 删除锁文件 del_lock(){ echo "删除锁文件" rm -f /tmp/deploy.pid write_log "删除锁文件" } # 增加日志功能 write_log(){ log_date='date +%F' log_time='date +%T' buzhou="$1" echo "${log_date} ${log_time} $0 ${buzhou}" >> "${LOG_FILE}" } # 打包代码 tar_code(){ echo "打包代码" ssh root@192.168.56.12 "/bin/bash /data/scripts/tar_code.sh" write_log "打包代码" } # 传输代码 scp_code(){ echo "传输代码" cd /data/codes/ [ -f django.tar.gz ] && rm -f django.tar.gz [ -d django ] && rm -rf django scp root@192.168.56.12:/data/code/django.tar.gz ./ write_log "传输代码" } # 关闭应用 serv_stop(){ echo "关闭nginx应用" /data/server/nginx/sbin/nginx -s stop write_log "关闭nginx应用" echo "关闭django应用" kill `lsof -Pti :8000` write_log "关闭django应用" } # 解压代码 untar_code(){ echo "解压代码" cd /data/codes tar xf django.tar.gz write_log "解压代码" } # 放置代码 fangzhi_code(){ echo "备份原文件" mv /data/server/itcast/test1/views.py /data/backup/views.py-`date +%Y%m%d%H%M%S` write_log "备份原文件" echo "放置新文件" mv /data/codes/django/views.py /data/server/itcast/test1/ write_log "放置新文件" } # 开启应用 serv_star(){ echo "开启django应用" source /data/virtual/venv/bin/activate cd /data/server/itcast/ python manage.py runserver >> /dev/null 2>&1 & deactivate write_log "开启django应用" echo "开启nginx应用" /data/server/nginx/sbin/nginx write_log "开启nginx应用" } # 检查 check(){ echo "检查" netstat -tnulp | grep :80 write_log "检查" } main(){ case "$1" in "deploy") if [ -f /tmp/deploy.pid ] then echo "脚本 $0 正在运行中....." exit else add_lock tar_code scp_code serv_stop untar_code fangzhi_code serv_star check del_lock fi ;; *) usage ;; esac } main $1
5.2.6 输入参数安全优化
需求:
对脚本传入的参数进行判断,如果传入的参数数量不对,直接提示脚本使用方式,然后退出
方案:
条件表达式 + $#
脚本实施
#!/bin/bash # 功能:打包代码 # 脚本名:deploy.sh # 作者:python 13期全体 # 版本:V 0.6 # 联系方式:长安街1号 太和殿旁边 国务院6号厅 LOG_FILE='/data/logs/deploy.log' # 脚本使用帮助 usage(){ echo "脚本 $0 的使用方式: $0 [ deploy ]" exit } [ "$#" -eq 1 ] || usage ...
5.2.7 脚本调试功能
-x
示例:
bash -x while.sh
+ a=1 + '[' 1 -lt 5 ']' + echo 1 1 + a=2 + '[' 2 -lt 5 ']' + echo 2 2 + a=3 + '[' 3 -lt 5 ']' + echo 3 3 + a=4 + '[' 4 -lt 5 ']' + echo 4 4 + a=5 + '[' 5 -lt 5 ']'
5.3 生产脚本编写总结
5.3.1 简单脚本编写总结
1、命令简单罗列
2、固定的内容变量化
3、功能函数化
5.3.2 复杂脚本编写总结
1、手工执行的命令一定要正确
2、根据流程编写脚本的框架
3、将手工执行的命令填充到对应的框架函数内部
4、增加日志功能,方便跟踪脚本历史执行记录
5、增加锁文件,保证代码发布的过程中,不受同类脚本影响
6、主函数中逻辑流程控制好,
7、设计安全的方面:
输入参数数量
输入参数匹配
脚本帮助信息
8、调试脚本
注意事项:
1、命令一定要保证能正常执行
2、成对的符号,要成对写,避免丢失
3、函数调用,
写好函数后,一定要在主函数中进行调用
4、避免符号出现中文
5、命令变量的写法一定要规范
6、固定的内容一定要变量实现,方便以后更改
7、日志的输出
8、脚本的传参和函数的传参要区别对待