环境准备
使用样板机克隆一台管理服务器,并做好初始化工作:
[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:1e:c2:14 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.200/24 brd 10.0.0.255 scope global noprefixroute ens160
valid_lft forever preferred_lft forever
inet6 fe80::b4cc:447f:3ee2:dbcc/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:1e:c2:1e brd ff:ff:ff:ff:ff:ff
inet 192.168.1.200/24 brd 192.168.1.255 scope global noprefixroute ens192
valid_lft forever preferred_lft forever
inet6 fe80::8af0:a3d4:7f94:bd90/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@localhost ~]# vi skel_refine.sh
[root@localhost ~]# head -5 skel_refine.sh
#!/bin/bash
hostname=m01
ens160Ipv4="10.0.0.61/24"
ens192Ipv4="192.168.1.61/24"
[root@localhost ~]# ./skel_refine.sh
安装Ansible批量管理软件:
[root@m01 ~]# dnf install ansible
Repository AppStream is listed more than once in the configuration
Repository extras is listed more than once in the configuration
Repository PowerTools is listed more than once in the configuration
Repository centosplus is listed more than once in the configuration
Last metadata expiration check: 0:27:38 ago on Fri 11 Sep 2020 08:38:08 AM CST.
Dependencies resolved.
===============================================================================================================================================================================================
Package Architecture Version Repository Size
===============================================================================================================================================================================================
Installing:
ansible noarch 2.9.11-1.el8 epel 17 M
........ omitted for brevity
查看其主要配置文件及可用命令:
[root@m01 ~]# rpm -ql ansible | grep -Ev "^/usr/(share|lib)"
/etc/ansible
/etc/ansible/ansible.cfg
/etc/ansible/hosts
/etc/ansible/roles
/usr/bin/ansible
/usr/bin/ansible-config
/usr/bin/ansible-connection
/usr/bin/ansible-console
/usr/bin/ansible-doc
/usr/bin/ansible-galaxy
/usr/bin/ansible-inventory
/usr/bin/ansible-playbook
/usr/bin/ansible-pull
/usr/bin/ansible-test
/usr/bin/ansible-vault
[root@m01 ~]#
编写/etc/ansible/hosts(管理主机清单)文件:
[root@m01 ~]# cd /etc/ansible/
[root@m01 ansible]# ls
ansible.cfg hosts roles
[root@m01 ansible]# cp hosts{,.bak}
[root@m01 ansible]# vi hosts
[root@m01 ansible]# cat hosts
# Ex 2: A collection of hosts belonging to the 'webservers' group
## [webservers]
## alpha.example.org
## 192.168.1.100
# If you have multiple hosts following a pattern you can specify
# them like this: www[001:006].example.com
[lbservers]
lb01
lb02
[webservers]
web[01:03]
[nfsservers]
nfs01
[dbservers]
db01
backup
zabbix
[root@m01 ansible]#
测试可连接性:
[root@m01 ~]# ansible all -a "hostname"
The authenticity of host 'lb02 (192.168.1.6)' can't be established.
ECDSA key fingerprint is SHA256:Jkev+sT88yTdhOzdskQQ5bg5vlpU5/JDxwB22QbtDMQ.
The authenticity of host 'lb01 (192.168.1.5)' can't be established.?
ECDSA key fingerprint is SHA256:Jkev+sT88yTdhOzdskQQ5bg5vlpU5/JDxwB22QbtDMQ.
The authenticity of host 'web02 (192.168.1.8)' can't be established.
ECDSA key fingerprint is SHA256:Jkev+sT88yTdhOzdskQQ5bg5vlpU5/JDxwB22QbtDMQ.
The authenticity of host 'web01 (192.168.1.7)' can't be established.
ECDSA key fingerprint is SHA256:Jkev+sT88yTdhOzdskQQ5bg5vlpU5/JDxwB22QbtDMQ.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
web03 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host web03 port 22: No route to host",
"unreachable": true
}
配置SSH
生成密钥文件(全部默认回车):
[root@m01 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:CMxWtEwUye6M5WDGbsLKKucNiL1qu3qD49EXfCE+j54 root@m01
The key's randomart image is:
+---[RSA 3072]----+
| +*o |
| o +o. |
| .=oo. |
| .B.+.. |
| . + %..S |
|.o+ + X |
|++o+ o . |
|=o=+o . |
|XX=..E |
+----[SHA256]-----+
[root@m01 ~]#
分发公钥
- ssh-copy-id:分发公钥指令
- sshpass:无需再手动输入远程主机的密码
- -p 22 :指定远程SSH端口号
- -o “StrictHostKeyChecking=no”:无需再提示是/否与远程主机建立连接
[root@m01 ~]# sshpass -pabcd1234.. ssh-copy-id -i .ssh/id_rsa.pub root@web01 -p 22 -o "StrictHostKeyChecking=no"
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -p '22' -o 'StrictHostKeyChecking=no' 'root@web01'"
and check to make sure that only the key(s) you wanted were added.
[root@m01 ~]# ssh web01
Last login: Fri Sep 11 09:24:46 2020 from 10.0.0.1
[root@web01 ~]#
现无需输入密码,直接SSH远程主机:
[root@m01 ~]# ssh web01
Last login: Fri Sep 11 09:25:08 2020 from 192.168.1.61
[root@web01 ~]# hostname
web01
[root@web01 ~]# exit
logout
Connection to web01 closed.
[root@m01 ~]#
分发其它公钥:
[root@m01 ~]# grep '^192' /etc/hosts | grep -v m01 | awk '{print $2}'
lb01
lb02
web01
web02
web03
nfs01
backup
db01
zabbix
[root@m01 ~]# grep '^192' /etc/hosts | grep -v m01 | awk '{print $2}' | \
> sed -E 's/(.*)/sshpass -pabcd1234.. ssh-copy-id -i .ssh\/id_rsa.pub root@\1 -p 22 -o "StrictHostKeyChecking=no"/g'
sshpass -pabcd1234.. ssh-copy-id -i .ssh/id_rsa.pub root@lb01 -p 22 -o "StrictHostKeyChecking=no"
sshpass -pabcd1234.. ssh-copy-id -i .ssh/id_rsa.pub root@lb02 -p 22 -o "StrictHostKeyChecking=no"
sshpass -pabcd1234.. ssh-copy-id -i .ssh/id_rsa.pub root@web01 -p 22 -o "StrictHostKeyChecking=no"
sshpass -pabcd1234.. ssh-copy-id -i .ssh/id_rsa.pub root@web02 -p 22 -o "StrictHostKeyChecking=no"
sshpass -pabcd1234.. ssh-copy-id -i .ssh/id_rsa.pub root@web03 -p 22 -o "StrictHostKeyChecking=no"
sshpass -pabcd1234.. ssh-copy-id -i .ssh/id_rsa.pub root@nfs01 -p 22 -o "StrictHostKeyChecking=no"
sshpass -pabcd1234.. ssh-copy-id -i .ssh/id_rsa.pub root@backup -p 22 -o "StrictHostKeyChecking=no"
sshpass -pabcd1234.. ssh-copy-id -i .ssh/id_rsa.pub root@db01 -p 22 -o "StrictHostKeyChecking=no"
sshpass -pabcd1234.. ssh-copy-id -i .ssh/id_rsa.pub root@zabbix -p 22 -o "StrictHostKeyChecking=no"
[root@m01 ~]# grep '^192' /etc/hosts | grep -v m01 | awk '{print $2}' | \
> sed -E 's/(.*)/sshpass -pabcd1234.. ssh-copy-id -i .ssh\/id_rsa.pub root@\1 -p 22 -o "StrictHostKeyChecking=no"/g' | bash
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -p '22' -o 'StrictHostKeyChecking=no' 'root@lb01'"
and check to make sure that only the key(s) you wanted were added.
...... omitted for breviry
再次测试Ansible可连接性:
[root@m01 ~]# ansible all -a "hostname"
lb01 | CHANGED | rc=0 >>
lb01
lb02 | CHANGED | rc=0 >>
lb02
web03 | CHANGED | rc=0 >>
web03
web02 | CHANGED | rc=0 >>
web02
web01 | CHANGED | rc=0 >>
web01
nfs01 | CHANGED | rc=0 >>
nfs01
db01 | CHANGED | rc=0 >>
db01
backup | CHANGED | rc=0 >>
backup
zabbix | CHANGED | rc=0 >>
zabbix
[root@m01 ~]#
编写剧本
目标:动态增加WEB服务器集群的数量。
准备一台虚拟机:
克隆机初始化:
[root@localhost ~]# vi skel_refine.sh
[root@localhost ~]# head -5 skel_refine.sh
#!/bin/bash
hostname=web001
ens160Ipv4="10.0.0.10/24"
ens192Ipv4="192.168.1.10/24"
[root@localhost ~]# sh skel_refine.sh
配置hosts文件并分发公钥,然后通过Ansible脚本一键使其成为WEB服务器集群中的一员:
[root@m01 ~]# sed -i '/web03/a 192.168.1.10 web001' /etc/hosts
[root@m01 ~]# sed -i '/^web/a web001' /etc/ansible/hosts
[root@m01 ~]# sshpass -pabcd1234.. ssh-copy-id -i .ssh/id_rsa.pub root@web001 -p 22 -o "StrictHostKeyChecking=no"
剧本:
- 安装相关软件(Nginx、PHP和NFS)
- 拷贝修改Nginx和PHP配置文件
- 挂载相关目录(备份和网站)
- 开启防火墙并配置SELinux及修复/etc/hosts文件
- 启动服务
[root@m01 ~]# cat deply_webserver.yaml
- hosts: web001
tasks:
- name: copy nginx-yum-repository file
copy:
src: /etc/yum.repos.d/nginx.repo
dest: /etc/yum.repos.d/
- name: install nginx, php and nfs-utils
dnf:
name: ['nginx', 'php', 'php-fpm', 'php-mysqlnd', 'php-json', 'nfs-utils']
state: latest
- name: copy nginx-config-file from web01 to web001
synchronize:
src: "/etc/nginx/conf.d/{{ item }}"
dest: /etc/nginx/conf.d/
with_items:
- cloudbarn.conf
- poplarleaf.conf
- cloth_poplarleaf.conf
delegate_to: web01
- name: replace php-fpm running user from apache to nginx
replace:
path: /etc/php-fpm.d/www.conf
regexp: 'apache$'
replace: 'nginx'
- name: copy /etc/fstab file from web01 to web001
synchronize:
src: /etc/fstab
dest: /etc/
delegate_to: web01
- name: replace backup mounting point
replace:
path: /etc/fstab
regexp: 'web01'
replace: 'web001'
- name: create mount point
file:
path: "{{ item }}"
state: directory
recurse: yes
with_items:
- /daily_bak
- /usr/share/nginx/html/cloudbarn
- /usr/share/nginx/html/poplarleaf
- /usr/share/nginx/html/cloth_poplarleaf
- name: remount all
command: mount -a
args:
warn: no
become: true
- name: add service http and https upon firewalld
firewalld:
zone: public
service: "{{ item }}"
permanent: yes
immediate: yes
state: enabled
with_items:
- http
- https
- name: repair /etc/hosts file
command: restorecon /etc/hosts
- name: config selinux
command: setsebool -P "{{ item }}" 1
with_items:
- httpd_use_nfs
- httpd_can_network_connect
- name: start service
service:
name: "{{ item }}"
state: started
enabled: yes
with_items:
- nginx
- php-fpm
当然,这些只是针对web001网站服务器所进行的批量操作。其实,还有很多预备工作需要做:
- 利用远程将web01上的配置文件拷贝到web001时,需先配置SSH公钥访问
[root@web01 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:ogk6MRw0ZRTwBQJuod3K1gAnoguoQSMNGOoE3Hd2TVk root@web01
The key's randomart image is:
+---[RSA 3072]----+
|&%**o. o.oE |
|&*Oo.. o . o |
|B=o.o o . |
|B+.+ |
|=o= . . S |
| = . o . |
|o o |
| . |
| |
+----[SHA256]-----+
[root@web01 ~]# ssh
ssh ssh-add ssh-agent ssh-copy-id sshd ssh-keygen ssh-keyscan
[root@web01 ~]# ssh
ssh ssh-add ssh-agent ssh-copy-id sshd ssh-keygen ssh-keyscan
[root@web01 ~]# sed -i '/web03/a 192.168.1.10 web001' /etc/hosts
[root@web01 ~]# sshpass -pabcd1234.. ssh-copy-id -i .ssh/id_rsa.pub root@web001 -p 22 -o "StrictHostKeyChecking=no"
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -p '22' -o 'StrictHostKeyChecking=no' 'root@web001'"
and check to make sure that only the key(s) you wanted were added.
[root@web01 ~]#
- 在NFS服务器上也要建立好相应目录被配置好访问权限:
[root@nfs01 ~]# cat /etc/exports
/data/web01 web01(rw)
/data/web02 web02(rw)
/data/web03 web03(rw)
/data/web001 web001(rw)
/data/cloudbarn web0[1-3](rw,anonuid=993,anongid=990)
/data/poplarleaf web0[1-3](rw,anonuid=993,anongid=990)
/data/cloth_poplarleaf web0[1-3](rw,anonuid=993,anongid=990)
/data/cloudbarn web001(rw,anonuid=993,anongid=990)
/data/poplarleaf web001(rw,anonuid=993,anongid=990)
/data/cloth_poplarleaf web001(rw,anonuid=993,anongid=990)
[root@nfs01 ~]#
修改Windows主机文件:
10.0.0.10 cloudbarn.com www.cloudbarn.com
10.0.0.10 poplarleaf.com www.poplarleaf.com
10.0.0.10 cloth.poplarleaf.com www.cloth_poplarleaf.com
做一下测试访问:
没问题后加入负载均衡服务器的网站服务器群组里就行了。
扩展
剧本
通过编写yaml剧本文件将管理流程化,编写剧本注意:
- 缩进:上下层级使用两个空格进行缩进
- 冒号:冒号后跟一个空格
- 横线:层级相同且构成列表关系
[root@m01 ~]# cat rsync_server.yaml
- hosts: 172.16.1.41
tasks:
- name: Copy file with owner and permissions
copy:
src: /etc/hosts
dest: /tmp/
owner: rayslee
group: rayslee
mode: '0644'
- name: Copy file with owner and permission, using symbolic representation
copy:
src: /etc/ssh/sshd_config
dest: /tmp/
owner: rayslee
group: rayslee
mode: u=rw,g=r,o=r
- hosts: 172.16.1.31
tasks:
[root@m01 ~]#
编写好的剧本首先进行语法检验:
[root@m01 ~]# ansible-playbook --syntax-check rsync_server.yaml
playbook: rsync_server.yaml
[root@m01 ~]#
通过后再进行模拟测试:
[root@m01 ~]# ansible-playbook -C rsync_server.yaml
PLAY [172.16.1.41] *************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************
ok: [172.16.1.41]
TASK [Copy file with owner and permissions] ************************************************************************************************************************************************************************
changed: [172.16.1.41]
TASK [Copy file with owner and permission, using symbolic representation] ******************************************************************************************************************************************
changed: [172.16.1.41]
PLAY [172.16.1.31] *************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************
ok: [172.16.1.31]
PLAY RECAP *********************************************************************************************************************************************************************************************************
172.16.1.31 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
172.16.1.41 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@m01 ~]#
最后执行:
[root@m01 ~]# ansible-playbook rsync_server.yaml
PLAY [172.16.1.41] *************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************
ok: [172.16.1.41]
TASK [Copy file with owner and permissions] ************************************************************************************************************************************************************************
changed: [172.16.1.41]
TASK [Copy file with owner and permission, using symbolic representation] ******************************************************************************************************************************************
changed: [172.16.1.41]
PLAY [172.16.1.31] *************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************
ok: [172.16.1.31]
PLAY RECAP *********************************************************************************************************************************************************************************************************
172.16.1.31 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
172.16.1.41 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@m01 ~]# ansible 172.16.1.41 -m shell -a "ls -l /tmp | egrep 'hosts|sshd'"
172.16.1.41 | CHANGED | rc=0 >>
-rw-r--r--. 1 rayslee rayslee 330 Sep 1 04:49 hosts
-rw-r--r--. 1 rayslee rayslee 4444 Sep 1 04:49 sshd_config
[root@m01 ~]#
rsync server
编写剧本使其能够自动在172.16.1.41虚拟机上搭建rsyncd备份服务(手动搭建参考
https://blog.csdn.net/weixin_42480750/article/details/108282570
)
[root@m01 ~]# mkdir /etc/ansible/playbook
[root@m01 ~]# vim /etc/ansible/playbook/rsync_server.yaml
[root@m01 ~]# cat /etc/ansible/playbook/rsync_server.yaml
# Deploy rsync-daemon service
- hosts: 172.16.1.41
tasks:
- name: install rsync-daemon package
yum:
name: rsync-daemon
state: latest
- name: copy rsyncd.conf file
copy:
src: /etc/ansible/playbook/rsyncd.conf
dest: /etc/
- name: create rsync user
user:
name: rsync
create_home: no
shell: /sbin/nologin
- name: create directory
file:
path: /backup/nfs01/
state: directory
owner: rsync
group: rsync
- name: create password file
copy:
content: rsync_backup:123456
dest: /etc/rsyncd.password
mode: 600
- name: start service
service:
name: rsyncd
state: started
enabled: yes
在管理服务器上准备好rsyncd.conf文件:
[root@m01 ~]# cat /etc/ansible/playbook/rsyncd.conf
# /etc/rsyncd: configuration file for rsync daemon mode
# See rsyncd.conf man page for more options.
uid = rsync
gid = rsync
port = 873
use chroot = no
max connections = 200
timeout = 300
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
ignore errors
read only = false
hosts allow = 172.16.1.0/24
auth users = rsync_backup
secrets file = /etc/rsyncd.password
# Each client server own a backup dir (or module)
[nfs01]
comment = "nfs-server-01 backup dir"
path = /backup/nfs01
# [nfs02]
# comment = "nfs-server-02 backup dir"
# path = /backup/nfs02
[root@m01 ~]#
运行剧本文件进行部署:
[root@m01 ~]# ansible-playbook /etc/ansible/playbook/rsync_server.yaml
PLAY [172.16.1.41] *************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************
ok: [172.16.1.41]
TASK [install rsync-daemon package] ******************************************************************************************************************************************************************************
changed: [172.16.1.41]
TASK [copy rsyncd.conf file] *************************************************************************************************************************************************************************************
changed: [172.16.1.41]
TASK [create rsync user] *****************************************************************************************************************************************************************************************
ok: [172.16.1.41]
TASK [create directory] ******************************************************************************************************************************************************************************************
changed: [172.16.1.41]
TASK [create password file] **************************************************************************************************************************************************************************************
changed: [172.16.1.41]
TASK [start service] *********************************************************************************************************************************************************************************************
changed: [172.16.1.41]
PLAY RECAP *********************************************************************************************************************************************************************************************************
172.16.1.41 : ok=7 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@m01 ~]#
lsyncd client
编写剧本使其能够自动在172.16.1.31虚拟机上搭建lsyncd实时数据同步服务(手动搭建参考
https://blog.csdn.net/weixin_42480750/article/details/108282570
)
[root@m01 ~]# cat /etc/ansible/playbook/lsyncd_client.yaml
# Deploy lsyncd service
- hosts: 172.16.1.31
tasks:
- name: install epel-release package which contains lsyncd package
yum:
name: epel-release
state: latest
- name: install lsyncd package
yum:
name: lsyncd
state: latest
- name: copy lsyncd.conf file
copy:
src: /etc/ansible/playbook/lsyncd.conf
dest: /etc/
- name: create directory
file:
path: /data/
state: directory
- name: create password file
copy:
content: 123456
dest: /etc/rsyncd.password
mode: 600
- name: start service
service:
name: lsyncd
state: started
enabled: yes
[root@m01 ~]#
在管理服务器上准备好lsyncd.conf文件:
[root@m01 ~]# cat /etc/ansible/playbook/lsyncd.conf
----
-- User configuration file for lsyncd.
--
-- Simple example for default rsync, but executing moves through on the target.
--
-- For more examples, see /usr/share/doc/lsyncd*/examples/
--
settings {
logfile = "/var/log/lsyncd/lsyncd.log",
statusFile = "/var/log/lsyncd/lsyncd-status.log",
statusInterval = 20,
nodaemon = true,
}
sync {
default.rsync,
source = "/data",
target = "rsync_backup@172.16.1.41::nfs01",
delay = 10,
rsync = {
binary = "/usr/bin/rsync",
archive = true,
compress = true,
password_file = "/etc/rsyncd.password"
}
}
[root@m01 ~]#
运行剧本文件进行部署:
[root@m01 ~]# ansible-playbook /etc/ansible/playbook/lsyncd_client.yaml
PLAY [172.16.1.31] *************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************
ok: [172.16.1.31]
TASK [install epel-release package which contains lsyncd package] **************************************************************************************************************************************************
ok: [172.16.1.31]
TASK [install lsyncd package] **************************************************************************************************************************************************************************************
changed: [172.16.1.31]
TASK [copy lsyncd.conf file] ***************************************************************************************************************************************************************************************
changed: [172.16.1.31]
TASK [create directory] ********************************************************************************************************************************************************************************************
changed: [172.16.1.31]
TASK [create password file] ****************************************************************************************************************************************************************************************
changed: [172.16.1.31]
TASK [start service] ***********************************************************************************************************************************************************************************************
changed: [172.16.1.31]
PLAY RECAP *********************************************************************************************************************************************************************************************************
172.16.1.31 : ok=7 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@m01 ~]#
做一下验证:
[root@m01 ~]# ansible 172.16.1.31 -m file -a "dest=/data/test01.sh state=touch"
172.16.1.31 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"dest": "/data/test01.sh",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "unconfined_u:object_r:default_t:s0",
"size": 0,
"state": "file",
"uid": 0
}
[root@m01 ~]# ansible 172.16.1.41 -a "tree /backup"
172.16.1.41 | CHANGED | rc=0 >>
/backup
└── nfs01
└── test01.sh
1 directory, 1 file
[root@m01 ~]#
NFS server
编写剧本使其能够自动在172.16.1.31虚拟机上搭建nfs数据存储服务(手动搭建参考
https://blog.csdn.net/weixin_42480750/article/details/108290467
)
[root@m01 ~]# vim /etc/ansible/playbook/nfs_server.yaml
[root@m01 ~]# cat /etc/ansible/playbook/nfs_server.yaml
- hosts: 172.16.1.31
tasks:
- name: install rpcbind package
dnf:
name: rpcbind
state: latest
- name: install nfs-utils package
dnf:
name: nfs-utils
state: latest
- name: create direcoty
file:
path: /data/web01
state: directory
owner: nobody
group: nobody
recurse: yes
- name: configure nfs-exports file
copy:
content: "/data/web01 172.16.1.7(rw,sync)"
dest: /etc/exports
- name: start rpcbind service
service:
name: rpcbind
state: started
enabled: yes
- name: start nfs-server service
service:
name: nfs-server
state: started
enabled: yes
[root@m01 ~]#
运行剧本文件进行部署:
[root@m01 ~]# ansible-playbook /etc/ansible/playbook/nfs_server.yaml
PLAY [172.16.1.31] *************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************
ok: [172.16.1.31]
TASK [install rpcbind package] *************************************************************************************************************************************************************************************
changed: [172.16.1.31]
TASK [install nfs-utils package] ***********************************************************************************************************************************************************************************
changed: [172.16.1.31]
TASK [create direcoty] *********************************************************************************************************************************************************************************************
changed: [172.16.1.31]
TASK [configure nfs-exports file] **********************************************************************************************************************************************************************************
changed: [172.16.1.31]
TASK [start rpcbind service] ***************************************************************************************************************************************************************************************
changed: [172.16.1.31]
TASK [start nfs-server service] ************************************************************************************************************************************************************************************
changed: [172.16.1.31]
PLAY RECAP *********************************************************************************************************************************************************************************************************
172.16.1.31 : ok=7 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@m01 ~]#
NFS client
编写剧本使其能够自动在172.16.1.7虚拟机上将每天的数据自动备份到NFS服务器(手动搭建参考
https://blog.csdn.net/weixin_42480750/article/details/108290467
)
[root@m01 ~]# vim /etc/ansible/playbook/nfs_client.yaml
[root@m01 ~]# cat /etc/ansible/playbook/nfs_client.yaml
- hosts: 172.16.1.7
tasks:
- name: install nfs-utils package
dnf:
name: nfs-utils
state: latest
- name: create directory as mounting point
file:
path: /daily_bak
state: directory
- name: mount nfs given mounting point
mount:
src: 172.16.1.31:/data/web01
path: /daily_bak
fstype: nfs
state: mounted
- name: create directory as scripts repository
file:
path: /server/scripts
state: directory
- name: copy daily_bak.sh
copy:
src: /etc/ansible/playbook/daily_bak.sh
dest: /server/scripts
- name: edit crontab
cron:
name: "web01 daily backup"
hour: "3"
minute: "0"
job: "/usr/bin/sh /server/scripts/daily_bak.sh &> /dev/null"
[root@m01 ~]#
在管理服务器上准备好daily_bak.sh文件:
[root@m01 ~]# cat /etc/an
anacrontab ansible/
[root@m01 ~]# cat /etc/ansible/playbook/daily_bak.sh
#!/bin/bash
# TARGET files or directories needed to backup
target="/etc/hosts /etc/rc.local
/server/scripts"
bak_dir=/daily_bak
# BACKUP everyday & keep 7 days
tar -zchvf /$bak_dir/`date +%F`.tar.gz $target &>> /$bak_dir/`date +%F`.log
find /$bak_dir -type f -mtime +6 | xargs rm &>> /$bak_dir/`date +%F`.log
[root@m01 ~]#
运行剧本进行部署:
[root@m01 ~]# ansible-playbook /etc/ansible/playbook/nfs_client.yaml
PLAY [172.16.1.7] **************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************
ok: [172.16.1.7]
TASK [install nfs-utils package] ***********************************************************************************************************************************************************************************
changed: [172.16.1.7]
TASK [create directory as mounting point] **************************************************************************************************************************************************************************
changed: [172.16.1.7]
TASK [mount nfs given mounting point] ******************************************************************************************************************************************************************************
changed: [172.16.1.7]
TASK [create directory as scripts repository] **********************************************************************************************************************************************************************
ok: [172.16.1.7]
TASK [copy daily_bak.sh] *******************************************************************************************************************************************************************************************
changed: [172.16.1.7]
TASK [edit crontab] ************************************************************************************************************************************************************************************************
changed: [172.16.1.7]
PLAY RECAP *********************************************************************************************************************************************************************************************************
172.16.1.7 : ok=7 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@m01 ~]#
最终的效果
- 在网站服务器运行备份脚本(其实每天早上3:00自动运行):
[root@web01 ~]# sh /server/scripts/daily_bak.sh
[root@web01 ~]# tree /daily_bak/
/daily_bak/
├── 2020-09-01.log
└── 2020-09-01.tar.gz
0 directories, 2 files
[root@web01 ~]#
- 由于备份目录是挂载在存储服务器上的:
[root@nfs01 ~]# tree /data
/data
└── web01
├── 2020-09-01.log
└── 2020-09-01.tar.gz
1 directory, 2 files
[root@nfs01 ~]#
- 而存储服务器的/data目录又实时与备份服务保持同步:
[root@backup ~]# tree /backup/
/backup/
└── nfs01
└── web01
├── 2020-09-01.log
└── 2020-09-01.tar.gz
2 directories, 2 files
[root@backup ~]#
角色
将服务器写入/etc/hosts
文件:
[root@m01 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.16.1.5 lb01
172.16.1.6 lb02
172.16.1.7 web01
172.16.1.8 web02
172.16.1.9 web03
172.16.1.51 db01 db01.etiantian.org
172.16.1.31 nfs01
172.16.1.41 backup
172.16.1.61 m01
[root@m01 ~]#
在/etc/ansible/hosts
文件中引用相关服务器的域名,预防其IP变动时已写好的剧本不受影响:
[root@m01 ansible]# cat hosts | tail -15
## db-[99:101]-node.example.com
[rsync_server]
backup
[rsync_client]
nfs01
[nfs_server]
nfs01
[nfs_client]
web01
[root@m01 ansible]#
角色位于/etc/ansible/roles
目录中,其目录结构固定:
[root@m01 ansible]# tree roles
roles
├── nfs_server
│ ├── files
│ │ └── exports
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ └── vars
│ └── main.yml
└── site.yml
6 directories, 5 files
[root@m01 ansible]#
nfs_server/tasks/main.yml
记录要执行的任务:
[root@m01 roles]# cat nfs_server/tasks/main.yml
- name: install rpcbind & nfs-utils package
dnf:
name: ['rpcbind', 'nfs-utils']
state: latest
- name: create direcoty
file:
path: "{{ nfs_dir_web01 }}"
state: directory
owner: nobody
group: nobody
recurse: yes
- name: copy configure file
copy:
src: exports
dest: /etc
notify: exportfs
- name: start rpcbind & nfs-server service
service:
name: "{{ item }}"
state: started
enabled: yes
with_items:
- rpcbind
- nfs-server
[root@m01 roles]#
nfs_server/files
目录存放要拷贝的文件:
[root@m01 roles]# cat nfs_server/files/exports
/data/web01 web01(rw,sync)
[root@m01 roles]#
nfs_server/vars/main.yml
文件存放角色需要使用到的变量:
[root@m01 roles]# cat nfs_server/vars/main.yml
nfs_dir_web01: /data/web01
[root@m01 roles]#
nfs_server/handlers/main.yml
文件存放任务中触发的处理器:
[root@m01 roles]# cat nfs_server/handlers/main.yml
- name: exportfs
shell: exportfs -ra
[root@m01 roles]#
执行时在roles根目录编写对应的yml文件并通过命令
ansible-playbook /etc/ansible/roles/site.yml
执行:
[root@m01 roles]# cat site.yml
- hosts: nfs_server
roles:
- nfs_server
[root@m01 roles]#