• Ansible


    Ansible

    Ansible 是一种 agentless(基于 ssh),可实现批量配置、命令执行和控制,基于 Python 实现的自动化运维工具。
    其特性有:

    • 模块化:通过调用相关模块,完成指定任务,且支持任何语言编写的自定义模块
    • playbook:剧本,可根据需要一次执行完剧本中的所有任务或某些任务
          
      /usr/bin/ansible: 命令行工具
      ansible 命令通用格式:ansible [options] [-m module_name] [-a args]
      /usr/bin/ansible-doc: 帮助文档
      /usr/bin/ansible-playbook: 剧本执行工具
      /etc/ansible/ansible.cfg: 主配置文件
      /etc/ansible/hosts: 管理的主机清单
      /etc/ansible/roles: 角色存放处

    1、安装ansible(依赖于epel源)

    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
    
    yum install ansible -y 
    

    执行ansible报错

    ERROR! Unexpected Exception, this is probably a bug: (cryptography 0.8.2 (/usr/lib64/python2.7/site-packages), Requirement.parse('cryptography>=1.1'))
    
    解决方法
    rpm -qa |grep python-crypto    把列出的 rpm 包全部删除
    rpm -e python-cryptography --nodeps    强制删除
    

    2、定义HOSTS文件,配置主机,配置登陆方式

    cd /etc/ansible/
    cp  hosts{,.bak}
    

    2-1使用配置文件认证方式(不推荐这种方式)

    vim hosts
    [webs]
    192.168.2.100 ansible_ssh_user=root ansible_ssh_pass=123456
    192.168.2.101 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22
    
    [dbs]
    192.168.2.102 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22
    

    若报这个错,需用SSH连接一次即可

    [root@ansibles ansible]# ansible
    
    192.168.2.101 | FAILED! => {
        "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."
    }
    
    [root@ansibles ansible]# ssh 192.168.2.101
    The authenticity of host '192.168.2.101 (192.168.2.101)' can't be established.
    ECDSA key fingerprint is 58:da:34:71:b4:08:0c:95:c3:ff:72:15:c4:05:10:24.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '192.168.2.101' (ECDSA) to the list of known hosts.
    root@192.168.2.101's password: 
    Last login: Tue Oct 23 13:26:43 2018 from 192.168.2.254
    

    2-2基于密钥方式登陆

    ssh-keygen -t rsa
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.2.100
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.2.101
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.2.102
    

    配置完测下

    ansible all -m ping
    192.168.2.101 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    192.168.2.100 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    192.168.2.102 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    

    3、如何查看模块帮助
    ansible-doc -l 列出哪些模块
    ansible-doc -s MODULE_NAME 查看模块参数

    语法
    ansible <host-pattern> [options]
    -f forks:启动的并发线程数
    -m module_name:要使用的模块
    -a args:模块物有的参数

    常用模块

    command:命令模块,默认模块,用于在远程执行命令

    • creates:一个文件名,当该文件存在,则该命令不执行
    • free_form:要执行的 linux 指令
    • chdir:在执行指令之前,先切换到该目录
    • removes:一个文件名,当该文件不存在,则该选项不执行
    • executable:切换 shell 来执行指令,该执行路径必须是一个绝对路径
      ansible all -a 'date'
      ansible all -m command 'date'

    cron:计划任务模块

    • minute=/hour=/day=/month=/weekday= 某个值不写,默认就是 *
    • name: 必选项,任务描述信息
    • job: 执行的任务,要加引号
    • state:present(创建)/absent(删除)
    ansible all -m cron -a 'minute="30" hour="3" job="usr/sbin/ntpdate ntp.aliyun.com" name="ntp date time"'
    
    查看下结果 
    [root@ansibles ~]# ansible all -a 'crontab -l'
    删除此计划任务
    ansible all -m cron -a 'name="ntp date time" state=absent'
    

    user模块

    • name: 用户名
    • password: 为用户设置登陆密码,此密码是明文密码加密后的密码
    • update_password:always/on_create
      • always: 只有当密码不相同时才会更新密码 (默认)
      • on_create: 只为新用户设置密码
    • shell: 用户的 shell 设定
    • groups: 用户组设定
    • home: 指定用户的家目录
    • state:present/absent
    • append:yes/no
      • yes: 增量添加 group
      • no: 全量变更 group, 只设置 groups 指定的 group 组 (默认)
    • remove: 配合 state=absent 使用,删除用户的家目录 ->remove=yes
    • expires: 设置用户的过期时间,值是一个时间戳
    创建用户
    ansible dbs -m user -a 'name="user1"'
    192.168.2.102 | SUCCESS => {
        "changed": true, 
        "comment": "", 
        "createhome": true, 
        "group": 1000, 
        "home": "/home/user1", 
        "name": "user1", 
        "shell": "/bin/bash", 
        "state": "present", 
        "system": false, 
        "uid": 1000
    }
    删除用户
    ansible dbs -m user -a 'name="user1" state=absent'
    

    group模块

    • name: 组名称
    • gid: 指定 GID
    • state:present/absent
    • system:yes/no
    ansible dbs -m group -a 'name=mysql gid=306 system=yes'
    ansible dbs -m user -a 'name=mysql uid=306 system=yes group=mysql'
    
    验证下
    ansible dbs -a 'grep mysql /etc/passwd'
    

    copy模块

    • backup:在覆盖之前,将源文件备份,备份文件包含时间信息。有两个选项:yes|no
    • content:用于替代 “src”,可以直接设定指定文件的值
    • dest:必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
    • directory_mode:递归设定目录的权限,默认为系统默认权限
    • force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为 no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为 yes
    • others:所有的 file 模块里的选项都可以在这里使用
    • src:被复制到远程主机的本地文件,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用 “/” 来结尾,则只复制目录里的内容,如果没有使用 “/” 来结尾,则包含目录在内的整个内容全部复制,类似于 rsync。
    复制文件
    ansible dbs -m copy -a 'src=/etc/fstab dest=/tmp/fstab.ans owner=root mode=600'
    ansible dbs -a 'ls /tmp/fstab.ans'
    
    content=取代src=,表明用此处的信息生成目标文件
    使用信息输出目标文件
    ansible dbs -m copy -a 'content="ansbile test" dest=/tmp/test.ans'
    ansible dbs -a 'cat /tmp/test.ans'
    

    file模块:设定文件属性

    • group:定义文件 / 目录的属组
    • mode:定义文件 / 目录的权限
    • owner:定义文件 / 目录的属主
    • path:必选项,定义文件 / 目录的路径 指定符号链接文件路径
    • recurse:递归设置文件的属性,只对目录有效
    • src:被链接的源文件路径,只应用于 state=link 的情况
    • dest:被链接到的路径,只应用于 state=link 的情况
    • state:
      • directory:如果目录不存在,就创建目录
      • file:即使文件不存在,也不会被创建
      • link:创建软链接
      • hard:创建硬链接
      • touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
      • absent:删除目录、文件或者取消链接文件
    更换文件权限
    ansible dbs -m file -a 'owner=mysql group=mysql mode=600 path=/tmp/test.ans'
    创建链接文件
    ansible dbs -m file -a 'path=/tmp/fstab.link src=/tmp/fstab.ans state=link'
    

    ping模块

    测试远程主机的是否在线

    ansible all -m ping
    

    service模块指定服务运行状态

    • enabled=是否开机自动启动,取值为true或者false
    • name=服务名称
    • state=状态,会有started stoped restarted
    • runlevel: 运行级别
    ansible dbs -m service -a 'enabled=true name=mysqld state=started'
    

    shell模块

    虽然执行成功,但密码没有设置成功,可能当做本地的命令符号
    注意:尤其是用到管道等功能的复杂命令,使用shell模块

    ansible all  -a 'echo password|passwd --stdin user1'
    若使用到管理符号请使用shell模块
    ansible all  -m shell -a 'echo password|passwd --stdin user1'
    

    script模块

    将本地脚本复制到远程主机并运行
    注意:要使用相对路径指定脚本

    ansible all -m script -a '/root/test.sh'
    

    yum模块

    安装程序包

    • name=指明要安装的程序包,可以带上版本号
    • state=present,latest表示安装,absent表示卸载
    ansible dbs -m yum -a 'name=vsftpd'
    

    setup模块

    查看远程主机的相关 facts 变量信息

    ansible all -m setup
    

    playbook组成结构

    inventory
    modules
    ad hoc commands
    playbooks
        tasks:任务
        variables:变量
        templates:模板
        handlers:处理器
        roles:角色
    

    示例1 安装httpd包,配置文件,启动服务

    vim webs.yml
    - hosts: webs
      remote_user: root
      tasks:
      - name: install httpd package
        yum: name=httpd
      - name: install httpd config
        copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
      - name: start httpd service
        service: enabled=true name=httpd state=started
    

    示例2 若更改配置文件,触发handlers将重启服务

    vim webs.yml
    - hosts: webs
      remote_user: root
      tasks:
      - name: install httpd package
        yum: name=httpd
      - name: install httpd config
        copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
        notify:
        - restart httpd
      - name: start httpd service
        service: enabled=true name=httpd state=started
      handlers:
      - name: restart httpd
        service: name=httpd state=restarted
    

    示例3 引用变量

    - hosts: webs
      remote_user: root
      vars:
      - package: httpd
      - service: httpd
      tasks:
      - name: install httpd package
        yum: name={{ package }}
      - name: install httpd config
        copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
        notify:
        - restart httpd
      - name: start httpd service
        service: enabled=true name={{ service }} state=started
      handlers:
      - name: restart httpd
        service: name={{ package }} state=restarted
    

    输出facts中的某个变量并输入到文件

    - hosts: dbs
      remote_user: root
      tasks:
      - name: copy file
        copy: content="{{ ansible_all_ipv4_addresses }}" dest=/tmp/vars.ans
    

    when 条件测试
    满足条件ansible_fqdn == "db1",将执行tasks

    vim when.yml
    - hosts: all
      remote_user: root
      vars:
      - username: user1
      tasks:
      - name: crate {{ username }} user
        user: name={{ username }}
        when: ansible_fqdn == "db1"
    

    迭代:重复同类task时使用
    调用:item
    定义循环列表:with_items
    - httpd
    - php
    - mysql-server

    注意:with_items中的列表值也可以是字典,但引用时要使用tiem.KEY
    - {name: httpd, conf: configfile/httpd.conf}
    - {name: php, conf: configfile/php.ini}
    - {name: mysql-server, conf: configfile/my.cnf}

    http_port 变量定义在/etc/ansible/hosts文件里

    [root@ansibles ~]# grep port /etc/ansible/hosts
    192.168.2.100 http_port=80 
    192.168.2.101 http_port=8080
    
    [root@ansibles ~]# vim webs.yml
    - hosts: webs
      remote_user: root
      vars:
      - package: httpd
      - service: httpd
      tasks:
      - name: install httpd package
        yum: name={{ package }}
      - name: install httpd config
        template: src=/root/httpd.conf.t1 dest=/etc/httpd/conf/httpd.conf
        notify:
        - restart httpd
      - name: start httpd service
        service: enabled=true name={{ service }} state=started
      handlers:
      - name: restart httpd
        service: name={{ package }} state=restarted
    
    • tags:在playbook可以为某个或某些任务定义一个标签,在执行此playbook时,通过为ansible-playbook命令使用--tags选项能实现仅运行指定的tasks而非所有的:
      template: src=/root/httpd.conf.t1 dest=/etc/httpd/conf/httpd.conf
      tags:
      - conf

      特殊tags: always

    --tags="conf" --tars="restart"

    - hosts: webs
      remote_user: root
      vars:
      - package: httpd
      - service: httpd
      tasks:
      - name: install httpd package
        yum: name={{ package }}
        tags:
        - always
      - name: install httpd config
        template: src=/root/httpd.conf.t1 dest=/etc/httpd/conf/httpd.conf
        tags:
        - conf
        notify:
        - restart httpd
      - name: start httpd service
        service: enabled=true name={{ service }} state=started
        tags:
        - restart
      handlers:
      - name: restart httpd
        service: name={{ package }} state=restarted
    

    roles:

    目录名同角色名
    目录结构有固定格式

    • files:静态文件
    • templates:jinjia2模板文件
    • tasks:至少有mail.yml文件,定义名tasks
    • handlers:至少有一个mail.yml定义handlers
    • vars:至少有一个mail.yml文件,定义变量
    • meta:定义依赖关系等信息
    • site.yml中定义playbook,额外也可以有其它的yml文件
    创建目录
    mkdir -pv ansible_playbooks/roles/{webs,dbs}/{tasks,files,templates,meta,handlers,vars}
    
    查看创建的目录结构 
    [root@ansibles ~]# tree ansible_playbooks/
    ansible_playbooks/
    ├── roles
    │   ├── dbs
    │   │   ├── files
    │   │   ├── handlers
    │   │   ├── meta
    │   │   ├── tasks
    │   │   ├── templates
    │   │   └── vars
    │   └── webs
    │       ├── files
    │       │   └── httpd.conf
    │       ├── handlers
    │       │   └── main.yml
    │       ├── meta
    │       ├── tasks
    │       │   └── main.yml
    │       ├── templates
    │       │   └── httpd.conf.j2
    │       └── vars
    │           └── main.yml
    └── site.yml
    

    下面是相关的配置文件

    vim /root/ansible_playbooks/roles/webs/handlers/main.yml
    - name: restart httpd
      service: name=httpd state=restarted
    
    vim /root/ansible_playbooks/roles/webs/tasks/main.yml
    - name: install httpd package
      yum: name=httpd
    - name: install conf file
      template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
      tags:
      - conf
      notify:
      - restart httpd
    - name: start httpd service
      service: name=httpd state=started enabled=true
    
    grep "{{" /root/ansible_playbooks/roles/webs/templates/httpd.conf.j2 
    Listen {{ http_port }}
    ServerName {{ ansible_fqdn }}
    
    vim /root/ansible_playbooks/roles/webs/vars/main.yml
    http_port: "{{ 8888 }}"
    

    验证下

    [root@ansibles ~]#ansible-playbook ansible_playbooks/site.yml
    [root@ansibles ~]# ansible webs -a 'ss -tnl'|grep 8888
    LISTEN     0      128         :::8888                    :::*                  
    LISTEN     0      128         :::8888                    :::*
    
  • 相关阅读:
    el标签 2016-06-05 21:39 477人阅读 评论(15) 收藏
    5月英语总结 2016-05-31 21:31 395人阅读 评论(12) 收藏
    通过在__init__.py中定义__all__变量,来简化from*import*的书写
    python已安装包的查看方法和requirements.text的使用
    virtualenv安装 以及在PyCharm中的使用
    利用Fitnesse测试外部jar包
    说一下个人对自动化测试以及测试的看法
    oracle 导入sql文件乱码
    问题收集
    Gson应用:从json格式简单字符串中获取value
  • 原文地址:https://www.cnblogs.com/fina/p/9844462.html
Copyright © 2020-2023  润新知