zoukankan      html  css  js  c++  java
  • ansiable学习笔记

    介绍

    Ansible 简单的说是一个配置管理系统(configuration management system)。你只需要可以使用 ssh 访问你的服务器或设备就行。它也不同于其他工具,因为它使用推送的方式,而不是像 puppet 等那样使用拉取安装agent的方式。你可以将代码部署到任意数量的服务器上。ansible可以帮助我们完成一些批量任务,或者完成一些需要经常重复的工作。

    模块化:调用特定的模块,完成特定任务有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块

    1. 支持自定义模块
    2. 基于Python语言实现
    3. 部署简单,基于python和SSH(默认已安装),agentless
    4. 安全,基于OpenSSH
    5. 支持playbook编排任务
    6. 幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
    7. 无需代理不依赖PKI(无需ssl)
    8. 可使用任何编程语言写模块
    9. YAML格式,编排任务,支持丰富的数据结构
    10. 较强大的多层解决方案

    安装

    yum安装

    wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo yum -y install ansible 
    配置文件:/etc/ansible/ansible.cfg 
    主机清单:/etc/ansible/hosts
    

    源码安装

    下载
    git clone git://github.com/ansible/ansible.git --recursive
    cd ./ansible
    复制ansible根目录中的examples目录下的ansible.cfg配置文件到/etc/ansible/目录下
    cp examples/ansible.cfg /etc/ansible/
    创建hosts文件
    vim /etc/ansible/hosts
    需要的python模块
    sudo pip install paramiko PyYAML Jinja2 httplib2 six
    启动
    source ./hacking/env-setup
    一旦运行env-setup脚本,就意味着Ansible从源码中运行起来了.默认的inventory文件是 /etc/ansible/hosts.inventory
    $ echo "127.0.0.1" > ~/ansible_hosts
    $ export ANSIBLE_HOSTS=~/ansible_hosts
    

    SSH认证

    在~/.ssh目录下生成钥id_rsa.pub(公钥)和id_rsa
    ssh-keygen
     将公钥发到被管节点的root用户下的.shh目录,生成authorized_keys
    ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.2.100
    

    验证是否成功
    ssh root@192.168.2.100
    提示Failed to connect to the host via ssh
    chown username: /home/username/.ssh
    chown username: /home/username/.ssh/*
    chmod 700 /home/username/.ssh
    chmod 600 /home/username.ssh/*

    目录结构

    *配置文件或指令* *描述*
    /etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性
    /etc/ansible/hosts 主机清单
    /etc/ansible/roles/ 存放角色的目录
    /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 配置文件/etc/ansible/ansible.cfg (一般保持默认)

    [defaults]
    inventory = /etc/ansible/hosts # 主机列表配置文件
    library = /usr/share/my_modules/ # 库文件存放目录
    remote_tmp = $HOME/.ansible/tmp #临时py命令文件存放在远程主机目录
    local_tmp = $HOME/.ansible/tmp # 本机的临时命令执行目录
    forks = 5 # 默认并发数
    sudo_user = root # 默认sudo 用户
    ask_sudo_pass = True #每次执行ansible命令是否询问ssh密码
    ask_pass = True      #连接时提示输入ssh密码
    remote_port = 22     #远程主机的默认端口,生产中这个端口应该会不同
    log_path = /var/log/ansible.log #日志
    host_key_checking = False # 检查对应服务器的host_key,建议取消注释。也就是不会弹出
    

    Ansible必须通过Inventory 来管理主机(即/etc/anAnsible/hosts文件。)可同时操作属于一个组的多台主机,组和主机之间的关系通过 inventory 文件配置。

    ansible_ssh_host
    将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置.
    ansible_ssh_port
    ssh端口号.如果不是默认的端口号,通过此变量设置.这种可以使用 ip:端口 192.168.1.100:2222
    ansible_ssh_user
    默认的 ssh 用户名
    ansible_ssh_pass
    ssh 密码(这种方式并不安全,我们强烈建议使用 --ask-pass 或 SSH 密钥)
    ansible_sudo_pass
    sudo 密码(这种方式并不安全,我们强烈建议使用 --ask-sudo-pass)
    ansible_sudo_exe (new in version 1.8)
    sudo 命令路径(适用于1.8及以上版本)
    ansible_connection
    与主机的连接类型.比如:local, ssh 或者 paramiko. Ansible 1.2 以前默认使用 paramiko.1.2 以后默认使用 'smart','smart' 方式会根据是否支持 ControlPersist, 来判断'ssh' 方式是否可行.
    ansible_ssh_private_key_file
    ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.
    ansible_shell_type
    目标系统的shell类型.默认情况下,命令的执行使用 'sh' 语法,可设置为 'csh' 或 'fish'.
    ansible_python_interpreter
    目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",比如  *BSD, 或者 /usr/bin/python 不是 2.X 版本的 Python.
    我们不使用 "/usr/bin/env" 机制,因为这要求远程用户的路径设置正确,且要求 "python" 可执行程序名不可为 python以外的名字(实际有可能名为python26).
    与 ansible_python_interpreter 的工作方式相同,可设定如 ruby 或 perl 的路径....
    

    快速定义主机组

    单台主机
    green.example.com    >   FQDN192.168.100.10       >   IP地址192.168.100.11:2222  >   非标准SSH端口
    
    [webservers]         >   定义了一个组名     
    alpha.example.org    >   组内的单台主机192.168.100.10 
    
    [dbservers]
    192.168.100.10       >   一台主机可以是不同的组,这台主机同时属于[webservers] 
    
    [group:children]     >  组嵌套组,group为自定义的组名,children是关键字,固定语法,必须填写。
    dns                  >  group组内包含的其他组名
    db                   >  group组内包含的其他组名
    
    [webservers] 
    www[001:006].hunk.tech > 有规律的名称列表,
    这里表示相当于:
    www001.hunk.tech
    www002.hunk.tech
    www003.hunk.tech
    www004.hunk.tech
    www005.hunk.tech
    www006.hunk.tech
    
    [databases]
    db-[a:e].example.com   >   定义字母范围的简写模式,
    这里表示相当于:
    db-a.example.com
    db-b.example.com
    db-c.example.com
    db-d.example.com
    db-e.example.com
    
    以下这2条定义了一台主机的连接方式,而不是读取默认的配置设定
    localhost       ansible_connection=local
    www.163.com     ansible_connection=ssh        ansible_ssh_user=hunk
    
    最后还有一个隐藏的分组,那就是all,代表全部主机,这个是隐式的,不需要写出来的。
    

    验证

    ansible 10.128.50.53 -u root -m ping
    返回
    10.128.50.53 | success >> {
        "changed": false, 
        "ping": "pong"
    }
    

    使用

    测试命令

    Anisble安装完成后(一般情况我们连ssh的免密登录一起做完,详见附录)我们会测试anisble是否可用。测试命令没有固定的格式,我们使用linux下hello world ,命令ping来测试是否可用。
    指令成功和失败都会有不同的颜色反映出来且配合changed :false,changed :SUCCESS,可以让我们非常清晰的知道执行的结果。
    绿色:执行成功并且不需要做改变的操作
    ×××:执行成功并且对目标主机做变更
    红色:执行失败
    可以在配置文件中定义

    • highlight = white
    • verbose = blue
    • warn = bright purple
    • error = red
    • debug = dark gray
    • deprecate = purple
    • skip = cyan
    • unreachable = red
    • ok = green
    • changed = yellow
    • diff_add = green
    • diff_remove = red
    • diff_lines = cyan

    命令执行过程

    ansible db -m command -a 'ls -l /' -vvv 这条命令为例

    1.加载自己的配置文件,默认/etc/ansible/ansible.cfg
    Using /etc/ansible/ansible.cfg as config file
    2.匹配主机清单
    Parsed /etc/ansible/hosts inventory source with ini plugin
    3.加载指令对应的模块文件,如command,生成.py的文件到本机的临时目录,这个目录就是在/etc/ansible/ansible.cfg定义的
    Using module file /usr/lib/python2.7/site-packages/ansible/modules/commands/command.py
    PUT /tmp/tmp4JvsLH TO /root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861/command.py
    4. 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件,
    这个目录就是在/etc/ansible/ansible.cfg定义的
    ( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861 `" ....)
    sftp> put /tmp/tmp4JvsLH /root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861/command.py
    '
    5. 给文件+x 权限
    'chmod u+x /root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861/ /root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861/command.py && sleep 0'
    6. 执行并返回结果
    '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861/command.py;
    7. 删除临时py文件,sleep 0退出
    rm -rf "/root/.ansible/tmp/ansible-tmp-1517301292.6-155771303493861/" > /dev/null 2>&1 && sleep 0
    8.断开远程主机连接
    'Shared connection to 7-db-3.hunk.tech closed.
    ')
    

    高级话题Playbooks

    playbook是ansible用于配置,部署,和管理被控节点的剧本。是由一个或多个play组成的列表,主要功能是将task定义好的角色归并为一组进行统一管理,也就是通过Ansible的模板将多个play组织在一个Playbook中运行。
    Playbook可以理解为批处理任务,不过palybook有自己的语法格式,使用playbook你可以方便的重用这些代码,可以移植到不同的机器上面,像函数一样,最大化的利用代码。你也会发现,你所处理的大部分操作都是编写playbook。可以把常见的应用都编写成playbook,之后管理服务器会变得十分简单。比如安装nginx、mysql等服务。

    yaml格式

    playbook由YMAL语言编写。YAML( /ˈjæməl/ )参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822,Clark Evans在2001年5月在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。
    YMAL格式是类似于JSON的文件格式,便于人理解和阅读,同时便于书写。

    文件的第一行应该以 ”—” (三个连字符)开始,表明YMAL文件的开始。在同一行中,#之后的内容表示注释,类似于shell,python和ruby。YMAL中的列表元素以”-”开头然后紧跟着一个空格,后面为元素内容。

    - apple - banana - orange等价于JSON的这种格式
    [ “apple”, “banana”, “orange” ]
    同一个列表中的元素应该保持相同的缩进。否则会被当做错误处理。
    

    play中hosts,variables,roles,tasks等对象的表示方法都是键值中间以”:”分隔表示,”:”后面还要增加一个空格。

    house:
    family: { name: Doe, parents: [John, Jane], children: [Paul, Mark, Simone] }
    address: { number: 34, street: Main Street, city: Nowheretown, zipcode: 12345 }
    

    剧本以.yml后缀

    如图所示:在mysql.yml中,主要由三个部分组成。
    hosts部分:
    使用hosts指示使用哪个主机或主机组来运行下面的tasks,每个playbook都必须指定hosts,hosts也可以使用通配符格式。主机或主机组在inventory清单中指定,可以使用系统默认的/etc/ansible/hosts,也可以自己编辑,在运行的时候加上-i选项,指定清单的位置即可。在运行清单文件的时候,–list-hosts选项会显示那些主机将会参与执行task的过程中。
    remote_user:
    指定远端主机中的哪个用户来登录远端系统,在远端系统执行task的用户,可以任意指定,也可以使用sudo,但是用户必须要有执行相应task的权限。
    tasks:
    指定远端主机将要执行的一系列动作。tasks的核心为ansible的模块,前面已经提到模块的用法。tasks包含name和要执行的模块,name是可选的,只是为了便于用户阅读,不过还是建议加上去,模块是必须的,同时也要给予模块相应的参数。

    使用ansible-playbook运行playbook文件,得到如下输出信息,输出内容为JSON格式。并且由不同颜色组成,便于识别。一般而言
    绿色代表执行成功,系统保持原样
    ×××代表系统代表系统状态发生改变
    红色代表执行失败,显示错误输出

    Playbook的核心元素

    · Playbook本身由以下各部分组成:
    (1)Hosts:运行指定任务的目标主机;
    (2)Tasks:任务,即调用模块完成的操作;
    (3)Variables:变量;
    (4)Templates:模板;
    (5)Handles:处理器,当某条件满足时,触发执行的操作;
    (6)Roles:角色

    Play的主体是任务列表。任务列表中的任务依照次序逐个在hosts中指定的所有主机上执行,如果发生错误会将所有已执行任务回滚。

    模块、模块参数格式
    task的任务是按照指定的参数去执行模块。
    (1)action:moudle options
    (2)moudle:options,其中后者可以实现向后兼容。
    注意:在Ansible自带模块中,command模块和shell模块只需要一个列表定义即可,无需使用key=value格式。
    Handles和tags的使用
    Handlers用于当关注的资源发生变化时所采取的操作。使用tags让用户选择跳过没有变化的代码,只运行Playbook中发生变化的部分代码。
    (1) 某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers;
    (2) 任务可以通过“tags“打标签,通过 ansible-playbook命令 使用 --tags选项能实现仅运行指定的tasks。

    - hosts: nginx
      remote_user: root
      tasks:
        - name:yum install epel-release -y    #安装epel源
          yum: name=epel-release state=latest
        - name: yum install nginx -y  #安装nginx
          yum: name=nginx state=latest
        - name: copy nginx.conf   #拷贝配置文件
          copy: src=/opt/nginx.conf dest=/etc/nginx/nginx.conf backup=yes
          notify:
            - reload     #会触发handlers中名字为reload的任务
          tags: 
            - reloadnginx
        - name: start nginx   #启动nginx服务
          service: name=nginx state=started
          tags: 
            - startnginx
      handlers:
        - name: reload  #重载配置
          service: name=nginx state=reloaded
    
    执行:ansible-playbook nginx.yml 
    



    修改配置文件内容之后执行时调用标签ansible-playbook nginx.yml --tags= "reloadnginx",就会跳过安装步骤直接重载配置文件并启动服务。

    variables:变量
    (1) facts:可直接调用
    注意:可使用setup模块直接获取目标主机的facters
    ansible xxx -m setup
    (2) 用户自定义变量:
    通过命令行传递变量
    ansible-playbook xxx.yml -extra-vars "host-www user-mageedu"
    在playbook中定义变量的方法
    vars:

    • var1: value1
    • var2: value2
      (3)通过roles传递变量
      (4)Host Inventory(主机清单)

    Templates:模板文件以.j2后缀
    Jinja是基于 Python的模板引擎。 Template类是 Jinja的另一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递 Python的变量给模板去替换模板中的标记。

    循环:迭代,即需要重复执行的任务。
    (1)when 语句:只需要在task之后添加when语句即可。

    vim /etc/ansible/when.yml
    
    - hosts: nginx
      remote_user: root
      vars:
        - username: user10
      tasks:
        - name: create {{username}} user
          user: name={{username}}
          when: ansible_fqdn=="promote.cache-dns.local"
    执行:ansible-playbook when.yml 就会创建在nginx组的主机上
    

    (2)迭代:直接将需要迭代的内容定义为item变量并进行引用,然后通过with_items语句来指明迭代的元素。

    vim /etc/ansible/items.yml
    
    - hosts: nginx
      remote_user: root
      tasks:
        - name: install packages  #安装with_items中列出的包
          yum: name={{ item }} state=latest
          with_items:
            - php
            - php-mysql
    
    执行:ansible-playbook items.yml 就会安装列表中的包
    

    角色列表: Roles
    Ansible为了层次化、结构化地组织 Playbook,使用了角色( roles),可以根据层次结构自动装载变量文件、 tasks以及 handlers等。只需要在 Playbook中使用 include指令即可使用 roles。简单来讲, roles就是通过分别将变量、文件、任务、模块及处理器设置于单独的目录中,便捷地使用他们。
    创建roles时的注意事项:
    (1)目录名同角色名的定义
    (2)目录结构有固定的格式:

    files 用来存放由copy模块或script模块调用的文件
    templates 用来存放jinjia2模板
    tasks 至少有一个main.yml文件,定义各tasks
    handlers 有一个main.yml文件,定义各handlers
    vars 有一个main.yml文件,定义变量
    default 有一个main.yml文件,定义默认变量
    meta 有一个main.yml文件,定义此角色的特殊设定及其依赖关系

    注意:在每个角色命令的目录中分别创建files、handlers、tasks、templates、meta、default和vars目录,用不到的目录可以创建为空目录,但不可以不创建。

    示例

    ·、在roles目录下生成对应的目录结构
    mkdir -pv /etc/ansible/roles/{httpd,mysql,php}/{files,templates,vars,tasks,handlers,meta,default}


    2、在每个角色的handlers、tasks、meta、default、vars目录下创建main.yml文件,千万不能自定义
    touch /etc/ansible/roles/{httpd,mysql,php}/{default,vars,tasks,meta,handlers}/main.yml

    3、定义每个角色中tasks/main.yml的配置文件。
    ------编写httpd模块------
    vim /etc/ansible/roles/httpd/tasks/main.yml

    - name: ensure apache is at the latest version 
      yum: name={{item}} state=latest
      with_items:
        - httpd
        - httpd-devel
    - name: conf
      template: src=/etc/ansible/roles/httpd/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
      tags: 
        - httpdconf
      notify: 
        - new conf to reload
      tags:
        - reload
    - name: start service
      service: name=httpd enabled=true state=started
    

    -------编写mysql模块-------
    vim /etc/ansible/roles/mysql/tasks/main.yml

    - name: ensure mysql is at the latest version 
      yum: name={{item}} state=latest
      with_items:
        - mariadb
        - mariadb-server
        - mariadb-libs
        - mariadb-devel
    - name: start service
      service: name=mariadb enabled=true state=started
    

    -------编写php模块-----
    vim /etc/ansible/roles/php/tasks/main.yml

    - name: ensure php is at the latest version
      yum: name={{item}} state=latest
      with_items:
        - php
        - php-mysql
        - php-gd
        - php-ldap
        - php-odbc
        - php-pear
        - php-xml
        - php-xmlrpc
        - php-mbstring
        - php-snmp
        - php-soap
        - curl
        - curl-devel 
        - php-bcmath
    

    4、修改变量文件vars/main.yml
    vim /etc/ansible/roles/httpd/vars/main.yml

    http_port : 80    #添加变量
    server_name : www.yun.com:80
    

    5、定义handlers文件handlers/main.yml
    vim /etc/ansible/roles/httpd/handlers/main.yml

    - name: new conf to reload
      service: name=httpd state=reloaded
    

    6、定义/etc/ansible/lamp.yml的playbook文件
    -----编写roles示例-----
    vi /etc/ansible/lamp.yml

    - hosts: lamp
      remote_user: root
      roles:
        - httpd
        - mysql
        - php
    

    7、执行lamp.yml的playbook文件
    ansible-playbook lamp.yml

    8、前往部署lamp的主机上编写php测试页,打开浏览器看网页是否正常。
    vim /var/www/html/index.php

    <?php
       phpinfo();
    ?>
    

    访问http://ip/index.php验证

    常用命令

    语法

    ansible <host-pattern> [-m module_name] [options]
    指令 匹配规则的主机清单 -m 模块名 选项
    --version 显示版本
    -a 模块参数(如果有)
    -m module 指定模块,默认为command
    -v 详细过程 –vv -vvv更详细
    --list-hosts 显示主机列表,可简写--list
    -k, --ask-pass 提示连接密码,默认Key验证
    -K,--ask-become-pass 提示使用sudo密码
    -C, --check 检查,并不执行
    -T, --timeout=TIMEOUT 执行命令的超时时间,默认10s
    -u, --user=REMOTE_USER 执行远程执行的用户
    -U, SUDO_USER, --sudo-user 指定sudu用户
    -b, --become 代替旧版的sudo 切换
    ansible-doc: 显示模块帮助
    ansible-doc [options] [module...]
    -a 显示所有模块的文档-l, --list 列出可用模块-s, --snippet 显示指定模块的简要说明
    

    命令

    /usr/bin/ansible:Ansibe AD-Hoc 临时命令执行工具,常用于临时命的执行
    /usr/bin/ansible-doc:Ansible 模块功能查看工具
    /usr/bin/ansible-galaxy:下载/上传优秀代码或Roles模块 的官网平台,基于网络的
    /usr/bin/ansible-playbook:Ansible 定制自动化的任务集编排工具
    /usr/bin/ansible-pull:Ansible远程执行命令的工具,拉取配置而非推送配置(使用较少,海量机器时使用,对运维的架构能力要求较高)
    /usr/bin/ansible-vault:Ansible 文件加密工具
    /usr/bin/ansible-console:Ansible基于Linux Consoble界面可与用户交互的命令执行工具
    Ansible-doc命令
    查看 ansible-doc 的使用说明:
    一般用法:
    ansible-doc -l 获取所有模块信息
    ansible-doc -s MOD_NAME 获取指定模块的使用帮助
    ansible-doc
    -h Usage: ansible-doc [options] [module...]
    Options:
    -h, --help show this help message and exit # 显示命令参数API文档
    -l, --list List available modules #列出可用的模块
    -M MODULE_PATH, --module-path=MODULE_PATH #指定模块的路径specify path(s) to module library (default=None)
    -s, --snippet Show playbook snippet for specified module(s) #显示playbook制定模块的用法
    --version show program's version number and exit # 显示ansible-doc的版本号查看模块列表:ion
    ansible-doc -l
    

    常用模块

    官方文档

    模块 功能
    ping 测试连通性
    command 命令行不能接收shell表达式
    shell 可以解析shell表达式、通配符等如管道
    copy 复制文件到远程主机,可以改权限等
    file file 设置文件属性
    Fetch fetch从远程某主机获取文件到本地
    cron cron 管理cron计划任务
    group 添加或删除组
    user 管理用户、获取用户信息
    yum 远程安装包
    service 管理服务
    setup 获取主机信息
    script 执行脚本
    get_url 下载指定文件存放到dest指定的目录
    --------------------------------------------------------- 恐惧是因为努力的还不够,加油 ~~---------------------------------------------
  • 相关阅读:
    怎样创建动态扩容数组?
    怎样终止一个线程?
    模式识别
    基于Linux根据僵尸网络病毒平台《比尔盖茨》
    web.xml在&lt;init-param&gt;一个错误
    DTD学习笔记
    Java排序算法(四):Shell排序
    VC6迁移到VS2008几个问题——良好的代码,从我做起,从现在开始。
    Maven 建 Struts2 基本实现 CURD Controller
    Andy&#39;s First Dictionary
  • 原文地址:https://www.cnblogs.com/zhaobowen/p/13338380.html
Copyright © 2011-2022 走看看