Ansible部署和模块应用

Ansible

Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstack能实现的功能,Ansible基本上都可以实现。

Ansible能批量配置、部署、管理上千台主机。比如以前需要切换到每个主机上执行的一或多个操作,使用Ansible只需在固定的一台Ansible控制节点上去完成所有主机的操作。

Ansible是基于模块工作的,它只是提供了一种运行框架,它本身没有完成任务的能力,真正执行操作的是Ansible的模块, 比如copy模块用于拷贝文件到远程主机上,service模块用于管理服务的启动、停止、重启等。

Ansible其中一个比较鲜明的特性是Agentless,即无Agent的存在,它就像普通命令一样,并非C/S软件,也只需在某个作为控制节点的主机上安装一次Ansible即可,通常它基于ssh连接来控制远程主机,远程主机上不需要安装Ansible或其它额外的服务。

使用者在使用时,在服务器终端输入命令或者playbooks,会通过预定好的规则将playbook拆解为play,再组织成ansible可以识别的任务,调用模块和插件,根据主机清单通过SSH将临时文件发给远程的客户端执行并返回结果,执行结束后自动删除

Ansible的另一个比较鲜明的特性是它的绝大多数模块都具备幂等性(idempotence)。所谓幂等性,指的是无论执行多少次同样的运算,结果都是相同的,即一条命令,任意多次执行所产生的影响均与一次执行的影响相同。比如执行 systemctl stop xxx 命令来停止服务,当发现要停止的目标服务已经处于停止状态,它什么也不会做, 所以多次停止的结果仍然是停止,不会改变结果,它是幂等的,而 systemctl restart xxx 是非幂等的。

Ansible的很多模块在执行时都会先判断目标节点是否要执行任务,所以,可以放心大胆地让Ansible去执行任务,重复执行某个任务绝大多数时候不会产生任何副作用。


---------- ansible 环境安装部署 ----------
管理端:192.168.80.10            ansible
被管理端:192.168.80.11
被管理端:192.168.80.12

//管理端安装 ansible
yum install -y epel-release            //先安装 epel 源
yum install -y ansible

//ansible 目录结构
/etc/ansible/
├── ansible.cfg            #ansible的配置文件,一般无需修改
├── hosts                #ansible的主机清单,用于存储需要管理的远程主机的相关信息
└── roles/                #公共角色目录

//配置主机清单
cd /etc/ansible
vim hosts       
[webservers]            #配置组名
192.168.80.11            #组里包含的被管理的主机IP地址或主机名(主机名需要先修改/etc/hosts文件)

[dbservers]
192.168.80.12

//配置密钥对验证
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa

yum install -y sshpass
sshpass -p 'abc1234' ssh-copy-id -o StrictHostKeyChecking=no [email protected]
sshpass -p 'abc1234' ssh-copy-id -o StrictHostKeyChecking=no [email protected]   


--------- ansible 命令行模块 ---------
命令格式:ansible <组名> -m <模块> -a <参数列表>

ansible-doc -l                #列出所有已安装的模块,按q退出

1.command 模块
//在远程主机执行命令,不支持管道,重定向等shell的特性。
ansible-doc -s command        #-s 列出指定模块的描述信息和操作动作

ansible 192.168.80.11 -m command -a 'date'        #指定 ip 执行 date
ansible webservers -m command -a 'date'            #指定组执行 date
ansible dbservers -m command -a 'date'       
ansible all -m command -a 'date'                #all 代表所有 hosts 主机
ansible all -a 'ls /'                            #如省略 -m 模块,则默认运行 command 模块

//常用的参数:
chdir:在远程主机上运行命令前提前进入目录
creates:判断指定文件是否存在,如果存在,不执行后面的操作
removes:判断指定文件是否存在,如果存在,执行后面的操作

ansible all -m command -a "chdir=/home  ls ./"

2.shell 模块
//在远程主机执行命令,相当于调用远程主机的shell进程,然后在该shell下打开一个子shell运行命令(支持管道符号等功能)
ansible-doc -s shell

ansible dbservers -m shell -a 'echo 123456 | passwd --stdin test"'
ansible dbservers -m shell -a 'echo $(ifconfig ens33 | awk "NR==2 {print $2}") | cut -d " " -f2'
ansible dbservers -m shell -a 'echo $(ifconfig ens33 | awk "NR==2 {print \$2}")'

3.cron 模块
//在远程主机定义任务计划。其中有两种状态(state):present表示添加(可以省略),absent表示移除。
ansible-doc -s cron                #按 q 退出

//常用的参数:
minute/hour/day/month/weekday:分/时/日/月/周
job:任务计划要执行的命令
name:任务计划的名称
user:指定计划任务属于哪个用户,默认是root用户

ansible webservers -m cron -a 'minute="*/1" job="/bin/echo helloworld" name="test crontab"'
ansible webservers -a 'crontab -l'
ansible webservers -m cron -a 'name="test crontab" state=absent'

4.user 模块
//用户管理的模块
ansible-doc -s user

//常用的参数:
name:用户名,必选参数
state=present|absent:创建账号或者删除账号,present表示创建,absent表示删除
system=yes|no:是否为系统账号
uid:用户uid
group:用户基本组
groups: 用户所属附加组
shell:默认使用的shell
create_home=yse|no: 是否创建家目录
password:用户的密码,建议使用加密后的字符串
remove=yes|no:当state=absent时,是否删除用户的家目录

ansible dbservers -m user -a 'name="test01"'                #创建用户test01
ansible dbservers -m command -a 'tail /etc/passwd'
ansible dbservers -m user -a 'name="test01" state=absent'    #删除用户test01

5.group 模块
//用户组管理的模块
ansible-doc -s group

ansible dbservers -m group -a 'name=mysql gid=306 system=yes'    #创建mysql组
ansible dbservers -a 'tail /etc/group'
ansible dbservers -m user -a 'name=test01 uid=306 system=yes group=mysql'    #将test01用户添加到mysql组中
ansible dbservers -a 'tail /etc/passwd'
ansible dbservers -a 'id test01'    

6.copy 模块
//用于复制指定主机文件到远程主机的
ansible-doc -s copy

//常用的参数:
dest:指出复制文件的目标及位置,使用绝对路径,如果源是目录,指目标也要是目录,如果目标文件已经存在会覆盖原有的内容
src:指出源文件的路径,可以使用相对路径或绝对路径,支持直接指定目录,如果源是目录则目标也要是目录
mode:指出复制时,目标文件的权限 
owner:指出复制时,目标文件的属主
group:指出复制时,目标文件的属组
content:指出复制到目标主机上的内容,不能与src一起使用

ansible dbservers -m copy -a 'src=/etc/fstab dest=/opt/fstab.bak owner=root mode=640'
ansible dbservers -a 'ls -l /opt'
ansible dbservers -a 'cat /opt/fstab.bak'

ansible dbservers -m copy -a 'content="helloworld" dest=/opt/hello.txt'  #将helloworld写入/opt/hello.txt文件中
ansible dbservers -a 'cat /opt/hello.txt' 

7.file 模块
//设置文件属性
ansible-doc -s file

ansible dbservers -m file -a 'owner=test01 group=mysql mode=644 path=/opt/fstab.bak'    #修改文件的属主属组权限等
ansible dbservers -m file -a 'path=/opt/fstab.link src=/opt/fstab.bak state=link'    #设置/opt/fstab.link为/opt/fstab.bak的链接文件
ansible dbservers -m file -a "path=/opt/abc.txt state=touch"            #创建一个文件
ansible dbservers -m file -a "path=/opt/abc.txt state=absent"            #删除一个文件

8.hostname 模块
//用于管理远程主机上的主机名
ansible dbservers -m hostname -a "name=mysql01"

9.ping 模块
//检测远程主机的连通性
ansible all -m ping

10.yum 模块
//在远程主机上安装与卸载软件包
ansible-doc -s yum

ansible webservers -m yum -a 'name=httpd'                    #安装服务
ansible webservers -m yum -a 'name=httpd state=absent'        #卸载服务

11.service/systemd 模块
//用于管理远程主机上的管理服务的运行状态
ansible-doc -s service

//常用的参数:
name:被管理的服务名称
state=started|stopped|restarted:动作包含启动关闭或者重启
enabled=yes|no:表示是否设置该服务开机自启
runlevel:如果设定了enabled开机自启去,则要定义在哪些运行目标下自启动

ansible webservers -a 'systemctl status httpd'            #查看web服务器httpd运行状态
ansible webservers -m service -a 'enabled=true name=httpd state=started'            #启动httpd服务

12.script 模块
//实现远程批量运行本地的 shell 脚本
ansible-doc -s script

vim test.sh
#!/bin/bash
echo "hello ansible from script" > /opt/script.txt

chmod +x test.sh
ansible webservers -m script -a 'test.sh'
ansible webservers -a 'cat /opt/script.txt'

vim test.sh
#!/bin/bash
echo $1 > /opt/test.txt
echo s2 >> /opt/test .txt

ansible dbservers -m script -a 'test.sh abc 123!

13. mount 模块
//挂载文件系统
ansible-doc -s mount

//常用的参数:
src:定义挂载设备的路径
path:定义挂载到哪个目录,必须指定
fstype:指定挂载文件的系统类型,必须指定,xfs、iso9660、nfs...
opts:定义挂载的参数,defaults、rw、ro...
state:定义挂载的状态,mounted(进行挂载,修改/etc/fstab信息)、absent(永久性卸载,并修改 /etc/fstab信息)、unmounted(临时卸载,不修改/etc/fstab信息)

ansible dbservers -m mount -a 'src=/dev/sr0 path=/mnt state=mounted fstype=iso9660'

14. archive 模块
//打包压缩
ansible-doc -s archive

//常用的参数:
path: 必须参数,远程主机上需要被打包压缩的源文件/目录
dest: 打包压缩后的包文件路径(包文件的父目录必须存在);如果包文件已存在,则会被覆盖
format: 指定压缩类型,包括: bz2、gz(默认)、tar、xz、zip
remove=yes|no: 是否删除源文件

ansible dbservers -m archive -a "path=/etc/yum.repos.d/ dest=/opt/repo.zip format=zip"
ansible dbservers -m archive -a "path=/opt/abc.txt,/opt/123.txt dest=/opt/abc123.tar.gz format=gz remove=yes"

15. unarchive 模块
//解包解压缩
ansible-doc -s unarchive

//常用的参数:
copy:默认为 copy=yes ,拷贝的文件从 ansible 主机复制到远程主机,copy=no 表示在远程主机上寻找源文件解压
src:tar包源路径,可以是 ansible 主机上的路径,也可以是远程主机上的路径,如果是远程主机上的路径,则需设置 copy=no
dest:解压后文件的目标绝对路径
remote_src: 和 copy 功能一样且互斥,设置 remote_src=yes 表示文件在远程主机上,设置为 remote_src=no 表示文件在 ansible 主机上

#将 ansible 主机的压缩文件拷贝到到远程主机并解压,修改文件所属组和用户
ansible dbservers -m unarchive -a "src=/opt/abc.tar.gz dest=/root copy=yes"
或者
ansible dbservers -m unarchive -a "src=/opt/abc.tar.gz dest=/root remote_src=no"

#在远程主机解包
ansible dbservers -m unarchive -a "src=/opt/123.tar.gz dest=/root copy=no"
或者
ansible dbservers -m unarchive -a "src=/opt/123.tar.gz dest=/root remote_src=yes"

16. replace 模块
//类似于sed命令,主要也是基于正则进行匹配和替换
ansible-doc -s replace

//常用的参数:
path:必须参数,指定要修改的文件
regexp:必须参数,指定一个正则表达式
replace:替换regexp参数匹配到的字符串
backup=yes|no: 修改源文件前创建一个包含时间戳信息的备份文件
before:如果指定,则仅替换/删除此匹配之前的内容,可以和after参数结合使用
after:如果指定,则仅替换/删除此匹配之后的内容,可以和before参数结合使用
owner:修改文件用户名
group:修改文件组名
mode:修改文件权限

vim /opt/test.txt
11 22 33 44 55 66
aa bb cc dd ee ff
1a 2b 3c 4d 5e 6f

#匹配 333 并修改为 ccc
ansible dbservers -m replace -a "path=/opt/test.txt regexp='33' replace='cc'"
#匹配到任意一个或多个开头的行增加注释
ansible dbservers -m replace -a "path=/opt/test.txt regexp='^(.*)' replace='#\1'"
#取消注释
ansible dbservers -m replace -a "path=/opt/test.txt regexp='^#(.*)' replace='\1'"
#匹配以 a 开头的后面有一个或者多个字符的行,并在前面添加 # 注释
ansible dbservers -m replace -a "path=/opt/test.txt regexp='^(a.*)' replace='#\1'"

ansible dbservers -m replace -a "path=/opt/test.txt regexp='3' replace='three' before=cc"

17.setup 模块
//facts 组件是用来收集被管理节点信息的,使用 setup 模块可以获取这些信息
ansible-doc -s setup

ansible webservers -m setup                #获取mysql组主机的facts信息
ansible dbservers -m setup -a 'filter=*ipv4'    #使用filter可以筛选指定的facts信息


--------- inventory 主机清单 ---------
//Inventory支持对主机进行分组,每个组内可以定义多个主机,每个主机都可以定义在任何一个或多个主机组内。

//如果是名称类似的主机,可以使用列表的方式标识各个主机。
vim /etc/ansible/hosts
[webservers]
192.168.80.11:2222        #冒号后定义远程连接端口,默认是 ssh 的 22 端口
192.168.80.1[2:5]

[dbservers]
db-[a:f].example.org    #支持匹配 a~f


//inventory 中的变量
Inventory变量名                  含义
ansible_host                  ansible连接节点时的IP地址
ansible_port                  连接对方的端口号,ssh连接时默认为22
ansible_user                  连接对方主机时使用的用户名。不指定时,将使用执行ansible或ansible-playbook命令的用户
ansible_password              连接时的用户的ssh密码,仅在未使用密钥对验证的情况下有效
ansible_ssh_private_key_file  指定密钥认证ssh连接时的私钥文件
ansible_ssh_common_args       提供给ssh、sftp、scp命令的额外参数
ansible_become                允许进行权限提升
ansible_become_method         指定提升权限的方式,例如可使用sudo/su/runas等方式
ansible_become_user           提升为哪个用户的权限,默认提升为root
ansible_become_password       提升为指定用户权限时的密码

(1)主机变量
[webservers]
192.168.80.11 ansible_port=22 ansible_user=root ansible_password=abc1234

(2)组变量
[webservers:vars]            #表示为 webservers 组内所有主机定义变量
ansible_user=root
ansible_password=abc1234

[all:vars]                    #表示为所有组内的所有主机定义变量
ansible_port=22

(3)组嵌套
[nginx]
192.168.80.20
192.168.80.21
192.168.80.22

[apache]
192.168.80.3[0:3]

[webs:children]        #表示为 webs 主机组中包含了 nginx 组和 apache 组内的所有主机
nginx
apache


    

CI  CD     DEVOPS

CI 持续集成
CD 持续发布 持续部署(ansible)

ansible   自动化运维工具  可以实现批量管理多台(成百上千)主机,应用级别的跨主机编排工具
          特性: 无agent的存在,不要在被控制节点上安装客户端应用
                 通过ssh协议与被控制节点通信
                 基于模块工作的,通过模块可以实现在被控制节点上执行命令操作
                 很多模块具有幂等性,可实现多次操作的状态如果没有发生变化,则不会重复执行
                 
模块:
command  在远程主机执行linux命令 ,不支持 管道符号 重定向符号    ansible的默认模块
shell    在远程主机执行linux命令 ,支持 管道符号  重定向符号
cron  在远程主机设置crontab计划任务   minute  hour  day  month  weekday  job   name   state=present/absent
user  在远程主机管理用户账户   name   uid   group   groups  shell   state=present/absent
group 在远程主机管理组账户     name   gid 
copy  将本地文件/目录复制到远程主机    src   dest 
file  在远程主机管理文件属性   state=link/touch/directory/absent  owner  group   mode   path
ping  测试与远程主机的连通性 
hostname   在远程主机设置主机名
mount      在远程主机挂载目录/设备文件
yum        在远程主机通过 yum 安装软件包
systemd/service    在远程主机管理应用服务的运行状态
script     在远程主机执行脚本
archive    在远程主机压缩文件
unarchive  将本地压缩包或远程主机的压缩包在远程主机解压
replace    在远程主机修改文件内容
setup      获取远程主机的facts信息


Inventory 主机清单管理
主机清单配置文件 /etc/ansible/hosts

[组名]
主机IP  ansible_user=  ansible_password=  ansible_port=     #主机变量
主机名[1:10][a:z]

[组名:vars]
ansible_user                  #组变量
ansible_password=
....

[大组名:children]
组名1
组名2
....

tasks任务 模块编写的格式
横向格式:
user: name=zhangsan  groups={{item}}

纵向格式:
user:
  name: zhangsan
  groups: "{{item}}"
  

with_items 的编写格式
横向格式:
值为纯量时
with_items: ["a", "b", "c"]

值为纯量对象时
with_items: 
- {key1: value1, key2: value2}
- {key1: value3, key2: value4}

纵向格式:
值为纯量时
with_items:
- a
- b
- c

值为纯量对象时
with_items: 
- key1: value1
  key2: value2
- key1: value3
  key2: value4


循环 迭代
with_items    with_flattened    with_list    loop
- a
- b
- c
在处理单层列表(每个列表只有一个元素)时,上面几个循环结构体是没有区别的,都会把每个列表的值遍历一遍

with_items    with_flattened    with_list    loop
- [a, b, c]
- [1, 2, 3]
- [A, B, C]
在处理嵌套的多层列表(每个列表只有多个元素)时,with_items 和 with_flattened 会将嵌套列表拉平扩展,将循环处理所有的元素
                        with_list 和 loop 不会嵌套列表拉平扩展,只会按照最外层的列表进行循环处理


with_together  将几个列表的元素对齐合并后输出,比如第一个列表的第一个元素和第二个列表的第一个元素合并输出
                                                   第一个列表的第二个元素和第二个列表的第二个元素合并输出

with_nested 和 with_cartesian 将每个列表的元素分别组合循环输出,比如 a1A a1B a1C  a2A a2B a2C ...


运行playbook
ansible-playbook XXX.yaml --syntax-check               检查剧本的语法是否正确
                          --list-task                  列出剧本里的所有任务
                          --list-hosts                 列出剧本在哪些主机执行
                          --start-at-task='任务名称'   指定从哪个任务开始执行

使用普通用户执行playbook
- remote_user: 普通用户  #远程主机需要事先sudo授权
  become: yes
  become_user: root
  
ansible-playbook XXX.yaml -k -K

定义/引用变量
- name:
  ...
  vars:
  - 变量1: 值1
  - 变量2: 值2
  - 变量3: 
    - key1: value1                     - {key1: value1, key2: value2}
      key2: value2                     - {key1: value3, key2: value4}
    - key1: value3
      key2: value4
  - 变量4:
    - 值1
    - 值2
    - 值3
  - 变量5: [值1, 值2, 值3]

   tasks:
   -name: xxxx
    模块: 参数选项1={{item}}
    with_items: "{{变量4}}"

 在tasks里引用变量时,可以从vars自定义的变量中引用,还可以直接引用 facts 字段的值,
                      还能 ansible-playbook -e "变量名=值" ,此方式优先级大于playbook中vars定义的变量的值

when条件判断
- name:
  ....
  tasks:
  - name: XXXX
    模块: ....
    when: 变量名   条件运算符   "值"             when判断结果为true才会执行当前任务,false不执行任务
                  == != >= <=

template模板模块
1)先要准备一个 xxx.j2 模板文件,在文件中使用 {{变量名}} 引用主机变量 或者 vars自定义的变量 及 facts 字段的值
2)在 playbook 中的 tasks 中定义 template 模板配置  template: src=XXX.j2  dest=XXX
                                                     

tags模块
根据 tags 标签仅执行拥有指定 tags 标签的任务,always 标签在指定任意标签时都会执行
- name:
  ....
  tasks:
  - name: XXXX
    模块:
    tags:
    - 标签1
    - 标签2
    
  - name: XXXX
    模块:
    tags:
    - always

ansible-playbook --tags="标签"  XXX.yaml


角色 roles 的作用?
把 playbook 里的各个 play 看作为角色,将各个角色的 tasks 任务、vars 变量、templates 模块、files 文件等内容放置到角色的目录中统一管理,需要的时候可在 playbook 中直接使用 roles 调用,所以 roles 可以实现代码的复用。

你可能感兴趣的:(ansible,运维,数据库)