1.1 早期手动部署代码

方式

1、纯手工scp上传

2、纯手工登录,git pull、svn update

3、纯手工xftp往上拉

4、开发给打一个压缩包,rz 上去然后解压

缺点

1、运维全程参与,占用大量时间

2、上线速度太慢

3、人为失误过多,管理混乱

4、回滚的太慢、不及时、并且难以回滚

1.2 如何设计自动代码部署系统

1、规划

2、实现

3、总结和扩展

4、在生产环境中应用

1.2.1 自动化部署环境

1、开发环境

开发者本地有自己的环境,然后运维需要配置公共的开发环境,大家可公用的服务,例如开发数据库mysql redis等

2、测试环境

功能测试环境和性能测试环境

3、预生产环境

生产环境集群中的某一个节点担任

4、生产环境

直接对用户提供的环境

1.2.2 自动化部署规划

  • 有一个可以上线代码的git仓库
  • 一个集群中有10个节点,实现一键部署、秒级回滚
  • 所有的web服务都应该使用普通用户
  • 所有的web服务都不应该监听80端口,除了负载均衡

1.2.3 自动化部署实现思路

  • 代码放在那里

    代码放在svn、git(优先选择)上

  • 编译(可选 java环境需要)
  • 获取什么版本的代码

1、svn+git:直接拉取某个分支

2、svn:指定版本号

3、git:指定tag

  • 差异解决

1、各个代码直接差异,配置文件未必一样

2、代码仓库和实际的差异,代码是否放在代码仓库中(配置单独进行存放)短信接口、支付,等敏感信息不能让所有的开发知道

-项目名设计
web-demo_456_2018-09-02-15-32-14

  • 如何更新

php、tomcat需要重新启动

  • 测试

1、测试关键的页面、API、后台等

2、测试一个与生产环境、通过则继续部署,失败则进行回滚

  • 日志记录

1、对部署进行设计

成功多少次

失败多少次

回滚多少次

  • 多人同时执行脚本

防止多人同时操作,导致重复上线失败,通过lock锁文件进行控制

  • 串行和并行

1、若集群中机器少,则串行看不出什么问题、若机器多则串行会非常的慢

2、分组部署、并行部署

3、测试预生产环境,成功则继续部署,失败则进行回滚

  • 如何执行

1、shell执行

2、web界面进行操作

1.2.4 自动话部署实践

1、获取最新代码

2、编译(可选)

3、配置文件(软连接或者cp)

4、打包

5、scp到目标服务器

6、解压

7、放置到webroot

8、scp差异文件

9、重启(可选)

10、测试

11、加入集群

自动化部署代码的精髓在于创建软连接

1.2.5 回退实践

1.2.5.1 正常回退实践

1、列出回滚版本

2、目标服务器移除集群

3、执行回滚(删除软连接、重建软连接)

4、重启和测试

5、加入集群

1.2.5.2 紧急回退实践

1、列出回滚版本

2、执行回滚(删除软连接、重建软连接)

3、重启对应服务

1.2.5.3 更紧急回退实践

1、执行回滚

2、重启

1.3 自动化部署系统构建实践

1.3.1 环境准备

linux_node1 10.0.0.7

linux_node2 10.0.0.8

1、创建普通用户(两台同时进行)

useradd -u 1000 lzh

echo '123456'|passwd --stdin lzh

2、配置密钥

[root@linux_node1 ~]# su - lzh  切换至普通用户

[lzh@linux_node1 ~]$ ssh-keygen -t dsa  生成密钥

Generating public/private dsa key pair.

Enter file in which to save the key (/home/lzh/.ssh/id_dsa): 默认一路回车

Created directory '/home/lzh/.ssh'.

Enter passphrase (empty for no passphrase): 

Enter same passphrase again:

Your identification has been saved in /home/lzh/.ssh/id_dsa. 钥匙

Your public key has been saved in /home/lzh/.ssh/id_dsa.pub. 锁

The key fingerprint is:

f9:bb:3a:7f:e3:17:56:12:d3:8a:7b:78:79:ab:e2:de lzh@linux_node1

The key's randomart image is:

+--[ DSA 1024]----+
|               . |
|              o .|
|             . + |
|         .  . o .|
|        S    o + |
|         .  o * .|
|          .  + o.|
|        .  o+ .. |
|        .+**oE.  |
+-----------------+

[lzh@linux_node1 ~]$ ssh-copy-id  -i ~/.ssh/id_dsa.pub [email protected]
The authenticity of host '172.16.1.8 (172.16.1.8)' can't be established.
RSA key fingerprint is c2:34:59:81:a2:a7:9c:0a:23:9b:cf:1d:bb:d4:8e:ad.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.16.1.8' (RSA) to the list of known hosts.
[email protected]'s password: 
Now try logging into the machine, with "ssh '[email protected]'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

[lzh@linux_node1 ~]$ ssh 172.16.1.8
[lzh@linux_node2 ~]$    

3、创建相关目录

mkdir -p /deploy/code/web-demo 
mkdir -p /deploy/config/web-demo/base
mkdir -p /deploy/config/web-demo/other
mkdir -p /deploy/tar
mkdir -p /deploy/tmp 
[root@linux_node1 ~]# tree /deploy/
/deploy/
├── code
│   └── web-demo
├── config
│   └── web-demo
│       ├── base
│       └── other
├── tar
└── tmp

8 directories, 0 files

chown -R lzh.lzh /deploy
chown -R lzh.lzh /opt/webroot/
chown -R lzh.lzh /webroot/

1.3.2 自动化脚本

查看脚本

#!/bin/bash 

#Dir List
#mkdir -p /deploy/code/web-demo 
#mkdir -p /deploy/config/web-demo/base 
#mkdir -p /deploy/config/web-demo/other
#mkdir -p /deploy/tar
#mkdir -p /deploy/tmp 
#mkdir -p /opt/webroot
#chown -R lzh.lzh /deploy
#chown -R lzh.lzh /opt/webroot
#chown -R lzh.lzh /webroot

#Node List
PRE_LIST="172.16.1.7"
GROUP1_LIST="172.16.1.8"
ROLLBACK_LIST="172.16.1.7 172.16.1.8"
#Date/Time Veriables
LOG_DATE='date "+%Y-%m-%d"'
LOG_TIME='date "+%H-%M-%S"'

CDATE=`date "+%Y-%m-%d"`
CTIME=`date "+%H-%M-%S"`

#PKG_NAME
TEST=pre
PRODUCT=master

# Shell Env 
SHELL_NAME="deploy.sh"
SHELL_DIR="/home/lzh"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"

# Code Env
PRO_NAME="web-demo"
CODE_DIR="/deploy/code/web-demo"
CONFIG_DIR="/deploy/config/web-demo"
TMP_DIR="/deploy/tmp"
TAR_DIR="/deploy/tar"
LOCK_FILE="/tmp/deploy.lock"

usage(){
    echo $"Usage: $0 {deploy | rollback [ list | version ]}"

}

writelog(){
    LOG_INFO=$1
    echo "${CDATE} ${CTIME}: ${SHELL_NAME} : ${LOG_INFO} " >> ${SHELL_LOG}
}

shell_lock(){
    touch ${LOCK_FILE}
}

url_test(){
    URL=$1
    curl -s --head $URL|grep "200 OK"
    if [ $? -ne 0 ];then
        shell_unlock;
        writelog "test error" && exit;
    fi
}

shell_unlock(){
    rm -f ${LOCK_FILE}
}

code_get(){
    writelog " code_get";
    cd $CODE_DIR && echo "git pull"
    cp -r ${CODE_DIR} ${TMP_DIR}/
    API_VER="456"
}

code_build(){
    echo code_build

}

code_config(){
    writelog "code_config"
    /bin/cp -r ${CONFIG_DIR}/base/* ${TMP_DIR}/"${PRO_NAME}"
    PKG_NAME="${PRO_NAME}"_"$API_VER"_"$TEST"_"${CDATE}-${CTIME}"
    cd ${TMP_DIR} && mv ${PRO_NAME} ${PKG_NAME}
}

code_tar(){
    writelog "code_tar"
    cd ${TMP_DIR} && tar zcf ${PKG_NAME}.tar.gz ${PKG_NAME}
    writelog "${PKG_NAME}.tar.gz"
}

code_scp(){
    writelog "code_scp"
    for node in $PRE_LIST;do
        scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/
    done
    for node in $GROUP1_LIST;do
        scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/
    done
}

pre_deploy(){
    writelog "remove from cluster"
                ssh $PRE_LIST "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
        ssh $PRE_LIST "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
}

pre_test(){
    url_test "http://${PRE_LIST}/index.html"
    echo "add to cluster"
}

group1_deploy(){
    writelog "remove from cluster"
        for node in $GROUP1_LIST;do
                ssh $node "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz"
        ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"
        done
    scp ${CONFIG_DIR}/other/172.16.1.8.crontab.xml 172.16.1.8:/webroot/web-demo/crontab.xml
}

group1_test(){
    url_test "http://172.16.1.8/index.html"
    echo "add to cluster"
}

cluster_node_in(){
    echo cluster_node_in

}

rollback_fun(){
if [ -z $1 ];then
        shell_unlock
        echo "Pls input rollback version" && exit
fi
        for node in $ROLLBACK_LIST;do
            ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/$1 /webroot/web-demo"
        done
}

rollback_list(){
    find /opt/webroot/*.tar.gz -mtime +1|tail -1 |awk -F "[/ .]" '{print$4}'
}

rollback(){
if [ -z $1 ];then
    shell_unlock
    echo "Pls input rollback version" && exit
fi
    case "$1" in
        list)
            ls -l /opt/webroot/*.tar.gz
            ;;
        *)
            rollback_fun $1
    esac
}

main(){
   if [ -f $LOCK_FILE ];then
    echo "Deploy is running" && exit;
   fi
    DEPLOY_METHOD=$1
    ROLLBACK_VER=$2
    case "$DEPLOY_METHOD" in
        deploy)
        shell_lock;
        code_get;
        code_build;
        code_config;
        code_tar;
        code_scp;
        pre_deploy;
        pre_test;
        group1_deploy;
        group1_test;
        shell_unlock;
        ;;
    list)
        rollback_list;
        ;;
       rollback)
        shell_lock;
        rollback $ROLLBACK_VER;
        shell_unlock;
        ;;
       *)
        usage;
  esac
}
main $1 $2

执行部署上线

[lzh@linux_node1 ~]$ ./deploy.sh deploy
git pull
code_build
web-demo_456_pre_2018-09-02-16-06-52.tar.gz                                                        100%  218     0.2KB/s   00:00    
web-demo_456_pre_2018-09-02-16-06-52.tar.gz                                                        100%  218     0.2KB/s   00:00    
HTTP/1.1 200 OK
pre add to cluster
172.16.1.8.crontab.xml                                                                             100%    0     0.0KB/s   00:00    
HTTP/1.1 200 OK
group1 add to cluster

查看当前版本

[lzh@linux_node1 ~]$ ./deploy.sh list
web-demo_456_2018-09-02-15-10-13
web-demo_456_2018-09-02-15-10-13

执行回滚操作

[lzh@linux_node1 ~]$ ./deploy.sh rollback 
Pls input rollback version
[lzh@linux_node1 ~]$ ./deploy.sh 配合list使用  web-demo_456_pre_2018-08-30-00-00-06

查看日志

[lzh@linux_node1 ~]$ tail deploy.sh.log 
2018-09-02 16-45-23: deploy.sh : code_scp 
2018-09-02 16-45-23: deploy.sh : remove from cluster 
2018-09-02 16-45-23: deploy.sh : remove from cluster 
2018-09-02 17-29-54: deploy.sh :  code_get 
2018-09-02 17-29-54: deploy.sh : code_config 
2018-09-02 17-29-54: deploy.sh : code_tar 
2018-09-02 17-29-54: deploy.sh : web-demo_456_pre_2018-09-02-17-29-54.tar.gz 
2018-09-02 17-29-54: deploy.sh : code_scp 
2018-09-02 17-29-54: deploy.sh : remove from cluster 
2018-09-02 17-29-54: deploy.sh : remove from cluster