zoukankan      html  css  js  c++  java
  • 第10章:深入浅出Ansible

    1.Ansible介绍

    1).Ansible的优点

        Ansible是一个简单的自动化引擎,可完成配置管理、引用部署、服务编排以及其他各种IT需求

        Ansible是Python开发并实现的开源软件,其依赖Jinja2,paramiko和PyYAML这几个Python库

        安装部署简单

        基于SSH进行配置管理

        Ansible不需要守护进程

        日志集中存储

        Ansible简单易用

        Ansible功能强大

        Ansible设计优秀

        Ansible对云计算和大数据平台都有很好的支持

    2).Ansible与Fabric之间比较

        Fabric像是一个工具箱,提供了很多好用的工具用于在远程服务器执行命令

        Ansible提供了一套简单的流程,只需要按照它的流程来做就能轻松完成任务

        Fabric是库,Ansible是框架

        Fabric简单,Ansible复杂

        Fabric通过SSH执行简单的命令,Ansible将模块拷贝到远程服务器后执行,执行完以后删除模块

        Fabric需要Python编程背景,Ansible不需要

        Fabric需要写代码,Ansible只需要编写YAML格式的配置文件来描述要做的事情

        Fabric提供了基本的接口,业务逻辑需要用户自己实现,Ansible提供了大量模块,用户只需要学习模块的用法即可

    3).Ansible与SaltStack之间比较

        Ansible安装部署简单,SaltStack需要安装客户端接收服务端发过来的命令

        SaltStack相应速度更快,Ansible使用标准SSH连接,而SaltStack使用ZeroMQ进行通信和传输

        Ansible更安全,Ansible使用标准SSH连接传输数据,不需要在远程主机上启动守护进程

        SaltStack对Windows支持比较友好

        Ansible自身运维比较简单,SaltStack需要在Master和Minion主机启动一个守护进程

    2.Ansible使用入门

    1).安装Ansible

        pip install ansible

    2).Ansible的架构

        Ansible的编排引擎由Inventory、API、Modules(模块)和Plugins组成

        工程师将需要在远程服务器执行的操作写在Ansible Playbook中,然后使用Ansible执行Playbook中的操作

    3).Ansible的运行环境

    Ansible会默认读取/etc/ansible/hosts文件中配置的远程服务器列表
    # mkdir /etc/ansible
    # cat /etc/ansible/hosts 
    [test]
    192.168.1.101
    192.168.1.102
    192.168.1.103
    
    # ansible test -m ping
    192.168.1.101 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    192.168.1.102 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }
    192.168.1.103 | SUCCESS => {
        "changed": false, 
        "ping": "pong"
    }

    4).Ansible的ad-hoc模式

    Ansible的ad-hoc模式,通过ansible命令执行操作的方式,称为ad-hoc
    # ansible test -m command -a "hostname"
    
    # ansible test -m command -a "whoami"
    
    将本地文件拷贝到服务器中:
    # ansible test -m copy -a "src=/etc/ansible/hosts dest=/tmp/hosts"
    
    修改文件的所有者和权限:
    # ansible all -m file -a "dest=/tmp/hosts mode=500 owner=mysql group=mysql" -become
    -become参数类似于Linux命令下的sudo
    
    在远程服务器中安装软件:
    # ansible test -m yum -a "name=git state=present" -become

    5).使用playbook控制服务器

    在实际的生产环境中,我们一般将远程服务器需要做的事情写在一个YAML配置文件中
    YAML文件称为Ansible Playbook
    
    # cat test_playbook.yaml
    ---
    - hosts : test
      become : yes
      become_method : sudo
      tasks : 
      - name : copy file
        copy : src=/etc/ansible/hosts dest=/tmp/data.txt
    
      - name : change mode
        file : dest=/tmp/data.txt mode=500 owner=mysql group=mysql
    
      - name : ensure packages installed
        yum : pkg="{{ item }}" state=present
        with_items : 
        - git
    
    # ansible-playbook test_playbook.yaml

    3.Inventory管理

    1).hosts文件位置

    在Ansible中,将可管理的服务器集合称为Inventory
    Inventory管理便是服务器管理
    默认读取/etc/ansible/hosts文件
    通过命令行参数的-i指定hosts文件
    通过ansible.cfg文件中的inventory选项指定hosts文件

    2).动态Inventory获取

    # cat hosts.py 
    import argparse
    import json
    from collections import defaultdict
    from contextlib import contextmanager
    import pymysql
    
    def to_json(in_dict):
        return json.dumps(in_dict, sort_keys=True, indent=2)
    
    @contextmanager
    def get_conn(**kwargs):
        conn = pymysql.connect(**kwargs)
        try:
            yield conn
        finally:
            conn.close()
    
    def parse_args():
        parser = argparse.ArgumentParser(description='OpenStack Inventory Module')
        group = parser.add_mutually_exclusive_group(required=True)
        group.add_argument('--list', action='store_true', help='List active servers')
        group.add_argument('--host', help='List details about the specific host')
        return parser.parse_args()
    
    def list_all_hosts(conn):
        hosts = defaultdict(list)
        with conn as cur:
            cur.execute('select * from hosts')
            rows = cur.fetchall()
            for row in rows:
                no, host, group, user, port = row
                hosts[group].append(host)
        return hosts
    
    def get_host_detail(conn, host):
        details = {}
        with conn as cur:
            cur.execute("select * from hosts where host='{0}'".format(host))
            rows = cur.fetchall()
            if rows:
                no, host, group, user, port = rows[0]
                details.update(ansible_user=user, ansible_port=port)
        return details
    
    def main():
        parser = parse_args()
        with get_conn(host='127.0.0.1', user='root', passwd='msds007', db='test') as conn:
            if parser.list:
                hosts = list_all_hosts(conn)
                print(to_json(hosts))
            else:
                details = get_host_detail(conn, parser.host)
                print(to_json(details))
    
    if __name__ == '__main__':
        main()

    4.YAML语法

    1).语法规则

    YAML文件的第一行为"---",表示是一个YAML文件
    YAML中的字段大小写敏感
    YAML与Python一样,使用缩进表示层级关系
    YAML的缩进不允许使用Tab键,只允许使用空格,且空格的数目不重要,只要相同层次的元素左对齐即可
    :冒号前后要有空格
    #表示注释,从这个字符一直到行尾都会被解析器忽略

    2).支持的数据格式

    对象:键值对的集合,又称为映射,类似于Python中的字典
    数组:一组按次序排列的值,又称为序列(sequence),类似于Python中的列表
    纯量:单个的、不可再分的值,如字符串、布尔值于数字

    3).解析

    pip install PyYAML
    
    使用PyYAML库解析YAML文件非常简单
    import yaml
    with open('data.yaml') as f:
        print(yaml.load(f))
    
    # cat data.yaml 
    ---
    name : Example Developer
    job : Developer
    skill : Elite
    employed : True
    foods:
        - Apple
        - Orange
        - Strawberry
        - Mango
    languages:
        ruby : Elite
        python : Elite
        dotnet : Lame

    5.Ansible模块

    1).Ansible的模块工作原理

    1)将模块拷贝到远程服务器
    2)执行模块定义的操作,完成对服务器的修改
    3)在远程服务器中删除模块

    2).常用的Ansible模块

    1.ping
    2.远程命令模块command
    3.file
    4.copy
    5.user/group
    6.yum
    7.get_url
    8.unarchive
    9.git

    3).模块的返回值

    changed
    failed

    6.Playbook

    1).Playbook的定义

        在Ansible中,将各个模块组合起来的文件是一个YAML格式的配置文件,这个配置文件,在Ansible中称为Playbook

        Ansible中的Playbook类似于Linux下的Shell脚本文件

    2).使用ansible-playbook

    # cat test_playbook.yaml
    ---
    - hosts : test
      become : yes
      become_method : sudo
      tasks : 
      - name : copy file
        copy : src=/py/data.txt dest=/tmp/data.txt
    
      - name : change mode
        file : dest=/tmp/data.txt mode=500 owner=mysql group=mysql
    
      - name : ensure packages installed
        yum : pkg="{{ item }}" state=present
        with_items : 
        - git
    
    # ansible-playbook test_playbook.yaml

    3).Playbook的详细语法

    1.权限
    在Ansible中,默认使用当前用户连接远程服务器执行操作,我们可以在ansible.cfg文件中配置连接远程服务器的默认用户
    2.通知
    3.变量
    4.Facts变量
    Facts变量是Ansible执行远程部署之前从远程服务器中获取的系统信息,包括服务器的名称、IP地址、操作系统、分区信息、硬件信息等
    Facts变量可以配合Playbook实现更加个性化的功能需求
    访问复杂变量的Playbook:
    ---
    - hosts : test
      gather_facts : yes
      tasks : 
      - shell : echo {{ ansible_eth0 ["ipv4"] ["address"] }}
        register : myecho
    
      - debug : var=myecho.stdout_lines
    
      - shell : echo {{ ansible_eth0.ipv4.address }}
        register : myecho
    
      - debug : var=myecho.stdout_lines
    5.循环
    # cat test_playbook.yaml 
    ---
    - hosts : test
      become : yes
      become_method : sudo
      tasks : 
      - name : Installed MySQL Package
        yum : pkg="{{ item }}" state=installed
        with_items : 
        - mysql-server
        - MySQL-python
        - libselinux-python
        - libsemanage-python
    # ansible-playbook test_playbook.yaml
    6.条件
    在Playbook中可以通过when选项执行条件语句,when类似于if语句
    7.任务执行策略

    4).使用Playbook部署ngix

    # cat deploy_nginx.yaml 
    ---
    - hosts: test
      become: yes
      become_method: sudo
      vars:
        worker_processes: 4
        worker_connections: 768
        max_open_files: 65506
      tasks:
        - name: install nginx
          yum: name=nginx update_cache=yes state=present
    
        - name: copy nginx config file
          template: src=/py/nginx.conf.j2 dest=/etc/nginx/nginx.conf
    
        - name: copy index.html
          template:
            src: /py/index.html.j2
            dest: /usr/share/nginx/html/index.html
            mode: 0644
          notify: restart nginx
    
      handlers:
        - name: restart nginx
          service: name=nginx state=restarted
    
    # ansible-playbook depoly_nginx.yml

    5).使用Playbook部署MongoDB

    # cat mongo.yml 
    ---
    - hosts: test
      become: yes
      become_method: sudo
      vars:
        mongodb_datadir_prefix: /data
        mongod_port: 27018
    
      tasks:
        - name: Create the mongodb user
          user: name=mongodb comment="MongoDB"
    
        - name: Create the data directory for the namenode metadata
          file: path={{ mongodb_datadir_prefix }} owner=mongodb group=mongodb state=directory
    
        - name: Install the mongodb package
          yum: name={{ item }} state=installed
          with_items:
            - mongodb-server
            - mongodb
    
        - name: create data directory for mongodb
          file:
            path: "{{ mongodb_datadir_prefix }}/mongo-{{ ansible_hostname }}"
            state: directory
            owner: mongodb
            group: mongodb
    
        - name: create log directory for mongodb
          file: path=/var/log/mongo state=directory owner=mongodb group=mongodb
    
        - name: Create the mongodb startup file
          template: src=mongod.j2 dest=/etc/init.d/mongod-{{ ansible_hostname }} mode=0655
    
        - name: Create the mongodb configuration file
          template: src=mongod.conf.j2 dest=/etc/mongod-{{ ansible_hostname }}.conf
    
        - name: Copy the keyfile for authentication
          copy: src=secret dest={{ mongodb_datadir_prefix }}/secret owner=mongodb group=mongodb mode=0400
    
        - name: Start the mongodb service
          command: creates=/var/lock/subsys/mongod-{{ ansible_hostname }} /etc/init.d/mongod-{{ ansible_hostname }} start
    
    # ansible-playbook mongo.yml

    7.role的定义与使用

        role并不是某一个具体的东西,而是一个规范与抽象,是一种将复杂的Playbook分割成多个文件的机制

        Ansible从复杂的Playbook中抽象出了role的概念,并在Playbook提供了roles选项来使用role,在命令行提供了ansible-galaxy命令来创建、删除和查看role

        所谓role,只是一种规范的文件组织方式。每个Ansible的role都会有一个名字,比如mongodb,与mongodb role相关的文件都存放在/etc/ansible/roles/mongodb目录下

    8.Ansible的配置文件

    1).配置文件的查找路径

    配置文件的查找路径
    Ansible命令行工具使用的配置文件是/etc/ansible/ansible.cfg文件
    一般将所有的role、Playbook、Inventory文件、ansible.cfg文件保存在一个版本控制的库中
    
    在Ansible中,可以有多种方式使用ansible.cfg文件。Ansible查找ansible.cfg文件的顺序如下:
    1)ANSIBLE_CONFIG环境变量指定的配置文件
    2)当前目录下的ansible.cfg文件
    3)当前用户home目录下的.ansible.cfg文件
    4)Ansible默认的/etc/ansible/ansible.cfg文件

    2).Ansible中的常用配置

    1.默认配置
    inventory
    remote_user
    remote_port
    private_key_file
    roles_path
    log_path
    host_key_checking
    forks
    gathering
    2.ssh连接配置
    ssh_args
    pipelining
    control_path
    3.权限提升配置
    become
    become_method
    become_user
    become_ask_pass
  • 相关阅读:
    Java的栈和队列
    Spring @Scheduled 在tomcat容器里面执行两次
    Java calendar获取月份注意事项
    mysql 查询今天,昨天,上个月sql语句 注解
    MySQL 查询最近几天的记录 最近7天的记录 本周内的记录
    关于mybatis 注解sql sum(参数)传参写法
    tomcat 部署war项目
    maven项目生成war包
    Cron表达式
    ### 获取当前日期的函数
  • 原文地址:https://www.cnblogs.com/allenhu320/p/11354121.html
Copyright © 2011-2022 走看看