ansible作为轻量级的运维管理工具,目前已被广泛使用,其已被redhat收购,

未来极为可能装入base仓库。

  • ansible的安装

    目前由于ansible位于epel仓库,我们需要创建epel源。方法如下:               1.wget https://mirrors.tuna.tsinghua.edu.cn/epel/7/x86_64/e/epel-release-7-9.noarch.rpm(此地址每隔一段时间会发生变化,如果以后发现该地址不正确,进入https://mirrors.tuna.tsinghua.edu.cn/epel/7/x86_64/e/去查找相应的资源)

          2.rpm -ivh epel-release-7-9.noarch.rpm

        3.yum clean all

        4.yum -y install ansible安装成功

    基本信息查看

        1.yum info ansible 查看ansible基本介绍

        2.rpm -qi ansible  查看程序包的信息

        3.rpm -ql ansible|less  查看支持的模块

    配置文件解读

        /etc/ansible/ansible.cfg  主配置文件,配置ansible程序的工作特性

        /etc/ansible/hosts        主机清单,各主机的分类的及IP地址等信息

        /etc/ansible/roles        存放角色的目录

        /usr/bin/ansible          主程序

        /usr/bin/ansible-doc      查看配置文档

        /usr/bin/ansible-galaxy

        /usr/bin/ansible-playbook 辅助工具:剧本

        /usr/bin/ansible-pull     取配置

     支持的模块的介绍

        command模块----在被管理远程主机上执行的命令

        shell模块------在被管理远程主机上执行的命令,但是为了调用shell进程,然后把命令在子进程中运行;在执行的命令中可使用管道符;

        copy模块-------用来复制文件到远程主机

        cron模块-------用来在远程主机定义计划任务

        ping模块-------用来探测主机存活性

        filesystem模块-制作文件系统,格式化分区

        known_hosts模块-管理ssh的hosts文件

        mysql_db模块----在远程管理数据库

        mysql_user模块--在远程管理数据库中的用户

        setup模块-------收集远程指定主机的变量

          ......

        如果没有需要的模块,可自行编写模块,使用任何语言;

        所以,要想使用ansible管理远程主机,就必须了解其中的模块,但前提是要把被管理主机纳入到管理列表中来;

        ansible在哪个目录查找模块,在配置文件中/etc/ansible/ansible.cfg中定义。

         ]# vim /etc/ansible/ansible.cfg

         显示部分内容:

         inventory = /etc/ansible/hosts 定义主机清单;

         pattern = * 默认匹配所有被管理主机;

         forks = 5 默认对远程主机执行命令时,5台主机一批,一批批的执行命令;

         module_lang = C 模块默认编程语言;

  • ansible的使用

    一、工作模式

       运维工具大体有两种模式

        1、agent模式:基于ssl实现。代理工作在被监控端。如:puppet

        2、agentless模式:基于ssh实现工作在被监控端。监控端是ssh的客户端。

        ansible是工作在agentless模式下具有幂等性。ansible在控制端只需要告诉监控端的期望状态就可以实现批量部署。

    二、基于密钥认证

       现在有三台机器作为被管理服务器,其中两台为centos6(IP分别为172.20.52.199、172.20.53.21),一台为centos7(172.20.52.185).管理机也为centos7.(IP:172.20.52.160)

       实现步骤:

          1.在管理主机上使用命令: ssh-keygen -t rsa -P ''     直接回车即可生成。

          2.把当前公钥复制到远程主机root用户的家目录下

            ssh-copy-id -i .ssh/id_rsa.pub root@172.20.52.199

            ssh-copy-id -i .ssh/id_rsa.pub root@172.20.52.185

            ssh-copy-id -i .ssh/id_rsa.pub root@172.20.53.21

          3.完成后最好使用ssh root@主机IP进行验证一下。

    三、命令使用

       1、通用格式 ansible <host-pattern> [options]

          host-pattern:指明对哪些主机执行命令    

          options:多为要执行的管理命令

          -a MODULE_ARGS指明模块参数

        例如:ansible all -m ping 对所有管理主机发起ping模块命令

              ansible-doc -s ping 查看ping模块使用参数,但ping没有参数;

     运行结果:    

    [root@centos7 yum.repos.d]# ansible all -m ping

    172.20.52.199 | SUCCESS => {

        "changed": false, 

        "ping": "pong"

    }

    172.20.52.185 | SUCCESS => {

        "changed": false, 

        "ping": "pong"

    }

    172.20.53.21 | SUCCESS => {

        "changed": false, 

        "ping": "pong"

    }

       2、command模块

         (1)ansible websrvs -m command -a 'ls /var'

         (2)注意:ansible websrvs -a 'ls /var' 省略模块时,默认为command模块;

        部分结果如下:            

    172.20.52.185 | SUCCESS | rc=0 >>

    account

    adm

    cache

    crash

    db

    empty

    games

    gopher

    kerberos

    lib

    local

    lock

    log

    mail

    nis

    opt

    preserve

    run

         (3) ansible websrvs -a 'useradd user1' 在websrvs主机组中执行命令添加user1用户;

         (4)执行的命令中有管道符'|'时,发生如下报错

    [root@centos7 ~]# ansible websrvs -m command -a 'ifconfig |head -3'

    172.20.52.199 | FAILED | rc=1 >>

    -3: Unknown host

    ifconfig: `--help' gives usage information.

    

    172.20.52.185 | FAILED | rc=1 >>

    -3: Unknown host

    ifconfig: `--help' gives usage information.

        3、shell模块

           在远程主机的shell进程下运行命令,支持shell特性,如管道,重定向等;

          上述的(4)问题,即可利用shell模块来解决。

        ansible websrvs -m shell -a 'echo user1 | passwd --stdin user1' 使用shell模块,在执行命令中能使用管道符;

        4、copy模块

           实现复制文件至远程主机            

            2种用法:

            (1)src= dest=

            (2)content= dest=

                owner,group,mode 可同时指明文件的属主、组及权限;

                一般有=号的选项为必有选项;

                src=为本地文件或目录;

                dest=为远程被管理主机文件或目录;

                content=表示把此处的内容直接当做源文件;

            (3)ansible dbsrvs -m copy "src=/etc/passwd dest=/tmp"

             (4)ansible all -m copy -a "content='hello there\n' mode=600 owner=user1 dest=/tmp/testfile1"         

                指明了权限、属主及换行符;默认复制后的权限为644;

        5、cron模块

           管理计划任务

                minute= 几分钟,范围0-59;

                day= 一个月的那一天,范围1-31,例如,1-5,*,*/2等

                month= 哪个月,范围1-12;

                hour= 哪个小时,范围0-23;

                weekday= 星期几,范围0-6;

                job= 表示state为present时,要执行的命令;

                *name= 必须指定计划任务条目;

                state=

                    present:创建cron计划任务;默认;

                    absent:删除cron计划任务;

            如:ansible all -m cron -a "minute=*/5 job='/sbin/ntpdate 172.20.52.160 &> /dev/null'name=synctime"          

            没有指明的时间默认为*,没有指明state默认为创建present;

            表示每5分钟执行一次时间同步任务,任务名为synctime;

            可在被管理主机查看计划任务;

            再如:ansible all -m cron -a "state=absent name=synctime"  删除计划任务

        6、fetch模块

            从远程主机拉取文件到本地

            src= 一般是目录

            dest=只能是文件

        7、file模块

            设定文件特性(修改属主、组等属性)

            用法:

                 (1)创建链接文件

                    *path=指明操作的文件

                    src=要链接的源文件

                    state-link

                 (2)修改属性

                     path= owner= mode= group=

                  (3) 创建目录:

                     path= state=directory

              举例:ansible dbsrvs -m file -a "path=/tmp/ansible_tmp state=directory"

                    ansible all -m file -a "src=/tmp/fstab path=/tmp/fstab.link state=link"

         8、hostname模块

            设定远程主机名

            name=

            要使用变量方式,写个循环实现批量更改远程主机主机名;

         9、pip模块

            管理Python模块;即使用pip安装依赖Python依赖到的模块;

         10、yum模块

            name=指定程序包名称,可以带版本号,默认最新版本

            state=

                    present,latest(最新版)安装程序;

                    absent卸载程序;

            disablerepo 安装时,指定临时禁用的仓库;

            enablerepo 安装时,指定临时启用的仓库。

            conf_file 表示yum运行时,指定(临时)使用的配置文件,而不是默认的配置文件。

            例如:ansible all -m yum -a "name=httpd state=latest" 在被管理上安装httpd程序

                  ansible all -m yum -a "name=httpd state=absent"在被管理上卸载httpd程序

                使用了安装命令后,如果之前该系统为安装过,运行结果显示为黄色字体。如果已经安装过了,则显示为绿色。都会显示成功安装。由于幂等性的原因(),一个程序在成功安装过后再次使用安装命令不会再次安装。

         11、service模块

             管理远程主机的服务

             *name=指定管理的服务

             state=

                started 启动服务

                stopped停止服务

                restarted重启服务

              enabled=开机自动启动;1或0;

              runlevel=在指定级别下为开机自动启动;默认为2345,或345级别;

              举例:ansible all -m shell -a "ss -ntl|grep :80" 查看被管理主机是否启动web服务

                    ansible all -m service -a "name=httpd state=started" 启动被管理主机web服务

          12、uri模块

               直接向被管理主机请求一个url;

                url=

                method指明请求的方法

                body如果请求方法是post,指明该body;

                user请求的url要求输入的用户名;

                password请求的url要求输入的密码;

                HEADER_发送请求的header;     

          13、user模块

                管理用户、组账号

                *name=指定要管理的用户

                state=为present|absent

                system=是否创建系统账号

                uid=指定UID

                shell=默认shell类型

                group=基本组

                groups=额外(附加)组

                comment=注释信息

                home=用户家目录

                move_home=移动已经存在用户的家目录

                password添加密码,应该指定的是openssl加密后的密码;

                remove当state=absent时,删除用户时同时删除家目录

               举例:

                    ansible all -m user -a "name=user2 system=yes state=presnet uid=306"

                    在被管理机上添加用户user2,为系统用户,UID为306;系统用户不应该有家目录,但此模块也创建了;

           14、setup模块

               获取facts,即收集远程主机的变量

                ansible 192.168.255.3 -m setup 手动收集指定远程主机的变量;

           15、group模块

                添加或者删除组

                name=组名,必有参数

                state={present|absent}

                system=

                gid=

           16、script模块

                一般为本地脚本,会自动复制到远程主机并执行;

                命令行使用:-a "/PATH/TO/SCRIPT_FILE"

                  注意:是本地文件路径

                removes如果脚本依赖的文件不存在,脚本不会运行

            17、templates模块

                就是文本文件,内部嵌套有脚本(这个脚本使用模板编程语言编写)

                基于模板方式生成一个文件符合到远程主机

                src=指定本地jinja2的模板文件路径

                dest=远程主机

                owner=

                group=

                mode=

                

                python只有在实现web框架时进行嵌入,将自己基于模板编程语言嵌入到其它文本中的机制,它的模板编程语言叫jinja2嵌入式的编程语言;类似于playbook,在python中叫resource资源和清单facts;在清单中定义资源时或定义使用的模板时会用到rubby的模板编程语言;

                jinja2模板编程语言所实现的功能是,可以在文本文件中,使用一个所谓的嵌入的标记语法,引入一段模板编程语言所编写的脚本;而这种脚本无法就是支持比较简单的编程元素,如条件判断、(迭代)循环、变量;

                wKiom1jQjyWR1jJUAADEe18YX-U528.png

               举例:演示模板应用

              使用ansible在三台主机上,安装nginx,提供配置文件,但其中的worker_processores的值要与主机的cpu核心数相同;此时,就可以把配置文件基于模板方式提供,而这个worker_processores的值,放的就是jinja2所支持的变量,直接使用变量的方式放在那个位置,而本机的template模板会自动套用这里面变量的值,给ansible facts所报告的结果,并把它生成在这个文件中,而后复制到目标主机上去。这就是模板的作用。

               能够把里面嵌入的代码执行完以后,把执行后生成的结果放在代码所在处并且生成内容作为文本流输出给目标主机;

                

                    编辑epel源复制到远程主机:

                    ]# vim files/epel.repo

                        [epel]

                        name=fedora epel

                        baseurl=http://mirrors.aliyun.com/epel/$releasever/$basearch

                        enabled=1

                        gpgcheck=1

                        ]# ansible all -m copy -a "src=files/epel.repo dest=/etc/yum.repos.d" --check 如果有epel源,可省略此步骤;

                        ]# ansible all -m yum -a "name=nginx state=present" --check 测试安装

                        ]# ansible all -m yum -a "name=nginx state=present" 安装nginx

                        

                        ]# cp /etc/nginx/nginx.conf files/nginx.conf.j2

                        ]# vim files/nginx.conf.j2

                        修改:

                        worker_processes ` ansible_processor_vcpus `;

                        注意:template模板不能在命令行中使用,只能编写yaml文件;

                

                        ]# vim nginx.yaml

                            - hosts: websrvs

                              remote_user: root

                              tasks:

                            - name: install nginx

                              yum: name=nginx state=present

                            - name: install conf file

                              template: src=files/nginx.conf.j2 dest=/etc/nginx/nginx.conf

                              notify: restart nginx

                              tags: instconf

                            - name: start nginx service

                              service: name=nginx state=started

                            handlers:

                            - name: restart nginx

                              service: name=nginx state=restarted

                                

                            ansible-playbook --check nginx.yaml 测试执行

                            ]# ansible-playbook nginx.yaml 执行

                            可观察两台主机上的worker进程个数均为该主机的cpu核心数;即开启了2个worker进程;

                            

                            还可使用主机变量,让不同主机监听不同端口:

                            ]# vim files/nginx.conf.j2

                            修改:

                            listen ` http_port `; 调用主机变量


                            ]# vim /etc/ansible/hosts

                            [websrvs]

                            192.168.255.3 http_port=80 定义主机变量

                            192.168.255.4 http_port=8080

                            ]# ansible-playbook --check nginx.yaml 测试执行

                            ]# ansible-playbook nginx.yaml 执行

                            可在两台远程主机验证,一个监听在80端口,另一个监听在8080端口;

            

                

                        对变量还可使用算术运算:

                        例如:

                        ]# vim files/nginx.conf.j2

                        修改:

                        worker_processes ` ansible_processor_vcpus-1 `; 变量参与了算术运算

                        ]# ansible-playbook --check nginx.yaml 测试执行

                        ]# ansible-playbook nginx.yaml 执行

                        可在两台远程主机验证,worker进程个数均减少了1个;

                    

            

           18、playbook

               (1)核心元素

                Hosts:

                Tasks:任务

                Variables:变量;可调用ansible的变量或自定义的变量

                Templates:包含了模板语法的文本文件;提供配置文件的办法,可在文件中使用变量;该变量时与目标主机相关的值;

                Handlers:任务处理器,由特定条件触发的任务;本质还是tasks;

                

                Roles:就是由以上元素组成;把主机列表分出来,用到哪个主机时,就放在哪个主机上执行,这就是roles;

                其实还有users,指明在目标主机上,使用哪个用户的身份运行命令;不指明则默认为root,但是通常用sudo的方式进行指定,因此,必要时,要指明远程主机运行此任务的用户身份;

                playbook的主要作用:

                    就是能够把多个相关联的任务,通过读取YAML格式的配置文件一次编完;要把任务、变量、模板、处理器放在一个YAML格式文件中进行指定,然后任务就可一次批量执行;

                    

                    其他组件

                      ansible facts可使用stup模块获取;收集远程主机变量;

                      ansible-playbook -e "var=value"自定义变量

                      host variable:host iventory主机变量

                      group variable(主机组上的变量)

                            [groupname:vars]

                             var=value

                      roles

                      变量调用方法:` variable `

                (2)举例:playbook的基础组件hosts和tasks

                      vim first.yaml    

                    - hosts: all

                      remote_user: root

                      tasks:

                      - name: create a user3

                        user: name=user3 system=true uid=307

                      - name: create a user4

                        user: name=user4 system=true uid=308

                    在远程三台主机,以root身份执行2个任务,添加两个用户指定用户名、uid且为系统用户。

                    ansible-playbook --check first.yaml测试执行

                

[root@centos7 ~]# vim first.yaml

[root@centos7 ~]# ansible-playbook --check first.yaml 


PLAY [all] *********************************************************************


TASK [setup] *******************************************************************

ok: [172.20.53.21]

ok: [172.20.52.185]


TASK [create a user3] **********************************************************

changed: [172.20.53.21]

changed: [172.20.52.185]


TASK [create a user4] **********************************************************

changed: [172.20.53.21]

changed: [172.20.52.185]


PLAY RECAP *********************************************************************

172.20.52.185              : ok=3    changed=2    unreachable=0    failed=0   

172.20.53.21               : ok=3    changed=2    unreachable=0    failed=0   

    

PLAY RECAP 返回的报告

172.20.52.185 : ok=3 changed=2 unreachable=0 failed=0 表示3个任务ok,其中2个是修改以后

ok,unreachable表示联系不到执行不了, failed表示执行失败;

172.20.53.21 : ok=3 changed=2 unreachable=0 failed=0

                     

                    ansible-playbook --list-hosts first.yaml 查看这个playbook运行在哪些主机上;

                    ansible-playbook first.yaml 真正执行

                (3)playbook实际运用举例

                   mkdir working

                   cd working

                   mkdir files    

                   cp /etc/httpd/conf/httpd.conf  files/

                    vim files/httpd.conf

                        修改其中的Listen 8080

                    vim web.yaml

                    - hosts:websrvs

                      remote_user: root

                      tasks:

                      - name: install httpd package

                        yum: name=httpd state=present

                      - name: install configure file

                        copy:src= files/httpd.conf dest= /etc/httpd/conf

                      - name: start httpd service

                        service: name=httpd state=started

                      - name: execute ss command    

                        shell: ss-ntl|grep :8080     

                    

                     ansible all -m yum -a "name=httpd state=absent" 把所有主机的文本服务停掉;

                     ansible-playbook --check web.yaml 测试

                     ansible-playbook web.yaml 执行   

                     ansible websrvs -m shell -a "ss -tnl|grep 8080" 查看远程主机是否监听了8080端口;注意:在ansible中执行ss -tnl | grep :8080,这种查询是不显示结果的,所以,一般不在ansible里执行有关查询显示的命令;

                 (4)演示handlers,触发执行

                    如果把监听端改为808,再执行,则不会生效,因为,服务已经启动了,除非重启服务,这时,就应该用到handlers处理器;

                    vim web-2.yaml

                    - hosts:websrvs

                      remote_user: root

                      tasks:

                      - name: install httpd package

                        yum: name=httpd state=present

                      - name: install configure file

                        copy: src=files/httpd.conf dest=/etc/httpd/conf/

                        notify: restart httpd       ##定义触发,调用处理器的名字

                      - name: started httpd service

                        service: name=httpd state=started

                      handlers:   ## 触发后处理器执行的命令

                      - name: restart httpd   ##必须与notify调用名保持一致;

                        service: name=httpd state=restarted

                      vim files/httpd.conf(管理机)

                        Listen 808

                      ansible-playbook --check web-2.yaml 只有触发时,才执行handlers里面定义的命令;

                      ansible-playbook web-2.yaml 直接运行

                    

                 (5)演示tag,调取标签执行指定任务   

                    根据上例,如果仅修改了配置文件,却还要从第一步,执行安装程序包,这样是没必要的,所以,可使用tag,给任务加标签,不指定标签时,执行所有任务,加标签时,只执行标签所在的任务;

                    vim web-3.yaml

                    - hosts:websrvs

                      remote_user: root                   

                      tasks:

                      - name: install httpd package

                        yum: name=httpd state=present

                        tags: insthttpd 

                      - name: install configure file

                        copy: src=files/httpd.conf dest=/etc/httpd/conf/

                        tags: instconf

                        notify: restart httpd

                      - name: started httpd service

                        service: name=httpd state=started

                        tags: starthttpd

                      handlers:

                      - name: restart httpd

                        service: name=httpd state=restarted


                       vim files/httpd.conf

                       Listen 80

                       ansible-playbook  -t instconf --check web-3.yaml 指定执行标签上的任务.

                       ansible-playbook -t insthttpd --check web-3.yaml 则发现只运行了一个任务;

                       还可为让两个任务标签相同。添加后--- ansible-playbook -t insthttpd --check web-3.yaml 发现,会运行两个任务;这就叫标签;

                        ansible-playbook -t instconf,insthttpd --check web-3.yaml 调用多个标签;

                (6)演示在ansible-playbook命令行调用变量

                    vim forth.yaml

                    - hosts:websrvs

                      remote_user:root

                      tasks:

                      - name: install ` pkname `必须使用双花括号,调用变量

                        yum: name=` pkname ` state=present

                    举例1:ansible-playbook -e pkname=memcached forth.yaml安装memcached,用变量传递。

                    举例2:

                         vim /etc/ansible/hosts

                         [websrvs]

                         172.20.52.185 hname=www1

                         172.20.53.21  hname=www2

                        

                         vim hostname.yaml

                         - hosts:websrvs

                           remote_user:root

                           tasks:

                           - name: set hostname

                             hostname: name=` hname `

                       ansible-playbook --check hostname.yaml 测试执行; 

                    举例3:向主机组中的主机传递相同的变量    

                          

                            [websrvs]

                            172.20.52.185 hname=baby1

                            172.20.53.21  hname=baby2



                             [websrvs:vars]

                             http_port=8080

                             [dbsrvs]

                             172.20.53.21



                  

                variables:变量

                    (1)facts:任何facts变量都由正在通信的目标主机发回的信息,ansible自动获取变量,可直接调用;在setup模块

中查看变量;

                    (2)ansible-playbook命令的命令行中的自定义变量;

                        -e VARS, --extra-vars=VARS

                    (3)通过roles传递变量;

                    (4)Host Inventory

                        (a)向不同的主机传递不同的变量;

                            IP/HOSTNAME varailble=value var2=value2

                        (b)向组中的主机传递相同的变量;

                            [groupname:vars]

                            variable=value

                            注意:invertory参数:

                            用于定义ansible远程路径目标主机时使用的参数,而非传递给playbook的变量;

                            ansible_ssh_host

                            ansible_ssh_port

                            ansible_ssh_user

                            ansible_ssh_pass

                            ansible_sudo_pass

                            ...

                            通常ansible中的inventory还有专门参数,不叫变量,因为它不是传递给playbook使用的,而是通过ansible连接每个被管理主机时使用的;

                        例如:

                        连接远程主机时,如果不使用密钥方式,需要输入账号、密码;还可编辑hosts文件:

]# vim /etc/ansible/hosts

[dbsrvs]

192.168.255.4

192.168.255.60 ansible_ssh_user=root ansible_ssh_pass=root

可以在模板中调用变量,为不同的主机生成不同的配置,虽然看上去是同一个配置文件,不同主机拿到的配置文件可以不一样;