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
# 微服务名称就是: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
# 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
#!/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
# -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