美文网首页
ansible介绍

ansible介绍

作者: 戈羽殇雪 | 来源:发表于2019-12-20 17:16 被阅读0次

    1.为什么选择ansible

    来源:ansible一词源于科幻小说,是一种超光速通信设备。


    ans.png

    配置管理、应用部署等。配置管理工具有Chef, Puppet, Salt等,应用部署(将代码编译或打包然后传输到服务器部署并启动服务)工具有Capistrano,Fabric等,ansible集两者于一身,操作很简单但是功能强大。此外,还可以对多个服务器进行服务编排,支持openstack,amazon ec2, docker等。

    ansible使用了一个DSL(domain-specific language)描述服务器状态。执行的文件称为playbook,文件格式为yaml。ansible简约而不简单。比起puppet的繁琐的配置和复杂语法,简直是一股清流。下图描述了ansible执行过程,执行了两个task和一个handler,先是使用了一个apt模块在web1,web2,web3上面执行了安装nginx的任务,再是用template模块拷贝了配置文件。另外,执行了一个notify nginx的handler重启了nginx。

    image.png

    执行流程:

    创建一个python脚本用于安装nginx包。
    拷贝python脚本到web1,web2,web3。
    分别在web1,web2,web3上执行该脚本。
    等待脚本在所有服务器上执行完毕。
    接着执行下一个task。
    

    注意的几点:

    • 1.在各个服务器执行脚本的过程是并行的,有个forks参数可以指定,默认是5,即一次可以在5个服务器上并行执行脚本。
    • 2.要在所有的服务器都执行完第一个task后才会接着执行第二个task。(新版本新增了异步参数,一个服务器在执行完了它的任务后可以不等其他服务器执行完直接执行下一个task)。
    • 3.ansible执行任务顺序与playbook中的顺序一致。

    优势:
    1)语法易读。yaml->json好比markdown->html。ansible的playbook可以被称之为可以执行的README。
    2)远程主机不需要安装任何东西。(这有点夸大了,python2.5+(python2.4+simplejson模块)和ssh是必须的,当然这现在已经是Linux服务器标配了)
    3)push-based。如chef和puppet是pull-based,先将文件修改推送到中心服务器,其他服务器的agent定期拉取新的配置管理脚本并在本机执行。而在ansible是push-based的,先在中心服务器修改playbook,执行该playbook,ansible会连接到各个服务器并执行模块改变服务器状态。push-based的好处就是只在需要的时候才操控去改变目标服务器状态。如果你更倾向于pull-based模式,可以用ansible-pull。
    4)ansible可以很方便的scaled down,单机跟多机没有什么区别。 Simple things should be simple, complex things should be possible 。

    1. 很轻量级的抽象。不像puppet之类的工具,有很高的抽象,比如有package这个概念,用于不用区分服务器版本来安装模块。但是在ansible中,提供的是apt和yum模块,由你自己采用,不要再额外学一些抽象的语法,简化你的学习成本。

    2.安装配置

    2.1 安装

    1.安装:

    Centos7:

    yum安装首先配置epel源,然后可以通过yum install –y ansible

    Pip安装:

    pip install ansible(可以配置在virtualenv中)

    2.2 配置

    1)ansible最大的优势是不需要单独配置从节点,只需配置免密码登录即可

    (将master节点的公钥下发到从节点上)

    2)ansible配置文件:ansible的配置文件一般都放在/etc/ansible下(无论是yum安装,还是pip安装都会在此目录下)默认的配置文件并不需要修改

    ansible.cfg,配置文件寻找路径如下:

    File specified by the ANSIBLE_CONFIG environment variable
     ./ansible.cfg (ansible.cfg in the current directory) 
    ~/.ansible.cfg (.ansible.cfg in your home directory) 
    /etc/ansible/ansible.cfg
    

    注意:若需要配置指定的用户以及指定的公钥文件等,都可以在这里配置,另外如果考虑安全方面ansible server上不存私钥,通过ssh forward,参考https://www.cnblogs.com/thatsit/p/6599309.html

    2.3测试

    需要配置hosts,在/etc/ansible下建立hosts文件

    [group1]
    10.122.66.107
    [group2]
    10.122.66.106
    

    执行ansible 指令测试是否配置完成:

    10.122.66.106 | SUCCESS => {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python"
        },
        "changed": false,
        "ping": "pong"
    }
    10.122.66.107 | SUCCESS => {
        "changed": false,
        "ping": "pong"
    }
    

    3实体关系图

    image.png
    • playbook包含很多个play
    • play中包含name,tasks,hosts,vars,handles属性。
    • tasks中包含各个真正执行的module,如apt,copy,file, git, svn,service,command,notify,mysql等。具体的模块参数和使用文档在这里

    一个例子

    ---
    - hosts: group1
      remote_user: root
      tasks:
      - name: ensure apache is at the latest version
        yum: pkg=httpd state=latest
      - name: write the apache config file
        template: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf
        notify:
        - restart apache
      - name: ensure apache is running
        service: name=httpd state=started
      handlers:
      - name: restart apache 
        service: name=httpd state=restarted
    

    可以看到用到了yum,file,copy,template,notify,service等模块。
    注意几个语法点:

    YAML truthy
    true, True, TRUE, yes, Yes, YES, on, On, ON, y, Y
     
    YAML falsey
    false, False, FALSE, no, No, NO, off, Off, OFF, n, N
    
    • true和yes,on或者1都是一样的意思,一般在模块参数里面用yes和no,true和false在playbook中其他地方。
    • 另外,比如下面的模块参数分行写,可以在第一行写 > , 后面几行跟参数来实现。
    • 注意notify是严格按照它在play中定义的顺序执行的,而不是notify调用的顺序执行的。比如下面的playbook,尽管先notify的是 handler test2 ,实际执行时时按照play中handlers定义的顺序,也就是先执行 handler test1。
    ---
    - name: test handlers
      hosts: group1
      tasks:
        - name: assure file exist
          file: >
            path=/tmp/test.conf
            state=touch owner=ssj mode=0644
    
        - name: task1
          command: date
          notify: handler test2
    
        - name: task2
          command: echo 'task2'
          notify: handler test1
    
      handlers:
        - name: handler test1
          command: echo 'handler test1'
        - name: handler test2
          command: echo 'handler test2'
    

    5 更多细节

    5.1 inventory 格式和配置

    inventory 格式:
    [webservers]
    foo.example.com
    bar.example.com
    [dbservers]
    one.example.com
    two.example.com
    three.example.com
    [test]
    localhost
    [webserver]
    dbserver1 ansible_ssh_host=127.0.0.1 ansible_ssh_port=22 color=red
    dbserver2 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2200 color=green
    

    可以用分组的方式,可以直接用域名(www.example.com),也可以用别名(如testserver2)+变量指定ssh的ip地址和端口,比如ansible_ssh_host和color变量。命令 ansible testserver2 -a date ,通常我们要控制多台服务器,于是可以分组服务器,要在所有服务器执行可以用all。 ansible all -a date。

    inventory除了可以指定主机的变量如上面的color之外,还可以将变量分组,也可以对主机变量单独存储到一个文件中,格式如下,注意如果host_vars中和group_vars中有相同变量,则以host_vars中的为准。host_vars变量只能本主机使用,group_vars是本group都可以使用。

    group_vars/dbserver
    -----------------------
    db:
       user: bbsdbuser
       password: bbsdbpasswd
       port: 3306
       name: bbs
       replica:
           host: slavedb
           port: 3307
    
    host_vars/dbserver1
    ---------------------
    db:
       user:server1dbuser
       password: server1password
       master: true
       
    ansible dbserver1 -i hosts -a 'echo {{db.user}}' #host_vars优先级高
    dbserver1 | SUCCESS | rc=0 >>
    server1dbuser
    
    ansible dbserver2 -i hosts -a 'echo {{db.master}}' #dbserver2所在的组变量文件没有db.master变量,报错。
    dbserver2 | FAILED | rc=0 >>
    the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'dict object' has no attribute 'master'
    

    甚至支持

    [web]
    web[1:20].example.com 
    web-[a-t].example.com
    

    inventory文件还支持动态的,通过 -i inventory 可以指定目录或者文件,这样目录下面可以放一个python脚本,用来动态获取主机列表。python脚本要可执行,同时实现下面两个命令:

    --host=<hostname> for showing host details
    --list for listing groups
    

    最后,还可以通过add_hosts模块在运行时增加host配置,使用group_by模块在运行时创建group。比如通过 ansible_distribution来根据操作系统创建不同的组,再分别安装软件。

    ---
    - name: group hosts by distribution
      hosts: all
      gather_facts: True
      tasks:
        - name: create groups based on distro
          group_by: key={{ ansible_distribution }}
    
    - name: do something to Ubuntu hosts
      hosts: Ubuntu
      tasks:
        - name: install htop
          apt: name=htop
    # ...
    - name: do something else to CentOS hosts
      hosts: CentOS
      tasks:
        - name: install htop
          yum: name=htop
    

    执行结果:

    (venv2) [root@vm-10-122-66-107 playbooks]# ansible-playbook group_test.yml -v
    Using /etc/ansible/ansible.cfg as config file
    
    PLAY [group hosts by distribution] *******************************************************************************************************************************************************************************************************
    
    TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************
    ok: [10.122.66.106]
    
    TASK [create groups based on distro] *****************************************************************************************************************************************************************************************************
    ok: [10.122.66.107] => {"add_group": "CentOS", "changed": false, "parent_groups": ["all"]}
    ok: [10.122.66.106] => {"add_group": "CentOS", "changed": false, "parent_groups": ["all"]}
    [WARNING]: Could not match supplied host pattern, ignoring: Ubuntu
    
    PLAY [do something to Ubuntu hosts] ******************************************************************************************************************************************************************************************************
    skipping: no hosts matched
    
    PLAY [do something else to CentOS hosts] *************************************************************************************************************************************************************************************************
    
    TASK [install htop] **********************************************************************************************************************************************************************************************************************
    ok: [10.122.66.107] => {"changed": false, "msg": "", "rc": 0, "results": ["htop-2.0.1-1.el7.x86_64 providing htop is already installed"]}
    ok: [10.122.66.106] => {"changed": false, "msg": "", "rc": 0, "results": ["htop-2.0.1-1.el7.x86_64 providing htop is already installed"]}
    
    PLAY RECAP *******************************************************************************************************************************************************************************************************************************
    10.122.66.106              : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    10.122.66.107              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    

    注意:使用-v的目的是为了获得详细的执行过程

    inventory默认配置:


    image.png

    参数解释如下:

    • ansible_connection: ssh连接方式,默认是smart,也就是看本地机器是否安装了ssh客户端且支持ControlPersist特性。如果支持,则使用本地的ssh客户端,如果不支持,则使用一个基于python的ssh客户端库paramiko。
      模式还有:local,ssh,以及network_cli(一般使用公私钥的方式连接的,建议使用local)
    • ansible_shell_type: ansible认为的远程服务器执行script的shell,默认认为是/bin/sh,当然也可以设置为csh,fish等,如果服务器支持的话。
    • ansible_python_interpreter: 服务器python解释器的路径。如果你的服务器python解释器不在这个目录,这要修改该配置。
    • ansible_*_interpreter: 如果用的是一个自定义的模块,不是python的,比如ruby,则设置该值指定解释器路径(比如/usr/bin/ruby)。

    5.2 变量和Facts

    变量

    变量可以在play中通过vars来指定,也可以通过var_file指定一个文件,文件中存储变量。例如:

    ---
    - name: Configure webserver with nginx and tls
      hosts: webservers
      sudo: True
      vars:
        key_file: /etc/nginx/ssl/nginx.key
        cert_file: /etc/nginx/ssl/nginx.crt
        conf_file: /etc/nginx/sites-available/default
        server_name: localhost
      tasks:
        - name: Install nginx
          yum: name=nginx update_cache=yes cache_valid_time=3600
        - name: create directories for TLS certificates
          file: path=/etc/nginx/ssl state=directory
        - name: copy TLS key
          copy: src=files/nginx.key dest={{ key_file }} owner=root mode=0600
          notify: restart nginx
        - name: copy TLS certificate
          copy: src=files/nginx.crt dest={{ cert_file }}
          notify: restart nginx
        - name: copy nginx config file
          template: src=templates/nginx.conf.j2 dest={{ conf_file }}
          notify: restart nginx
        - name: enable configuration
          file: dest=/etc/nginx/sites-enabled/default src={{ conf_file }} state=link
          notify: restart nginx
        - name: copy index.html
          template: src=templates/index.html.j2 dest=/usr/share/nginx/html/index.html mode=0644
      handlers:
        - name: restart nginx
          service: name=nginx state=restarted
    
    

    上面的任务是,配置安装nginx,启动nginx服务的任务,过程中需要配置证书,以及自己的配置文件,里面使用了vars(变量),指定了几个文件,包括证书文件,而这里的文件可以改写成:

    vars_files:
         - nginx.yml
    
    ##nginx.yml文件内容
    key_file: /etc/nginx/ssl/nginx.key
    cert_file: /etc/nginx/ssl/nginx.crt
    conf_file: /etc/nginx/sites-available/default
    server_name: localhost
    

    可以在play中使用debug模块打印变量的值,注意debug支持的参数有var,msg等,var中的变量不要使用 {{}}包裹。

    ---
    - name: Print debug infomation eg1 
      hosts: group1
      gather_facts: F 
      vars: 
        user: jingyong 
      tasks: 
      - name: Command run line 
        shell: date 
        register: result 
      - name: Show debug info 
        debug: var=result verbosity=0
    

    使用register来注册一个变量后面使用,register注册的变量在这个playbook的其他play中也是可以使用的,不局限于这一个play。比如command模块的输出如下所示,可以通过login.stdout得到用户名。注意不同模块的输出可能是不一样的,同一个模块在不同情况下也不一样,比如apt模块安装nginx,如果机器已经安装了nginx,则输出里面change为false,而且不会有stdout,stderr和stdout_lines这些key。如果模块执行出错,则其他的host默认不会再执行,可以设置 ignore_erros:True 忽略模块的错误。

    其他指定变量的方式如 host_vars目录,group_vars目录等。

    ok: [10.122.66.107] => {
        "result": {
            "changed": true,
            "cmd": "date",
            "delta": "0:00:00.058444",
            "end": "2019-12-13 10:22:26.214990",
            "failed": false,
            "rc": 0,
            "start": "2019-12-13 10:22:26.156546",
            "stderr": "",
            "stderr_lines": [],
            "stdout": "Fri Dec 13 10:22:26 CST 2019",
            "stdout_lines": [
                "Fri Dec 13 10:22:26 CST 2019"
            ]
        }
    }
    

    Facts

    如果在playbook中配置了 gather_facts:True,则会看到真正的任务开始前,会先执行一个[setup]的模块,用于收集服务器信息,包括cpu架构,操作系统类型,ip地址等信息。这些信息存储在特定的变量中,我们称之为facts。如果你的playbook中不需要这些信息,也可以设置gather_facts:False来加快playbook执行速度,收集服务器信息需要花费不少时间的。

    通过命令 ansible webserver -m setup 可以看到ansible的gathter_facts的输出内容,软硬件信息都有。因为信息太多,还可以通过在setup模块加上参数filter来筛选你需要的内容,如果只需要网络信息,可以这样: ansible webserver -m setup -a 'filter=ansible_eth*’ ,其中ansible_facts这个key是固定的。

    127.0.0.1 | SUCCESS => {
        "ansible_facts": {
            "ansible_eth0": {
                "active": true, 
                "device": "eth0", 
                "ipv4": {
                    "address": "xxx.xxx.xxx.xxx", 
                    "broadcast": "xxx.xxx.xxx.xxx",
                    "netmask": "xxx.xxx.xxx.xxx.xxx", 
                    "network": "xxx.xxx.xxx.xxx"
                }, 
                "macaddress": "xx.xx.xx.xx.xx.xx", 
                "module": "bnx2", 
                "mtu": 1500, 
                "pciid": "0000:10:00.0", 
                "promisc": false, 
                "type": "ether"
            },
        }, 
        "changed": false
    }
    

    可以在定义本地facts,在 /etc/ansible/facts.d/ 目录新建example.fact文件,内容如下:

    ansible group1 -m setup -a "filter=ansible_local"
    10.122.66.107 | SUCCESS => {
        "ansible_facts": {
            "ansible_local": {
                "perferences": {
                    "general": {
                        "asdf": "1",
                        "bar": "2"
                    }
                }
            }
        },
        "changed": false
    }
    

    另外,还可以通过 set_fact 模块设置变量,比如之前得到了一个命令的输出,register到一个变量,然后把我们需要的变量提取出来用set_fact存储到另外一个变量中,简化了变量的引用。

    ---
    - name: test name
      hosts: group1
      gather_facts: True
      tasks:
        - name: print ansible_local
          debug: var=ansible_local
    
        - name: capture output of id command
          command: id -un 
          register: login
          ignore_errors: True
    
        - set_fact: loginuser={{ login.stdout }}
        - name: show login user
          debug: var=loginuser
    

    内置变量

    image.png

    命令行传递变量

    还可以在运行playbook的时候在命令行传递变量。如果要传递一个包含变量的文件,可以用
    ansible-playbook greet.yml -e @greetvars.yml

    vim greetvars.yml
    ---
    - name: pass a message on the command line
     hosts: group1
     vars:
       greeting: "you didn't specify a message"
     tasks:
       - name: output a message
         debug: msg="{{ greeting }}"
    
    ansible-playbook greet.yml -e greeting=hiya  
    

    变量优先级

    ansible在很多地方可以设置变量,尽量不要重名。优先级由高到低如下:

    • 命令行的参数, 上面的 -e greeting=‘hello’ 。
    • host, group中的变量,不管是在inventory中还是yaml文件中定义的。
    • Facts变量
    • role目录下的 defaults/main.yml 。

    5.3 playbook要点

    实用模块
    如果想在控制机器而不是远程机器运行命令,可以用local_action。
    如果机器没有启动起来,需要先等待机器启动再执行play,用wait_for模块。

    ---
    - name: Deploy mezzanine
      hosts: web
      gather_facts: False
       # vars & vars_files section not shown here 
      tasks:
            - name: wait for ssh server to be running
              local_action: wait_for port=22 host="{{ inventory_hostname }}" search_regex=OpenSSH
            - name: gather facts
              setup:
    

    如果不想一次在所有的hosts都执行,可以设置serial参数来设置每次执行几个host,比如升级服务器,我们不想影响服务,会一个一个跑。可以设置max_fail_percentage来指定最大失败的比率,比如设置为25%,则如果有4台机器,有2台任务执行失败则终止整个play,其他任务不再执行。

    ---
     - name: upgrade packages on servers behind load balancer
       hosts: myhosts
       serial: 1
       max_fail_percentage: 25
       tasks:
            # tasks go here
    

    加密数据

    一些数据如db密码等不能直接提交到代码库,可以提交一个加密的版本。加密文件可以用ansible-vault工具。运行playbook的时候加上参数

    ansible-vault encrypt secrets.yml
    ansible-vault create secrets.yml
    ansible-vault view secrets.yml
    
    $ ansible-playbook test.yml --ask-vault-pass
    $ ansible-playbook mezzanine --vault-password-file ~/password.txt
    

    hosts格式

    可以用冒号:表示合并服务器组,:& 求交集等。
    指定运行的hosts可以在命令行加上 —limit 。

    ansible-playbook -l 'staging:&database' playbook.yml
    ansible-playbook —limit 'staging:&database' playbook.yml
    
    image.png

    Filters

    filter可以用在很多方面,比如默认值filter。如果database_host没有定义,则HOST的值设置为localhost。

    "HOST": "{{ database_host | default('localhost') }}"
    

    针对任务返回值的filter。可以的取值有 failed,changed,skipped,success等。
    failed_when: result|failed

    文件路径的filter。

     vars:
        homepage: /usr/share/nginx/html/index.html
     tasks:
     -  name: copy home page
        copy: src=files/{{ homepage | basename }} dest={{ homepage }}
    

    自定义filter:
    写一个自定义的filter,放在项目的 filter_plugins 目录下即可。下面是一个用于字符串分割的filter模块,使用时使用filter语法即可。

    from ansible import errors
    def split_string(string, seperator=' '):
        try:
            return string.split(seperator)
        except Exception, e:
            raise errors.AnsibleFilterError('split plugin error: %s, string=%s' % str(e),str(string) )
    
    class FilterModule(object):
        def filters(self):
            return {
                'split' : split_string,
            }
    

    lookups

    查找变量可以通过lookup实现,支持file,redis,pipe,cvsfile等多种格式。(redis的需要安装python的redis模块)

    复杂循环

    *   with_items
    *   with_lines
    *   with_fileglob
    *   with_dict
    *   ...
    

    debug你的playbook

    检查语法:ansible-playbook --syntax-check playbook.yml 
    查看host列表:ansible-playbook --list-hosts playbook.yml 
    查看task列表:ansible-playbook --list-tasks playbook.yml 
    检查模式(不会运行): ansible-playbook --check playbook.yml 
    diff模式(查看文件变化): ansible-playbook --check --diff playbook.yml 
    从指定的task开始运行:ansible-playbook --start-at-task="install packages" playbook.yml 
    逐个task运行,运行前需要你确认:ansible-playbook --step playbook.yml 
    指定tags:ansible-playbook --tags=foo,bar playbook.yml 跳过tags:ansible-playbook --skip-tags=baz,quux playbook.yml
    

    6 角色(Roles)

    6.1 角色基本结构

    roles可以简化playbook编写,让playbook更清晰和方便复用。一个名为database的role的目录结构如下,这些目录都是可选的,如果你的角色没有任何handler,则不需要handlers目录。roles的查找路径默认是/etc/ansible/roles,也可以在 /etc/ansible/ansible.cfg的roles_path中设置。

    roles/database/tasks/main.yml
    Tasks
    
    roles/database/files/
    Holds files to be uploaded to hosts
    
    roles/database/templates/
    Holds Jinja2 template files
    roles/database/handlers/main.yml
    Handlers
    
    roles/database/vars/main.yml
    Variables that shouldn’t be overridden
    
    roles/database/defaults/main.yml
    Default variables that can be overridden
    
    roles/database/meta/main.yml
    Dependency information about a role
    

    6.2 pre_tasks和post_tasks

    在角色执行任务前做一些前置工作,任务执行完后做一些后置处理。

    - name: test 
      hosts: dbserver
      vars_files:
        - secrets.yml
      pre_tasks:
        - name: update the apt cache
          apt: update_cache=yes
      roles:
        - role: database
      post_tasks:
        - name: send email
          command: xxx
    

    6.3 依赖角色

    如果怕遗漏一些任务,比如设置ntp之类的,可以使用依赖角色的功能。这样在执行你的角色任务时会先执行依赖角色。

    roles/database/meta/main.yml
    dependencies:
        - { role: ntp, ntp_server=ntp.ubuntu.com }
    

    6.4 Ansible Galaxy

    可以通过ansible galaxy工具方便的创建一个角色目录。

    ansible-galaxy init -p playbooks/roles database

    如果不用-p指定路径,那么默认是会在当前目录创建角色的目录结构。创建后的目录结构如下:

    playbook/roles/database
    ├── README.md
    ├── defaults
    │   └── main.yml
    ├── files
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── tasks
    │   └── main.yml
    ├── templates
    ├── tests
    │   ├── inventory
    │   └── test.yml
    └── vars
        └── main.yml
    

    ansible galaxy还是一个开源的角色库,你可以在其中下载到许多其他人写好的角色代码或者提交自己的角色代码。角色仓库的使用说明在这里

    6.5 Ansible Tower

    ansible tower是ansible公司提供的一套商用的web管理平台,也有试用版本,还没有试用过,后续使用了再补充。

    7 加速你的ansible

    7.1 SSH ControlPersist

    ControlMaster auto
    ControlPath $HOME/.ansible/cp/ansible-ssh-%h-%p-%r 
    ControlPersist 60s
    

    7.2 Pipelining(ansible的特性)

    ansible通常执行的原理是在 ~/.ansible下面创建一个临时目录(通过ssh),然后通过sftp或者scp拷贝python脚本到临时目录,然后执行这个脚本代码(再次通过ssh)。使用pipeline可以使得这些操作只要一个ssh连接去执行python脚本。即便是开启了ControlPersist,这个性能提升也很可观。在配置文件中加入pipelining=true即可开启。

    需要注意的是,开启pipeling要关闭服务器的requiretty功能。增加文件/etc/sudoers.d/disable-requiretty,其中的内容为 Defaults:ansibleuser !requiretty,ansibleuser为你的用户名。

    7.3 Fact Cache

    如果你不需要用到服务器信息,可以关闭获取fact的功能,这样也可以加快playbook的执行效率。配置文件中加入 gathering = explicit即可,这样你要获取服务器信息,需要显示的在play中指定。

    如果要用到fact信息,可以使用fact缓存,这样每个机器的fact信息只会获取一次而不是每次都去获取。fact缓存支持json,redis,memcached。如果用redis则需要在控制机上安装python的redis模块,自然redis也是要安装的。

    [defaults]
    gathering = smart
    # 24-hour timeout, adjust if needed
    fact_caching_timeout = 86400
    # You must specify a fact caching implementation
    
    # JSON file implementation
    fact_caching = jsonfile //或者redis,memcached
    fact_caching_connection = /tmp/ansible_fact_cache
    

    7.4 Parallelism

    可以设置ANSIBLE_FORKS环境变量或者在配置文件加上forks=n来指定并行执行的host的数目。

    7.5 关于异步

    ansible的1.7版本开始增加了异步参数 async,也就是说执行一个时间很长的任务时,可以不用等待它结束,而是直接先执行后面的任务,在后续的play中定时检查任务执行结果即可。

    有几点注意一下,一个是async参数,是指任务执行的超时时间,如果这个时间设置的比任务执行时间短,则任务会超时失败。poll值为轮询任务状态的时间间隔,如果设置为0,表示启动并忽略,也就是说设置为0才是真正的开始异步执行,也就是直接执行后面的task,而为了知道异步任务执行的结果,可以用async_status来实现。如果poll设置为非0值,则还是阻塞执行的,并非异步。

    - hosts: dbserver
      tasks:
      - name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
        command: /bin/sleep 15
        async: 20
        poll: 0
        register: asynctest
    
      - name: check async status
        async_status: jid="{{ asynctest.ansible_job_id }}"
        register: job_result
        until: job_result.finished
        retries: 30
        delay: 2
    

    8 创建自定义模块

    在某些情况下,可能ansible自带的模块不能满足你的需求,需要自定义模块。可以通过python或者bash来写自定义模块,符合ansible的模块编写标准即可,这里有很详细的文档

    9 Docker

    docker是目前很火爆的技术,它提供了一套远程API供第三方程序调用,ansible的docker模块就是使用了这套API对docker操作。ansible用在docker上主要有两点:一是编排docker容器。通常一个系统需要很多个docker容器来支持,每个容器都运行一个服务。服务之间需要相互通信,同时你也要保证容器启动的顺序等,原生docker并没有这些工具支持,ansible则是非常合适的一个选择。二是创建镜像。官方的方式是通过Dockerfile来创建镜像,但是通过ansible来实现更加简单方便。

    基于docker的应用的生命周期是这样的:

    1. 在本地机器创建docker镜像。
    2. 将docker镜像push到registry。
    3. 远程机器上将镜像从registry上pull下来。
    4. 在远程机器上启动容器。

    使用ansible之后,则是下面这样的:

    1. 写好用来创建docker镜像的playbook。
    2. 运行playbook来创建镜像。
    3. 将docker镜像推送到registry。
    4. 写好一个拉取docker镜像并启动容器的playbook。
    5. 执行playbook拉取和启动容器。

    参考 :https://ansible-tran.readthedocs.io/en/latest/docs/playbooks_intro.html#about-playbooks
    https://www.cnblogs.com/sunsky303/p/11175299.html

    相关文章

      网友评论

          本文标题:ansible介绍

          本文链接:https://www.haomeiwen.com/subject/frhinctx.html