ansible运维自动化

来源:互联网 发布:log4cplus ubuntu 编辑:程序博客网 时间:2024/06/06 08:23


ansible是由 Python 编写的强大的配置管理解决方案,ansible 的特点就在于它的简洁与高效率
ansible与其他的配置管理工具不同点在于:不需要你在想要配置的每个节点上安装自己的组件,也就是说,ansible管理各个节点不需要依赖于agent端

ansible是基于模块工作的,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible本身没有批量部署的能力,真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架


(一)Ansible 入门

官网:https://www.ansible.com
官方文档:http://docs.ansible.com/ansible/latest/index.html

  • Ansible 其他的配置管理工具对比
1:Puppet 由Ruby语言所研发
2:Saltstack 由Python语言研发
3:Ansible 由Python语言研发
  • Ansible 如何工作
Ansible 工具并不使用agent端守护进程,它也不需要任何额外的自定义安全架构,因此它的部署可以说是十分容易。你需要的全部东西便是 SSH 客户端和服务器了。

Alt text

①:192.168.1.100 - 在你本地的工作站或服务器上安装 Ansible。
②:文件服务器1到代理服务器3 - 使用 192.168.1.100 和 Ansible 来自动管理所有的服务器。
③:SSH - 在 192.168.1.100 和本地/远程的服务器之间设置 SSH 密钥。
  • ansible的框架

Alt text

(二)Ansible 安装(也可以使用pip3进行安装)


  • ansible安装与配置
1: 在ansible主机上安装ansible
yum install -y ansible
2:由于ansible支持ssh协议,因此使用ssh协议实现对被管理节点的管理是ansible的常用做法,且将对于的hosts文件分发下去
ssh-keygen -t rsa -P ""
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.23.10
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.23.11
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.23.12
3:配置文件介绍
主配置文件:/etc/ansible/ansible.cfg
主程序:
ansible
ansible-playbook
ansible-doc -l 可以列出所有的ansible所支持的模块
4:在ansible的配置目录中一共有三个文件
[root@centos ansible]# ll
总用量 24
-rw-r--r-- 1 root root 18066 62 05:49 ansible.cfg
-rw-r--r-- 1 root root 1016 62 05:49 hosts
drwxr-xr-x 2 root root 6 62 05:49 roles
hosts文件是用来指定被ansible管理的主机,也就是资产清单
roles是用来指定每一个节点的角色
编辑hosts文件(hosts文件有些注释的说明,可以先删除)。只要是hosts文件中定义的主机都可被ansible管理
# 指定web服务的主机
[webservers]
192.168.23.9
192.168.23.10
# 指定db服务的主机
[dbservers]
192.168.23.10
192.168.23.11
5:ansible不需要启动,就像一个脚本程序一样,可以直接的运行
ansible all -m ping # 这里的all指的是所有在hosts文件中定义的主机 -m:表示调用ansible自带的模块ping,对所有被管控的主机执行ping操作
6:获取所有的ansible的模块列表,模块的使用
ansible-doc -l 查看哪些模块可以用
ansible-doc -s 模块名 查看如何只用模块

(三)ansible主要模块介绍


  • ansible主要模块一次介绍,演示
1: 显示ansible自身可调用的模块
ansible-doc -l
2:显示指定模块ping的功能
ansible-doc -s ping
3command模块介绍
command模块就是在远程主机上执行命令,执行shell命令的模块,例如下面的 -a:指的是运行命令。而 -mcommand可以省略掉,默认就是 -m command,就是执行shell命令。 下面两条命令是一样的结果
ansible webservers -m command -a "ifconfig"
ansible webservers -a "ifconfig"
4shell模块介绍
-m command模块是不支持管道的,如果要支持管道的话,需要使用shell模块
下面是通过shell模块给被管理主机的yhy用户创建密码
ansible webservers -m command -a "useradd yhy"
ansible webservers -m shell -a "echo '123' | passwd --stdin yhy"
5copy模块介绍
将ansible主机上的文件复制到指定的远程节点上
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts"
当然在复制过程中也可以指定 owner=,group= ,mode= , 例如:
ansible all -m copy -a "src=/etc/fstab dest=/tmp owner=yhy group=yhy mode=644"
同样的也可以将内容复制过去。例如
ansible all -m copy -a "content='hello i will come back ' dest=/tmp/hello owner=yhy group=yhy mode=644"
6:cron模块
设置远程节点的cron定时任务,这里的minute指的是时间,job指的是定时任务,name指的是这个定时任务的名称,其实这里隐含了一个state参数,默认的state参数是present,表示是创建名称为synctime的任务
ansible all -m cron -a "minute=*/30 job='/usr/sbin/ntpdate time.nist.gov $> /dev/null' name=time_async"
既然有创建任务也有删除任务,指定absent就是删除任务
ansible all -m cron -a "state=absent name=time_async"
7:fetch模块(基本不用)
从远端节点拉取文件到本地,将/etc/fstab拷贝到本机的/tmp目录下
ansible 192.168.43.13 -m fetch -a "src=/etc/fstab dest=/tmp"
[root@7 ansible]# ll /tmp/192.168.43.13/etc/fstab
-rw-r--r-- 1 root root 501 927 19:30 /tmp/192.168.43.13/etc/fstab
8file模块
设定被管控主机的文件的属性
创建链接文件
创建目录
ansible all -m file -a "src=/tmp/fstab path=/tmp/fstab.link state=link" 给管控主机的文件创建链接文件
ansible 192.168.43.13 -m file -a "path=/root/anaconda-ks.cfg owner=root group=root mode=777" 给被管控主机的文件修改权限和属主
ansible all -m file -a "path=/tmp/tmpdir state=directory" 给被管控主机创建目录
9hostname模块
管理远程节点的hostname
ansible 192.168.23.10 -m hostname -a "name=nginx"
10:pip模块
管理Python库依赖(首先确保pip2已经安装,如果没有安装,需要先安装python2-pip)
ansible 192.168.43.11 -m pip -a "name=Jinja2"
11:yum模块:
基于yum管理程序包
ansible all -m yum -a "name=httpd state=latest" 安装httpd程序包,latest表示安装最新的包
ansible all -m yum -a "name=httpd state=absent" 卸载httpd程序包
12:service模块
管理被监控主机的服务
ansible all -m service -a "name=httpd state=stopped"
ansible all -m service -a "name=httpd enabled=1 runlevel=3"
13:user模块
管理用户账号,创建用户
ansible all -m user -a "name=user2 system=yes uid=306"
还可以指定这么多参数:name= system= yes|no uid= shell= group= groups= comment= home=
13:group模块
创建用户组,且指定gid
ansible 192.168.23.10 -m group -a "name=apache gid=48"
14: setup模块:
获取被管控主机的系统指标,拿到这些指标后,ansible就可以直接调用这些系统指标了,就像采集系统数据一样的
ansible 192.168.23.10 -m setup
15: script模块:
将ansible主机的脚本传递到被管控的主机上执行
ansible 192.168.43.11 -m script -a "/root/useradd.sh" 将本地的/root/useradd.sh脚本在192.168.43.11中执行
16: template模块:
基于模板的方式生成一个文件复制到被管理的主机,这样就可以在模板语言中判断,不同的系统复制不同的配置文件,这就是template模块区别与copy模块的地方
17:unarchive模块
将本地的归档文件拷贝到被管控的主机上,解压归档文件
ansible all -m unarchive -a "src=/files/wordpress.tar dest=/data/dynamic/"
18:mount模块
挂载和卸载模块,path指定本地挂载点,src指定需要挂载的设备
ansible 192.168.23.12 -m mount -a "path=/var/www/html src=192.168.23.25:/data/static fstype=nfs state=mounted"
小结:这里列举了18个常用的模块,当然,远远不止这18个模块,可以通过ansible-doc -l 查看其他模块,也可以使用ansible-doc -s moduels_name 查看模块的使用方式,还有官方文档

(四)YAML文件格式介绍


  • 一个简单的YAML格式示例文件
1:YAML文件的格式介绍
YAML文件的格式与其他的高级语言中的字典嵌套类似,就是一层一层的,如:
- hosts: webservers # 这里第一个列表指明运行同一种任务的主机组
remote_user: root
tasks:
- name: install httpd # 每一个任务都应该有一个名字,用于显示哪个任务完成了
yum: name=httpd state=present
- name: distribute configuration file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
- name: start httpd service
service: name=httpd state=started
- name: port
shell: netstat -lntup | grep httpd
上面这个就是一个YAML的文件格式,横杠就表示列表,冒号表示字典。任务执行的顺序一般都是列表写明

(五)ansible-playbook详解

示例:http://docs.ansible.com/ansible/latest/playbooks.html

  • ansible-playbook说明
1:Playbook的实质就是运行YAML配置文件:将多个相关的任务,通过读取YAML格式的配置文件一次性完成
2:playbook运行的核心元素有:
Hosts:指明运行在哪个主机上
Remote_user:以哪个用户的身份运行任务
Tasks:任务
Variables:变量
Templates:包含了模板语法的文本文件
Handlers:由特定条件出发的任务
Roles:
3:playbook的元素
Hosts:运行指定任务的目标主机,这些主机必须是定义在hosts文件中的主机
remoute_user:在远程主机上执行任务的用户
sudo_user:sudo到哪个用户的身份运行
tasks:任务列表,调用模块和指明参数
格式:
action动作形式:module arguments (新版本支持)
module模块形式:arguments (通用格式)
注意:shell和command模块后面加的是命令,而非key=value类的参数列表
(1)测试(只检测可能会发生的改变,但不真正执行操作)
ansible-playbook --check
ansible-playbook --list-hosts 列出运行任务的被管控的主机
ansible-playbook --check firsh.yaml 测试
(2)运行
ansible-playbook firsh.yaml
  • YAML示例文件(最好是确保webservers的主机的系统版本一样,因为配置文件的格式不一样会导致服务无法启动)
- hosts: webservers
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
- name: distribute configure file # 这里的src可以使用相对路径也可以使用绝对路径,相对路径表示与yaml文件在同一级目录下
copy: src=files/httpd.conf dest=/etc/httpd/conf/
- name: start httpd service
service: name=httpd state=started
- name: port
shell: netstat -lntup|grep httpd
  • handlers 详解 任务在特定条件下被触发,接收到其他任务的通知时被触发,某任务的状态在运行后为changed时,可通过notify通知给相应的handlers
- hosts: webservers
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
- name: distribute configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
# notify的意义在于只要配置文件发生了变化,就调用handlers的restart httpd任务执行
notify: restart httpd
- name: start httpd service
service: name=httpd state=started
- name: port
shell: netstat -lntup | grep httpd
# handlers的意义和tasks的区别在于,handlers中的任务需要被tasks中的任务调用才能够陪执行
handlers:
- name: restart httpd
service: name=httpd state=restarted
  • tags详解(用来标记指定执行的任务,在执行playbook的时候,如果指定tags所标记的任务,那么其他定义的任务将不会再执行)
- hosts: webservers
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
- name: distribute configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
# 在安装配置文件处加上一个tags标签,在执行playbook的时候,就可以指明运行的任务了
tags: distributeConfig
notify: restart httpd
- name: start httpd service
service: name=httpd state=started
- name: port
shell: netstat -lntup|grep httpd
handlers:
- name: restart httpd
service: name=httpd state=restarted
例如:ansible-playbook -t distributeConfig http.yaml 这里指定运行的是copy任务 (在执行tags对应的任务时,如果被notify检查到了发生改变,那么也会调用handlers中的任务进行执行的)
  • variables变量 详解
(1)facts: 可以直接调用,有setup模块提供的
(2)ansible-playbook命令行中自定义的变量
-e VARS : 指定需要传递给playbook的变量的名称
(3)通过roles角色传递变量
(4)Host inventory (/etc/ansible/hosts文件):向不同的主机传递不同的变量 , 这样就不需要在ansible-playbook命令行中给变量赋值了
(5)在playbook中定义变量
vars:
- username: testuser1
- groupname: testgroup1
- hosts: all
remote_user: root
vars:
- username: home
- groupname: uplooking
tasks:
- name: create group
group: name={{ groupname }} state=present
- name: create user
user: name={{ username }} state=present
# 在second.yaml中
- hosts: webservers
remote_user: root
tasks:
- name: install {{ service }}
# 注意:这里的变量引用使用的是{{ }}
yum: name={{ service }} state=present
# 这里是在命令行给定pkname的值
ansible-playbook -e service=memcached second.yaml
# 在/etc/ansible/hosts文件中指定变量名
# 第一个使得不同主机使用不同值的变量
[webservers]
192.168.23.20 host_name=www1
192.168.23.21 host_name=www2
# 第二个使得不同主机使用相同的变量,直接给组定义一个变量值就是了,这里的vars表示给不同的主机名指定相同的变量,在YAML文件中引用就好了
[webservers:vars]
service=httpd
# 在third.yaml中引用变量名,这样就使用不同的远端主机可以使用不同变量的值了,
- hosts: webservers
remote_user: root
tasks:
- name: set hostname {{ host_name }}
hostname: name={{ host_name }}
# 这里的service变量表示,所有的主机都使用一个变量名
- name: install {{ service }}
yum: name={{ service }} state=present

(六)ansible 模板template使用


  • template 模板
1:首先通过ansible在被管控的主机上安装Nginx
2:再在ansible的主机上安装Nginx,拿到配置文件。且配置文件是centos 7安装Nginx的配置文件,在配置文件中有一个参数叫worker_processes,是设置Nginx的进程的数量的参数,使得模板复制过去之后,就会使得系统的CPU的数量为多少,Nginx的worker_processes进程数就是多少。
Nginx的配置文件中,worker_processes的数量是这样定义的,在模板中引用ansible_processor_vcpus变量名,这个变量名是ansible通过setup模块自带的参数,因此可以直接获取。
worker_processes {{ ansible_processor_vcpus }};
3:那么在ansible主机就可以编写YAML文件了
- hosts: webservers
remote_user: root
tasks:
- name: install nginx
yum: name=nginx state=present
- name: install configure file
template: src=files/nginx.conf dest=/etc/nginx/nginx.conf
notify: restart nginx
tags: instconf
- name: start nginx service
service: name=nginx state=started
handlers:
- name: restart nginx
service: name=nginx state=restarted
4:执行ansible-playbook
ansible-playbook third.yaml
5:在被管控主机上检查:不同的CPU核心数的Nginx的配置文件中的worker_processes的数量不一样
  • 也可以在template需要拷贝的文件中,使用运算符
# 在需要复制的文件中使用变量
worker_processes {{ ansible_processor_vcpus-1 }};
# 使用ansible-playbook中使用模板
- hosts: webservers
remote_user: root
tasks:
- name: install nginx
yum: name=nginx state=present
- name: install configure file
template: src=files/nginx.conf dest=/etc/nginx/nginx.conf
notify: restart nginx
tags: distributeConf
- name: start nginx service
service: name=nginx state=started
handlers:
- name: restart nginx
service: name=nginx state=restarted
  • Playbook的条件判断机制(在tasks中使用) 
    • 条件判断
tasks:
- name: distribute config file to centos7
template: src=files/nginx.conf.centos7 dest=/etc/nginx/nginx.conf
# 这里指定只有在主版本号为7的时候,才会复制这个文件
when: ansible_distribution_major_version == "7"
- name: distribute config file to centos6
template: src=files/nginx.conf.centos6 dest=/etc/nginx/nginx.conf
# 这里指定只有在主版本号为6的时候,才会复制这个文件
when: ansible_distribution_major_version == "6"
    • 要在task中使用with_items给定要迭代的元素列表
with_items的表示方式
1:使用list
2:使用dictionary
这就是item实现的循环,让yum安装不同的软件的时候,可以使用列表的形式,然后使用一个yum任务就安装了所有在列表中需要安装的软件
tasks:
- name: install some packages
yum: name={{item}} state=present
with_items:
- nginx
- memcached
- php-fpm
- name: add some groups
# 这是用列表存储变量
group: name={{ item }} state=present
with_items:
- group11
- group12
- group13
- name: add somen users
# 这是用字典存储变量
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- { name: 'user11',group: 'group11' }
- { name: 'user12',group: 'group12' }
- { name: 'user13',group: 'group13' }

(七)roles角色 定义服务名详解

前言:roles角色定义在ansible自动化过程中非常重要,这里必须牢记,通过定义不同的角色,那么在通过ansible-playbook执行一个YAML文件的时候,就可以通过指定不同的主机安装什么角色,这里的角色就是服务,比如haproxy。

  • 定义LNMP角色集合
[root@7 roles]# tree -L 1 /etc/ansible/roles/
/etc/ansible/roles/
├── mysql
├── nginx
└── php-fpm
[root@7 roles]# tree -L 2 /etc/ansible/roles/
/etc/ansible/roles/
├── mysql
├── nginx
│ ├── default :设定默认变量时使用此目录中的main.yml文件
│ ├── files :存放由copy或script模块等调用的文件
│ ├── handlers:至少包含一个名为main.yml的文件,其他的文件需要在此文件中通过include进行包含
│ ├── meta:至少包含一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系,其他的文件需要在此文件中通过include进行包含
│ ├── tasks:至少包含一个名为main.yml的文件,其他的文件需要在此文件中通过include进行包含
│ ├── templates:template模块查找所需的模板文件目录
│ └── vars:至少包含一个名为main.yml的文件,其他的文件需要在此文件中通过include进行包含
└── php-fpm
  • 在playbook调用角色方法
hosts:webservers
remote_user:root
rolse:
-mysql
-php-fpm
-nginx
# 在playbook调用角色方法2:可以传递变量给角色 ,可以在模板中使用这个变量
hostswebservers
remote_userroot
rolse
-{ role: nginx, username: nginx }
1: roles的目录结构所示
[root@7 ansible]# pwd
/etc/ansible
[root@7 ansible]# tree
.
├── ansible.cfg
├── hosts
├── hosts.backup
└── roles
└── nginx
├── default
├── files
├── handlers
│ └── main.yml - name: restart nginx
service: name=nginx state=restarted
├── meta
├── tasks
│ └── main.yml - name: install nginx package
yum: name=nginx state=present
- name: install config file
# 自动回到templates目录下去找
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
tags: instconf
- name: start nginx
service: name=nginx state=started enabled=true
├── templates
│ └── nginx.conf.j2
└── vars
└── main.yml username: daemon
2# 查看nginx.yml文件
[root@7 ansible]# cat nginx.yml
- hosts: webservers
remote_user: root
roles:
- nginx
3:ansible-playbook运行nginx.yml文件
ansible-playbook --check nginx.yml
ansible-playbook nginx.yml
  • 还可以在调用角色的时候进行条件判断
# playbook内容部分
# 指定基于字典的形式调用role,并且向模板传递参数,且进行条件判断,只有在系统版本是7的时候才调用这个role
- hosts: webservers
remote_user: root
roles:
- { role: nginx, username: nginx, when: "ansible_distribution_major_version" == "7" }
# 定义两个role都加条件判断
- hosts: all
remote_user: root
roles:
# 使用系统的发行版本做条件判断
- { role: nginx, when: ansible_distribution_major_version == '7' }
# 使用主机名做条件判断
- { role: php-fpm, when: ansible_hostname == '6' }
原创粉丝点击