笔记--ansible

        -----ansible-----
            查看帮助文档:

                ansible-doc -l 列出模块
                ansible-doc  file    #详细
                ansible-doc -s file #简略

            调试:
                检测语法    ansible-playbook --syntax-check rsync.yml
                模拟执行    ansible-playbook -C rsync.yml


            解决环境变量:
                ansible cs1 -m shell -a "source /etc/profile && java -version"
                错误:
                    /usr/lib/python2.7/site-packages/pywin32.pth
                    /usr/lib64/python2.7/site-packages/pywin32.pth
                    
            解决子shell:
                ansible 172.17.1.66 -m shell -a "source /etc/profile &>/dev/null;set -m;cd /home/tomcat && find -name startup.sh|xargs -i nohup bash {} &"
                    set指令能设置所使用shell的执行方式,-m  使用监视模式。

            多引号嵌套:
                ansible 172.17.1.1 -m cron -a "name='rm_access.log' minute=0 hour=0 job='"'if [ $(ls -l /usr/local/nginx/logs/access.log|awk "{print $5}") -gt 20000000000 ];then cat /usr/local/nginx/logs/access.log >/home/nginx_access.log && >/usr/local/nginx/logs/access.log true;fi'"' "
                或者:
                ansible 172.17.1.1 -m cron -a 'name="rm_access.log" minute=0 hour=0 job="if [ $(ls -l /usr/local/nginx/logs/access.log|awk \"{print $5}\") -gt 20000000000 ];then cat /usr/local/nginx/logs/access.log >/home/nginx_access.log && >/usr/local/nginx/logs/access.log true;fi"'

            切换用户:
                ansible oracle -SR oracle -m shell -a 'pwd' #-S sudo -R 制定sudo用户
                
            模块:
                setup模块:
                    格式:
                        ansible nginx -m setup -a 'filter=ansible_hostname'
                        ansible nginx -m setup -a 'filter=ansible_*ipv4*'    #通配符匹配
                    常用fact变量:
                        ansible_all_ipv4_addresses # ipv4的所有地址
                        ansible_default_ipv4 # 默认的ipv4地址
                        ansible_hostname #系统的主机名
                        ansible_env #系统的环境变量
                
                cron模块:
                    ansible test -m cron -a "name='ntpdate' minute=1 hour=1 day=*/3 job='ntpdate 172.17.1.1' "        --每3天的1点1分
                    ansible test -m cron -a "name='ntpdate' state=absent"            --取消任务
                    
                file模块:
                    ansible test -m file -a 'path=/etc/CentOS7.repo state=absent'    --删除文件
                    ansible ansible-demo3 -m file -a "path=/testdir/linkfile1 state=link src=/testdir/testfile1"
                    
                copy模块:
                    ansible all -m copy -a 'src=/usr/bin/history dest=/usr/bin/ mode=777'
                    

                fetch   

                   Fetch files from remote nodes(会根据ip保存文件夹,并保持目录结构)
                   ]# ansible node01,node02 -m fetch -a 'src=/etc/hosts dest=/tmp'


                template:
                    ]# cat test_template.yml
                    ---
                    - hosts: node01
                      #gather_facts: no
                      vars:
                        teststr: 'redhat'
                        testnum: 18
                        testlist: ['aA','bB','cC']
                        testlist1:
                        - AA
                        - BB
                        - CC
                        testdic:
                          name: pp
                          age: 22
                        tpath: "{ { tpath }}"
                      tasks:
                      - template:
                          src: /root/jinja2/test.j2
                          dest: /opt/test

                    ]# cat /root/jinja2/test.j2
                    { { teststr }}
                    { { testnum }}
                    { { testlist[1] }}
                    { { testlist1[1] }}
                    { { testdic['name'] }}
                    ip: { { ansible_default_ipv4.address }}
                    dir: { { tpath }}

                    ]# cat /opt/test
                    redhat
                    18
                    bB
                    BB
                    pp
                    ip: 192.168.80.172
                    dir: /root/test

                lineinfile:
                    常用选项:
                        regexp: "^DefaultLimitNOFILE.*"    #正则匹配
                        insertafter: xxx    #在匹配到的行前插入
                        insertbefore: xxx    #在匹配到的行后插入
                        line: dest_str                        #要替换为的目标字符串
                        backrefs参数:
                            1    默认情况下,当根据正则替换文本时,即使regexp参数中的正则存在分组,在line参数中也不能对正则中的分组进行引用,除非将backrefs参数的值设置为yes。backrefs=yes表示开启后向引用,这样,line参数中就能对regexp参数中的分组进行后向引用了
                            2    backrefs=yes除了能够开启后向引用功能,还有另一个作用,默认情况下,当使用正则表达式替换对应行时,如果正则没有匹配到任何的行,那么line对应的内容会被插入到文本的末尾,不过,如果使用了backrefs=yes,情况就不一样了,当使用正则表达式替换对应行时,同时设置了backrefs=yes,那么当正则没有匹配到任何的行时,则不会对文件进行任何操作,相当于保持原文件不变。
                            3    backrefs=yes,会忽略insertafter和insertbefore参数
                        backup参数:是否在修改文件之前对文件进行备份。
                        create参数 :当要操作的文件并不存在时,是否创建对应的文件。
                        注意:此模块只替换最后一次匹配,多行匹配进行替换需要使用replace模块
                    例:
                        - hosts: "{ {host}}"
                          gather_facts: no
                          tasks:
                          - name: modify DefaultLimitNOFILE
                            lineinfile:
                              dest: /etc/systemd/system.conf
                              regexp: "^DefaultLimitNOFILE.*"
                              line: DefaultLimitNOFILE=100000
                          - name: modify DefaultLimitNPROC
                            lineinfile:
                              dest: /etc/systemd/system.conf
                              regexp: "^DefaultLimitNPROC.*"
                              line: DefaultLimitNPROC=65535
                          - name: daemon-reexec
                            shell: systemctl daemon-reexec
                        例2:删除
                            ....
                          lineinfile:
                            path: /etc/sudoers
                            state: absent
                            regexp: '^%wheel'

                replace:
                    path参数:必须参数,指定要操作的文件
                    regexp参数:必须参数,指定一个python正则表达式,文件中与正则匹配的字符串将会被替换。
                    replace参数:指定最终要替换成的字符串。
                    backup参数:是否在修改文件之前对文件进行备份,最好设置为yes
                    ansible 172.19.2.74 -m replace -a 'path=/root/system.conf regexp="^#(.*)" replace="\1" backup=yes'

                user模块:
                    user: name=deploy password='$1$kRvBETZa$evc2YK9qSshy2dZvrng4c.' update_password=on_create uid=1025
                        password    参数用于指定用户密码,但是这个密码不能是明文密码,而是一个对明文密码加密后的字符串,默认为空
                            openssl passwd -1 '123456'
                            openssl passwd -1 -salt 'abcdefg' '123456'
                        update_password    参数可选值有always 和 on_create,默认为always 。 当设置为always时,password参数的值与 /etc/shadow 中密码字符串不一致时更新用户的密码; 当设置为on_create时,password参数的值与 /etc/shadow 中密码字符串不一致时也不会更新用户的密码,但如果是新创建的用户,则此参数即使为on_create,也会更新用户密码。

                debug:
                    - name: uid重复检测
                      shell: "awk -F: '{print $3}' /etc/passwd|sort|uniq -c|grep -Ev '^\s+1'||echo ok"
                      register: uid
                    - debug: var=uid.stdout_lines

               expect:
                   #ansible-doc expect

            --history    
                查看硬盘空间:
                    ansible all -m shell -a "df -h|grep -v Filesystem|awk -F'[ %]+' '{if(\$5>=80){print \$5\"%\",\$6}}'"
                    删除上下行都为空的行
                    ^$\r?\n.+\r?\n^$    
                    
                    ansible all -m shell -a "df -h|awk -F'[ T]+' '{if(\$2 ~ /^[0-9]+$/ && \$2>10 || NR==1){print \$0}}'"
                启动kibana:
                    ansible es -m shell -a  "su - elastic -c 'nohup kibana-5.6.11-linux-x86_64/bin/kibana &>kibana-5.6.11-linux-x86_64/kibana.log &'"
                切换用户执行
                    ansible testn -m shell -a "su - postgres -c 'pg_ctl status'"        
                
        -----Inventory----------
            逻辑运算:
                与:
                    ansible zk:\&cs1 -m ping
                或:
                    ansible 192.168.104.1:192.168.104.8 -m ping
                    或者:ansible 192.168.104.4,192.168.104.8 -m ping
                排除主机:
                    ansible testn:\!172.17.16.81 -m copy -a "src=dbsync dest=/home/postgres/"
                    playbook中:- hosts: all:!192.168.100.102            
            通配:
                ansible-playbook ntp.yml -e 'host=172.17.17.8*'
            正则:
                ansible '~(cs1|cs2)_hadoop' -m ping
            多主机+通配+排除:
                ansible cs1,cs2,cs3:\!hadoop* -m shell -a 'hostname'
            分组:
                [abc:children]    #:children 固定写法
                g1
                g2
                g3

                [g1]
                172.17.1.6
                [g2]
                172.17.1.8
                [g3]
                172.17.1.5
                使用:
                    ansible abc -m ping    #所有dbc
                    ansible abc:\!g1 -m ping    #所有dbc(除cho外)
                    ansible g1:g2 -m ping    #调用两个主机组

            注意:
                分组组名中不能包含'-'
                
            密码:
                1, 方式1,直接跟在主机后面
                    [temp]
                    172.17.1.8 ansible_ssh_pass='password'
                2,方式2,定义分组变量
                    [temp]
                    172.17.1.7
                    172.17.1.8
                    [temp:vars]
                    ansible_ssh_pass='password'
                其他常用变量:
                    ansible_ssh_host     #用于指定被管理的主机的真实IP
                    ansible_ssh_port     #用于指定连接到被管理主机的ssh端口号,默认是22
                    ansible_ssh_user     #ssh连接时默认使用的用户名
                    ansible_ssh_pass     #ssh连接时的密码

            --become
                /etc/ansible/hosts
                    [all:vars]
                    ansible_ssh_user=test01
                    ansible_ssh_pass=test123
                    ansible_ssh_port=22
                    ansible_become=true
                    ansible_become_user=root
                    ansible_become_method='su'
                    ansible_become_pass=root123

                    ansible_become_flags='-lc'

 

        ----------playbook------------

            参数

                -v   显示详细信息,也可以用-vv  
                -i    可以在test.yml中指定hosts,在-i 指定hosts文件中配置,两者取交集
                    ansible-playbook test.yml -i hosts

            常用指令:
                gather_facts: no             禁止收集主机信息:
                any_errors_fatal: no         强制任何主机上的任何未处理任务错误传播到所有主机并结束播放。
                ignore_errors: yes            布尔值,允许您忽略任务失败并继续执行。它不会影响连接错误(可放在tasks中)
                remote_user: root            使用的远程用户
                vars:                                变量,值使用列表
                vars_files:                        变量文件,值使用列表
            变量设置:
                方式1:
                    剧本中编写:
                    vars:
                      var_name01: value01
                      var_name02: value02
                方式2:
                    命令行指定: -e 'var=value'
                方式3:
                    主机清单中
                    [web:vars]
                    var_name01=value01
                    var_name02= value02
                优先级:命令行 > 剧本 > 主机清单
            变量注册:
                - shell: ss -tnlp    #常用shell输出注册
                  register: listen_port    #注册变量
                - debug: msg={ { listen_port.stdout_lines }} #显示变量,listen_port是一个字典,stdout_lines是其字段,也可以用listen_port["stdout_lines"]
                也可用debug注册:
                  - debug:
                      msg:
                      - "{ { inventory_hostname }}"
                      - "{ { ansible_default_ipv4.gateway }}"
                    register: res
                  - debug:
                      var: res.msg
            变量引用:
                { { var_name }}            
            debug:(可以输出调试信息msg/var,根据设置输出级别- verbosity)
                ansible-doc debug:
                    - msg
                            The customized message that is printed. If omitted, prints a generic message.
                            [Default: Hello world!]
                            type: str

                    - var
                            A variable name to debug.
                            Mutually exclusive with the `msg' option.
                            Be aware that this option already runs in Jinja2 context and has an implicit `{ { }}' wrapping, so you should not be
                            using Jinja2 delimiters unless you are looking for double interpolation.
                            [Default: (null)]
                            type: str

                    - verbosity #debug的级别(默认是0级,全部显示)
                            A number that controls when the debug is run, if you set to 3 it will only run debug when -vvv or above
                            [Default: 0]
                            type: int
                            version_added: 2.1
                官方示例:
                    # Example that prints the loopback address and gateway for each host
                    - debug:
                        msg: System { { inventory_hostname }} has uuid { { ansible_product_uuid }}

                    - debug:
                        msg: System { { inventory_hostname }} has gateway { { ansible_default_ipv4.gateway }}
                      when: ansible_default_ipv4.gateway is defined

                    # Example that prints return information from the previous task
                    - shell: /usr/bin/uptime
                      register: result

                    - debug:
                        var: result
                        verbosity: 2        #-vv 才会显示

                    - name: Display all variables/facts known for a host
                      debug:
                        var: hostvars[inventory_hostname]
                        verbosity: 4

                    # Example that prints two lines of messages, but only if there is an environment value set
                    - debug:
                        msg:
                        - "Provisioning based on YOUR_KEY which is: { { lookup('env', 'YOUR_KEY') }}"
                        - "These servers were built using the password of '{ { password_used }}'. Please retain this for later use."


                #打印自定义的信息(调用facts)
                - debug: msg="System { { inventory_hostname }} has uuid { { ansible_product_uuid }}"
                # 显示已注册的信息
                - debug: msg={ { register_var.stdout_lines }} #stdout_lines显示列表格式信息,字符串格式可以使用stdout
            判断:
                基本示例:
                    - hosts: all
                      tasks:
                      - name: "IP if"
                        debug: msg={ {ansible_default_ipv4.address}}
                        when: ansible_default_ipv4.address == '192.168.80.172' or not ansible_default_ipv4.address == '192.168.80.173' 
                        #变量不用{ {}}
                        #等值判断用‘==’,逻辑关键词使用'or','and','not',改变优先级使用小括号()
                        #多个and可以使用列表'-'
                正则匹配:
                    - hosts: node01
                      vars:
                        url: "http://example.com/users/foo/resources/bar"

                      tasks:
                          - debug: "msg='matched pattern 1'"
                            when: url is match("http://example.com/users/.*/resources/.*")    #正则判断    

                          - debug: "msg='matched pattern 2'"
                            when: url is search("/users/.*/resources/.*")    #正则判断

                          - debug: "msg='matched pattern 3'"
                            when: url is search("/users/")    #正则判断    其他类似函数还有,version/subset等,以及文件(directory,file,link,exists)或任务(failed,changed,succeeded,skipped)测试关键字

                          - debug: msg={ { url | regex_search("/users/.*/resources/.*") }}    #jinja2模板正则过滤器,输出正则匹配的结果,类似还有regex_findall,regex_replace
            循环:
                循环列表:
                    - name: install package
                      yum: name={ { item }} state=present
                      with_items:
                        - wget
                        - tree
                        - lrzsz
                    建议使用另一种格式:
                        - name: install package
                          yum:
                            name: ['wget','tree','lrzsz']
                            state: present
                循环字典:
                    - name: copy file
                      copy: src=/etc/ansible/server_file/rsync_server/{ { item.src }} dest={ { item.dest }} mode={ { item.mode }}
                      with_items:
                        - { src: 'rsyncd.conf', dest: '/etc/', mode: '644' }
                        - { src: 'rsync.password', dest: '/etc/', mode: '600' }
            标签:
                定义:
                    tasks:
                      - name: xxx
                        ...
                        tag: test_tag
                使用:
                    执行标签任务:ansible-playbook --tags=test_tag xxx.yml
                    跳过标签任务:ansible-playbook --skip-tags=test_tag xxx.yml
            触发(handlers):
                例:
                - hosts: xxx
                  tasks:
                    ...
                    - name: push config file
                      copy: src=... desc=...
                      notify: restart xxx server
                    ...
                    
                  handlers:
                    - name: restart xxx server
                      service: name=xxx state=restarted
                      
            整合: import_playbook
                cat main.yml
                - import_playbook: base.yml
                - import_playbook: xxx.yml
                ...
                      
        roles:
            目录结构:
                ├── site.yml        #总配置
                ├── test
                │   ├── files
                │   ├── handlers
                │   ├── tasks
                │   │   └── main.yml
                │   ├── templates
                │   │   └── main.yml
                │   └── vars
                │       └── main.yml
                └── test02
                ]# cat site.yml
                - hosts: node02
                  roles:
                    - test
            
            tags
                - hosts: sqlserver
                  remote_user: root
                  tasks:
                   - name: build a new file
                     copy: content="this is a test" dest=/root/test1.txt
                     tags:
                      - only
                   - name: bulid another file
                     ...
                     
                只执行某tag的任务:
                    ansible-playbook a.yml --tags="only"
                
            给yml传递变量:--extra-var 或 -e
                ansible-playbook   $PWD/yml/zabbix_agent_install.yml --extra-var "foo=$zabbix_server_ip host=$group"
                    playbook内引用:
                        "{ { foo }}"
                        "{ { host }}"
              
                
            ------返回信息、引用facts:
                - hosts: "{ { host }}"
                  #gather_facts: F  #F为禁用收集,默认为True
                  tasks:
                        - name: is_pm
                          shell: "dmidecode |grep -A4 'System Information'|awk -F: '(NR==2){if($2 ~ \".*Xen.*\"){print \"虚拟机\"}else{print \"物理机\"}}'"
                          register: is_pm_out
                        - name: show
                          #debug: var=is_pm_out verbosity=0
                          debug: var=is_pm_out.stdout verbosity=0 #verbosity 显示信息多少,大于等于3为详细信息
                        # 多种引用方式:
                        - debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']
                        - debug: var=ansible_default_ipv4.address
                        - debug: msg="ip_addr:{ {ansible_default_ipv4.address}}"
                        
            ------jianjia模板的循环语句,及使用debug注册变量
                dns_var.yml内容(字典+列表):
                    ---
                    zone_dns:
                      cs1:
                      - 172.19.2.13
                      cs2:
                      - 172.19.2.12
                      cs3:
                      - 172.17.16.69
                      iv2:
                      - 172.19.2.68
                      - 172.19.2.69
                  
                ---
                - hosts: "{ { host }}"
                  vars_files:
                    - dns_var.yml    #引用变量文件
                  tasks:
                  - name: has 10 net
                    shell: ifconfig|grep 'inet 10\.'
                    register: net_10        #shell对象有stdout方法
                    ignore_errors: yes
                #  - debug: msg="{ { net_10.stdout }}"
                  - name: display
                    debug: msg="{% for i in zone_dns[zone] %}nameserver { { i }}\n{% endfor %}"
                    register: dns_str        #debug也可注册变量
                #  - debug: msg="{ { zone_dns[zone][0] }}"  #引用列表
                  - name: set small dns
                    shell: grep "{ { zone_dns[zone][0] }}" /etc/resolv.conf || echo -e "{ { dns_str['msg'] }}" >>/etc/resolv.conf        #引用debug注册的变量使用字典
                    when: net_10.stdout == ''
                  - name: set big  dns
                    shell: grep '^nameserver 8.8.8.8' /etc/resolv.conf || echo 'nameserver 8.8.8.8' >>/etc/resolv.conf
                    when: net_10.stdout != ''
  
 

猜你喜欢

转载自blog.csdn.net/weixin_42573277/article/details/114182551