Day38 - 39 课堂笔记

SSH批量管理项目如何一键一秒钟完成:一秒完成。

1.ssh-keygen非交互式创建秘钥对:

具体命令:ssh-keygen -f ~/.ssh/id_rsa  -P '' -q

参数讲解:

ssh-keygen:密钥对创建工具

[-P old_passphrase]  密码

[-f output_keyfile]  输出的秘钥文件

    [-q]      不输出信息     

[-t dsa ]  指定秘钥类型。

2.ssh-copy-id不需要提示yes/no分发秘钥

具体命令:ssh-copy-id -f -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no 172.16.1.8

参数讲解:

ssh-copy-id  -f  -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no root172.16.1.8

ssh-copy-id [-f] [-i [identity_file]] [-p port] [[-o ] ...] [user@]hostname

说明:

-f: force mode 强制

[-i [identity_file]] 指定秘钥文件

[[-o ] ...] 指定ssh参数选项。

3.sshpass工具:指定密码非人工交互分发秘钥

sshpass -p123456 ssh-copy-id -f -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 172.16.1.7

[root@web02 ~]# sshpass -help

Usage: sshpass [-f|-d|-p|-e] [-hV] command parameters

sshpass -p123456 ssh-copy-id -f -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 172.16.1.7

sshpass [-f|-d|-p|-e] [-hV] command parameters

参数讲解:

-p password  Provide password as argument (security unwise)    #指定用户密码操作

4.一键配置实践

把web02作为分发服务器:

web02(8)-->m01(61)

web02(8)-->web01(7)

ssh-keygen -f ~/.ssh/id_rsa  -P '' -q

ssh-copy-id -f -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 172.16.1.7

sshpass -p123456 ssh-copy-id -f -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 172.16.1.7

#!/bin/bash

#yum install sshpass -y

ssh-keygen -f ~/.ssh/id_rsa  -P '' -q

for ip in 7 61

do

  sshpass -p123456 ssh-copy-id -f -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 172.16.1.$ip

done

#test

ssh 172.16.1.7 "ifconfig eth0"

ssh 172.16.1.61 "ifconfig eth0"

老男孩Linux58期-ansible自动化管理实践

0.运维发展历史

开发给运维打工:

人肉运维(1万-2万)---自动化(使用自动5000工资)--->平台化(5000元工资)---

                      开发自动化(2-3万)          开发平台的(2-4万)(Python/Shell)


--->可视化运维(简单化、表现价值)----->智能化(人也不要了)(aiops)

开发可视化(2-5万)(Python/Shell)    开发智能化的产品(机器人)(大数据+人工智能) 机器学习、深度学习。

834万,本科400万



1.ansible介绍

ssh秘钥认证+脚本批量管理,特点:简单、实用,

但是看起来比较LOW,需要人工写脚本,类似实时复制的inotify工具。

2013以前这种方式很普遍。

MySQL高可用 MHA集群,要求所有机器互相秘钥认证。

大数据集群也需要。 服务器越多价值越大

2.批量管理工具历史

SSH+脚本 CFEngine、Puppet、saltstack              、ansible

08年以前 07-08年  10-13年  14-17(python开发)      16-(python开发)

        sina网

3.为什么用ansible?

简单、方便、容易学习、功能同样强大。

ansible有配置文件,可以多线程直接实现。不需要写脚本,类似实时复制的sersync。

4.什么是ansible?

Ansible是一个用来远程管理服务器的工具软件。

Ansible是一个用来批量部署远程主机上服务的工具。这里“远程主机(Remote Host)”是指任

何可以通过SSH登录的主机,所以它既可以是远程虚拟机或物理机,也可以是本地主机。

Ansible通过SSH协议实现管理节点与远程节点之间的通信。理论上来说,只要能通过SSH登录到

远程主机来完成的操作,都可以通过Ansible实现批量自动化操作。

涉及管理操作:复制文件、安装服务、服务启动停止管理、配置管理等等。

5.为什么要用批量管理工具运维?

提高效率,百度几万台服务器,阿里几十万台服务器。

如何省钱?

SSD+SATA 热点存储 15 15 7


6.Ansible特点

Ansible基于Python语言实现,由Paramiko和PyYAML两个关键模块构建。

Shell、Python是Linux运维学员必会的两门语言。

1)安装部署过程特别简单,学习曲线很平坦。

2)不需要单独安装客户端,只是利用现有的SSHD服务(协议)即可。

3)不需要服务端(no servers)。

4)ansible playbook,采用yaml配置,提前编排自动化任务。

5)ansible功能模块较多,对于自动化的场景支持丰富。

官方:http://docs.ansible.com

7.Ansible架构介绍(见图说明)

1、连接插件connectior plugins用于连接主机 用来连接被管理端

2、核心模块 core modules 连接主机实现操作, 它依赖于具体的模块来做具体的事情

3、自定义模块 custom modules,根据自己的需求编写具体的模块

4、插件 plugins,完成模块功能的补充

5、剧本 playbooks,ansible的配置文件,将多个任务定义在剧本中,由ansible自动执行

6、主机清单 inventor,定义ansible需要操作主机的范围

最重要的一点是 ansible是模块化的 它所有的操作都依赖于模块

(懂Python可以二次开发)

超过13K:

54期郑赫杨 15K 18K 20K

1、自我要求特别高(AQ特别高)。

2、学习特别努力(周六日自习)

3、媳妇硕士,北京市公务员。

4、入学1个月左右 单独学了周末MySQL班,好几个一起学的。

5、中专 99年 7个offer,中下等学生。

建议:期中架构以后学一门周末课程

网络安全课程、python自动化课程、周末MySQL班、GO语言

8.ansible实践环境准备

61(m01)====>31(nfs01)

61(m01) ====>41(backup)

9.安装ansible

m01管理机:

yum install epel-release -y

yum install ansible -y

#如果有libselinux-python就不执行下面的命令了。

#rpm -qa |grep libselinux-python

#yum install libselinux-python -y

其他所有机器:

#rpm -qa |grep libselinux-python

#yum install libselinux-python -y

10.主机列表配置

ssh列表实现方法:

for n  in 7 8

do

echo 172.16.1.$n

done

/etc/ansible/hosts主机资产清单文件,用于定义被管理主机的认证信息,

例如ssh登录用户名、密码以及key相关信息。如何配置Inventory文件

1.主机支持主机名通配以及正则表达式,例如web[1:3].oldboy.com代表三台主机

2.主机支持基于非标准的ssh端口,例如web1.oldboyedu.com:6666

3.主机支持指定变量,可对个别主机的特殊配置,如登陆用户\密码

4.主机组支持指定变量[group_name:vars],同时支持嵌套组[game:children]

实践:

cp /etc/ansible/hosts{,.ori}

cat >/etc/ansible/hosts<

[oldboy]

172.16.1.31

172.16.1.41

[oldgirl]

172.16.1.31

172.16.1.41

172.16.1.51

EOF

cat /etc/ansible/hosts

/etc/ansible/ansible.cfg #ansible的配置文件

11.小试牛刀

直接执行如下命令或报错

ansible oldboy -m command -a "free -m"

基于SSH秘钥认证的前提下:

如果没有做SSH秘钥认证,可以把用户名密码写到

/etc/ansible/hosts

[oldboy_pass]

172.16.1.7 ansible_ssh_user=root ansible_ssh_pass=123456

172.16.1.8 ansible_ssh_user=root ansible_ssh_pass=123456

ansible oldboy -m command -a "free -m" 要想成功,先解决yes/no的问题。

1、ssh连接一遍。

2、ssh -o 参数

上述命令就是sshpass的封装

==========================================

ansible关闭ssh首次连接时yes/no提示

使用ssh连接时,可以使用-o参数将StrictHostKeyChecking设置为no,

避免使用ssh连接时避免首次连接时让输入yes/no部分的提示。

方法1:修改 /etc/ansible/ansible.cfg中的374行

369 [ssh_connection]

370

371 # ssh arguments to use

372 # Leaving off ControlPersist will result in poor performance, so use

373 # paramiko on older platforms rather than removing it, -C controls compression use

374 #ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s

374行改为:

ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no

方法2:修改 /etc/ansible/ansible.cfg中的71行

70 # uncomment this to disable SSH key host checking

71 #host_key_checking = False

71行的注释取消:host_key_checking = False

==========================================

[root@m01 /server/scripts]# > ~/.ssh/known_hosts

[root@m01 /server/scripts]# ssh 172.16.1.31

The authenticity of host '172.16.1.31 (172.16.1.31)' can't be established.

ECDSA key fingerprint is SHA256:qZSBkrmOv7xO/63qOU1uLXkPyNVHdkqvrNAcAmXqNEk.

ECDSA key fingerprint is MD5:23:d0:cb:a9:f4:7c:0b:eb:2d:07:00:e1:a3:12:d8:33.

Are you sure you want to continue connecting (yes/no)? ^C

[root@m01 /server/scripts]# ansible oldboy -m command -a "free -m"

172.16.1.31 | CHANGED | rc=0 >>

              total        used        free      shared  buff/cache  available

Mem:            972          88        592          13        291        708

Swap:          767          0        767

172.16.1.41 | CHANGED | rc=0 >>

              total        used        free      shared  buff/cache  available

Mem:            972          89        572          13        310        706

Swap:          767          0        767

目标:ansible是不是需要免秘钥认证(ssh免秘钥认证)? yes

[root@m01 ~]# cat /etc/ansible/hosts

[oldboy]

172.16.1.31

172.16.1.7

还原ansible.cfg配置,重启服务器

[root@m01 ~]# ansible oldboy -m command -a "free -m"

The authenticity of host '172.16.1.7 (172.16.1.7)' can't be established.

ECDSA key fingerprint is SHA256:qZSBkrmOv7xO/63qOU1uLXkPyNVHdkqvrNAcAmXqNEk.

ECDSA key fingerprint is MD5:23:d0:cb:a9:f4:7c:0b:eb:2d:07:00:e1:a3:12:d8:33.

Are you sure you want to continue connecting (yes/no)? The authenticity of host '172.16.1.31 (172.16.1.31)' can't be established.

ECDSA key fingerprint is SHA256:qZSBkrmOv7xO/63qOU1uLXkPyNVHdkqvrNAcAmXqNEk.

ECDSA key fingerprint is MD5:23:d0:cb:a9:f4:7c:0b:eb:2d:07:00:e1:a3:12:d8:33.

Are you sure you want to continue connecting (yes/no)?

解决yes/no不需要输入问题:

修改ansible.cfg 374行:

ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no

在执行报错:

[root@m01 ~]# ansible oldboy -m command -a "free -m"

172.16.1.7 | UNREACHABLE! => {

    "changed": false,

    "msg": "Failed to connect to the host via ssh: Warning: Permanently added '172.16.1.7' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,password).",

    "unreachable": true

}

172.16.1.31 | UNREACHABLE! => {

    "changed": false,

    "msg": "Failed to connect to the host via ssh: Warning: Permanently added '172.16.1.31' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",

    "unreachable": true

}

解决公钥问题:

ssh-keygen -f ~/.ssh/id_rsa  -P '' -q

for ip in 7

do

  sshpass -p123456 ssh-copy-id -f -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 172.16.1.$ip

done

#test

ssh 172.16.1.7 "ifconfig eth0"

执行ansible命令:

[root@m01 ~]# ansible oldboy -m command -a "free -m"

172.16.1.31 | UNREACHABLE! => {

    "changed": false,

    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",

    "unreachable": true

}

172.16.1.7 | CHANGED | rc=0 >>

              total        used        free      shared  buff/cache  available

Mem:            972          69        807          7          95        771

Swap:          767          0        767

for ip in 31

do

  sshpass -p123456 ssh-copy-id -f -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 172.16.1.$ip

done

#test

ssh 172.16.1.31 "ifconfig eth0"

[root@m01 ~]# ansible oldboy -m command -a "free -m"

172.16.1.7 | CHANGED | rc=0 >>

              total        used        free      shared  buff/cache  available

Mem:            972          69        807          7          95        771

Swap:          767          0        767

172.16.1.31 | CHANGED | rc=0 >>

              total        used        free      shared  buff/cache  available

Mem:            972          71        804          7          96        768

Swap:          767          0        767

验证:删除公钥,是不是不可以了?

重启后,不行,重启前可以

[root@m01 ~]# ansible oldboy -m command -a "free -m"

172.16.1.7 | UNREACHABLE! => {

    "changed": false,

    "msg": "Failed to connect to the host via ssh: Warning: Permanently added '172.16.1.7' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,password).",

    "unreachable": true

}

172.16.1.31 | UNREACHABLE! => {

    "changed": false,

    "msg": "Failed to connect to the host via ssh: Could not create directory '/root/.ssh'.\r\nWarning: Permanently added '172.16.1.31' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",

    "unreachable": true

}

修改Host增加用户和密码:

[root@m01 ~]# cat /etc/ansible/hosts

#[oldboy]

#172.16.1.31

#172.16.1.7

[oldboy_pass]

172.16.1.31 ansible_ssh_user=root ansible_ssh_pass=123456

172.16.1.7 ansible_ssh_user=root ansible_ssh_pass=123456

结果:

[root@m01 ~]# ansible oldboy_pass -m command -a "free -m"

172.16.1.31 | CHANGED | rc=0 >>

              total        used        free      shared  buff/cache  available

Mem:            972          79        791          7        101        758

Swap:          767          0        767

172.16.1.7 | CHANGED | rc=0 >>

              total        used        free      shared  buff/cache  available

Mem:            972          69        806          7          95        771

Swap:          767          0        767

结论:使用SSH连接:

密码认证 host里主机后面加密码        Paramiko模块 重点:

秘钥认证:提前发公钥,才能用ansible.  SSHPASS工具

http://docs.ansible.com/ansible/latest/intro_inventory.html#list-of-behavioral-inventory-parameters

特殊端口:

[oldboy]

172.16.1.7  ansible_port=52113  ansible_user=root ansible_ssh_pass=123456

172.16.1.8  ansible_port=52113  ansible_user=root ansible_ssh_pass=123456

12.基于SSH秘钥认证的实践

一键创建及分发秘钥:

#!/bin/bash

ssh-keygen -f ~/.ssh/id_rsa  -P '' -q

for ip in 7 8 41 31

do

  sshpass -p123456 ssh-copy-id -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 172.16.1.$ip

done

[root@m01 ~]# cat /etc/ansible/hosts

[oldboy]

172.16.1.31

172.16.1.41

172.16.1.7

[root@m01 ~]# ansible oldboy -m command -a "free -m" #和前面sh cmd.sh "free -m"

11.ansible命令参数

-m MODULE_NAME, 模块名字,默认command

-a MODULE_ARGS, 模块参数

-f FORKS     并发进程数,默认5个。

-i INVENTORY(default=/etc/ansible/hosts)指定主机列表文件

===================

ansible

ansible-doc

ansible-playbook

ansible-galaxy

===================

12.ansible模块查看和帮助*****

查找模块

ansible-doc -l          #模块就Linux命令了。

查看某个模块的具体参数帮助

ansible-doc -s command  #Linux命令参数

[root@m01 /data]# ansible 172.16.1.31 -m copy -a "src=/data/root dest=/var/spool/cron/root"

172.16.1.31 | SUCCESS => {

    "changed": false,

    "checksum": "05bdd2e97b52cbd90bd71b6c3ee78118ebbbcad5",

    "dest": "/var/spool/cron/root",

    "gid": 0,

    "group": "root",

    "mode": "0600",

    "owner": "root",

    "path": "/var/spool/cron/root",

    "size": 166,

    "state": "file",

    "uid": 0

}

12.1 command模块 *****

1)功能说明:

command  Executes a command on a remote node

功能说明:执行一个命令在远程节点上

操作实践:

ansible oldboy -m command -a "free -m"

ansible oldboy -m command -a "df -h"

ansible oldboy -m command -a "ls /root"

ansible oldboy -m command -a "cat redhat-release"

ansible oldboy -m command -a "cat /etc/redhat-release"

最通用的功能。

[root@m01 ~]# ansible oldboy -m command -a "cat /etc/redhat-release"

172.16.1.7 | CHANGED | rc=0 >>

CentOS Linux release 7.6.1810 (Core)

172.16.1.31 | CHANGED | rc=0 >>

CentOS Linux release 7.6.1810 (Core)

172.16.1.41 | CHANGED | rc=0 >>

CentOS Linux release 7.6.1810 (Core)

[root@m01 ~]# cat /server/scripts/cmd.sh

for n in 31 41

do

  echo "=====172.16.1.$n======"

  ssh 172.16.1.$n "$1"

done

[root@m01 ~]# sh /server/scripts/cmd.sh "cat /etc/redhat-release"

=====172.16.1.31======

CentOS Linux release 7.6.1810 (Core)

=====172.16.1.41======

CentOS Linux release 7.6.1810 (Core)

特殊:不支持的东西,例如 > < | &等 $HOME,替代方案用shell模块

ansible oldboy -m shell -a "ps -ef|grep ssh"

ansible oldboy -m shell -a "echo oldboy >/tmp/a.log"

2)常用参数说明及实践

[root@m01 ~]# ansible-doc -s command

- name: Executes a command on a remote node

  command:

      argv:                  # Allows the user to provide the command as a list vs. a string.  Only the

                              string or the list form can be provided, not

                              both.  One or the other must be provided.

      chdir:                # Change into this directory before running the command.

      creates:              # A filename or (since 2.0) glob pattern. If it already exists, this step

                              *won't* be run.

      free_form:            # (required) The command module takes a free form command to run.  There is no

                              parameter actually named 'free form'. See the

                              examples!

      removes:              # A filename or (since 2.0) glob pattern. If it already exists, this step *will*  be run.

      stdin:                # Set the stdin of the command directly to the specified value.

      warn:                  # If command_warnings are on in ansible.cfg, do not warn about this particular

                              line if set to `no'.




参数:chdir=/tmp配置相当于cd /tmp

[root@m01 ~]# ansible oldboy  -m command -a "pwd chdir=/etc"

ansible oldboy  -m shell -a "cd /etc/;pwd"

参数:creates=/etc  相当于条件测试  [ -e /etc ]||pwd 和下面removes相反

[root@m01 ~]# ansible oldboy  -m command -a "pwd creates=/etc"

参数:removes=/root 相当于条件测试 [ -e /root ]&&ls /root

ansible oldboy  -m command -a "ls /root removes=/root"

ansible oldboy  -m shell -a "[ -d /etc ]||pwd"

[root@m01 ~]# ansible oldboy  -m command -a "cat /etc/hosts removes=/etc/hosts"

参数:warn=False 忽略警告

[root@m01 ~]# ansible oldboy  -m command -a "chmod 000 /etc/hosts warn=False"

更多官方链接:http://docs.ansible.com/ansible/latest/command_module.html或ansible-doc -s command

=====================================================================================

项目实践:

rsync服务器端:31、41

rsync客户端:7、8

实现:从7推送文件到31,从8推送文件到41.

shell模块:实现上面

12.2 shell模块功能说明:

功能说明:执行一个命令在远程节点上

shell  Execute commands in nodes.

官方链接:http://docs.ansible.com/ansible/latest/shell_module.html

  shell:

      chdir:                # cd into this directory before running the command

      creates:              # a filename, when it already exists, this step will *not* be

                              run.

      executable:            # change the shell used to execute the command. Should be an

                              absolute path to the

                              executable.

      free_form:            # (required) The shell module takes a free form command to run,

                              as a string.  There's not an

                              actual option named "free

                              form".  See the examples!

      removes:              # a filename, when it does not exist, this step will *not* be

                              run.

      stdin:                # Set the stdin of the command directly to the specified value.

      warn:                  # if command warnings are on in ansible.cfg, do not warn about

                              this particular line if set to  no/false.

[root@m01 ~]# cat /etc/ansible/hosts

[oldboy]

172.16.1.31

172.16.1.41  

实践:增加文本文件

[root@m01 ~]# ansible oldboy -m shell -a "echo oldboy >/tmp/tmp.txt"

172.16.1.41 | CHANGED | rc=0 >>

172.16.1.31 | CHANGED | rc=0 >>

[root@m01 ~]# ansible oldboy -m shell -a "cat /tmp/tmp.txt"

172.16.1.41 | CHANGED | rc=0 >>

oldboy

172.16.1.31 | CHANGED | rc=0 >>

oldboy

要执行的脚本必须在远程机器上存在:

[root@m01 ~]# ansible oldboy -m shell -a "sh /server/scripts/bak.sh"

172.16.1.41 | FAILED | rc=127 >>

sh: /server/scripts/bak.sh: 没有那个文件或目录non-zero return code

172.16.1.31 | CHANGED | rc=0 >>

实践1:把/etc/hosts拷贝到/opt下,权限设置400,用户和组设置root

ansible oldboy -m copy -a "src=/etc/hosts dest=/opt mode=0400 owner=root group=root backup=yes"

实践2:把/etc/passwd拷贝/tmp下改名为oldgirl,用户和组为oldboy,权限600,如果有存在同名文件覆盖


ansible oldboy -m copy -a "src=/etc/passwd dest=/tmp/oldgirl.txt owner=oldboy group=oldboy mode=0600 force=yes"

批量分发host需求,操作前备份:

ansible oldboy -m copy -a "src=/etc/hosts dest=/etc/hosts mode=0644 owner=root group=root backup=yes"

结果:

[root@backup /tmp]# ls /etc/hosts* -l

-rw-r--r--  1 root root 353 4月  24 10:49 /etc/hosts

----------  1 root root 332 4月  12 11:24 /etc/hosts.21951.2019-04-24@10:49:00~

项目实践作业:

1、写好rsync一键客户端配置,一键服务端配置。

2、写好nfs一键服务端端配置,一键客户端挂载,并且加到自启动文件里(/etc/rc.local,/etc/fstab)。

shell模块远程执行脚本:脚本必须在远端存在

ansible oldboy  -m shell -a "/bin/bash /server/scripts/setup.sh"

12.3  script模块功能说明:

功能说明:远程节点上运行本地脚本模块

官方链接:http://docs.ansible.com/ansible/latest/script_module.html

参数说明:

ansible oldboy -m shell -a "sh /server/scripts/bak.sh"

[root@m01 /server/scripts]# ansible oldboy -m shell -a "sh /server/scripts/bak.sh"

172.16.1.41 | FAILED | rc=127 >>

sh: /server/scripts/bak.sh: 没有那个文件或目录non-zero return code

172.16.1.31 | FAILED | rc=127 >>

sh: /server/scripts/bak.sh: 没有那个文件或目录non-zero return code

[root@m01 /server/scripts]# cat new.sh

#!/bin/sh

echo oldboy >/tmp/oldboy.txt

本地脚本,在远端执行。

[root@m01 /server/scripts]# ansible oldboy -m script -a "/server/scripts/new.sh"

项目实践作业:

rsync服务端写成脚本 r1.sh

rsync客户端写成脚本 r2.sh

nfs服务端写成脚本 n1.sh

nfs客户端写成脚本 n2.sh

sersync服务端写成脚本 s1.sh

sersync客户端写成脚本 s2.sh

/server/scripts/one_key_gaoding.sh

ansible r1 -m copy -a "src=/server/scripts/r1.sh dest=/server/scripts/ mode=ugo+x"

ansible r1 -m shell -a "sh /server/scripts/r1.sh"

ansible r1 -m copy -a "src=/server/scripts/r2.sh dest=/server/scripts/ mode=ugo+x"

ansible r2 -m shell -a "sh /server/scripts/r2.sh"

ansible n1 -m shell -a "sh /server/scripts/n1.sh"

ansible n2 -m shell -a "sh /server/scripts/n2.sh"

ansible s1 -m shell -a "sh /server/scripts/s1.sh"

ansible s2 -m shell -a "sh /server/scripts/s2.sh"

/bin/sh /server/scripts/one_key_gaoding.sh

也可以使用script模块,替代copy+shell模块

12.4 copy模块功能说明:

功能说明:复制文件到远程主机

官方链接:http://docs.ansible.com/ansible/latest/copy_module.html

参数说明:

[root@m01 ~]# ansible oldboy -m shell -a "sh /server/scripts/bak.sh"

172.16.1.31 | FAILED | rc=127 >>

sh: /server/scripts/bak.sh: 没有那个文件或目录non-zero return code

172.16.1.41 | FAILED | rc=127 >>

sh: /server/scripts/bak.sh: 没有那个文件或目录non-zero return code

ansible oldboy -m copy -a "src=/server/scripts/bak.sh dest=/server/scripts/ mode=ugo+x"

12.5 file模块功能说明:

功能说明:设置文件属性

官方链接:http://docs.ansible.com/ansible/latest/copy_module.html

参数实践:创建数据文件(普通文件 目录 软链接文件)

ansible oldboy -m file -a "dest=/tmp/oldboy_dir state=directory"

ansible oldboy -m command -a "mkdir -p /tmp/oldboy_dir1 warn=false"

ansible oldboy -m file -a "dest=/tmp/oldboy1 state=touch"

ansible oldboy -m command -a "touch /tmp/oldboy_file1.txt warn=false"

================================================================

替代方案:

ansible oldboy  -m command -a "chmod 777 /etc/hosts warn=false"

ansible oldboy  -m command -a "chmod 644 /etc/hosts warn=false"

ansible oldboy  -m command -a "chown oldboy /etc/hosts warn=false"

ansible oldboy  -m command -a "chown root /etc/hosts warn=false"

创建目录:mkdir /tmp/oldboy_dir

ansible oldboy -m file -a "dest=/tmp/oldboy_dir state=directory"

递归设置权限:

ansible oldboy -m file -a "dest=/tmp/oldboy_dir state=directory mode=644 recurse=yes"

创建文件:touch /tmp/oldboy_file

ansible oldboy -m file -a "dest=/tmp/oldboy_file state=touch"

删除文件:rm -f /tmp/oldboy_file

ansible oldboy -m file -a "dest=/tmp/oldboy_file state=absent"

创建链接文件:ln -s /etc/hosts /tmp/link_file

ansible oldboy -m file -a "src=/etc/hosts dest=/tmp/link_file state=link"

ansible oldboy -m file -a "dest=/tmp/oldboy_file state=touch owner=oldboy group=oldboy mode=000"

ansible oldboy -m file -a "dest=/tmp/oldboy_file state=touch owner=oldboy group=oldboy mode=ugo=rwx"

作业:批量创建5个用户oldboy01-05,然后设置123456密码,然后同时在所有客户端执行。

知识----能力-----价值-----金钱

12.6 yum模块功能说明:

功能说明:yum包管理模块

官方链接:http://docs.ansible.com/ansible/latest/yum_module.html

ansible oldboy  -m command -a "yum install nginx -y"

ansible oldboy -m yum -a "name=nginx state=installed"

ansible oldboy -m yum -a "name=nc state=installed"

[root@nfs01 oldboy_dir]# rpm -qa nginx

nginx-1.10.2-1.el6.x86_64

###不要用yum卸载,可用rpm -e卸载。

ansible系统类型模块说明

12.7 systemd模块功能说明:(service模块)

功能说明:yum包管理模块

官方链接:http://docs.ansible.com/ansible/latest/service_module.html

参数说明:

service nfs restart

/etc/init.d/nfs restart

systemctl restart nfs

[root@backup /server/scripts]# ansible-doc -s systemd

- name: Manage services

  systemd:

      daemon_reload:        # run daemon-reload before doing any other operations, to make sure systemd has read any

                              changes.

      enabled:              # Whether the service should start on boot. *At least one of state and enabled are

                              required.*

      force:                # Whether to override existing symlinks.

      masked:                # Whether the unit should be masked or not, a masked unit is impossible to start.

      name:                  # Name of the service. When using in a chroot environment you always need to specify the  full name i.e. (crond.service).

      no_block:              # Do not synchronously wait for the requested operation to finish. Enqueued job will

                              continue without Ansible blocking on its completion.

      scope:                # run systemctl within a given service manager scope, either as the default system scope

                              (system), the current user's scope (user), or the scope of

                              all users (global). For systemd to work with 'user', the

                              executing user must have its own instance of dbus started

                              (systemd requirement). The user dbus process is normally

                              started during normal login, but not during the run of

                              Ansible tasks. Otherwise you will probably get a 'Failed

                              to connect to bus: no such file or directory' error.

      state:                # `started'/`stopped' are idempotent actions that will not run commands unless necessary.

                              `restarted' will always bounce the service. `reloaded'

                              will always reload.

      user:                  # (deprecated) run ``systemctl`` talking to the service manager of the calling user, rather

                              than the service manager of the system. This option is

                              deprecated and will eventually be removed in 2.11. The

                              ``scope`` option should be used instead.


实践:

ansible oldboy -m systemd -a "name=crond.service enabled=no state=stopped "

ansible oldboy -m command -a "systemctl status crond"

ansible oldboy -m systemd -a "name=crond.service enabled=yes state=started"

百度 ansible systemd

https://hoxis.github.io/ansible-system-modules.html

https://www.cnblogs.com/mcsiberiawolf/articles/10083626.html

[root@backup ~]# service crond restart

Redirecting to /bin/systemctl restart crond.service


#service模块功能说明:

功能说明:启动停止服务

官方链接:http://docs.ansible.com/ansible/latest/service_module.html

#相当于

#service crond stop|/etc/init.d/crond stop

#chkconfig crond off

ansible oldboy -m service -a "name=crond state=stop enabled=no"

#相当于/etc/init.d/crond start

chkconfig crond on

ansible oldboy -m service -a "name=crond state=started enabled=yes"

ansible oldboy -m command -a "name=crond state=started enabled=yes"

有选择才叫有能力。

足球场上,让拿球队员有选择,就容易进球。

不让对方有选择,就得人盯人。

12.8 cron模块功能说明:

功能说明:管理定时任务条目信息模块

cron    Manage cron.d and crontab entries

官方链接:http://docs.ansible.com/ansible/latest/cron_module.html

定时任务格式:

* * * * * CMD

[root@backup ~]# ansible-doc -s cron

- name: Manage cron.d and crontab entries

  cron:

      backup:                # If set, create a backup of the crontab before it is modified.

                              The location of the backup is

                              returned in the `backup_file'

                              variable by this module.

      cron_file:            # If specified, uses this file instead of an individual user's

                              crontab. If this is a relative

                              path, it is interpreted with

                              respect to /etc/cron.d. (If it

                              is absolute, it will typically

                              be /etc/crontab). Many linux

                              distros expect (and some

                              require) the filename portion

                              to consist solely of upper- and

                              lower-case letters, digits,

                              underscores, and hyphens. To

:...skipping...

- name: Manage cron.d and crontab entries

  cron:

      backup:                # If set, create a backup of the crontab before it is modified.

                              The location of the backup is  returned in the `backup_file'

                              variable by this module.

      cron_file:            # If specified, uses this file instead of an individual user's

                              crontab. If this is a relative

                              path, it is interpreted with

                              respect to /etc/cron.d. (If it

                              is absolute, it will typically

                              be /etc/crontab). Many linux

                              distros expect (and some

                              require) the filename portion

                              to consist solely of upper- and

                              lower-case letters, digits,

                              underscores, and hyphens. To

                              use the `cron_file' parameter

                              you must specify the `user' as

                              well.

      disabled:              # If the job should be disabled (commented out) in the crontab.

                              Only has effect if  `state=present'.

      env:                  # If set, manages a crontab's environment variable. New

                              variables are added on top of

                              crontab. "name" and "value"

                              parameters are the name and the

                              value of environment variable.

      insertafter:          # Used with `state=present' and `env'. If specified, the

                              environment variable will be

                              inserted after the declaration

                              of specified environment

                              variable.

      insertbefore:          # Used with `state=present' and `env'. If specified, the

                              environment variable will be

                              inserted before the declaration

                              of specified environment

                              variable.

      name:                  # Description of a crontab entry or, if env is set, the name of

                              environment variable. Required      if state=absent. Note that if

                              name is not set and    state=present, then a new

                              crontab entry will always be

                              created, regardless of existing

                              ones.

      reboot:                # If the job should be run at reboot. This option is deprecated.

                              Users should use special_time.

      special_time:          # Special time specification nickname.

      state:                # Whether to ensure the job or environment variable is present

                              or absent.

      user:                  # The specific user whose crontab should be modified.


定时任务格式:

* * * * * CMD

  定时任务时间参数:

      minute:                # Minute when the job should run ( 0-59, *, */2, etc )

  hour:                  # Hour when the job should run ( 0-23, *, */2, etc )

  day:                  # Day of the month the job should run ( 1-31, *, */2, etc )

      month:                # Month of the year the job should run ( 1-12, *, */2, etc )

      weekday:              # Day of the week that the job should run ( 0-6 for Sunday-Saturday, *, etc )

      job:                  # The command to execute or, if env is set, the value of  environment variable. The

                              command should not contain line  breaks. Required if    state=present.


创建定时任务:

ansible oldboy -m cron -a "name='sync time' minute=00 hour=00 job='/usr/sbin/ntpdate time.nist.gov >/dev/null 2>&1'"

[root@backup ~]# crontab -l

#crond-id-001:time sync by oldboy

*/5 * * * * /usr/sbin/ntpdate ntp3.aliyun.com >/dev/null 2>&1

#Ansible: sync time

00 00 * * * /usr/sbin/ntpdate time.nist.gov >/dev/null 2>&1

结果:

#Ansible: sync time

00 00 * * * /usr/sbin/ntpdate time.nist.gov >/dev/null 2>&1

添加如下定时任务:

05 03 * * * /bin/sh /server/scripts/backup.sh >/dev/null 2>&1

命令如下:

ansible oldboy -m cron -a "name='backup data' minute=05 hour=03 job='/bin/sh /server/scripts/backup.sh >/dev/null 2>&1'"

结果:

#Ansible: backup data

05 03 * * * /bin/sh /server/scripts/backup.sh /server/scripts/list >/dev/null 2>&1

删除定时任务:state=absent backup=yes

ansible oldboy -m cron -a "name='backup data' state=absent backup=yes"

名字不变的前提下,修改ansible参数内容,就是修改定时任务。

查看结果:

[root@nfs01 /server/scripts]# crontab -l

#crond-id-001:time sync by oldboy

*/5 * * * * /usr/sbin/ntpdate ntp3.aliyun.com >/dev/null 2>&1

##bak config by oldboy at 2020.10.10

00 00 * * * /bin/sh /server/scripts/bak.sh >/dev/null 2>&1

[root@nfs01 /server/scripts]#

[root@nfs01 /server/scripts]# cat /tmp/crontabdMTe3e

#crond-id-001:time sync by oldboy

*/5 * * * * /usr/sbin/ntpdate ntp3.aliyun.com >/dev/null 2>&1

##bak config by oldboy at 2020.10.10

00 00 * * * /bin/sh /server/scripts/bak.sh >/dev/null 2>&1

#Ansible: backup data

05 03 * * * /bin/sh /server/scripts/backup.sh >/dev/null 2>&1

注释定时任务:disabled=yes

[root@m01 ~]# ansible oldboy -m cron -a "name='backup data' minute=05 hour=04 job='/bin/sh /server/scripts/backup.sh' disabled=yes"

替代方案:

自学mount模块。

============================================================

============================================================

今晚24日项目实践一分钟内,一键完成三个项目的安装:

1)各一键完成rsync服务端和客户端。  #完成

2)各一键完成nfs服务端和客户端。

3)各一键完成sersync服务端和客户端。

一个脚本one_key.sh或者一个ansible命令。完成

项目说明见:

老男孩教育_Linux58期-集群项目实战-03-三个项目实战大考察.pdf

管理配置好:

1、创建分发秘钥

2、安装ansible工具。

3、一键执行各服务脚本

具体服务一键实现的几个步骤:

1、计划要做。

2、单机安装好,步骤抽出来。

3、写成脚本,一键安装。

4、拿到管理机安装

1)一键完成rsync服务端安装。

剧本:

#1)安装

#yum install rsync -y

#2)配置配置文件/etc/rsyncd.conf

cp /etc/rsyncd.conf{,.ori}

cat>/etc/rsyncd.conf<

#rsync_config_______________start

#created by oldboy

#site: http://www.oldboyedu.com

uid = rsync

gid = rsync

use chroot = no

fake super = yes

max connections = 200

timeout = 600

pid file = /var/run/rsyncd.pid

lock file = /var/run/rsync.lock

log file = /var/log/rsyncd.log

ignore errors

read only = false

list = false

hosts allow = 172.16.1.0/24

hosts deny = 0.0.0.0/32

auth users = rsync_backup

secrets file = /etc/rsync.password

[backup]

comment = welcome to oldboyedu backup!

path = /backup/

EOF

#3)创建用户和备份目录

useradd rsync

id rsync

mkdir -p /backup

chown -R rsync.rsync /backup/

ls -ld /backup/

#4)启动和检查

systemctl start rsyncd

systemctl enable rsyncd

systemctl status rsyncd

ps -ef|grep sync|grep -v grep  #检查进程

netstat -lntup|grep 873        #检查端口

#5)配置密码文件

echo "rsync_backup:oldboy" > /etc/rsync.password

chmod 600 /etc/rsync.password

cat /etc/rsync.password

ls -l /etc/rsync.password

#rsync服务端配置完成。

#最终脚本路径/server/scripts/install_rsync_server.sh,需提前测试成功。

2)一键完成rsync客户端安装。

#方法1:认证密码文件

echo "oldboy" > /etc/rsync.password

chmod 600 /etc/rsync.password

cat /etc/rsync.password

ls -l /etc/rsync.password

rsync -avz /etc/hosts [email protected]::backup --password-file=/etc/rsync.password

#最终脚本路径/server/scripts/install_rsync_client.sh,需提前测试成功。

3)配置管理机61-m01:

1)实现批量分发秘钥,免秘钥管理

#!/bin/bash

yum install ansible -y                #含sshpass

[ ~/.ssh/id_rsa ]&& rm -fr ~/.ssh

ssh-keygen -f ~/.ssh/id_rsa  -P '' -q

for ip in 31 41 7 8

do

  sshpass -p123456 ssh-copy-id -f -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 172.16.1.$ip

  ssh 172.16.1.$ip "ifconfig eth0"

done

#脚本路径/server/scripts/create_key.sh

4)实现文件分发和命令管理

方法1:脚本开发分发工具

[root@m01 /server/scripts]# cat fenfa.sh

#!/bin/sh

. /etc/init.d/functions

if [ $# -ne 2 ]

then

    echo "usage:/bin/sh $0 localfile remotedir"

    exit 1

fi

for n in  `cat /etc/ssh/hosts`

do

  scp -P 22 -rp $1 root@$n:$2 &>/dev/null

  if [ $? -eq 0  ]

  then

    action "$n successful" /bin/true

  else

            action "$n failure" /bin/false

  fi

done

=============

[root@m01 /server/scripts]# cat fenfa.sh

#!/bin/sh

for n in  7 31 41

do

  scp -P 22 -rp $1 root@$n:$2 &>/dev/null

done

[root@m01 /server/scripts]# cat cmd.sh

for n in 31 41 7

do

  echo "=====172.16.1.$n======"

  ssh 172.16.1.$n "$1"

done

方法2:使用ansible工具

yum install ansible -y

[root@m01 /server/scripts]# cat /etc/ansible/hosts

[oldboy]

172.16.1.31

172.16.1.41

172.16.1.7

2)优化所有机器SSH

优化目标sshd_config

[root@m01 /server/scripts]# sed -n '17,22p' /etc/ssh/sshd_config

####Start by oldboy#2020-04-26###

PermitEmptyPasswords no

UseDNS no

GSSAPIAuthentication no

#ListenAddress 172.16.1.7:22

####End by oldboy#2018-04-26###

方法1:脚本分发

[root@m01 /server/scripts]# sh fenfa.sh /etc/ssh/sshd_config /etc/ssh/

7 successful                                              [  确定  ]

31 successful                                              [  确定  ]

41 successful                                              [  确定  ]

[root@m01 /server/scripts]#

[root@m01 /server/scripts]#

[root@m01 /server/scripts]#

[root@m01 /server/scripts]# sh cmd.sh "systemctl restart sshd"

=====172.16.1.31======

=====172.16.1.41======

=====172.16.1.7======

方法2:使用ansible分发

ansible oldboy -m copy -a "src=/etc/ssh/sshd_config dest=/etc/ssh/sshd_config backup=yes"

ansible oldboy -m shell -a "systemctl restart sshd"

从管理机实现一键安装install_rsync_server.sh

ansible 172.16.1.41 -m script -a "/server/scripts/install_rsync_server.sh"

[root@m01 /server/scripts]# cat /etc/ansible/hosts

[oldboy]

172.16.1.31

172.16.1.41

172.16.1.7

172.16.1.8

[rsync_client]

172.16.1.31

172.16.1.8

ansible rsync_client -m script -a "/server/scripts/install_rsync_client.sh"

实现从管理机一键完成安装rsync服务端和客户端

3)一键完成nfs服务端。

4)一键完成nfs客户端。

5)一键完成sersync服务端。

6)一键完成sersync客户端。

一个脚本one_key.sh或者一个ansible命令。完成

项目实践作业:

rsync服务端写成脚本 r1.sh

rsync客户端写成脚本 r2.sh

nfs服务端写成脚本 n1.sh

nfs客户端写成脚本 n2.sh

sersync服务端写成脚本 s1.sh

sersync客户端写成脚本 s2.sh

/server/scripts/one_key_gaoding.sh

ansible r1 -m copy -a "src=/server/scripts/r1.sh dest=/server/scripts/ mode=ugo+x"

ansible r1 -m shell -a "sh /server/scripts/r1.sh"

ansible r1 -m copy -a "src=/server/scripts/r2.sh dest=/server/scripts/ mode=ugo+x"

ansible r2 -m shell -a "sh /server/scripts/r2.sh"

ansible n1 -m shell -a "sh /server/scripts/n1.sh"

ansible n2 -m shell -a "sh /server/scripts/n2.sh"

ansible s1 -m shell -a "sh /server/scripts/s1.sh"

ansible s2 -m shell -a "sh /server/scripts/s2.sh"

/bin/sh /server/scripts/one_key_gaoding.sh

也可以使用script模块,替代copy+shell模块

你可能感兴趣的:(Day38 - 39 课堂笔记)