设为首页 收藏本站
查看: 935|回复: 0

[经验分享] 自动化运维工具之ansible的简单应用

[复制链接]
发表于 2018-7-30 09:08:33 | 显示全部楼层 |阅读模式
  ansible:
  ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,例如shell,copy,ping等,ansible只是提供一种框架。ansible的主要特性:
  模块化:调用特定的模块,完成特定任务
  基于Python语言实现,由Paramiko,PyYAML和jinja2三个关键模块
  部署简单:agentless,无需在管控主机安装任何客户端
  支持自定义模块;
  支持playbook(剧本);
  运维工具的工作模式:
  1、agent :需要在管控主机上安装客户端,和客户端通信,比如:zabbix,puppt
  2、agentless:无需安装客户端,基于SSH协议通信,比如:ansible
  ansible是工作在agentless模式下具有幂等性,意思就是无论任务执行一遍或者多遍,对结果都不会产生影响。ansible在控制端只需要告诉监控端的期望状态就可以实现批量部署,只需告诉管控主机需要干什么就行。
  ansible的架构图:
DSC0000.png

  ansible通过连接插件Connaction Plugins来负责基于SSH和管控主机进行通信,Host Inventoy则记录了需操作主机的信息。ansible除了直接使用命令行控制外,还可以基于PlayBooks(剧本)来实现管理主机,通过各种模块和自定义模块来操作主机,并借助插件来记录日志和邮件等。
  一、ansible的安装
]# yum -y install ansible  
]# ls /etc/ansible/
  
ansible.cfg                    //配置文件
  
hosts                         //主机清单
  
roles/                       //定义角色
  1、定义hosts:
  ]# vim /etc/ansible/hosts
  [webserver]     //定义主机组
  172.18.250.77  ansible_ssh_user=root ansible_ssh_pass=123456  //连接主机的账号密码
  172.18.250.78  ansible_ssh_user=root ansible_ssh_pass=123456
  2、直接给出主机的账号密码不太安全,这时可以基于密钥方式认证:
]# ssh-keygen -t rsa -f ~/.ssh/id_rsa -P''  
]# ansible webserver -m copy -a "src=/root/.ssh/id_rsa.pub dest=/root/"
  
]# ansible webserver -m shell -a "cat /root/id_rsa.pub >>/root/.ssh/authorized_keys"
  3、可以把账号密码去掉,试试能不能执行
]# vim /etc/ansible/hosts  
[webserver]
  
172.18.250.77
  
172.18.250.78
  
]# ansible webserver -m ping
  
172.18.250.78 | success >> {
  
    "changed": false,
  
    "ping": "pong"
  
}
  

  
172.18.250.77 | success >> {
  
    "changed": false,
  
    "ping": "pong"
  
}
  4、ansible的简单语法格式:
  ansible HOST-PATTERN [-f forks] [-m MODULE_name] [-a args]
  HOST-PATTERN:主机清单,可以是单个主机,也可以是主机组
  -m module:       指明模块,默认为command
  -f forks:           指明一次发送几个连接请求
  -a args:              在远程主机上执行的参数
  查看ansible的常用模块命令: ansible-doc -l
  5、常用模块
  command模块:在远程主机上执行命令,不支持管道
]# ansible webserver -m command -a "cat /etc/issue"  
172.18.250.77 | success | rc=0 >>
  
\S
  
Kernel \r on an \m
  

  
172.18.250.78 | success | rc=0 >>
  
\S
  
Kernel \r on an \m
  shell模块:在远程主机shell上执行命令,支持管道
]# ansible webserver -m shell -a "ss -tan |grep :8080"  
172.18.250.78 | success | rc=0 >>
  
LISTEN     0      128                      :::8080                    :::*
  

  
172.18.250.77 | success | rc=0 >>
  
LISTEN     0      128                      :::8080                    :::*
  copy模块:复制本地文件到远程主机,或者直接在远程主机上写内容
  1、src=/path/to/somefile        dest=/path/to/somefile
  2、content=someting              dest=/path/to/somefile
]# ansible webserver -m copy -a "src=/etc/issue dest=/tmp"  
172.18.250.78 | success >> {
  
    "changed": true,
  
    "checksum": "5f63a8ace67bf6a8b62aa7da2cf5eccc05a89308",
  

  
172.18.250.77 | success >> {
  
    "changed": true,
  
    "checksum": "5f63a8ace67bf6a8b62aa7da2cf5eccc05a89308",
  

  
]# ls /tmp/
  
issue
  cron模块:管理定时计划任务
]# ansible webserver -m cron -a "minute=*/5 state=present job='ntpdate 172.18.0.1 >/dev/null' name=Rsynctime"  
172.18.250.78 | success >> {
  
    "changed": true,
  
    "jobs": [
  
        "Rsynctime"
  
    ]
  
}
  

  
172.18.250.77 | success >> {
  
    "changed": true,
  
    "jobs": [
  
        "Rsynctime"
  
    ]
  
}
  
]# crontab -l
  
#Ansible: Rsynctime
  
*/5 * * * * ntpdate 172.18.0.1 >/dev/null
  

  
mintue=    //分钟
  
hour=      //小时
  
day=       //哪天
  
weekday=   //星期几
  
month=     //哪月
  
job=       //内容
  
name=      //名称
  
state=     //对内容做什么操作,present:创建  absent:删除
  ping模块,对远程主机实行ping操作
]# ansible webserver -m ping  
172.18.250.78 | success >> {
  
    "changed": false,
  
    "ping": "pong"
  
}
  

  
172.18.250.77 | success >> {
  
    "changed": false,
  
    "ping": "pong"
  
}
  yum模块,程序包管理
]# ansible webserver -m yum -a "name=httpd state=present"  
172.18.250.78 | success >> {
  
    "changed": false,
  
    "msg": "",
  
    "rc": 0,
  
    "results": [
  
        "httpd-2.4.6-31.el7.centos.x86_64 providing httpd is already installed"
  
    ]
  
}
  

  
172.18.250.77 | success >> {
  
    "changed": false,
  
    "msg": "",
  
    "rc": 0,
  
    "results": [
  
        "httpd-2.4.6-40.el7.centos.x86_64 providing httpd is already installed"
  
    ]
  
}
  service模块,管理远程主机上的服务
]# ansible webserver -m service -a "name=httpd state=started enabled=1"  
172.18.250.78 | success >> {
  
    "changed": true,
  
    "enabled": true,
  
    "name": "httpd",
  
    "state": "started"
  
}
  

  
172.18.250.77 | success >> {
  
    "changed": true,
  
    "enabled": true,
  
    "name": "httpd",
  
    "state": "started"
  
}
  
name=         //程序名称
  
state=        //执行的操作,started、stoped、restarted、reloaded
  
enabled=      //是否开机自启
  
runlevel=     //运行的级别
  script模块,在远程主机上执行本地脚本,无需传递脚本过去
]# ansible webserver -m script -a "/tmp/mkdir.sh"(本地路径)  
172.18.250.78 | success >> {
  
    "changed": true,
  
172.18.250.77 | success >> {
  
    "changed": true,
  

  
默认是运行在用户的家目录下
  user模块和group模块,在远程主机上创建用户和组
]# ansible webserver -m group -a "name=testgroup system=no gid=2000 state=present"  
]# ansible webserver -m user -a "name=usertest system=no uid=2000 group=testgroup state=present"
  二、playbooks的应用
  运行playbook的方式:
  1、只检测可能会发生的改变,但不真正执行操作
  ansible-playbook --check file.yaml
  2、运行
  ansible-playbook file.yaml
  先要了解YAML的语法,YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用"-"来代表,Map里的键值对用":"分隔。
  YAML文件扩展名通常为.yaml,如example.yaml。
列表(list)的所有元素均使用“-”打头,例如:  
# A list of tasty fruits
  
- Apple
  
- Orange
  

  
字典(dictionary)通过key与value进行标识,例如:
  
---
  
# An employee record
  
name: Example Developer
  
job: Developer
  
skill: Elite
  

  
也可以将key:value放置于{}中进行表示,例如:
  
---
  
# An employee record
  
{name: Example Developer, job: Developer, skill: Elite}
  playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联同起来按事先编排的机制同唱一台大戏。
  playbook的核心元素:
  Tasks: 任务
  Variables: 变量
  Templates:  包含了模板语法的文本文件;
  Handlers:   由特定条件触发的任务;
  Roles: 角色
  Hosts:  主机
  1、hosts主机和用户
  playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,其可以是一个或多个由冒号分隔主机组;remote_user则用于指定远程主机上的执行任务的用户。
  - hosts: webserver  
    remote_user: root
  
    tasks:
  
    - name: ping
  
      ping:
  
      remote_user: usertest
  
      sudo: yes
  

  
    remote_user也可用于各task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户。
  2、tasks任务和action
  play的主体部分是task list。task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。在运行自下而下某playbook时,如果中途发生错误,所有已执行任务都将回滚,因此,在更正playbook后重新执行一次即可。
  task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。
  每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出。
tasks:  
    - name: yum install httpd packages
  
      yum:  name=httpd state=present
  
    - name: start httpd
  
      service: name=httpd state=started
  3、   Variables: 变量
  3.1、由ansible自己提供的变量:facts,可以直接调用
]# ansible webserver -m setup  
172.18.250.78 | success >> {
  
    "ansible_facts": {
  
        "ansible_all_ipv4_addresses": [
  
            "172.18.250.78"
  
        ],
  
        "ansible_all_ipv6_addresses": [
  
            "fe80::20c:29ff:fefa:c47b"
  
        ],
  
        "ansible_architecture": "x86_64",
  
        "ansible_bios_date": "07/31/2013",
  
        "ansible_bios_version": "6.00",
  3.2、ansible-playbook命令的命令行中的自定义变量
]# vim /tmp/test.yaml  
- hosts: webserver
  
  remote_user: root
  
  tasks:
  
  - name: useradd
  
    user: name={{ pkiname }} state=present
  
]# ansible-playbook  -e pkiname=user111 --check test.yaml
  3.3 向不同的主机中传递变量,在服务的配置文件中直接调用就行
]# vim /etc/ansible/hosts  
[webserver]
  
172.18.250.77  http_port=80
  
172.18.250.78  http_port=8080
  3.4、向组中的主机传递相同的变量,以便在playbook中使用
]# vim /etc/ansible/hosts  
[webserver]
  
172.18.250.77
  
172.18.250.78
  
[webserver:vars]
  
httpd_port=8080
  4、 Templates:  包含了模板语法的文本文件,嵌套有脚本(使用模板编程语言编写)
  有时候需要根据服务器的配置来修改服务配置文件,这时可以根据模板来解决
]# vim /tmp/nginx.conf.j2  
user nginx;
  
worker_processes {{ ansible_processor_vcpus-1 }};    //根据服务器cpu核数减1
  
]# vim /tmp/test.yaml
  
- hosts: webserver
  
   remote_user: root
  
   tasks:
  
   - name: nginx conf
  
     template: src=/tmp/template/nginx.conf.j2 dest=/etc/nginx/nginx.conf
  
   - name: restart
  
     service: name=nginx state=restarted
  5、Handlers:   由特定条件触发的任务;
  “notify”这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。
]# vim /tmp/test.yaml  
- hosts: webserver
  
  remote_user: root
  
  tasks:
  
  - name: install nginx
  
    yum: name=nginx state=present
  
  - name: nginx conf
  
    template: src=/tmp/template/nginx.conf.j2 dest=/etc/nginx/nginx.conf
  
    notify: restart            //只有当配置文件发生改变时才会触发notify
  
  - name: start nginx
  
    service: name=nginx state=started
  
  handlers:
  
    - name: restart           //触发notify时就执行重启操作
  
      service: name=nginx state=restarted
  6、playbook还支持条件测试和循环:
条件测试:  
when语句:在task中使用,jinja2语法格式
  
      tasks:
  
      - name: install conf file to centos7
  
        template:src=files/nginx.conf.c7.j2
  
        when: ansible_distribution_major_version == "7"
  
      - name:  install conf file to centos7
  
        template:src=files/nginx.conf.c6.j2
  
        when: ansible_distribution_major_version == "6"
  

  
循环语句:对迭代项的引用,固定变量名为"item",而后,要在task中使用with_items给定要迭代的元素列表;
  
   with_items两个方法表示:
  
      列表方法:字符串、字典
  

  
   1、字符串表示
  
       - hosts: all
  
         remote_user: root
  tasks:
  - name: install some package
  
           yum: name={{ item }} state=present
  with_items:
  - nginx
  - httpd
  
   2、字典表示:
  
      - hosts: all
  remote_user: root
  
        tasks:
  
        - name: add group
  group: name={{ item }} state=present
  with_items:
  
          - group11
  - group22
  
          - group33
  
        - name: add user
  user: name={{ item.name }} group={{ item.group }} state=present
  with_items:
  - { name: 'user11',group: 'group11' }
  
          - { name: 'user22',group: 'group22' }
  - { name: 'user33',group: 'group33' }
  7、tags:标签
  tags用于让用户选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断。
]# vim /tmp/test.yaml  
- hosts: webserver
  
  remote_user: root
  
  tasks:
  
  - name: install nginx
  
    yum: name=nginx state=present
  
  - name: nginx conf
  
    template: src=/tmp/template/nginx.conf.j2 dest=/etc/nginx/nginx.conf
  
    notify: restart
  
    tags: res                //在配置文件修改这打标签,执行时不会测试instll和start两部分   - name: start nginx          代码
  
    service: name=nginx state=started
  
  handlers:
  
    - name: restart
  
      service: name=nginx state=restarted
  
]# ansible-playbook  --tags=res --check test.yaml
  三、roles
  ansilbe自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。
  创建role的步骤
  (1) 创建以roles命名的目录;
  (2) 在roles目录中分别创建以各角色名称命名的目录,如webservers等;
  (3) 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建;
  (4) 在playbook文件中,调用各角色;
  role内各目录中可用的文件
  tasks目录:至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表;此文件可以使用include包含其它的位于此目录中的task文件;
  files目录:存放由copy或script等模块调用的文件;
  templates目录:template模块会自动在此目录中寻找Jinja2模板文件;
  handlers目录:此目录中应当包含一个main.yml文件,用于定义此角色用到的各handler;在handler中使用include包含的其它的handler文件也应该位于此目录中;
  vars目录:应当包含一个main.yml文件,用于定义此角色用到的变量;
  meta目录:应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系;ansible 1.3及其以后的版本才支持;
  default目录:为当前角色设定默认变量时使用此目录;应当包含一个main.yml文件;
  示例:创建个nginx角色,实现nginx的安装
]# mkdir /etc/ansible/roles/nginx  
]# cd /etc/ansible/roles/nginx/
  
]# mkdir tasks files templates handlers vars meta default
  
]# cd tasks/
  
]# vim main.yml              //编辑task
  
- name: install nginx
  
  yum: name=nginx state=present
  
- name: nginx conf
  
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
  
  notify: restart nginx
  
  tags: res
  
- name:  start nginx
  
  service: name=nginx state=started
  

  
]# cd handlers/
  
]# vim main.yml             //编辑handlers
  
- name: restart nginx
  
  service: name=nginx state=restarted
  

  
]# cd templates/
  
]# cp /tmp/nginx.conf.j2 ./    //准备模板
  
]# vim /etc/ansible/roles/nginx/templates/nginx.conf.j2
  
user {{ username }};
  

  
]# cd vars/
  
]# vim main.yml            //定义变量
  
username: deamon          //变量定义时较特殊,不要加“-”,定义运行nginx的用户
  

  
]# vim /tmp/nginx.yml
  
- hosts:websrvs
  
  remote_user:root
  
  roles:
  
  - nginx                 //直接调用nginx
  
# 调用变量:
  
- host:
  
   remote_user:
  
   roles:
  
   - { role: nginx,username: nginx }
  
# 还可以基于条件测试实现角色调用;
  
- host:
  
   remote_user:
  
   roles:
  
   - { role: nginx,when: ansible_distribution_majro_version == ’7‘ }
  

  
]# ansible-playbook --check /tmp/nginx.yml
  

  
PLAY [webserver] **************************************************************
  

  
GATHERING FACTS ***************************************************************
  
ok: [172.18.250.78]
  
ok: [172.18.250.77]
  

  
TASK: [nginx | install nginx] *************************************************
  
changed: [172.18.250.78]
  
changed: [172.18.250.77]
  

  
TASK: [nginx | nginx conf] ****************************************************
  
changed: [172.18.250.78]
  
changed: [172.18.250.77]
  

  
TASK: [nginx | start nginx] ***************************************************
  
changed: [172.18.250.78]
  
changed: [172.18.250.77]
  

  
NOTIFIED: [nginx | restart nginx] *********************************************
  
changed: [172.18.250.78]
  
changed: [172.18.250.77]
  

  
PLAY RECAP ********************************************************************
  
172.18.250.77              : ok=5    changed=4    unreachable=0    failed=0
  
172.18.250.78              : ok=5    changed=4    unreachable=0    failed=0

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-543366-1-1.html 上篇帖子: ansible部署简单高可用LAMP-liberalism 下篇帖子: Ansible批量快速初始化新机器运维环境
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表