ansible快速掌握

一、课前介绍

Ansible

  • 学完后:批量、自动管理主机

怎么理解运维?

  • 规划架构--架构师
  • 采购服务器、服务器上线、安装os、安装web程序
  • 维护服务器正常工作

运维工作的内容?

  • 安装系统:pxe、kickstart、cobbler、image template
  • 安装应用、配置应用、启动应用(服务):puppet、saltstack、chef
  • 发布程序:puppet、saltstack、chef
  • 监控(服务器、系统、应用、程序):zabbix

程序发布:

  • 灰度发布
  • 金丝雀发布

ansible解决的问题:

  • 批量安装应用、配置应用、启动应用
  • 批量发布程序

ansible的资源站点

使用ansible的方法

  • ad-hoc:执行一个命令,使用场景
    • 批量检查主机是否在线
    • 批量重启主机的
  • playbook:执行一组命令,使用场景

    • 部署lamp,需要配置ip、修改配置文件的等

    面试问题:ansible工作原理

  • ansible的管理节点通过ssh登录远程主机执行命令

二、安装ansible

2.1 节点规划

  • 通过一个master节点,可以批量管理两个node节点

具体规划

  • master:192.168.31.63
  • node1:192.168.31.65
  • node2:192.168.31.66

2.2 安装epel源

  • ansible已经被收入到epel源中了
[root@master ~]# yum install epel-release -y
[root@master ~]# yum repolist
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.zju.edu.cn
 * epel: fedora.cs.nctu.edu.tw
 * extras: mirrors.163.com
 * updates: mirrors.njupt.edu.cn
repo id                             repo name                                                         status
base/7/x86_64                       CentOS-7 - Base                                                   10,097
epel/x86_64                         Extra Packages for Enterprise Linux 7 - x86_64                    13,212
extras/7/x86_64                     CentOS-7 - Extras                                                    335
updates/7/x86_64                    CentOS-7 - Updates                                                 1,77
[root@master ~]# yum install ansible -y

查看ansible的版本信息

[root@master ~]# ansible --version
ansible 2.9.6
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Aug  7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

2.3 其他安装ansible的方式

2.4 ansible相关文件和目录

  • 配置文件目录:/etc/ansible
  • 执行文件目录:/usr/bin

2.4.1 ansible的主配置文件

  • /etc/ansible/ansible.cfg
[defaults]
#inventory         = /etc/ansible/hosts     # 指定主机清单文件
#forks             = 5                      # 指定每批次向几台主机发送指令
#sudo_user         = root                   # sudo的目标用户
#remote_port       = 22                     # 设置ssh端口号
#roles_path        = /etc/ansible/roles     # role文件的路径
#host_key_checking = False                  # 设置是否检查目标主机的指纹信息
#module_name       = command                # 设置默认模块名称 

[privilege_escalation]
#become=True                                # 是否允许进行sudo
#become_method=sudo
#become_user=root
#become_ask_pass=False

2.4.2 ansible的主机清单文件

  • 文件:/etc/ansible/hosts
  • 作用:记录用于被管理的主机

定义被管理主机有两种方式

  • 基于ip或者主机名定义单个主机
  • 基于一个主机组来集中定义多个主机
可以直接用ip来定义一个主机
192.168.31.66
也可以使用hostname(主机名)后面跟ssh的端口,默认是22
web1.zxhk.com:22
定义一台主机组webservers
[webservers]
192.168.31.65
192.168.31.66

定义主机组会用到参数

ansible_ssh_port :ssh端口号.如果不是默认的端口号,通过此变量设置.
ansible_ssh_user:默认的 ssh 用户名
[webservers]
192.168.31.63  ansible_ssh_port=232 ansible_ssh_user=tuser
192.168.31.65
192.168.31.66

2.5 远程管理node1和node2

2.5.1 ansible使用说明

ansible有两种方式

  • ah-hoc
  • playbook

Ad-Hoc应用的场景

  • 情景1:节假日将近,我们需要关闭所有不必要的应用服务器,并且对所有服务器进行借钱健康检查
  • 情景2:临时更新Apache或者Nginx的配置文件,且需要同时将其分发至所有更新该配置的web服务器
  • 一次性操作和简单操作

playbook应用场景

  • 情景1:新购置的服务器在安装完系统后需要做一些固化的初始环境配置,诸如:定制防火墙策略、添加NTP时间同步配置、添加EPEL源等
  • 情景2:每周定期对生产环境发布更新代码
  • 周期性操作和复杂操作

2.5.2 定义主机清单文件

  • node1:192.168.31.65
  • node2:192.168.31.66
[root@master ~]# vim /etc/ansible/hosts 

添加三行

[myservers]
192.168.31.65 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22
192.168.31.66 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22

2.5.3 禁止校验指纹信息

编译/etc/ansible/ansible.cfg文件,将#host_key_checking = False前面的#去掉,如下

host_key_checking = False

2.5.4 检查内存

可以使用ansible ad-hoc模式

ansible命令格式

ansible <host-pattern> [-f forks] [-m module_name] [-a args]

  • <host-pattern>:是Inventory定义的主机和主机组,可以为iphostname、Inventory中的group组名、可以使用“.”、“*****”或者“:”等特殊字符的匹配型字符串,all设置所有

  • [-f forks]:指明每批管控多少主机,默认为5个主机一批次

  • [-m module_name]:使用何种模块管理操作,所有的操作都需要通过模块来指定,默认是command模块

[root@master ~]# ansible myservers -m command -a "free -m"
192.168.31.65 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           1819         275        1191           9         352        1388
Swap:          2047           0        2047
192.168.31.66 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           1819         262        1396           9         160        1408
Swap:          2047           0        2047

2.5.5 检查是否在线

[root@master ~]# ansible myservers -m ping
192.168.31.65 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.31.66 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

2.6 配置秘钥认证

2.6.1 生成秘钥

[root@master ~]# ssh-keygen -t rsa -P ""
[root@master ~]# ls /root/.ssh/id_rsa*
/root/.ssh/id_rsa  /root/.ssh/id_rsa.pub

2.6.2 分发秘钥

[root@master ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
[root@master ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]

验证一下

[root@master ~]# ssh 192.168.31.65  ip addr

2.6.3 基于秘钥管理主机

1)首先修改主机清单文件:

  • 定义主机主机组
  • 主机中的主机只写主机IP或者名称,不需要指定账户和密码

2)查看目标主机内存信息

2.7 作业:

  • 安装三个虚拟机(centos7)
  • 在一个节点安装ansible
  • 查看其它节点的内存信息、查看节点是否在线

答案:

1) 略
2) # yum install epel-release -y
   # yum install ansible -y
3) vim /etc/ansible/ansible.cfg ===> host_key_checking = False
   vim /etc/ansible/hosts ===> 
           [myser]
           1.1.1.1 ansible_ssh_user=xx ansible_ssh_pass=xx
           1.1.1.2 ansible_ssh_user=xx ansible_ssh_pass=xx
   ansible myser -m command -a "free -m"
   ansible myser -m ping

三、ansible的模块

  • ansible的模块非常多:600+
  • ansible依赖模块完成具体工作

3.1 command模块

功能:

  • 用来执行命令的模块
  • 默认模块,可以省略

格式:

  • -m command -a 命令

查看各个节点的内存

[root@master ~]# ansible myservers -a "free -m"
192.168.31.65 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           1819         272        1387           9         158        1398
Swap:          2047           0        2047
192.168.31.66 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           1819         272        1383           9         164        1399
Swap:          2047           0        2047
  • command是默认的,可以省略

3.2 cron模块

作用:

  • 定时周期完成特定的操作

格式

  • -m cron -a "选项"

选项

  • minute:设置以分钟为单位来运行
  • state:设置添加或者删除计划任务
    • present:添加计划任务
    • absent:删除计划任务
  • job:设置要执行的操作
  • special_time:设置特殊时间点
    • reboot:在系统重启的时候执行的操作
    • daily:每天都执行一次的计划任务
    • hourly:
    • weekly:
    • monthly:
    • yearly:

案例:每隔2分钟执行一次echo操作

[root@master ~]# ansible myservers -m cron \
> -a 'name="mycron" state="present" job="echo \"123\"">>/tmp/test.log" minute=*/2'

结果会在各个节点创建接话任务

[root@master ~]# ansible myservers  -a 'crontab -l'
192.168.31.65 | CHANGED | rc=0 >>
#Ansible: None
*/2 * * * * echo "123">>/tmp/test.log
192.168.31.66 | CHANGED | rc=0 >>
#Ansible: None
*/2 * * * * echo "123">>/tmp/test.log

删除计划任务

[root@master ~]# ansible myservers -m cron -a 'name="mycron" state="absent"'

3.3 user模块

作用:

  • 管理各个节点上的用户

格式

  • -m user -a "选项"

选项

  • name:指定用户名
  • password:指定用户的密码
  • state:是创建还是删除
  • createhome:是否创建家目录 yes|no
  • remove:当state=absent时,remove=yes则表示连同家目录一起删除
  • groups:指定用户的属组
  • system:是否为系统用户
  • uid:用户uid

案例:在所有被管理节点上创建用户tom

[root@master ~]# ansible myservers -m user -a 'name="tom"'
[root@master ~]# ansible myservers -a 'tail -n1 /etc/passwd'
192.168.31.65 | CHANGED | rc=0 >>
tom:x:1000:1000::/home/tom:/bin/bash
192.168.31.66 | CHANGED | rc=0 >>
tom:x:1000:1000::/home/tom:/bin/bash

案例:删除tom用户

[root@master ~]# ansible myservers -m user -a 'name="tom" state="absent"'

案例:创建用户jerry,uid 为3000,所在组为gp001,shell为/bin/bash

[root@master ~]# ansible myservers -m group -a "name=gp001"
[root@master ~]# ansible myservers -m user \
> -a 'name="jerry" uid="3000" group="gp001" shell="/bin/bash"'

3.4 copy模块

作用:

  • 目录和文件的复制

格式

  • -m copy -a "选项"

选项

  • src 指定原文件或目录。
  • dest 被复制到远程主机的本地对象文件或者文件夹
  • mode 设置复制后文件的权限 ,比如644
  • owner 指定复制后的文件的属主
  • backup 设置是否先将源文件备份.设定值:yes/no 缺省为yes
  • force 是否强制覆盖同名文件.设定值:yes/no 缺省为no
  • content 可替换 src,也就是直接用这个内容生成文件内容

案例1:将文件passwd复制到目标主机的tmp下,然后修改权限为777,属主改为jerry

[root@master ~]# ansible myservers -m copy \
> -a "src=/etc/passwd dest=/tmp mode=777 owner=jerry"

案例2:将两行内容复制tmp下,保存为文件b.txt

i am zxhk
i love golnag
[root@master ~]# ansible myservers -m copy \
> -a 'content="i am zxhk\ni love golang\n" dest=/tmp/b.txt' 

3.5 file模块

作用:

  • 对文件进行操作的模块,可以操作的内容包括
  • 创建空文件、拷贝、移动、删除、链接

格式

  • -m file -a "选项"

选项

  • follow 如果原来的文件是link,拷贝后依旧是link
  • force 强制执行
  • group 设定一个群组拥有拷贝到远程节点的文件权限
  • mode 等同于chmod
  • owner 设定一个用户拥有拷贝到远程节点的文件权限
  • path 目标路径,也可以用dest,name代替
  • src 待拷贝文件/文件夹的原始位置。
  • state 代表拷贝后是文件类型;
    • link代表最终是个软链接;
    • directory代表文件夹;
    • hard代表硬链接;
    • touch代表生成一个空文件;
    • absent代表删除

案例1:在每个主机的tmp下创建一个空文件,文件名是new.txt

[root@master ~]# ansible all -m file -a 'path="/tmp/new.txt" state="touch"'

案例2:在每个主机的tmp的new.txt创建软链接new.txt.soft

[root@master ~]# ansible all -m file \
> -a 'src="/tmp/new.txt" path="/tmp/new.txt.soft" state="link"'

案例3:修改每个主机的tmp下new.txt的权限为000,属主为jerry

[root@master ~]# ansible all -m file -a "path=/tmp/new.txt mode=000 owner=jerry"

3.6 ping模块

作用:

  • 这是个测试模块,测试主机是否都正常连接

案例:

[root@master ~]# ansible all -m ping
192.168.31.65 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.31.66 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

3.7 service模块

作用:

  • 这模块很重要,是用来管理服务的
  • 管理centos6的服务器,只能用service模块

格式

  • -m service -a "选项"

选项

  • state 有多个子选项
    • started:启动服务
    • stopped:关闭服务
    • restarted:重启服务
    • reloaded:重读服务的配置文件
  • enabled 表示是否设置开机自动启动
  • name 表示要控制的服务的名称
  • runlevel 设置在哪些级别下自动启动

案例:查看httpd服务运行状态

[root@master ~]# ansible all -m command -a "systemctl status httpd"
[root@master ~]# ansible all -m command -a "service httpd status

案例:启动httpd服务,并且设置为开机自动启动

[root@master ~]# ansible all -m service -a 'name="httpd" state="started" enabled="on"'

3.8 systemd模块

作用:

  • 这模块很重要,是用来管理服务的
  • 管理centos7的服务器,可以用service和systemd,建议用systemd模块

格式

  • -m systemd -a "选项"

选项

  • state 有多个子选项
    • started:启动服务
    • stopped:关闭服务
    • restarted:重启服务
    • reloaded:重读服务的配置文件
  • enabled 表示是否设置开机自动启动
  • name 表示要控制的服务的名称
  • runlevel 设置在哪些级别下自动启动
[root@master ~]# ansible all -m systemd \
> -a 'name="httpd.service" state="restarted" enabled="no"'

3.9 shell模块

作用:

  • 与command模块类似,也是用于执行命令
  • command只能执行简单命令
  • shell模块可以执行复杂命令,可以使用变量

格式

  • -m shell -a "选项"

案例:

[root@master ~]# ansible all -m shell -a 'echo "123" | passwd --stdin jerry'

3.10 script模块

作用:

  • 将一个脚本文件发送到被管理节点,并执行较

格式

  • -m scribe -a "选项"

案例:

首先创建一个shell脚本

[root@master ~]# cat /root/t.sh 
#!/bin/bash
useradd tom01
mkdir /tmp/qq
touch /tmp/baidu

使用ansible将脚本发送到被管理节点,并执行

[root@master ~]# ansible all -m script -a '/home/t.sh'

3.11 yum模块

作用:

  • 管理软件

格式

  • -m yum -a "选项"

选项:

  • name:软件名
  • state:安装或者卸载
    • present
    • absent

案例:在所有节点上安装epel yum源

[root@master ~]# ansible all -m yum -a 'name="epel-release" state="present"'

案例:在安装了epel源的节点上,安装nginx

[root@master ~]# ansible all -m yum -a 'name="nginx" state="present"'

案例:启动nginx

[root@master ~]# ansible all -m systemd  \
> -a 'name="nginx.service" state="started" enabled="on"'

3.12 setup模块

作用:

  • 收集各个节点的参数信息:facts

格式

  • -m setup
[root@master ~]# ansible all -m setup

3.13 作业:

1)准备3台虚拟机,1台为ansible管理主机,2台为nginx服务器

2)请检查ansible主机的ansible是否安装,若未安装请安装

# rpm -q ansible

3)请合理添加服务器组,将两台nginx服务器分配在webserver组当中

# vim /etc/ansible/hosts
将两个nginx节点的ip定义成一个主机组
[webserver]
ip1
ip2

4) 配置免密码登录

# ssh-keygen -t rsa -P ""
# ssh-copy-id -i ~/.ssh/id_rsa.pub

5) 合理调用相关模块,安装nginx依赖环境

# ansible all -a "yum install pcre pcre-devel ncurses ncursese-devel openssl*"

6) 批量分发Nginx源码包至Nginx服务器

  • 用copy模块,将nginx源码包发送到各个nginx节点

7) 批量分发安装指令至Nignx服务器(提示:可分发Nginx安装脚本,执行脚本安装,但脚本不可使用提前编写好的脚本!可以现写脚本使用)

  • 编写编译安装nginx的脚本
  • 用copy/script模块,将安装nginx的脚步分发到各个节点,并执行

8) 启动所有Nginx服务器的Nginx服务

  • 用service/systemd启动服务

9) 查看所有Nginx的端口监听是否正常

  • 在各个节点检查80端口是否监听
[root@master ~]# ansible all -m shell -a "ss -tnl | grep 22" 
192.168.31.65 | CHANGED | rc=0 >>
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      128       [::]:22                    [::]:*                  
192.168.31.66 | CHANGED | rc=0 >>
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      128       [::]:22                    [::]:* 

10) 访问所有Nginx服务器,测试是否可以访问到测试页面

3.14 unarchive模块

作用:

  • 将压缩包解压到目标主机的特定目录下

格式

  • -m unarchive -a "选项"

选项:

  • src:压解压的那个压缩包文件
  • dest:指定解压到远程主机的哪个目录

案例:下载nginx的1.17.9版本,解压到远程主机的/usr/local/

[root@master ~]# yum install wget -y
[root@master ~]# wget http://nginx.org/download/nginx-1.17.9.tar.gz
[root@master ~]# ansible all -m unarchive -a "src=nginx-1.17.9.tar.gz dest=/usr/local/"

3.15 reboot模块

作用:

  • 重启远程主机

格式

  • -m reboot
[root@master ~]# ansible all -m reboot

3.16 selinux模块

作用:

  • 改变selinux的状态

格式

  • -m selinux -a "选项"

选项:

  • state:disabled
[root@master ~]# ansible all -m selinux -a "state=disabled"

3.17 sysctl模块

作用:

  • 用来修改内核参数

格式

  • -m sysctl -a "选项"

选项:

  • sysctl_file:知道内核文件的文件名
  • name:内核参数的名称
  • value:内核参数的值

案例:实现路由转发功能

[root@master ~]# ansible all -m sysctl \
> -a 'sysctl_file=/etc/sysctl.conf name=net.ipv4.ip_forward value=1'

3.18 stat模块

作用:

  • 用来显示文件的属性信息,比如时间戳信息、uid、gid、inode、md5值等等

格式

  • -m stat -a "选项"

选项:

  • path:文件的绝对路径

案例:查看各个节点的/etc/passwd文件属性

[root@master ~]# ansible all -m stat \
> -a 'path="/etc/passwd" get_checksum="yes" checksum_algorithm="md5"'

3.19 replace模块

作用:

  • 对字符串进行替换,支持正则表达式

格式

  • -m replace -a "选项"

选项

  • path:指定目标文件
  • regexp:要替换的目标字符串,也可以是一个表达式
  • replace:将目标字符串替换为什么字符串
  • backup:是否对原始文件仅备份

案例:将目标主机的/tmp/passwd中的bash替换为BASH

[root@master ~]# ansible all -m replace
> -a 'path=/tmp/passwd regexp=bash replace=BASH backup=yes'

3.20 git模块

  • 将到gitlab再说

四、练习

练习1

1)准备3台服务器,在其中一台上安装ansible

[root@master ~]# yum install epel-release -y
[root@master ~]# yum install ansible -y

2)将另外两台服务器ip添加到主机清单中

首先将主配置文件中的指纹信息查验关闭

[root@master ~]# sed -i \
> 's/#host_key_checking = False/host_key_checking = False/g' /etc/ansible/ansible.cfg

然后修改主机清单

[root@master ~]# vim /etc/ansible/hosts 
添加下面内容
[myservers]
192.168.31.65 ansible_ssh_user=root ansible_ssh_pass=123456
192.168.31.66 ansible_ssh_user=root ansible_ssh_pass=123456

3)使用模块连接远程主机测试连接情况

[root@master ~]# ansible myservers -m ping
192.168.31.65 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.31.66 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

4)修改ssh远程端口号为222并显示连接成功

首先关闭被管理的节点的防火墙

[root@node1 ~]# systemctl stop firewalld 
[root@node2 ~]# systemctl stop firewalld 

修改被管理节点的端口为222

[root@node2 ~]# vim /etc/ssh/sshd_config
修改一行
Port 222
[root@node2 ~]# systemctl restart sshd
[root@node2 ~]# ss -tnl | grep 222
LISTEN     0      128          *:222                      *:*                  
LISTEN     0      128       [::]:222                   [::]:*  

修改ansible的清单文件,指定目标主机端口是222

[root@master ~]# vim /etc/ansible/hosts
[myservers]
192.168.31.65 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=222
192.168.31.66 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=222

测试主机连接情况

[root@master ~]# ansible myservers -m ping
192.168.31.65 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.31.66 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

5)生成RSA秘钥进行ssh免密配置

将ssh端口改回为22

[root@node1 ~]# vim /etc/ssh/sshd_config 
Port 22
[root@node1 ~]# systemctl restart sshd
[root@node1 ~]# ss -tnl | grep 22
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      128       [::]:22                    [::]:* 

生成和分发秘钥

[root@master ~]# ssh-keygen -t rsa -P ""
[root@master ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
[root@master ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
[root@master ~]# ssh 192.168.31.65 ip addr

修改清单文件,使用秘钥认证

[root@master ~]# vim /etc/ansible/hosts
[myservers]
192.168.31.65 
192.168.31.66 

测试一下

[root@master ~]# ansible myservers -m ping
192.168.31.65 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.31.66 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

6)使用service模块在两台远程主机上安装apache

[root@master ~]# ansible all -m yum -a 'name=httpd state=present'
[root@master ~]# ansible all -m command -a 'rpm -q httpd'
[root@master ~]# ansible all -m service -a 'name=httpd state=started enabled=on'  ^C
[root@master ~]# ansible all -m shell -a 'ss -tnl | grep 80'
192.168.31.65 | CHANGED | rc=0 >>
LISTEN     0      128       [::]:80                    [::]:*                  
192.168.31.66 | CHANGED | rc=0 >>
LISTEN     0      128       [::]:80                    [::]:*  

7)更改apache访问页面显示为hello + 自己的名字

[root@master ~]# ansible all -m shell -a 'echo "hello 1704A">/var/www/html/index.html'
192.168.31.65 | CHANGED | rc=0 >>

192.168.31.66 | CHANGED | rc=0 >>

8)使用浏览器进行访问,验证修改页面正确。

image-20200321120134807

练习2:ansible模块应用

1) 使用命令获取666的秘文

[root@master ~]# openssl passwd
Password: 
Verifying - Password: 
CUepnknVdx.Tg

2) 使用秘文及ansible模块创建用户tom

[root@master ~]# ansible all -m user -a 'name=tom password=CUepnknVdx.Tg'

3) 远程登录tom用户成功

[root@master ~]# ssh [email protected]
[email protected]'s password: 
Last login: Sat Mar 21 00:07:11 2020 from master
[tom@node1 ~]$ 
[tom@node1 ~]$ 

4) 使用模块将本地nginx压缩包解压推送到远程主机

[root@master ~]# ansible all -m unarchive -a 'src=nginx-1.17.9.tar.gz dest=/root/'

5) 使用模块在远程主机上查看是否推送成功

[root@master ~]# ansible all -m shell -a ‘ls /root/’

6) 在ansible主机上编写安装nginx的脚本

首先安装编译需要的组件

[root@master ~]# ansible all -m shell -a 'yum install gcc gccc-c++ ncurses* pcre* zlib* openssl* -y'

编写安装nginx的脚本文件

[root@master ~]# vim install_nginx.sh
#!/bin/bash
cd /root/nginx-1.17.9/ && ./configure --prefix=/usr/local/nginx && make && make install

7) 将脚本批量分发到远程主机上并成功执行

[root@master ~]# ansible all -m script -a 'install_nginx.sh'

8) 使用shell模块修改nginx首页为welcome!

[root@master ~]# ansible all -m shell -a 'echo "welcome"> /usr/local/nginx/html/index.html'
192.168.31.65 | CHANGED | rc=0 >>

192.168.31.66 | CHANGED | rc=0 >>

9) 成功访问,截图完整

关闭apache

[root@master ~]# ansible all -m shell -a 'systemctl stop httpd'

启动nginx

[root@master ~]# ansible all -m shell -a '/usr/local/nginx/sbin/nginx &'

访问测试

image-20200321122225042

四、playbook

4.1 yaml文件介绍

  • yaml就是一种文件格式,用于定义一组数据格式

案例:用yaml文件描述tom的信息

name: tom
age: 35
gender: Male
spouse:
    name: jerry
    age: 32
    gender: Femal
children:
    - name: bajie
      gender: Male
      age: 15
    - name: bajie
      gender: Male
      age: 15  
  • 字段:一级和二级字段

yaml文件的特点

  • 易读
  • 扩展性好
  • 和程序交互性好

4.2 ansile使用yaml文件的元素

  • 变量
  • 主机清单
  • 循环
  • 判断

4.2.1 变量

自定义变量的变量名:

  • 仅仅可以是数字、字母、下划线
  • 而且只能以字母为开头

内置变量

  • setup模块来获得

通过命令行的方式来使用变量

[root@master ~]# ansible-playbook a.yml --extra-vars "name=tom"

4.3 如何编写playbook

为什么要用playbook

  • 通过playbook可以实现一些复杂的操作,比如:安装epel,然后安装nginx的依赖包,然后编译安装nginx,启动nginx,这一系列的操作可以定义成一个yaml文件,通过调用这个yaml文件,可以自动批量的完成全部工作。

playbook中包含的内容

  • play:一个play就是一组要执行的操作
  • inventory:要对哪些主机进行操作
  • tasks:具体要完成操作
  • template:通过template可以动态生成服务的配置文件
  • handler:检查一个事件,并触发另一个事件
  • roles:通过roles可以实现文件的复用

案例:编译yaml文件实现批量自动安装apache,然后启动apache

首先创建yaml文件

[root@master ~]# vim install_nginx.yml
- hosts: myservers
  tasks:
  - name: install epel repo
    yum: name=epel-release state=latest
  - name: install nginx
    yum: name=nginx state=latest
  - name: start nginx 
    service: name=nginx state=started

然后执行yaml文件来创建服务

[root@master ~]# ansible-playbook install_nginx.yml

4.3.1 hosts参数

  • 就是用来指定被管理主机的ip或者组名

4.3.2 remote_user参数

  • 让远程主机以特定的用户身份来运行
- hosts: myservers
  remote_user: root
  tasks:
  - name: install epel repo
    yum: name=epel-release state=latest
  - name: install nginx
    yum: name=nginx state=latest
  - name: start nginx
    service: name=nginx state=started

4.3.3 tasks参数

用了指定需要完成具体的操作

通常由两部分构成一个操作

  • name:指定一个输出的名称
  • 模块 和 参数:指定要做的事情
  tasks:
  - name: install epel repo
    yum: name=epel-release state=latest
  - name: install nginx
    yum: name=nginx state=latest
  - name: start nginx 
    service: name=nginx state=started

task的执行流程

  • 如果有多个task操作,那么首先在第一个被管理阶段上执行第一个任务;所有阶段的这个任务执行完成后,才会开始在所有节点执行第二个任务,以此类推;
  • 一旦某个指定执行任务失败,那么所有的阶段都会停止继续执行,甚至会执行回滚操作

案例:在所有的节点上,创建用户组gp002,然后再创建用户user002,要求user002的组为gp002

- name: create user
  hosts: all
  remote_user: root
  tasks:
  - name: create group
    group: name=gp002 state=present
  - name: create user
    user: name=user002 group=gp002

4.3.4 handler参数

作用

  • 用来监控一个task操作是否执行了,一旦这个监控的task执行,那么立刻触发一个特定的操作

使用方法:

  • 第一步:定义handler事件和要执行的操作
  • 第二步:在需要监控的对象下面通过notify指定handler的名称

案例:安装nginx,将本地的nginx配置文件发生到远程节点,作为nginx服务的配置文件

1)在本地生成nginx的配置文件

[root@master ~]# yum install nginx -y
[root@master ~]# cp /etc/nginx/nginx.conf ./ -a
[root@master ~]# vim /root/nginx.conf
将nginx的端口改为8800

2)编写yaml文件,在远处主机安装nginx,并使用这个配置文件

- hosts: myservers
  tasks:
  - name: install epel repo
    yum: name=epel-release state=latest
  - name: install nginx
    yum: name=nginx state=latest
  - name: send nginx config file
    copy: src=/root/nginx.conf dest=/etc/nginx/nginx.conf
    notify:
    - restart nginx service
  - name: start nginx 
    service: name=nginx state=started
  handlers:
  - name: restart nginx service
    service: name=nginx state=restarted

3)执行yaml文件,检查远程主机端口

[root@master ~]# ansible-playbook install_nginx.yml

4.3.5 案例:部署tomcat服务

梳理思路:操作有4个

  1. 安装jdk:java-1.8.0-openjdk
  2. 下载tomcat:http://mirror.hust.edu.cn/apache/tomcat/tomcat-8/v8.5.51/bin/apache-tomcat-8.5.51.tar.gz
  3. 解压tomcat
  4. 启动tomcat
- name: install tomcat
  hosts: all
  tasks:
  - name: 安装openjdk
    yum: name=java-1.8.0-openjdk state=present
  - name: 下载tomcat
    get_url: url=http://mirror.hust.edu.cn/apache/tomcat/tomcat-8/v8.5.51/bin/apache-tomcat-8.5.51.tar.gz dest=/tmp
  - name: 解压tomcat
    unarchive: src=/tmp/apache-tomcat-8.5.51.tar.gz dest=/usr/local/ copy=no
  - name: 启动tomcat
    shell: cd /usr/local/apache-tomcat-8.5.51/bin/ && nohup ./startup.sh &

从yum中找openjdk的安装包

[root@master ~]# yum list all | grep "openjdk"

使用变量的方式定义

- name: install tomcat
  hosts: all
  vars:
    version: 8.5.51
    dir: /usr/local/
  tasks:
  - name: 安装openjdk
    yum: name=java-1.8.0-openjdk state=present
  - name: 下载tomcat
    get_url: url=http://mirror.hust.edu.cn/apache/tomcat/tomcat-8/v{{ version }}/bin/apache-tomcat-{{ version }}.tar.gz dest=/tmp
  - name: 解压tomcat
    unarchive: src=/tmp/apache-tomcat-{{ version }}.tar.gz dest={{ dir }} copy=no
  - name: 启动tomcat
    shell: cd {{ dir }}apache-tomcat-{{ version }}/bin/ && nohup ./startup.sh &

4.3.6 作业

使用ansible-playbook 批量部署tomcat

1、 思路要求

1) 准备3台虚拟机,1台为ansible管理主机,2台为tomcat服务器

2) 请检查ansible主机的ansible是否安装,若未安装请安装

  • ansible --version

3) 请合理添加服务器组,将两台tomcat服务器分配在tomcatservers组当中

  • 修改清单文件

4) 配置免密码登录

  • ssh-keygen
  • ssh-copy-id

5) 合理调用相关模块,安装tomcat依赖环境,并配置环境变量

  • ansible tomcatservers -m yum -a 'name=java-1.8.0-openjdk state=present'

6) <font color=red>批量分发tomcat安装包至tomcat服务器</font>

- name: install tomcat
  hosts: tomcatservers
  tasks:
  - name: 解压tomcat
    unarchive: src=/tmp/apache-tomcat-8.5.51.tar.gz dest=/usr/local/ copy=yes

7) 启动所有Tomcat服务器的tomcat服务

- name: start tomcat
  hosts: tomcatservers
  tasks:
  - name: start service
    shell:cd /usr/local/apache-tomcat-8.5.51/bin/ && nohup ./startup.sh &

8) 查看所有Tomcat的8080端口监听是否正常

  • [root@master ~]# ansible all -m shell -a "ss -tnl | grep 8080"

9) 访问所有Tomcat服务器,测试是否可以访问到Tomcat测试页面

2、提交时间:23日晚晚自习下课前

4.3.7 vars参数

vars是用来在playbook中使用变量的。

playbook使用变量有4种方式:

  • 直接在yaml文件中定义和使用变量
  • 使用ansible的内置变量
  • 在主机清单中定义变量
  • 主机组变量

第一种变量:yaml中自定义变量

  • 定义变量方法:vars
  • 使用变量方法:{{ xx }}
嗯嗯- hosts: all
  remote_user: root
  vars:
  - package: mariadb-server
  - serviceName: mariadb
  - configFile: /tmp/my.cnf
  tasks:
  - name: install maraidb
    yum: name={{ package }} state=latest
  - name: create my.cnf
    copy: src={{ configFile }} dest=/etc/my.cnf
    notify:
    - restart sql
  - name: start sql
    service: name={{ serviceName }} state=started
  handlers:
  - restart sql
    service: name={{ serviceName }} state=restarted

第二种变量:使用ansible中的内置变量

1)获取内置变量:setup模块

案例:获取主机的完全限定名称变量

[root@master ~]# ansible tomcatservers -m setup | grep "ansible_fqdn"
        "ansible_fqdn": "node2", 
        "ansible_fqdn": "node1", 

2)使用内置变量

案例:在每个主机上创建一个用户,用户名是当前主机的主机名(主机名就是fqdn)

- name: create user
  hosts: tomcatservers
  tasks:
  - name: create new user
    user: name={{ ansible_fqdn }} state=present

第三种变量:清单文件主机变量

  • 在主机清单中,为每个和自己设置一个变量

案例:通过主机清单设置id值

1)在主机清单中定义变量

[tomcatservers]
192.168.31.65 id=5 state=no
192.168.31.66 id=3 state=yes

2)在yaml文件中使用变量

- hosts: tomcatservers
  tasks
  - name: user vars
    shell: echo "{{ id }}">/tmp/{{ state }}.log
  • 此时在每个被管理节点的tmp下,都会生成一个t.log,但是其中的值不同,一个是5一个是3

第四种变量:主机组变量

  • 和主机变量相同,也是定义在主机清单中

案例:为tomcatservs主机组添加四个变量

[tomcatservers]
192.168.31.65 id=5 state=no
192.168.31.66 id=3

[tomcatservers:vars]
node=workNode
addrs=beijing
type=webServer
pro=https

思考:什么时候用主机变量?什么时候用主机组变量?

4.3.8 循环

思考:怎么在所有主机都安装gcc gcc-c++ pcre-devel ncurses-devel zlib-devel

答案:

  • shell模块:-m shell -a “yum isntall xxxxxx”

ansible的循环依赖两部分

  • 内置变量:item
  • tasks的子选项:with_items

案例:循环创建5个用户

- hosts: all
  tasks:
  - name: create user
    user: name=user{{ item }} state=present
    with_items:
    - 1
    - 2
    - 3
    - 4
    - 5

4.3.9 判断

  • ansible实现判断是用tasks的when字句实现的判断的
  • 通常都是在when中对自定义和内置变量进行判断

案例:在node2上创建用test007

- hosts: all
  tasks:
  - name: create user
    user: name=test007 state=present
    when: ansible_fqdn == "node1"
  - name: install zsh
    yum: name=zsh state=present

4.4 template

  • template称之为模板
  • 模板通常用来动态生成配置文件

案例:在所有节点安装nginx,两个节点的nginx分别监听在810和820的端口上,两个nginx的虚拟主机名分别为www.当前节点名称.com,两个节点的keepalived的超时时间分别是30和80.

1)创建存储模板的目录

[root@master ~]# mkdir /root/template
[root@master ~]# cp /etc/nginx/nginx.conf /root/template/nginx.conf.j2 -a
  • nginx.conf.j2是用于作为模板的配置文件

2)编辑配置文件模板

[root@master ~]# vim /root/template/nginx.conf.j2 

修改模板文件的4个位置

keepalive_timeout   {{ keepalive_timeout }};
listen       {{ listen_port }} default_server;
listen       [::]:{{ listen_port }} default_server;
server_name  www.{{ ansible_fqdn }}.com;

3)通过主机变量向模板传递参数

[root@master ~]# vim /etc/ansible/hosts 
[myservers]
192.168.31.65 keepalive_timeout=30 listen_port=810
192.168.31.66 keepalive_timeout=80 listen_port=820

4)编写yaml安装nginx,并基于模提供配置信息

- hosts: all
  tasks:
  - name: 安装epel源
    yum: name=epel-release state=present
  - name: 安装nginx
    yum: name=nginx state=latest
  - name: 基于模板生成配置文件,并发送
    template: 
      src=/root/template/nginx.conf.j2 
      dest=/etc/nginx/nginx.conf
    notify:
    - restart nginx
  - name: 启动服务
    service: name=nginx state=started enabled=on
  handlers:
  - name: restart nginx
    service: name=nginx state=restarted

5)执行yaml文件,并检查结果

4.5 tag

- hosts: all
  vars:
  - listen_port: 888
  tasks:
  - name: 安装epel源
    yum: name=epel-release state=present
  - name: 安装nginx
    yum: name=nginx state=latest
  - name: 基于模板生成配置文件,并发送
    tags:
    - sendFile
    template: 
      src=/root/template/nginx.conf.j2 
      dest=/etc/nginx/nginx.conf
    notify:
    - restart nginx
  - name: 启动服务
    service: name=nginx state=started enabled=on
  handlers:
  - name: restart nginx
    service: name=nginx state=restarted 

执行

[root@master ~]# ansible-playbook i.yaml --tags='sendFile'

五、作业

1) 准备3台虚拟机,1台为ansible管理主机,2台为nginx服务器,请更改nginx主机名为:web1和web2

node1上的操作
# hostnamectl set-hostname web1   # hostnamectl命令仅适用于centos7
node2上的操作
# hostnamectl set-hostname web2

2) 请检查ansible主机的ansible是否安装,若未安装请安装

检查的命令
# rpm -q ansible
如果没有安装,则安装
# yum install epe-release -y
# yum install ansible -y

3) 请合理添加服务器组,将两台nginx服务器分配在webserver组当中

[root@master ~]# vim /etc/ansible/hosts

添加如下

[myservers]
192.168.31.65
192.168.31.66

4) 配置免密码登录

[root@master ~]# ssh-keygen -t rsa -P "" 
[root@master ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
[root@master ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]

5) 请调用yum模块,安装nginx

[root@master ~]# ansible all -m yum -a 'name=nginx state=latest'

6) 修改nginx配置文件模板,将nginx监听端口修改为8090,默认网站根目录设置为/opt/html,将修改好的配置文件分发至目标服务器

[root@master ~]# mkdir /root/template/
[root@master ~]# cp /etc/nginx/nginx.conf /root/template/nginx.conf.j2 -a
[root@master ~]# vim /root/template/nginx.conf.j2 

修改

listen       8090 default_server;
listen       [::]:8090 default_server;
server_name  _;
root         /opt/html/;

7) 为分发配置文件任务配置handlers,触发重启nginx

8) 通过template模块分发测试页面,测试页面内容要包含目标主机的主机名和主机ip

[root@master ~]# cd /root/template/
[root@master template]# echo "test page">./index.html.j2

9) playbook语法检测通过,并成功执
10) 访问所有Nginx服务器,测试可以成功访问

yaml文件如下

- hosts: all
  tasks:
  - name: 创建网络根目录
    file: state=directory path=/opt/html
  - name: 安装epel源
    yum: name=epel-release state=present
  - name: 安装nginx
    yum: name=nginx state=latest
  - name: 基于模板生成配置文件,并发送
    tags:
    - sendFile
    template:
      src=/root/template/nginx.conf.j2
      dest=/etc/nginx/nginx.conf
    notify:
    - restart nginx
  - name: 启动服务
    service: name=nginx state=started enabled=on
  - name: 分发测试页面
    template: src=/root/template/index.html.j2 dest=/opt/html/index.html
  handlers:
  - name: restart nginx
    service: name=nginx state=restarted

作业:部署lnmp

1) 准备3台虚拟机,1台为ansible管理主机,2台为nginx服务器,修改两台web服务器主机名为:web-node1和web-node2

2) 请检查ansible主机的ansible是否安装,若未安装请安装

3) 请添加web服务器主机组和数据库服务器主机组:webservers和db-servers

4) 配置免密码登录

5) 请合理编排palybook剧本完成LNMP环境的批量部署,编排要求:

​ a. 请添加自动分发nginx配置文件任务,要求修改nginx监听端口修改为8000

​ b. 网站根目录修改为:/opt/html

​ c. 请为分发配置文件任务添加tags,命名为nginx-config

​ d. 请为分发配置文件任务配置handlers,触发重启nginx

​ e. 请自动分发php测试页面至nginx网站根目录

6) playbook语法检测通过,并成功执行

[root@master ~]# ansible-playbook a.yaml --syntax-check
playbook: a.yaml

7) 访问所有Nginx服务器,测试可以成功访问即可

8) 最终成功上线电商

- hosts: all
  tasks:
  - name: 创建html目录
    shell: mkdir /opt/html
  - name: 安装epel
    shell: yum install epel-release -y
  - name: 安装组件
    shell: yum install nginx php php-mysql php-devel php-fpm mariadb-server -y
  - name: 生成nginx的配置文件
    tags:
    - nginx-config
    template: src=/root/template/nginx.conf.j2 dest=/etc/nginx/nginx.conf
    notify:
    - restart nginx
  - name: start nginx
    service: name=nginx state=started
  - name: 启动php-fpm
    service: name=php-fpm state=started
  - name: 发生nginx测试页
    copy: src=/root/files/index.php dest=/opt/html
  handlers:
    - name: restart nginx
      service: name=nginx state=restarted

扩展:用三个节点部署lnmp

猜你喜欢

转载自blog.51cto.com/54dev/2482968