综合架构 -- 管理服务器

环境准备

使用样板机克隆一台管理服务器,并做好初始化工作:

[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]# 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值