(1). 前言

(2). 目录定义

lixin-macbook:deploy lixin$ tree
.
├── deploy_roles.yml
├── files -> /Users/lixin/WorkspaceAnsible/files    # 注意:这里的files实际是git clone到本地的一个目录,把clone后目录,软引用过来的
├── handlers
│   └── main.yml
├── tasks
│   ├── def-vars.yml
│   ├── deploy.yml
│   ├── init.yml
│   ├── main.yml
│   └── service.yml
├── templates
│   └── app.sh.j2
└── vars
    └── main.yml


# *************************************************************************
# files结构
# 注意:发版时,定位的构建物的方式是: test-service/2019-09-20/18.20,个人觉得,一个微服务,发版精确到分钟应该差不多.
# 所以,三个参数都要传递,从Jenkins传递变量进来.
# *************************************************************************
lixin-macbook:~ lixin$ tree WorkspaceAnsible/
WorkspaceAnsible/
├── files                                                        # 所有要发版的内容都放在这个目录下
│   └── test-service                                             # 某个微服务
│       ├── 2019-09-20
│       │   └── 18.20
│       │       ├── conf
│       │       │   └── application.properties
│       │       └── lib
│       │           └── hello-service.jar
│       └── 2019-09-21
├── hosts                                                         # 存放所有的hosts
│   └── test-service
└── shell                                                         # 所有的shell
    ├── list-dir.sh
    └── list-hosts.sh

(3). 规定hosts

# 微服务名称就是:hosts文件名称
# /Users/lixin/WorkspaceAnsible/hosts/test-service
[erp]
10.211.55.100 ansible_ssh_user=root
10.211.55.101 ansible_ssh_user=root

# 针对灰度发布
[erp-a]
10.211.55.100 ansible_ssh_user=root

[erp-b]
10.211.55.101 ansible_ssh_user=root

[alibaba]
10.211.55.100 ansible_ssh_user=root

[tencent]
10.211.55.101 ansible_ssh_user=root

(4). Playbook定义

由于jekyll语法和代码有冲突,建议直接去github下载,参照学习,在笔记里,我只记录了过程.
# 1. 创建部署目录
lixin-macbook:~ lixin$ cd ~/GitRepository/
lixin-macbook:GitRepository lixin$ mkdir ansible_roles/
lixin-macbook:WorkspaceAnsible lixin$ mkdir -p deploy/{files,handlers,tasks,templates,vars}
lixin-macbook:WorkspaceAnsible lixin$ cd deploy


# 2. 定义变量(在Ansible中,变量不能包含中划线)
# service_name,通过jenkins读取变量,传递进来.
lixin-macbook:deploy lixin$ cat > vars/main.yml <<EOF
app:
  dir: /home/tomcat
  name: ""
  bin:  bin
  conf: conf
  lib:  lib
  logs: logs
  shell: app.sh
EOF
  
# 3. 定义task(定义变量)
lixin-macbook:deploy lixin$ cat > tasks/def-vars.yml <<EOF
- name: define local var local_conf
  set_fact: local_conf="///conf/*"
  tags :
    - deploy

- name: define local var local_lib
  set_fact: local_lib="///lib/*"
  tags :
    - deploy

- name: define remote var app_path
  set_fact: app_path="/"
  tags :
    - init

- name: define remote var app_bin
  set_fact: app_bin="//"
  tags :
    - stop
    - start
    - restart
    - init
    - deploy

- name: define remote var app_conf
  set_fact: app_conf="//"
  tags :
    - deploy
    - init

- name: define remote var app_lib
  set_fact: app_lib="//"
  tags :
    - deploy
    - init

- name: define remote var app_logs
  set_fact: app_logs="//"
  tags :
    - init

# 日志输出
#- name: print vars
#  ansible.builtin.debug:
#    msg: " ,  ,  ,  ,  ,  "

EOF

# 3. 定义task(deploy.yml)
#   注意:这里只有配置文件或者JAR包有变化的情况下,才会触发:restarts,切记
lixin-macbook:deploy lixin$ cat > tasks/deploy.yml <<EOF
- name: copy config
  copy: src="" dest="/" backup=yes
  notify: restart app handler
  with_fileglob:
    - ""

- name: copy lib
  copy: src="" dest="/" backup=yes
  notify: restart app handler
  with_fileglob:
    - ""

EOF

# 3. 定义task(init.yml)
lixin-macbook:deploy lixin$ cat > tasks/init.yml <<EOF
- name: mkdir app dir
  file: state=directory recurse=yes path=
  with_items:
    - ""
    - ""
    - ""
    - ""
- name: create shell app.sh
  template: src=app.sh.j2 dest="/app.sh" owner=root group=root mode=755 force=yes

EOF

# 3. 定义task(停止/启动微服务)
lixin-macbook:deploy lixin$ cat >  tasks/service.yml  <<EOF
- name: stop app
  shell: "/ stop"
  tags :
    - stop
- name: start app
  shell: "/ start"
  tags :
    - start
- name: restart app task
  shell: "/ restart"
  tags :
    - restart

EOF


# 3. 定义task(man.yml)
lixin-macbook:deploy lixin$ cat > tasks/main.yml <<EOF
# init                   :  主要用于创建项目脚手架(mkdir -p test-service/{bin/conf/lib/logs}),以及创建可执行文件app.sh
# deploy                 :  主要用于拷贝conf/lib到被管控机器上
# stop/start/restart     :  主要用于服务的启动/关闭/重启(app.sh start/stop/restart)

- include: def-vars.yml
- include: init.yml
  tags :
    - init

- include: deploy.yml
  tags :
    - deploy

- include: service.yml

EOF

# 4. 定义handler(main.yml)
lixin-macbook:deploy lixin$ cat >  handlers/main.yml  <<EOF
- name: restart app handler
  shell: "/ restart"

EOF

# 5. 定义roles
lixin-macbook:deploy lixin$ cat >  deploy_roles.yml  <<EOF
 - hosts: ""    # 要给哪些host发版,也通过变量传递
   remote_user: root
   gather_facts: no
   roles:
     - role: jdk            # 会先安装JDK
     - role: deploy         # 再进行部署

EOF

(5). 定义模板app.sh.j2

#!/bin/bash
error_exit ()
{
    echo "ERROR: $1 !!"
    exit 1
}

[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=$HOME/jdk/java
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/java
[ ! -e "$JAVA_HOME/bin/java" ] && error_exit "Please set the JAVA_HOME variable in your environment, We need java(x64)!"

APP_HOME=
PID_FILE=${APP_HOME}/bin/pid
JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m"

# 如果参数小于1个,则提示,并退出.
if [ $# -ne 1 ]; then
   echo "Usage: $0 {start|stop|restart}"
   exit 1;
fi


check(){
   # 如果pid文件存在,则不允许重新启动
   if [ -f ${PID_FILE} ]; then
       echo "应用程序已经启动,不允许重复启动!";
       exit 1;
   fi
}

start(){
        # 提示启动中
        echo "start..."
        nohup $JAVA_HOME/bin/java $JAVA_OPT -jar ${APP_HOME}/lib/* > /dev/null 2>&1 &
        # 生成pid文件
    echo $! > ${PID_FILE}
}

stop(){
        # 文件存在的情况下,才能根据进程pid kill
        if [ -f ${PID_FILE} ]; then
            echo "kill pid:`cat ${PID_FILE}`"
            echo "stop..."
                kill -SIGTERM `cat ${PID_FILE}`
                rm -rf ${PID_FILE}
        fi
}

case "$1" in
  "start")
    check
    start
  ;;

  "stop")
    stop
  ;;

  "restart")
    stop
    start
  ;;
esac

(6). 调用Ansible

# -t init要先执行,相当于运维先打一个脚手架出来,也可以:init,deploy一起执行.
# 创建骨架以及停止,启动,重启之所以需要servie_name,是因为:要定位到该目录下执行:app.sh stop/start/restart
# -t init: 创建项目骨架
ansible-playbook deploy/deploy_roles.yml -e "service_name=test-service"  -t init

# -t stop/start/restart 服务管理
ansible-playbook deploy/deploy_roles.yml -e "service_name=test-service"  -t stop
ansible-playbook deploy/deploy_roles.yml -e "service_name=test-service"  -t start
ansible-playbook deploy/deploy_roles.yml -e "service_name=test-service"  -t restart

# -t deploy: 部署项目
# Ansible会把以下三个变量拼接出来,来定位要发版的构建物.  
# -e "service_name=test-service"  : 微服务的名称
# -e "second_dir=2019-09-20"      : 二级目录
#  -e "three_dir=18.20"           : 三级目录
ansible-playbook deploy/deploy_roles.yml -e "service_name=test-service" -e "second_dir=2019-09-20" -e "three_dir=18.20" -t init,deploy

(7). 下载地址

“ansible roles”