Ansible

Ansible

一款自动化运维工具,基于Python开发

批量系统配置

批量程序部署

批量运行命令等功能


特色:

基于SSH架构,所以不需要在被管端安装任何软件

模块丰富

支持自定义模块

部署简单,容易上手

社区活跃

支持异构IT架构

配置ansible管理环境

一、软件包安装

[root@pubserver ~]# yum -y install ansible

二、配置名称解析 /etc/hosts

[root@pubserver ~]# echo -e "192.168.88.240\tpubserver" >> /etc/hosts 
[root@pubserver ~]# for i in 1 2
> do
> echo -e "192.168.88.1$i\tweb$i" >> /etc/hosts
> done
[root@pubserver ~]# echo -e "192.168.88.13\tdb1" >> /etc/hosts
[root@pubserver ~]# tail -4 /etc/hosts
192.168.88.240  pubserver
192.168.88.11   web1
192.168.88.12   web2
192.168.88.13   db1

三、配置ansible到被管机的免密登录

[root@pubserver ~]# ssh-keygen    #三个问题都直接回车,使用默认值
[root@pubserver ~]# for i in web{1..2} db1
> do
> ssh-copy-id $i
> done            #

四、创建工作目录

[root@pubserver ~]# mkdir ansible                         #创建ansible工作目录,目录名自己定义
[root@pubserver ~]# cd ansible
[root@pubserver ansible]# touch ansible.cfg inventory    #创建配置文件。默认的配置文件是/etc/ansible/ansible.cfg,但是一般不使用它,而是在工作目录下创建自己的配置文件
[root@pubserver ansible]# vim ansible.cfg                #文件名必须是ansible.cfg
[defaults]
inventory = inventory                                    #定义主机清单文件为当前目录的inventory
host_key_checking = false                                #不检查主机密钥,=号两边空格可有可无
[root@pubserver ansible]# vim inventory                  #创建主机清单文件。写在[]里的是组名,[]下面的是组内的主机名
[webservers]
web[1:2]                                                 #web1和web2的简化写法,表示从1到2

[dbs]
db1

[cluster:children]                                    #cluster是组名,自定义的;children是固定写法,表示下面的组名是cluster的子组
webservers
dbs
[root@pubserver ansible]# ansible all --list-hosts    #查看被管理的所有主机。注意:一定在工作目录下执行命令
  hosts (3):
    web1
    web2
    db1
[root@pubserver ansible]# ansible webservers --list-hosts    #查看webservers组中所有的主机
  hosts (2):
    web1
    web2

ansible进行远程管理的两个方法

无论哪种方式,都是通过模块加参数进行管理。

一、adhoc临时命令。就是在命令行上执行管理命令。

语法:

ansible 主机或组列表 -m 模块 -a "参数"

帮助指令:

[root@pubserver ansible]# ansible-doc -l    #列出全部可用模块
[root@pubserver ansible]# ansible-doc -l | grep yum    #查看包含yum的模块名
[root@pubserver ansible]# ansible-doc yum              #查看yum模块的帮助文档

ping模块

通过ping模块测试到远程主机的连通性

[root@pubserver ansible]# ansible all -m ping
该命令检查是否可以管理远程主机。如果结果为绿色的SUCCESS,则表示成功。
如果是红色的UNREACHABLE,则检查网络是否可通,是否已经可以免密登录。

command模块

ansible默认模块,用于在远程主机上执行任意命令

command不支持shell特性,如管道、重定向

[root@pubserver ansible]# ansible all -m command -a "mkdir /tmp/demo"
[root@pubserver ansible]# ansible web1 -a "ip a s"
[root@pubserver ansible]# ansible web1 -a "ip a s | head"    #报错

shell模块

与command模块类似,但是支持shell特性,如管道、重定向

[root@pubserver ansible]# ansible web1 -m shell -a "ip a s | head"    #成功

script模块

用于在远程主机上执行脚本

[root@pubserver ansible]# vim test.sh    #在控制端创建脚本即可
#!/bin/bash
for user in user{1..5}
do
    useradd $user
    echo '123456' | passwd --stdin $user
done
[root@pubserver ansible]# ansible webservers -m script -a "test.sh"    #在webservers组的主机上执行脚本

file模块

可以创建文件、目录、链接等,还可以修改权限、属性等

常用的选项:

path:指定文件路径

owner:设置文件所有者

group:设置文件所属组

state:状态。touch表示创建文件,directory表示创建目录,link表示创建软链接,absent表示删除

mode:设置权限

src:source的简写,源

dest:destination的简写,目标

[root@pubserver ansible]# ansible-doc file    #查看使用帮助
[root@pubserver ansible]# ansible webservers -m file -a "path=/tmp/file.txt state=touch"    #touch是指如果文件不存在则创建;如果存在则改变它的时间戳
[root@pubserver ansible]# ansible webservers -m file -a "path=/tmp/demo state=directory"    #在webservers组的主机上创建/tmp/demo目录
[root@pubserver ansible]# ansible webservers -m file -a "path=/tmp/file.txt owner=sshd group=adm mode='0777'"    #将webservers组的主机上/tmp/file.txt的属主改为sshd,属组改为adm,权限改为0777
[root@pubserver ansible]# ansible webservers -m file -a "path=/tmp/file.txt state=absent"    #删除webservers组的主机上/tmp/file.txt
[root@pubserver ansible]# ansible webservers -m file -a "path=/tmp/demo state=absent"    #删除webservers组的主机上/tmp/demo
[root@pubserver ansible]# ansible webservers -m file -a "src=/etc/hosts dest=/tmp/hosts.txt state=link"    #在webservers组的主机上创建/etc/hosts的软链接,目标是/tmp/hosts.txt

copy模块

用于将文件从控制端拷贝到被控端

可以上传目录,但不能上传空目录

常用选项:

src:源。控制端的文件路径

dest:目标。被控端的文件路径

content:内容。需要写到文件中的内容

[root@pubserver ansible]# echo AAA > test.txt
[root@pubserver ansible]# ansible webservers -m copy -a "src=test.txt dest=/root"
[root@pubserver ansible]# ansible webservers -m copy -a "dest=/tmp/mytest.txt content='Hello World\n'"

fetch模块

与copy模块相反,copy是上传,fetch是下载

不能下载目录

常用选项:

src:源。被控制端的文件路径

dest:目标。控制端的文件路径

[root@pubserver ansible]# ansible webservers -m fetch -a "src=/etc/hostname dest=/root"

lineinfile模块

用于确保目标文件中有某一行内容

常用选项:

path:待修改的文件路径

line:写入文件的一行内容

regexp:正则表达式,用于查找文件中的内容

#webservers组中的主机,/etc/issue中一定要有一行Hello World。如果该行不存在,则默认添加到文件结尾
[root@pubserver ansible]# ansible webservers -m lineinfile -a "path=/etc/issue line='Hello World'"
#webservers组中的主机,把/etc/issue中有Hello的行,替换成chi le ma
[root@pubserver ansible]# ansible webservers -m lineinfile -a "path=/etc/issue line='chi le ma' regexp='Hello'"

replace模块

lineinfile会替换一行,replace可以替换关键词

常用选项:

path:带修改的文件路径

replace:将正则表达式查到的内容,替换成replace的内容

regexp:正则表达式,用于查找文件中的内容

#把webservers组中主机上/etc/issue文件中的chi,替换成he
[root@pubserver ansible]# ansible webservers -m replace -a "path=/etc/issue regexp='chi' replace='he'"

user模块

实现linux用户管理

常用选项:

name:待创建的用户名

uid:用户ID

group:设置主组

groups:设置附加组

home:设置家目录

password:设置用户密码

state:状态。present表示创建,它是默认选项;absent表示删除

remove:删除家目录、邮箱等。值为yes或true都可以

#在webservers组中的主机上,创建zhangsan用户
[root@pubserver ansible]# ansible webservers -m user -a "name=zhangsan"
#在webservers组中的主机上,创建lisi用户。设置其uid为1010,主组是adm,附加组是daemon和root,家目录是/home/lisi
[root@pubserver ansible]# ansible webservers -m user -a "name=lisi uid=1010 group=adm groups=daemon,root home=/home/lisi"
#设置zhangsan的密码是123456
#{{}}是固定格式,表示执行命令。password_hash是函数,sha512是加密算法,则password_hash函数将会把123456通过sha512加密变成zhangsan的密码
[root@pubserver ansible]# ansible webservers -m user -a "name=zhangsan password={{'123456'|password_hash('sha512')}}"
#删除zhangsan用户,不删除家目录
[root@pubserver ansible]# ansible webservers -m user -a "name=zhangsan state=absent"
#删除lisi用户,同时删除家目录
[root@pubserver ansible]# ansible webservers -m user -a "name=lisi state=absent remove=yes"

group模块

创建、删除组

常用选项:

name:待创建的组名

gid:组的ID号

state:present表示创建,它是默认选项。absent表示删除

#在webservers组中的主机上创建名为devops的组
[root@pubserver ansible]# ansible webservers -m group -a "name=devops"
#在webservers组中的主机上删除名为devops的组
[root@pubserver ansible]# ansible webservers -m group -a "name=devops state=absent"

yum_repository模块

用于配置yum

常用选项:

file:指定文件名

#在webservers组中的主机上,配置yum
[root@pubserver ansible]# ansible webservers -m yum_repository -a "file=myrepo name=myApp description='My App' baseurl=ftp://192.168.88.240/dvd/AppStream gpgcheck=no enabled=yes"
[root@pubserver ansible]# ansible webservers -m yum_repository -a "file=myrepo name=BaseOS description='Base OS' baseurl=ftp://192.168.88.240/dvd/BaseOS gpgcheck=no enabled=yes"
#查看验证
[root@web1 ~]# cat /etc/yum.repos.d/myrepo.repo 
[myApp]
async = 1
baseurl = ftp://192.168.88.240/dvd/AppStream
enabled = 1
gpgcheck = 0
name = My App
[BaseOS]
async = 1
baseurl = ftp://192.168.88.240/dvd/BaseOS
enabled = 1
gpgcheck = 0
name = Base OS

yum模块

用于rpm软件包管理、如安装、升级、卸载

常用选项:

name:包名

state:状态。present表示安装,如果已安装则忽略;latest表示安装或升级到最新版本;absent表示卸载

#在webservers组中的主机上安装tar
[root@pubserver ansible]# ansible webservers -m yum -a "name=tar state=present"

#在webservers组中的主机上安装wget、net-tools
[root@pubserver ansible]# ansible webservers -m yum -a "name=wget,net-tools"

#在webservers组中的主机上卸载wget
[root@pubserver ansible]# ansible webservers -m yum -a "name=wget state=absent"

service模块

用于控制服务。启动、关闭、重启、开机是否自启

常用选项:

name:控制的服务名

state:started表示启动;stopped表示关闭;restarted表示重启

enabled:yes表示设置开机自启;no表示设置开机不要自启

#在test主机上安装nginx
[root@pubserver ansible]# ansible webservers -m yum -a "name=nginx state=latest"

#在test主机上启动nginx,并设置它开机自启
[root@pubserver ansible]# ansible webservers -m service -a "name=nginx state=started enabled=yes"

逻辑卷相关模块

逻辑卷可以动态管理存储空间。可以对逻辑卷进行扩容或删减

可以把硬盘或分区转换成物理卷PV;再把1到多个PV组合成卷组VG;然后在VG上划分逻辑卷LV。LV可以像普通分区一样,进行格式化、挂载

lvg模块

创建、删除卷组,修改卷组大小

常用选项:

vg:定义卷组名

pvs:由哪些物理卷构成

#在web1上安装lvm2,state不写,默认是present
[root@pubserver ansible]# ansible web1 -m yum -a "name=lvm2"

#手工在web1上对vdb进行分区
[root@web1 ~]# fdisk /dev/vdb
Command (m for help): g    #创建GPT分区表
Command (m for help): n    #新建分区
Partition number (1-128, default 1):    #回车,使用1号分区
First sector (2048-41943006, default 2048):   #起始位置,回车
Last sector, +sectors or +size{K,M,G,T,P} (2048-41943006, default 41943006): +5G   #结束位置+5G

Command (m for help): n   #新建分区
Partition number (2-128, default 2):   #回车,使用2号分区
First sector (10487808-41943006, default 10487808): #起始位置,回车
Last sector, +sectors or +size{K,M,G,T,P} (10487808-41943006, default 41943006): #结束位置,回车,分区到结尾
Command (m for help): w   #保存退出
[root@web1 ~]# lsblk    # vdb被分出来了两个分区

#在web1上创建名为myvg的卷组,该卷组由/dev/vdb1组成
[root@pubserver ansible]# ansible web1 -m lvg -a "vg=myvg pvs=/dev/vdb1"
#在web1上查看卷组
[root@web1 ~]# vgs

#扩容卷组。卷组由PV构成,只要向卷组中加入新的PV,即可实现扩容
[root@pubserver ansible]# ansible web1 -m lvg -a "vg=myvg pvs=/dev/vdb1,/dev/vdb2"
#在web1上查看卷组
[root@web1 ~]# vgs

lvol模块

创建、删除逻辑卷,修改逻辑卷大小

常用选项:

vg:指定在哪个卷组上创建逻辑卷

lv:创建的逻辑卷名

size:逻辑卷的大小,不写单位,以M为单位

#在web1上创建名为mylv的逻辑卷,大小为2GB
[root@pubserver ansible]# ansible web1 -m lvol -a "vg=myvg lv=mylv size=2G"
#在web1上查看逻辑卷
[root@web1 ~]# lvs

#mylv扩容至4GB
[root@pubserver ansible]# ansible web1 -m lvol -a "vg=myvg lv=mylv size=4G"

filesystem模块

用于格式化,也就是创建文件系统

常用选项:

fstype:指定文件系统类型

dev:指定要格式化的设备,可以是分区,可以是逻辑卷

#在web1上,把/dev/myvg/mylv格式化为xfs
[root@pubserver ansible]# ansible web1 -m filesystem -a "fstype=xfs dev=/dev/myvg/mylv"
#在web1上查看格式化结果
[root@web1 ~]# blkid /dev/myvg/mylv

mount模块

用于挂载文件系统

常用选项:

path:挂载点。如果挂载点不存在,自动创建

src:待挂载的设备

fstype:文件系统类型

state:mounted 写入自动挂载并直接挂载

#在web1上,把/dev/myvg/mylv永久挂载到/data
[root@pubserver ansible]# ansible web1 -m mount -a "path=/data src=/dev/myvg/mylv state=mounted fstype=xfs"
#在web1上查看
[root@web1 ~]# tail -1 /etc/fstab
[root@web1 ~]# df -h /data/

#在web1上,卸载/dev/myvg/mylv
[root@pubserver ansible]# ansible web1 -m mount -a "path=/data state=absent"

#在web1上,强制删除/dev/myvg/mylv
[root@pubserver ansible]# ansible web1 -m lvol -a "lv=mylv state=absent vg=myvg force=yes"   # force是强制

#在web1上,删除myvg卷组
[root@pubserver ansible]# ansible web1 -m lvg -a "vg=myvg state=absent"

二、playbook剧本。把管理任务用特定格式写到文件中。

常用于复杂任务的管理,以及管理经常要完成的任务

playbook也是通过模块和它的参数,在特定主机上执行任务

playbook是一个文件,该文件中需要通过yaml格式进行书写

yaml语法规范:

yaml文件的文件名,一般以yml或yaml作为扩展名

文件一般以---作为第一行,不是必须的,但是常用

键值对使用冒号:表示,冒号后面必须有空格

数组使用-表示,-后面必须有空格

相同的层级必须有相同的缩进。如果缩进不对,则有语法错误。每一级缩进,建议2个空格

全文不能使用tab,必须使用空格

配置vim适应yaml语法

#文件位置和名字是固定的,用于设置vim的格式
[root@pubserver ansible]# cat ~/.vimrc 
set ai    #设置自动缩进
set et    #将tab转换成相应个数的空格
set ts=2  #设置按tab键,缩进2个空格
set cursorcolumn

编写playbook

一个剧本(即playbook),可以包含多个play

每个play用于在指定的主机上,通过模块和参数执行相应的任务

每个play可以包含多个任务

任务由模块和参数构成

#编写用于测试连通性的playbook,相当于执行ansible all -m ping
[root@pubserver ansible]# cat ping.yml 
---
- name: test netwok
  hosts: all
  tasks:
    - name: test ping
      ping:
[root@pubserver ansible]# ansible-playbook ping.yml    #执行playbook
#在dbs组的主机和web1上创建/tmp/demo目录,权限是0755。将控制端/etc/hosts拷贝到目标主机的/tmp/demo中
[root@pubserver ansible]# vim fileop.yml 
---      
- name: create dir and copy file
  hosts: dbs,web1                #这里的名称,必须出现在主机清单文件中
  tasks: 
    - name: create dir
      file:
        path: /tmp/demo
        state: directory
        mode: '0755'
         
    - name: copy file
      copy:
        src: /etc/hosts
        dest: /tmp/demo/
[root@pubserver ansible]# ansible-playbook fileop.yml    #执行playbook
#在webservers组中的主机上,创建用户bob,附加组是adm;在db1主机上,创建/tmp/hi.txt,其内容为Hello World
[root@pubserver ansible]# vim two.yml 
---      
- name: create user
  hosts: webservers
  tasks: 
    - name: create bob
      user:
        name: bob
        groups: adm

- name: create file
  hosts: db1
  tasks: 
    - name: make file
      copy:
        dest: /tmp/hi.txt
        content: "Hello World\n"
[root@pubserver ansible]# ansible-playbook two.yml    #执行playbook

| 和 > 的区别

| 保留换行符

> 把多行合并为一行 

#通过copy模块创建/tmp/1.txt,文件中有两行内容,分别是Hello World和ni hao
[root@pubserver ansible]# vim f1.yml
---      
- name: play 1
  hosts: webservers
  tasks: 
    - name: mkfile 1.txt
      copy:
        dest: /tmp/1.txt
        content: |        #测试 | 的效果
          Hello World!
          ni hao.
[root@web1 ~]# cat /tmp/1.txt 
Hello World!
ni hao.

#通过copy模块创建/tmp/2.txt,文件中有一行内容,分别是Hello World! ni hao
[root@pubserver ansible]# vim f1.yml
---      
- name: play 1
  hosts: webservers
  tasks: 
    - name: mkfile 2.txt
      copy:
        dest: /tmp/2.txt
        content: >
          Hello World!
          ni hao.
[root@web1 ~]# cat /tmp/2.txt 
Hello World! ni hao.
#在webservers组中的主机上创建john用户,它的uid是1040,主组是daemon,密码为123
[root@pubserver ansible]# vim user_john.yml 
---      
- name: create user
  hosts: webservers
  tasks: 
    - name: create user john
      user:
        name: john
        uid: 1040
        group: daemon
        password: "{{'123'|password_hash('sha512')}}"

#在webservers组中的主机上删除用户john
[root@pubserver ansible]# vim del_john.yml 
---      
- name: remove user
  hosts: webservers
  tasks: 
    - name: remove user john
      user:
        name: john
        state: absent

硬盘管理

常用的分区表类型有:MBR(主引导记录)、GPT(GUID分区表)

MBR最多支持4个主分区,或3个主分区加1个扩展分区。最大支持2.2TB左右的硬盘

GPT最多支持128个主分区。支持大硬盘

parted模块

用于硬盘分区管理

常用选项:

device:待分区的设备

number:分区编号

state:present表示创建,absent表示删除

part_start:分区的起始位置,不写表示从开头

part_end:表示分区的结束位置,不写表示到结尾

#在web1主机上,对/dev/vdc进行分区,创建1个1GB的主分区
[root@pubserver ansible]# vim disk.yml
---
- name: disk manager
  hosts: web1
  tasks:
    - name: create a partition
      parted:
        device: /dev/vdc
        number: 1
        state: present
        part_end: 1GiB
[root@pubserver ansible]# ansible-playbook disk.yml
#在目标主机上查看结果
[root@web1 ~]# lsblk /dev/vdc 
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
vdc    253:32   0   20G  0 disk 
└─vdc1 253:33   0 1023M  0 part

#继续编辑disk.yml,对/dev/vdc进行分区,创建1个新的5GB的主分区
......
    - name: add a new partition
      parted:
        device: /dev/vdc
        number: 2
        state: present
        part_start: 1GiB
        part_end: 6GiB
[root@pubserver ansible]# ansible-playbook disk.yml
[root@web1 ~]# lsblk /dev/vdc 
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
vdc    253:32   0   20G  0 disk 
├─vdc1 253:33   0 1023M  0 part 
└─vdc2 253:34   0    5G  0 part

#继续编辑disk.yml,创建名为my_vg的卷组,它由上面创建的vdc1和vdc2构成
......
    - name: create my_vg
      lvg:
        vg: my_vg
        pvs: /dev/vdc1,/dev/vdc2

#继续编辑disk.yml,在my_vg卷组上创建名为my_lv的逻辑卷,大小1G
......
    - name: create my_lv
      lvol:
        vg: my_vg
        lv: my_lv
        size: 1G

#继续编辑disk.yml,格式化my_lv为ext4
......
    - name: mkfs my_lv
      filesystem:
        dev: /dev/my_vg/my_lv
        fstype: ext4

#继续编辑disk.yml,将my_lv挂载到/data
......
    - name: mount my_lv
      mount:
        path: /data
        src: /dev/my_vg/my_lv
        fstype: ext4
        state: mounted

playbook 安装软件

#在webservers组中的主机上,安装httpd、php、php-mysqlnd
[root@pubserver ansible]# vim pkg.yml
---
- name: install pkgs
  hosts: webservers
  tasks:
    - name: install web pkgs
      yum:
        name: httpd,php,php-mysqlnd
        state: present
#安装多个软件包,还可以写为:
---
- name: install pkgs
  hosts: webservers
  tasks:
    - name: install web pkgs
      yum:
        name: [httpd,php,php-mysqlnd]
        state: present
#安装多个软件包,还可以写为:
---
- name: install pkgs
  hosts: webservers
  tasks:
    - name: install web pkgs
      yum:
        name: 
          - httpd
          - php
          - php-mysqlnd
        state: present

#根据功能等,可以将一系列软件放到一个组中,安装软件包组,将会把很多软件一起安装上。比如gcc、java等都是开发工具,安装开发工具包组,将会把它们一起安装
[root@node1 ~]# yum grouplist   # 列出所有的软件包组
[root@node1 ~]# yum groupinstall "Development Tools"
# 如果列出的组名为中文,可以这样进行:
[root@node1 ~]# LANG=C yum grouplist

ansible变量

一、facts变量

facts翻译过来就是事实

facts变量是ansible自带的预定义变量,用于描述被控端软硬件信息

facts变量通过setup模块获得

#通过setup模块查看所有facts变量
[root@pubserver ansible]# ansible webservers -m setup

facts变量是一个大的由{}构成的键值对字典。在{}中,有很多层级的嵌套。可以通过参数过滤出第一个层级的内容。

#查看所有的IPV4地址,filter是过滤的意思
[root@pubserver ansible]# ansible web1 -m setup -a "filter=ansible_all_ipv4_addresses"

#查看可用内存
[root@pubserver ansible]# ansible web1 -m setup -a "filter=ansible_memfree_mb"

常用的facts变量:

ansible_all_ipv4_addresses:所有的IPV4地址

ansible_bios_version:BIOS版本信息

ansible_memtotal_mb:总内存大小

ansible_hostname:主机名

在playbook中使用变量

[root@pubserver ansible]# ansible webservers -m setup | less
#在ansible中,变量使用{{}}表示
#debug模块用于输出信息,常用的参数是msg,用于输出指定内容
[root@pubserver ansible]# vim debug.yml
---      
- name: display host info
  hosts: webservers
  tasks: 
    - name: display host info
      debug:
        msg: "hostname:{{ansible_hostname}},mem:{{ansible_memtotal_mb}}MB,IP:{{ansible_eth0.ipv4.address}},vda1 size{{ansible_devices.vda.partitions.vda1.size}}"

二、自定义变量

引入变量,可以方便playbook重用。比如装包的playbook,包名使用变量。多次执行playbook,只要改变变量名即可,不用编写新的playbook

ansible支持10种以上的变量定义方式。常用的变量来源如下:

inventory变量。变量来自于主机清单文件

facts变量。

playbook变量。变量在playbook中定义。

变量文件。专门创建用于保存变量的文件。推荐变量写入单独的文件。

#使用inventory变量。
[root@pubserver ansible]# vim inventory
[webservers]
web1
web2

[dbs]
db1 username="wangwu"   # 定义主机变量的方法

[webservers:vars]       # 定义组变量的方法,:vars是固定格式
username="zhaoliu"

#通过变量创建用户
[root@pubserver ansible]# vim var1.yml
---
- name: webservers create user
  hosts: webservers
  tasks:
    - name: create user
      user:
        name: "{{username}}"
        state: present
       
- name: create user in dbs
  hosts: dbs
  tasks:
    - name: create some users
      user:
        name: "{{username}}"
        state: present

#上述两个play也可以合并为一个,如下:
[root@pubserver ansible]# vim var1.yml
---
- name: webservers create user
  hosts: dbs,webservers    # 指定执行的目标是dbs组和webservers组
  tasks:
    - name: create user
      user:
        name: "{{username}}"
        state: present
#在playbook中定义变量
#在webservers组中的主机上创建用户jack,他的密码是123456
[root@pubserver ansible]# vim user_jack.yml
---
- name: create user
  hosts: webservers
  vars:                 #固定格式,用于声明变量
    username: "jack"    #此处引号可有可无
    mima: "123456"      #此处引号是需要的,表示数字字符
  tasks:
    - name: create some users
      user:
        name: "{{username}}"   #{}出现在开头,必须有引号
        state: present
        password: "{{mima|password_hash('sha512')}}"

#将变量定义在文件中
[root@pubserver ansible]# vim vars.yml   #文件名自定义
---
yonghu: rose
mima: abcd
[root@pubserver ansible]# vim user_rose.yml 
---
- name: create user
  hosts: webservers
  vars_files: vars.yml       #vars_files用于声明变量文件
  tasks:
    - name: create some users
      user:
        name: "{{yonghu}}"   #这里的变量来自于vars.yml
        state: present
        password: "{{mima|password_hash('sha512')}}"

cw

r改

ctrl+n

ctrl+r

光标放到需要缩进的第一行

ctrl + v

向下到需要缩进的最后一行

大I

4个空格

Esc

补充模块

一、firewalld模块

用于配置防火墙的模块

常用选项:

port:声明端口

permanent:永久生效,但不会立即生效

immediate:立即生效,临时生效

state:enabled,放行;disabled拒绝

防火墙一般默认拒绝,明确写入允许的服务。

有一些服务有名字,有些服务没有名字。但是最终都是基于TCP或UDP的某些端口。比如http服务基于TCP80端口。服务名和端口号对应关系的说明文件是:/etc/services

配置服务器的防火墙,一般来说只要配置开放哪些服务或端口即可。没有明确开放的,都默认拒绝。

应用:

在webservers组中的主机上安装并启动nginx

客户端访问服务器的nginx服务

在webservers组中的主机上安装并启动firewalld

客户端访问服务器的nginx服务

在webservers组中的主机上开放nginx服务

#配置nginx服务
[root@pubserver ansible]# vim firewall.yml
---
- name: configure webservers
  hosts: webservers
  tasks:
    - name: install nginx pkg     #这里通过yum模块装httpd
      yum:
        name: nginx
        state: present
    - name: start nginx service   #这里通过service模块启httpd服务
      service:
        name: nginx
        state: started
        enabled: yes
[root@pubserver ansible]# ansible-playbook firewall.yml
[root@pubserver ansible]# curl http://192.168.88.11/    #可访问

#安装并启动firewalld
[root@pubserver ansible]# vim firewall.yml
---
- name: configure webservers
  hosts: webservers
  tasks:
    - name: install nginx pkg       #这里通过yum模块装httpd
      yum:
        name: nginx
        state: present
    - name: start nginx service     #这里通过service模块启httpd服务
      service:
        name: nginx
        state: started
        enabled: yes
    - name: install firewalld pkg   #这里通过yum模块装firewalld
      yum:
        name: firewalld
        state: present
    - name: start firewalld service  #这里通过service模块启firewalld服务
      service:
        name: firewalld
        state: started
        enabled: yes
[root@pubserver ansible]# ansible-playbook firewall.yml
[root@pubserver ansible]# curl http://192.168.88.11/    #被拒绝
curl: (7) Failed to connect to 192.168.88.11 port 80: 没有到主机的路由

#配置防火墙规则,放行http协议
[root@pubserver ansible]# vim firewall.yml
---
- name: configure webservers
  hosts: webservers
  tasks:
    - name: install nginx pkg         #这里通过yum模块装httpd
      yum:
        name: nginx
        state: present
    - name: start nginx service       #这里通过service模块启httpd服务
      service:
        name: nginx
        state: started
        enabled: yes
    - name: install firewalld pkg     #这里通过yum模块安装firewalld
      yum:
        name: firewalld
        state: present
    - name: start firewalld service   #这里通过service模块启firewalld服务
      service:
        name: firewalld
        state: started
        enabled: yes
    - name: set firewalld rules       #通过firewalld模块开放80端口
      firewalld:
        port: 80/tcp
        permanent: yes
        immediate: yes
        state: enabled
[root@pubserver ansible]# ansible-playbook firewall.yml 
[root@pubserver ansible]# curl http://192.168.88.11/  # 可访问

二、template模块

copy模块可以上传文件,但是文件内容固定

template模块可以上传具有特定格式的文件(如文件中包含变量)

当远程主机接收到文件之后,文件中的变量将会变成具体的值

template模块上传的文件,使用的语法叫Jinja2。

常用选项:

src:要上传的文件

dest:目标文件路径

#使用template模块将含有变量的文件上传到webservers组中的主机
[root@pubserver ansible]# vim index.html
Welcome to {{ansible_hostname}} on {{ansible_eth0.ipv4.address}}
[root@pubserver ansible]# vim templ.yml
---
- name: upload index
  hosts: webservers
  tasks:
    - name: create web index
      template:
        src: index.html
        dest: /usr/share/nginx/html/index.html
[root@pubserver ansible]# ansible-playbook templ.yml
[root@pubserver ansible]# curl http://192.168.88.11/
Welcome to web1 on 192.168.88.11
[root@pubserver ansible]# curl http://192.168.88.12
Welcome to web2 on 192.168.88.12
[root@web1 ~]# cat /usr/share/nginx/html/index.html
Welcome to web1 on 192.168.88.11
[root@web2 ~]# cat /usr/share/nginx/html/index.html
Welcome to web2 on 192.168.88.12

进阶语法

一、错误处理

当Playbook中包含很多任务时,当某一个任务遇到错误,它将崩溃,终止执行

#在webservers组中的主机上启动mysqld服务,然后创建/tmp/service.txt
#因为目标主机上没有mysqld服务,所以它将崩溃,终止执行。即,不会创建/tmp/service.txt文件
[root@pubserver ansible]# vim myerr.yml
---
- name: my errors
  hosts: webservers
  tasks:
    - name: start mysqld service  #通过service模块启动mysqld服务
      service:
        name: mysqld
        state: started
        enabled: yes       
    - name: touch a file          #通过file模块创建文件
      file:
        path: /tmp/service.txt
        state: touch
#执行playbook,第1个任务就会失败
[root@pubserver ansible]# ansible-playbook myerr.yml
#到web1上查看,因为第2个任务没有执行,所以文件不会创建
[root@web1 ~]# ls /tmp/service.txt
ls: cannot access '/tmp/service.txt': No such file or directory

可以指定某一个任务如果出现错误,则忽略它

#编辑myerr.yml,如果myslqd服务无法启动,则忽略它
[root@pubserver ansible]# vim myerr.yml
---
- name: my errors
  hosts: webservers
  tasks:
    - name: start mysqld service
      service:
        name: mysqld
        state: started
        enabled: yes
      ignore_errors: yes    #即使这个任务失败了,也要继续执行下去

    - name: touch a file
      file:
        path: /tmp/service.txt
        state: touch


[root@pubserver ansible]# ansible-playbook myerr.yml
[root@web1 ~]# ls /tmp/service.txt   #第2个任务已执行
/tmp/service.txt

通过全局设置,无论哪个任务出现问题,都要忽略

[root@pubserver ansible]# vim myerr.yml
---
- name: my errors
  hosts: webservers
  ignore_errors: yes
  tasks:
    - name: start mysqld service
      service:
        name: mysqld
        state: started
        enabled: yes
    - name: touch a file
      file:
        path: /tmp/mysql.txt
        state: touch

[root@pubserver ansible]# ansible-playbook myerr.yml
[root@web1 ~]# ls /tmp/mysql.txt 
/tmp/mysql.txt

二、触发执行任务

通过handlers定义触发执行的任务

handlers中定义的任务,不是一定会执行的

在tasks中定义的任务,通过notify关键通知handlers中的哪个任务要执行

只有tasks中的任务状态是changed才会进行通知。

#下载web1上的/etc/nginx/nginx.conf
[root@pubserver ansible]# vim get_conf.yml
---
- name: download nginx.conf
  hosts: web1
  tasks:
    - name: get nginx.conf
      fetch:
        src: /etc/nginx/nginx.conf
        dest: ./
        flat: yes    #直接下载文件,不要目录
[root@pubserver ansible]# ansible-playbook get_conf.yml

#修改nginx.conf的端口为变量
[root@pubserver ansible]# vim +39 nginx.conf
... ...
    server {
        listen       {{http_port}} default_server;
        listen       [::]:{{http_port}} default_server;
        server_name  _;
... ...

#修改nginx服务的端口为8000,重启nginx
[root@pubserver ansible]# vim trigger.yml
---
- name: configure nginx
  hosts: webservers
  vars:
    http_port: "8000"           #定义nginx.conf中的变量和值
  tasks:
    - name: upload nginx.conf   #上传nginx.conf
      template:
        src: ./nginx.conf
        dest: /etc/nginx/nginx.conf
    - name: restart nginx       #重启服务
      service:
        name: nginx
        state: restarted
#第一次执行trigger.yml,上传文件和重启服务两个任务的状态都是黄色changed
#第二次执行trigger.yml,上传文件的任务状态是绿色的ok,重启服务任务的状态是黄色changed

#既然配置文件没有改变,那么服务就不应该重启
#修改Playbook,只有配置文件变化了,才重启服务
[root@pubserver ansible]# vim trigger.yml
---
- name: configure nginx
  hosts: webservers
  vars:
    http_port: "80"
  tasks:
    - name: upload nginx.conf
      template:
        src: ./nginx.conf
        dest: /etc/nginx/nginx.conf
      notify: restart nginx   #通知restart httpd需要执行
  handlers:
    - name: restart nginx
      service:
        name: nginx
        state: restarted
#第一次运行Playbook,因为第1个任务是黄色的changed,所以handlers中的任务也被触发执行
#第二次运行Playbook,因为第1个任务是绿色的OK,也就不会再触发执行其他任务了

三、when条件

只有满足某一条件时,才执行任务

常用的操作符:

==:相等

!=:不等

>:大于

<:小于

<=:小于等于

>=:大于等于

多个条件或以使用and或or进行连接

when表达式中的变量,可以不使用{{}}

#当dbs组中的主机内存大于2G的时候,才安装mysql-server
[root@pubserver ansible]# vim when1.yml
---
- name: install mysql-server
  hosts: dbs
  tasks:
    - name: install mysql-server pkg
      yum:
        name: mysql-server
        state: present
      when: ansible_memtotal_mb>2048
#如果目标主机没有2GB内存,则不会安装mysqld-server

#多条件。系统发行版是Rocky8才执行任务
#/etc/motd中的内容,将会在用户登陆时显示在屏幕上
[root@pubserver ansible]# yum -y install cowsay
[root@pubserver ansible]# cowsay Hello World > motd
[root@pubserver ansible]# vim when2.yml
---
- name: when condition
  hosts: webservers
  tasks:
    - name: modify /etc/motd
      copy:
        dest: /etc/motd
        src: motd
      when: >     # 以下三行合并成一行
        ansible_distribution == "Rocky"
        and
        ansible_distribution_major_version == "8"
[root@pubserver ansible]# ansible-playbook when2.yml
[root@pubserver ansible]# echo 'nocows = 1' >> ansible.cfg
[root@pubserver ansible]# ansible-playbook when2.yml

四、regitster注册变量

Ansible的“register”模块是用于捕获和保存任务执行结果的,它允许将其他任务的输出作为变量使用。register是一个关键字,可以将任务执行的结果赋值给指定的变量名称。这个变量可以在后续任务中使用。 register模块可以捕获各种类型的输出,包括stdout、stderr、rc、changed等。它可以与其他模块一起使用,例如“when”条件、“loop”循环等。

#在web1组的主机上执行任务,创建/tmp/regfile1.txt,并打印创建结果
[root@pubserver ansible]# vim reg1.yml
---
- name: create file /tmp/regfile1.txt
  hosts: web1
  tasks:
    - name: create file
      file:
        path: /tmp/rgefile1.txt
        state: touch
      register: result
    - name: display output
      debug:
        msg: "{{result}}"

#在web1主机上执行任务,创建文件/tmp/ademo/abc。如果创建不成功,则通过debug输出create failed
[root@pubserver ansible]# vim reg2.yml
---
- name: create file /tmp/ademo/abc
  hosts: web1
  ignore_errors: yes
  tasks:
    - name: create file
      file:
        path: /tmp/ademo/abc
        state: touch
      register: result
    - name: debug output
      debug:
        msg: "create failed"
      when: result.failed
#
---      
- name: create file /tmp/ademo/abc
  hosts: webservers
  ignore_errors: yes
  tasks: 
    - name: create file
      file:
        path: /tmp/ademo/abc
        state: touch
      register: result
         
    - name: debug output
      debug:
        msg: "create failed"
      when: result.failed == True
#
---                
- name: create file /tmp/ademo/abc
  hosts: webservers
  ignore_errors: yes
  tasks:           
    - name: create file
      file:        
        path: /tmp/abc
        state: touch
      register: result
                   
    - name: debug output
      debug:       
        msg: "create failed"
      when: result.failed == True

关于cowsay

# cowsay是一个软件,可以在以下地址获得
# https://rpmfind.net/linux/epel/8/Everything/x86_64/Packages/c/cowsay-3.04-16.el8.noarch.rpm
# 使用方式如下:
[root@pubserver ansible]# yum install -y /root/cowsay-3.04-16.el8.noarch.rpm
[root@pubserver ansible]# cowsay ni hao a
__________
< ni hao a >
----------
  \   ^__^
   \  (oo)\_______
      (__)\       )\/\
          ||----w |
          ||     ||
# 查看其他形象
[root@pubserver ansible]# cowsay -l
Cow files in /usr/share/cowsay:
beavis.zen blowfish bud-frogs bunny cheese cower default dragon
dragon-and-cow elephant elephant-in-snake eyes flaming-sheep fox
ghostbusters head-in hellokitty kiss kitty koala kosh luke-koala
mech-and-cow meow milk moofasa moose mutilated ren sheep skeleton small
stegosaurus stimpy supermilker surgery telebears three-eyes turkey turtle
tux udder vader vader-koala www
[root@pubserver ansible]# cowsay -f elephant are you ok?
_____________
< are you ok? >
-------------
\     /\  ___  /\
\   // \/   \/ \\
((    O O    ))
\\ /     \ //
 \/  | |  \/
  |  | |  |
  |  | |  |
  |   o   |
  | |   | |
  |m|   |m|
# 如果执行playbook时也会出现奶牛,则可以使用以下方式取消
[root@pubserver ansible]# echo 'nocows = 1' >> ansible.cfg


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值