Ansible运维自动化


Ansible是一种自动化管理工具,相较于其他管理工具,ansible的最大优点就是不需要安装客户端,但需要ssh道路畅通。基于Python开发,可以实现批量系统配置,批量程序部署,批量运行命令等。

一、Ansible安装
1.Epel源安装
[root@node ~]#curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
[root@node ~]#yum install ansible
2.编译安装
[root@node ~]#yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
[root@node ~]#tar xf ansible-1.5.4.tar.gz
[root@node ~]#cd ansible-1.5.4
[root@node ~]#python setup.py build
[root@node ~]#python setup.py install
[root@node ~]#mkdir /etc/ansible
[root@node ~]#cp -r examples/* /etc/ansible
3.Git方式安装
[root@node ~]#git clone git://github.com/ansible/ansible.git --recursive
[root@node ~]#cd ./ansible
[root@node ~]#source ./hacking/env-setup
4.pip安装
[root@node ~]#yum install python-pip python-devel
[root@node ~]#yum install gcc glibc-devel zibl-devel  rpm-bulid openssl-devel
[root@node ~]#pip install  --upgrade pip
[root@node ~]#pip install ansible --upgrade
确认安装
[root@node ~]#ansible --version
ansible 2.9.5
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Nov 21 2019, 19:31:34) [GCC 8.3.1 20190507 (Red Hat 8.3.1-4)]
二、Ansible相关工具
  • /usr/bin/ansible 主程序,临时命令执行工具
  • /usr/bin/ansible-doc 查看配置文档,模块功能查看工具
  • /usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台
  • /usr/bin/ansible-playbook 定制自动化任务,编排剧本工具
  • /usr/bin/ansible-pull 远程执行命令的工具
  • /usr/bin/ansible-vault 文件加密工具
  • /usr/bin/ansible-console 基于Console界面与用户交互的执行工具

使用ansible实现管理的主要方式:

  • Ad-Hoc 即使用ansible命令
  • Ansible-playbook

Ansible程序结构(yum安装):

配置文件目录:/etc/ansible/
  执行文件目录:/usr/bin/
  Lib库依赖目录:/usr/lib/pythonX.X/site-packages/ansible/
  Help文档目录:/usr/share/doc/ansible-X.X.X/
  Man文档目录:/usr/share/man/man1/

ansible-doc
#列出所有模块
ansible-doc -l
#查看指定模块的帮助用法
ansible-doc ping
ansible-doc -s ping
ansible

通过ssh协议,实现对远程主机的配置管理、应用部署、任务执行等功能

ansible <host-pattern> [-f forks] [-m module_name] [-a args]
--version               #显示版本
-m module               #指定模块,默认为command
-a                      #指定模块的参数
-i INVENTORY            #指定主机清单的路径,默认为/etc/ansible/hosts
-v                      #详细过程 –vv  -vvv更详细
-C, --check             #检查,并不执行
--list-hosts            #显示主机列表,可简写 --list
-k, --ask-pass          #提示输入ssh连接密码,默认Key验证    
-T, --timeout=TIMEOUT   #执行命令的超时时间,默认10s
-u, --user=REMOTE_USER  #执行远程执行的用户
-b, --become            #代替旧版的sudo 切换
--become-user=USERNAME  #指定sudo的runas用户,默认为root
-K, --ask-become-pass   #提示输入sudo时的口令
ansible主机清单

/etc/ansible/hosts 默认主机清单

ansible_host
ansible_port 用于配置对应主机上的sshd服务端口号
ansible_user 用于配置连接到对应主机时所使用的用户名称
ansible_ssh_pass 用于配置对应用户的连接密码
三、Ansible常用模块
1.ping模块

用来进行主机连通性测试

[root@node ~]# ansible all -m ping
192.168.157.130 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.157.129 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
2.command模块

默认模块,可忽略-m选项,在远程主机上执行命令,但不支持$VARNAME < > | ; & 等

[root@node ~]# ansible all -m command -a 'chdir=/etc/yum.repos.d/ ls' 
192.168.157.129 | CHANGED | rc=0 >>
CentOS-Base.repo
epel.repo
192.168.157.130 | CHANGED | rc=0 >>
CentOS-Base.repo
epel.repo
[root@node ~]# ansible all -a 'creates=/etc/yum.repos.d/epel.repo ls' #如果文件存在,不执行ls
192.168.157.129 | SUCCESS | rc=0 >>
skipped, since /etc/yum.repos.d/epel.repo exists
192.168.157.130 | SUCCESS | rc=0 >>
skipped, since /etc/yum.repos.d/epel.repo exists
[root@node ~]# ansible all -a 'removes=/etc/yum.repos.d/epel.repo ls'  #如果文件存在,执行ls
192.168.157.130 | CHANGED | rc=0 >>
test.txt
192.168.157.129 | CHANGED | rc=0 >>
test.txt
3.shell模块

和command相似,用shell执行命令

[root@node ~]# ansible all -m shell -a "ls |grep txt"
192.168.157.130 | CHANGED | rc=0 >>
test.txt
192.168.157.129 | CHANGED | rc=0 >>
k8s.txt

工作中可将shell模块代替command模块

[root@node ~]# vim /etc/ansible/ansible.cfg
module_name = shell
4.script模块

在远程主机上运行ansible服务器的脚本

[root@node data]# ansible all -m  script -a "chdir=/root /data/test.sh"
192.168.157.130 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.157.130 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.157.130 closed."
    ], 
    "stdout": "/root\r\n", 
    "stdout_lines": [
        "/root"
    ]
}
5.copy模块

将文件复制到远程主机

常用选项:
src       #源文件,如果路径是目录,会递归复制
content   #用于替换src,表示文件的值
dest      #复制到的远程主机的绝对路径
backup    #当文件发生改变时,覆盖之前备份原文件
directory_mode     #递归设置目录的权限
owner
group
mode
force

用法

[root@node data]# ansible all -m copy -a "src=/data/test.sh dest=/data/test.sh owner=root mode=644 backup=yes"
[root@node data]# ansible all -m copy  -a 'content="This is test" dest=/data/test2.txt mode=666'
6.fetch模块

从远程主机提取文件到ansible主机,与copy相反,目前不支持目录

[root@node ~]# ansible all -m fetch -a 'src=/etc/hostname dest=/data'
192.168.157.129 | CHANGED => {
    "changed": true, 
    "checksum": "62343d9fe31e6f9b93f4507094248c44aaf32ac7", 
    "dest": "/data/192.168.157.129/etc/hostname", 
    "md5sum": "221a057e91928a3651f31d376b907d60", 
    "remote_checksum": "62343d9fe31e6f9b93f4507094248c44aaf32ac7", 
    "remote_md5sum": null
}
192.168.157.130 | CHANGED => {
    "changed": true, 
    "checksum": "471de9b108f7f57e58c240a4ca3bfe24b7b69bfc", 
    "dest": "/data/192.168.157.130/etc/hostname", 
    "md5sum": "21d192a7f99b9d042621777150ea8a5f", 
    "remote_checksum": "471de9b108f7f57e58c240a4ca3bfe24b7b69bfc", 
    "remote_md5sum": null
}
[root@node ~]# tree /data/
/data/
├── 192.168.157.129
│   └── etc
│       └── hostname
└── 192.168.157.130
    └── etc
        └── hostname

4 directories, 2 files
---
- hosts: all 

  tasks:
    - name: tar packages
      shell: chdir=/var/ warn=false  tar zcvf log.tar.gz log 
    - name: fetch logs
      fetch: src=/var/log.tar.gz dest=/data/log
7.file模块

用于设置文件的属性,比如创建文件或目录、创建链接文件、删除文件、修改权限等

path    #必须项,指定操作的对象,为了兼容旧版本,用dest或name也可以
state   #directory:创建目录,touch:创建文件,link:创建软连接,hard:创建硬连接,absent:删除
src     #指定连接源
force   
owner
group
mode
recurse #当操作目录时,recurse=yes,可以递归修改属性
#创建目录
[root@node ~]# ansible all -m file -a 'path=/data/testdir state=directory'
#创建文件
[root@node ~]# ansible all -m file -a 'path=/data/testfile state=touch'
[root@node ~]# ansible all -m file -a 'path=/data/testfile owner=root mode=755'
#创建软链接
[root@node ~]# ansible all -m file -a 'src=/data/testfile  dest=/date/testfile-link state=link'
#删除文件
[root@node ~]# ansible all -m file -a 'path=/data/testfile-link state=absent'
8.archive和unarchive

archive用于打包压缩

[root@node ~]# ansible all -m archive -a 'path=/var/log/ dest=/var/log.tar.gz'

unarchive用于解包解压缩,有两种方式:

1.将ansible主机上的压缩包传到远程主机后解压缩至特定的目录,copy=yes(默认)

2.将远程主机的某个压缩文件解压缩到指定路径,copy=no

#将远程主机的压缩文件解压
[root@node ~]# ansible all -m unarchive -a 'src=/var/log.tar.gz dest=/data copy=no mode=700'
#将ansible主机的压缩文件解压到远程主机
[root@node ~]# ansible all -m unarchive -a 'src=/root/nginx-1.10.3.tar.gz dest=/data  mode=700'
9.cron模块

用于管理cron计划任务

选项:

minute、hour、day、month、weekday

name #定时任务的描述

job #指明运行的命令

user #以哪个用户

state #present 添加,默认设置;absent删除

#新建定时任务
[root@node ~]# ansible all -m cron -a 'name="test cron"   minute=*/5 job="/sbin/ntpdate ntp.aliyun.com &> /dev/null"'
[root@node ~]# ansible all -a "crontab -l"
192.168.157.130 | CHANGED | rc=0 >>
#Ansible: test cron
*/5 * * * * /sbin/ntpdate ntp.aliyun.com &> /dev/null
192.168.157.129 | CHANGED | rc=0 >>
#Ansible: test cron
*/5 * * * * /sbin/ntpdate ntp.aliyun.com &> /dev/null
#删除定时任务
[root@node ~]# ansible all -m cron -a 'name="test cron" state=absent'
192.168.157.129 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": []
}
192.168.157.130 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "envs": [], 
    "jobs": []
}
[root@node ~]# ansible all -a "crontab -l"
192.168.157.130 | CHANGED | rc=0 >>

192.168.157.129 | CHANGED | rc=0 >>

10.yum模块

软件包管理,只支持RHEL,CentOS,fedora,不支持Ubuntu其它版本

state
	present 确保已经安装,但不升级
	installed 确认已经安装
	latest 确保安装,且升级为最新
	absent和removed确认已移除
	
[root@node ~]# ansible all -m yum -a "name=lrzsz state=present"
[root@node ~]# ansible all -m yum -a "name=lrzsz state=absent"
11.service和systemd

用于服务程序的管理

name

state:

​ started,stopped,restarted,reloaded

enabled:

​ yes,no

[root@node ~]# ansible all -m service -a 'daemon_reload=yes'
[root@node ~]# ansible all -m service -a 'daemon_reload=yes'
[root@node ~]# ansible all -m service -a "name=network state=started enabled=yes"
12.user和group
#创建组
[root@node ~]# ansible all -m group -a 'name=user gid=88 system=yes'
#删除组
[root@node ~]# ansible all -m group -a 'name=user state=absent'
#创建用户
[root@node ~]# ansible all -m user -a 'name=user1 comment="test user" uid=2048 home=/data/user1 group=root'
[root@node ~]# ansible all -m user -a 'name=nginx comment=nginx uid=88 group=nginx group=root shell=/sbin/nologin system=yes create_home=no home=/data/nginx non_unique=yes'
#删除目录及家目录等数据
[root@node ~]# ansible all -m user -a 'name=nginx state=absent remove=yes'
13.Setup模块

setup 模块来收集主机的系统信息,这些 facts 信息可以直接以变量的形式使用,但是如果主机较多,会影响执行速度,可以使用gather_facts: no来禁止 Ansible 收集 facts 信息

[root@node ~]# ansible all  -m setup -a 'filter=ansible_nodename' --tree /data
[root@node ~]# tree /data/
/data/
├── 192.168.157.129
└── 192.168.157.130

0 directories, 2 files
四、Ansible-playbook
核心元素
  • hosts 执行远程主机的列表
  • tasks 任务集
  • variables 变量在playbook中调用
  • templates 模板
  • handlers 和notify结合使用
  • tags 标签

实例

[root@node ~]# vim first.yml
- hosts: all
  remote_user: root
  vars: httpd_port=80
  gather_facts: no
  
  tasks:
  - name: install httpd
    yum: name=httpd state=present
  - name: install php
    yum: name=php state=present
  - name: start httpd
    service: name=httpd state=start enabled=ture

说明:

hosts定义单个主机或组,vars定义变量,remote_user定义执行命令的远程用户,tasks定义执行哪些步骤
ansible-playbook filename.yml [options]
常见选项
-C --check          #只检测可能会发生的改变,但不真正执行操作
--syntax-check      #语法检查
--list-hosts        #列出运行任务的主机
--list-tags         #列出tag
--list-tasks        #列出task
--limit 主机列表      #只针对主机列表中的主机执行
-v -vv  -vvv        #显示过程
tags标签

给playbook中task指定标签,当在执行playbook时,可以只执行特定的tags的task,而非整个playbook文件

[root@node ~]# vim httpd.yaml
- hosts: all
  remote_user: root
  gather_facts: no
  
  tasks:
  - name: install httpd
    yum: name=httpd state=present
    tags: httpd
  - name: install php
    yum: name=php state=present
  - name: start httpd
    service: name=httpd state=start enabled=ture
    tags: service
##
语法一:
tags:
 - testtag
 - t1
 
语法二:
tags: tag1,t1
 
语法三:
tags: ['tagtest','t2']
##

[root@node ~]# ansible-playbook --list-tag httpd.yaml   #列出tags

playbook: httpd.yaml

  play #1 (all): all	TAGS: []
      TASK TAGS: [httpd, service]
      
[root@node ~]# ansible-playbook -t httpd,service httpd.yaml  #指定tags执行
[root@node ~]# ansible-playbook --skip-tags httpd,service httpd.yaml #跳过tags执行
变量

由字母数字下划线组成,只能以字母开头
种类:

  • facts(内置变量)
    有远程主机发回ansible主机的属性信息
    ansible 192.168.157.129 -m setup可获取,filter指定过滤项,在ansible-playbook中如果不需要,可禁止:

    [root@129 ~]#ansible all -m setup -a 'filter=ansible_memory_mb'
    ###
    - hosts: all
      remote_user: root
    gater_fact: no
    
    • 命令行传递
    [root@129 ~]# ansible-playbook -h
    -e EXTRA_VARS, --extra-vars EXTRA_VARS
    [root@129 ~]# ansible-playbook test.yml –e httpd_port=80
    
    • yaml文件中定义
    ---
    - hosts: all
      remote_user: root
      vars:
        - username: user1
        - groupname: group1
      tasks:
        - name: create group
          group: name={{ groupname }} state=present
        - name: create user
          user: name={{ username }} state=present
    ...
    ###
      vars:
        nginx:
          conf80: /etc/nginx/conf.d/80.conf
          conf8080: /etc/nginx/conf.d/8080.conf
    引用
    "{{nginx.conf80}}"
    
    • 变量文件定义
    [root@node ~]# vi vars.yaml
    username: user2
    groupname: group2
    [root@node ~]# vim test.yaml
    - hosts: all
      remote_user: root
      vars_files:
        - vars.yaml
    
      tasks:
        - name: create group
          group: name={{ groupname }} state=present
        - name: create user
          user: name={{ username }} state=present
    
    • 通过主机或组变量
    [web1]
    192.168.1.1 name=haha
    [group_name:vars]
    foo=bar
    
handlers和notify
[root@node ~]# vim first.yml
- hosts: all
  remote_user: root
  gather_facts: no
  
  tasks:
  - name: install httpd 
    yum: name=httpd state=present  
  - name: config file
    copy: src=file/httpd.conf dest=/etc/httpd/conf/
    notify: restart httpd
  - name: start httpd
    service: name=httpd state=start enabled=ture
    
  handlers:
  - name: restart httpd
    service: name=httpd state=restarted
template模板

命名以j2结尾

模板中可嵌套jinja2语言

#范例1
#temnginx1.yml
---
- host: websrvs
  remote_user: root
  vars:
    nginx_vhosts:
      - 81
      - 82
      - 83
      
  tasks:
    - name: config file
      template: src=nginx2.conf.j2 dest=/data/nginx2.conf
#templates/nginx.conf1.j2
{% for vhost in nginx_vhosts %}
server {
  listen {{ vhost }}
}
{% endfor %}
#生成结果:
server {
  listen 81
}
server {
  listen 82
}
server {
  listen 83
}
#范例2
#temnginx1.yml
---
- host: websrvs
  remote_user: root
  vars:
    nginx_vhosts:
      - listen: 81
        server_name: "www.web1.com"
        root: "/var/www/html/web1"
      - listen: 82
        server_name: "www.web2.com"
        root: "/var/www/html/web2"
      - {listen: 83, server_name: "www.web3com", root: "/var/www/html/web3"}
      
  tasks:
    - name: config file
      template: src=nginx2.conf.j2 dest=/data/nginx2.conf
#templates/nginx.conf1.j2
{% for vhost in nginx_vhosts %}
server {
  listen {{ vhost.listen }}
  server_name {{ vhost.server_name }}
  root {{ vhost.root }}
}
{% endfor %}
#生成结果:
server {
  listen 81
  server_name www.web1.com
  root /var/www/html/web1
}
server {
  listen 82
  server_name www.web1.com
  root /var/www/html/web2
}
server {
  listen 83
  server_name www.web1.com
  root /var/www/html/web3
}
when

when语句可以实现条件判断,然后决定是否执行task。

- hosts: all
  remote_user: root
  
  tasks:
  - name: install httpd
    yum: name=httpd state=present
    when: ansible_distribution_major_version == "7"
  - name: install php
    yum: name=php state=present
    when: ansible_distribution_major_version == "7"
  - name: start httpd
    service: name=httpd state=start enabled=ture
    when: ansible_distribution_major_version == "7"
 #通过判断ansible_distribution_major_version是否等于7来决定是否执行tasks
with_items

迭代,重复执行task

#简单使用
---
- hosts: all
  remote_user: root
  
  tasks:
    - name: add users
      user: name={{ item }} state=present 
      with_items:
        - testuser1
        - testuser2
 #上面的语句等同于
     - name: add users1
       user: name=testuser1 state=present
     - name: add users2
       user: name=testuser2 state=present
...
#迭代嵌套子变量:在迭代中还可以嵌套子变量,关联多个变量在一起使用
---
- hosts: all
  remote_user: root
  
  tasks:
    - name: add group
      user: name={{ item }} state=present 
      with_items:
        - nginx
        - mysql
        - apache
        
    - name: add user
      user: name={{ item.name }} state=present group={{ item.group }}
      with_items:
        - { name: 'nginx', group: 'nginx' }
        - { name: 'mysql', group: 'mysql' }
        - { name: 'apache', group: 'apache' }
五、roles角色

用于层次性、结构化地组织playbook。roles能够根据层次型结构自动化装载变量文件、tasks以及handlers等。多个角色的集合,可以将多个的role,分别放到roles目录下的独立子目录中

roles/
├── httpd
│   ├── files
│   │   ├── httpd.conf
│   │   └── index.html
│   ├── handlers
│   │   └── main.yaml
│   └── tasks
│       ├── config.yml
│       ├── index.yml
│       ├── install.yml
│       ├── main.yml
│       └── service.yml
└── nginx
    ├── handlers
    ├── tasks
    ├── templates
    └── vars

---
- hosts: all
  remote_user: root
  
  tasks:
    - name: 关闭firewalld
      service: name:firewalld state=stopped enabled=no

    - name: 关闭selinux1
      shell: "setenforce 0"
      failed_when: false

    - name: 关闭selinux2
      lineinfile: dest=/etc/selinux/config regexp="^SELINUX=" line="DELINUX=disabled"
    
    - name: 安装常用的软件
      yum: name=vim,lrzsz,net-tools,wget,curl,bash-completion,unzip state=latest
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值