在生产中使用ansible playbook进行新服务(一对一)部署
我们在运维生产环境中,经常会遇到服务的迁移部署,在完成服务初始化及免密登录之后,我们就需要将程序和数据同步到新的机器上,以下是我们在生产中使用 ansible playbook 编写的脚本,由于线上环境的复杂性,我们采用一对一进行新机器环境的部署工作,在实际使用 ansible playbook 的过程中,我们重点使用了 ansible 的变量,此文可能并非最优方案,只希望能做到抛砖引玉的作用,欢迎大佬指正
1 目录结构如下
[@bjyf_50_20 roles]# pwd
/search/ansible/roles
[@bjyf_50_20 roles]# tree
.
|-- adtech
| |-- files
| |-- handlers
| |-- tasks
| | |-- check.yml
| | |-- cron.yml
| | |-- group.yml
| | |-- hadoop_client.yml
| | |-- main.yml
| | |-- monitor.yml
| | |-- pkg_install.yml
| | |-- rsync_data.yml
| | |-- rsync_lib64.yml
| | |-- rsync_sysconf.yml
| | `-- user.yml
| |-- templates
| `-- vars
| `-- main.yml
`-- init
`-- tasks
|-- main.yml
`-- ssh_key.yml
8 directories, 14 files
[@bjyf_50_20 roles]#
2 免密初始化
此脚本有一个缺憾,那就是机器的密码相同,当然如果密码不同也可以定义在 hosts 中,不过为了提高效率,我们写了一个 shell 脚本(查看脚本)
# 免密文件
cat /search/ansible/roles/init/tasks/ssh_key.yml
---
- debug: msg="user=root state=present key={{ lookup('file', '/root/.ssh/id_rsa.pub') }}"
- name: ssh-key copy
authorized_key: user=root state=present key="{{ lookup('file', '/root/.ssh/id_rsa.pub') }}"
#入口文件
cat /search/ansible/roles/init/tasks/main.yml
- include: ssh_key.yml
# hosts文件
cat /etc/ansible/hosts
[rs]
10.162.39.66
10.162.39.64
10.162.49.44
10.162.49.41
10.162.49.42
10.162.49.40
10.162.47.29
10.162.42.60
10.162.38.85
10.162.38.133
10.162.42.58
[rs:vars]
ansible_ssh_pass="noSafeNoWork@2020"
#执行文件
cat /search/ansible/rs.yml
- hosts: rs
remote_user: root
gather_facts: no
roles:
- role: init
#语法检查
ansible-playbook -C rs.yml
#执行
ansible-playbook rs.yml
#效果验证
ansible all -m shell -a 'whoami'
3 task任务
- 环境检查
cat /search/ansible/roles/adtech/tasks/check.yml
---
- debug: msg="rsync {{ src_ip }}::root{{ item }}"
with_items: "{{ src_path }}"
- name: Get IP address
shell: hostname -I |awk '{print $1}'
register: remoteIP
- name: Whether in Caesar or not
shell: curl -s "http://www.test.com/php/ip_search_exec.php?user_name=song&search_ip={{ remoteIP.stdout }}"|grep -ow "{{ remoteIP.stdout }}"
register: caesar
failed_when: caesar.rc == 0
- name: check directory
shell: "rsync {{ src_ip }}::root{{ item }}"
with_items: "{{ src_path }}"
register: result
failed_when: result.rc != 0
- debug: msg="check ok"
- 创建组
cat /search/ansible/roles/adtech/tasks/group.yml
---
- name: create op_biz group
group: name=op_biz system=yes state=present
- name: create hermes group
group: name=hermes system=yes state=present
- 创建用户
cat /search/ansible/roles/adtech/tasks/user.yml
---
- name: Create a username and password
user: name={{ item.name }} password={{ item.pass | password_hash('sha512') }} update_password=always group={{ item.group }} home={{ item.home }}
with_items:
- { name: 'op_biz', pass: 'op_biz2020', group: 'op_biz', home: '/search/odin' }
- { name: 'hermes', pass: 'hermes2020', group: 'hermes', home: '/home/hermes' }
- { name: 'adpc', pass: 'adpc2020', group: 'op_biz', home: '/home/adpc' }
- { name: 'adwl', pass: 'adwl2020', group: 'op_biz', home: '/home/adwl' }
- name: rsync passwd file
shell: rsync -aP {{ src_ip }}::root/etc/passwd /tmp
register: passDone
ignore_errors: True
- name: Check the user home directory
shell: awk 'BEGIN{FS=":"}/op_biz/{print $6}' /tmp/passwd
when: passDone.rc == 0
register: userHome
ignore_errors: True
#- name: print variable
# debug: msg="{{ userHome }}"
- name: usermod op_biz
shell: usermod -d {{ userHome.stdout }} op_biz
register: result
failed_when: result.rc != 0
ignore_errors: True
- debug: msg="useradd done"
- 同步监控脚本
cat /search/ansible/roles/adtech/tasks/monitor.yml
---
- debug: msg="rsync -aP {{ src_ip }}::root/opt/monitor/ /opt/monitor/"
- name: rsync monitor
shell: rsync -aP {{ src_ip }}::root/opt/monitor/ /opt/monitor/
register: result
failed_when: result.rc != 0
- debug: msg="rsync done"
- 同步cron任务
cat /search/ansible/roles/adtech/tasks/cron.yml
---
- name: Turn off the cron service
service: name=crond state=stopped
- debug: msg="rsync -aP {{ src_ip }}::root/var/spool/cron/ /var/spool/cron/"
- name: rsync cron
shell: rsync -aP {{ src_ip }}::root/var/spool/cron/ /var/spool/cron/
register: result
failed_when: result.rc != 0
- debug: msg="rsync done"
- 同步hadoop客户端
cat /search/ansible/roles/adtech/tasks/hadoop_client.yml
---
- debug: msg="rsync -aP {{ src_ip }}::root/opt/hadoop-client /opt/"
- name: rsync hadoop-client
shell: rsync -aP {{ src_ip }}::root/opt/hadoop-client /opt/
register: result
failed_when: result.rc != 0
- name: insert op_biz slave user
copy: content='slave,slave\n' dest=/search/odin/ugi_config
- name: insert root slave user
copy: content='slave,slave\n' dest=/root/ugi_config
- debug: msg="rsync done"
- 同步数据和代码
cat /search/ansible/roles/adtech/tasks/rsync_data.yml
---
- debug: msg="rsync -aP {{ src_ip }}::root{{ item }} {{ item }}"
with_items: "{{ src_path }}"
- name: rsync dir
shell: rsync -aP {{ src_ip }}::root{{ item }} {{ item }} --include='*/' --exclude='*'
with_items: "{{ src_path }}"
register: result
failed_when: result.rc != 0
- debug: msg="rsync -aP {{ src_ip }}::root{{ item }} {{ item }} --exclude={{ ext_data }}"
with_items: "{{ src_path }}"
- name: rsync data
shell: rsync -aP {{ src_ip }}::root{{ item }} {{ item }} --exclude={{ ext_data }}
with_items: "{{ src_path }}"
register: result
failed_when: result.rc != 0
- debug: msg="rsync done"
- 拉取sysconf配置
cat /search/ansible/roles/adtech/tasks/rsync_sysconf.yml
---
- debug: msg="rsync -aP {{ src_ip }}::root/etc/sysctl.conf /etc/"
- name: rsync sysctl.conf
shell: rsync -aP {{ src_ip }}::root/etc/sysctl.conf /etc/
register: result
failed_when: result.rc != 0
- name: reload sysconf
shell: sysctl -p
register: result
failed_when: result.rc != 0
ignore_errors: True #忽略命令执行的错误
- debug: msg="rsync done"
- 拉取lib库文件(请注意不同的操作系统版本不能进行此操作,否则将会导致系统出现错误)
cat /search/ansible/roles/adtech/tasks/rsync_lib64.yml
---
- debug: msg="rsync -aP {{ src_ip }}::root/usr/lib64/{{ lib_file }} /usr/lib64/"
- name: Whether the biddingServer
shell: /usr/bin/ls /search/odin/bin/lead_server
register: isBidding
ignore_errors: True
#- name: print isBidding
# debug: msg="{{ isBidding }}"
- name: rsync /usr/lib64/{{ lib_file }}
shell: rsync -aP {{ src_ip }}::root/usr/lib64/{{ lib_file }} /usr/lib64/
when: isBidding.rc == 0
register: result
failed_when: result.rc != 0
ignore_errors: True
- debug: msg="rsync done"
- 入口文件(按顺序执行)
cat /search/ansible/roles/adtech/tasks/main.yml
- include: check.yml
- include: group.yml
- include: user.yml
- include: monitor.yml
- include: cron.yml
- include: hadoop_client.yml
- include: rsync_data.yml
- include: rsync_sysconf.yml
- include: rsync_lib64.yml
- 变量定义
cat /search/ansible/roles/adtech/vars/main.yml
src_path: ["/search/", "/home/"]
ext_data: "{'log/*','bak/*','*core*','update_data/index/*','update_data/data/*','debug/*','backup/*'}"
lib_file: "{'libcurl*','libhiredis*','libboost_regex*','libboost_thread*','libboost_date*','libboost_filesystem*'}"
pkg_name: ["jemalloc", "htop"]
4. 运行play-book
- 引入roles
cat /search/ansible/deployment.yml
---
- hosts: "{{ server }}"
remote_user: root
gather_facts: no
roles:
- role: init # init是免密文件夹名(做过免密之后可注释此项)
- role: adtech # adtech是tasks文件夹名
- 一对一同步hosts
cat /etc/ansible/hosts
[bidding]
10.162.39.63 src_ip=10.134.57.126 # 前面是旧机器IP,后面是新机器IP
10.162.42.59 src_ip=10.134.49.40
10.162.38.82 src_ip=10.134.49.41
10.162.39.84 src_ip=10.134.57.86
10.162.42.55 src_ip=10.134.57.34
10.162.42.54 src_ip=10.134.57.35 # 同上
- 执行playbook
cd /search/ansible/roles
ansible-playbook deployment.yml -e 'server=bidding'