zoukankan      html  css  js  c++  java
  • ansible混合知识点 一介凡人

    一、ansible的特性

    1、Ansible是一个基于Python开发的配置管理和应用部署工具;

    2、它基于模块化工作;

    3、无Agent的存在,并非CIS软件,也只需在某个作为控制节点的主机上安装一次Ansible即可,通常它基于ssh连接来控制远程主机,远程主机上不需要安装Ansible或其它额外的服务。

    4、Ansible的绝大多数模块都具备幂等性(idempotence)。
          所谓幂等性,指的是多次操作或多次执行不影响结果

    5、Ansible吸引人的地方在于它提供的playbook能批量整合不同主机上执行的不同任务,同时还提供一些额外的机制让用户可以去协调这些任务的执行策略。

    二、ansible的配置文件

    Ansible依赖于SSH协议(默认),对于RHEL系列的系统来说,配置好epel镜像即可安装最新版的Ansible。

    $ cat >>/etc/yum.repos.dlepel.repo<<'EOF'
    [epel]
    name=epel repo
    baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch
    enabled=1
    gpgcheck=O
    EOF

    查看配置文件

    rpm -qc  ansible
    /etc/ansible/ansible.cfg
    /etc/ansible/hosts

    ansible参数补全功能

    ansible 2.9版本开始,它支持命令的选项补全功能,它依赖于python的argcomplete插件。

    1)安装argcomplete:

    # yum -y install python-argcomplete
    #或者任何系统都可以使用pip工具安装argcomplete,如下
    # pip3 install argcomplete
    

    2)安装完成后,还需要激活该插件

    bash -version     #要求bash版本大于或等于'4.2'
    GNU bash, 版本 4.2.46(2)-release (x86_64-redhat-linux-gnu)
    
    activate-global-python-argcomplete   #激活插件

    3) 重新进入bash环境测试是否可用

    # bash
    # ansible --syntax-check      #只需要输入ansible --syn 即可补全
    

    什么是ansible的ad-hoc命令

     

    ad-hoc命令是指使用 /usr/bin/ansible  命令行工具在一个或多个管理节点上执行单个任务的命令。

    这其实是一个概念性的名字,是相对于 Ansible playbook 来说的。当我们需要快速的完成一些任务而不需要将执行的命令保存下来,这样的命令就称为ad-hoc命令。

    命令结构

    ansible  [pattern]  -m  [module]   -a  "[module options]"
    

    ansible:命令主体

    pattern:指定该命令要在哪些管理节点或者哪组管理节点上执行,比如例子中的devops主机组。

    -m [module]:指定该命令要执行哪个模块

    -a [module options]:指定该模块执行时所需要的选项

    配置ansible 的ssh免密登录

    1、在control_node节点上生成密钥对:

    ssh-keygen -t rsa -b 4096
    
    ##当远程服务器默认的ssh 端口被更改
    ssh-copy-id -p 28 root@192.168.40.132
    
    
    在 /root/.ssh中添加ssh config
    cat config 
    Host node3
            HostName 192.168.40.135
            Port 28
            User root
            ServerAliveInterval 60
            IdentityFile ~/.ssh/id_rsa
    Host node2
            HostName 192.168.40.134
            Port 28
            User root
            ServerAliveInterval 60
            IdentityFile ~/.ssh/id_rsa
    Host master
            HostName 192.168.40.132
            Port 28
            User root
            ServerAliveInterval 60
            IdentityFile ~/.ssh/id_rsa
    
    或者修改ansible.cfg
    remote_port   =  28

    ###⒉、将各节点的主机信息(host key)写入control_node的~/.ssh/known_hosts文件:

    for host in 192.168.200.{27..33} node{1..7};
    do
    ssh-keyscan $host >>~/.ssh/known_hosts 2>/dev/null
    done

    # sshpass -p选项指定的是密码

    sshpass 命令的安装:

    # yum -y install sshpass

    ####3.将control_node上的ssh公钥分发给各节点:

    for host in 192.168.200.{27..33} node{1..7};
    do
    sshpass -p'123456' ssh-copy-id root@$host &>/dev/null
    done

    有时候为了方便快速寻找模块,可以使用ansible-doc  -l  |  grep 'xxx’ 命令来筛选模块。

    ansible-doc  -l  |  grep copy

    ansible-doc -s copy
    ansible-doc   copy

    ansible读取配置文件的顺序

    通过操作系统自带的包管理器安装的Ansible一般都会提供Ansible的配置文件/etc/ansible/ansible.cfg。
    这是Ansible默认的全局配置文件。

    实际上,Ansible支持4种方式指定配置文件,它们的读取顺序从高到低:
    (1)、ansible_config:首先,Ansible命令会检查环境变量,及这个环境变量将指向的配置文件

    (2)、.ansible.cfg:当前目录下的ansible.cfg

    (3)、~/.ansible.cfg:家目录下的ansible.cfg

    (4)、/etc/ansible/ansible.cfg:默认的全局配置文件
    Ansible配置文件采用 ini 风格进行配置,每一项配置都使用key=value的方式进行配置。

    三、定制演员表,即inventory主机清单

    1.1 inventory文件路径

    默认的inventory文件是/etcl/ansible/hosts,可以通过Ansible配置文件的inventory 配置指令去修改路径。

    $ grep '/etc/ansible/hosts' letclansible/ansible.cfg
    #inventory = /etc/ansible/hosts

    但通常我们不会去修改这个配置项,如果在其它地方定义了inventory文件,可以直接在ansible的命令行中使用 -i 选项去指定我们自定义的inventory文件。

    $ ansible -i /tmp/myinv.ini ...
    $ ansible-playbook -i /tmp/myinv.ini ...
    

    1.2 配置inventory
    Ansible inventory文件的书写格式遵循 ini 配置格式。从Ansible 2.4开始支持其它格式,比如yaml格式的inventory。此处以ini格式为例,循序渐进地介绍inventory的规则。假设所有的规则都定义在/etc/ansible/hosts文件中。
    1.2.1 一行一主机的定义方式
    Ansible默认是基于ssh连接的,所以一般情况下inventory中的每个目标节点都配置主机名或IP地址、sshd监听的端口号、连接的用户名和密码、ssh连接时的参数等等。当然,很多参数有默认值,所以最简单的是直接指定主机名或IP地址即可。
    例如,在默认的inventory文件/etc/ansible/hosts添加几个目标主机:

    node1
    node2 ansible_host=192.168.200.28192.168.200.31
    192.168.200.32:22
    192.168.200.3[2:3] ansible_port=22
    

    上面的inventory配置中:
    (1).第一行通过主机名定义,在ansible连接该节点时会进行主机名DNS解析
    (2).第二行也是通过主机名定义,但是使用了一个主机变量ansible_host=IP,此时Ansible去连接该主机时将直接通过IP地址进行连接,而不会进行DNS解析,所以此时的node2相当于是主机别名,它可以命名为任何其它名称,如node_2
    (3).第三行通过IP地址定义主机节点
    (4).第四行定义时还指定了端口号
    (5).最后一行通过范围的方式展开成了两个主机节点192.168.200.32和192.168.200.33,同时还定义了这两个节点的主机变量ansible_port=22表示连接这两个节点时的端口号为22
    范围展开的方式还支持字母范围。下面都是有效的:

    • Ansible 可同时操作属于一个组的多台主机,组和主机之间的关系通过 inventory 文件配置. 默认的文件路径为 /etc/ansible/hosts
    • /etc/ansible/hosts 例子
    • mail.example.com
      [webservers]
      foo.example.com
      bar.example.com
      [dbservers]
      one.example.com
      two.example.com
      three.example.com
      • [ ] 内为组名,用于对系统进行分类
      • 一台服务器可以同时属于不同组
      • 如果有主机的SSH端口不是标准的22端口,可在主机名之后加上端口号,用冒号分隔

    四、ansible的剧本元素

    1、role角色:Ansible-role-组团学 (zutuanxue.com)

    role是task文件、变量文件、handlers文件的集合体,这个集合体的显著特点是:可移植性和可重复执行性。

    通常文件如下,不一定必须都要有

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

    实践中,通常我们以部署某个服务为单元作为一个role ,然后将这些服务单元(role)放在一个roles目录下。

    主playbook文件通过调用roles目录下的role,来实现各种灵活多变的部署需求。

    tree roles/consul                                                                 
    roles/consul
    ├── tasks
    │   ├── actions
    │   │   ├── consul_core.yml.back
    │   │   ├── start_consul_agent.yml
    │   │   ├── start_registrator.yml
    │   │   ├── stop_consul_agent.yml
    │   │   └── stop_registrator.yml
    │   └── main.yml
    └── templates
        └── consul_server

    五、ansible的优化

    1、关闭gathering facts功能

    gather_facts: False
    

    2、开启SSH pipelining

    pipeline是openssh的一个特性,ssh pipelining 是一个加速Ansible执行速度的简单方法。

    在ansible执行每个任务的整个流程中,有一个过程是将临时任务文件put到远程的ansible客户机上,然后通过ssh连接过去远程执行这个任务。如果开启了pipelining,一个任务的所有动作都在一个ssh会话中完成,也会省去sftp到远端的过程,它会直接将要执行的任务在ssh会话中进行。ssh pipelining 默认是关闭!!!!之所以默认关闭是为了兼容不同的sudo配置,主要是 requiretty 选项。如果不使用sudo,建议开启!!!
    打开此选项可以减少ansible执行没有传输时ssh在被控机器上执行任务的连接数。
    不过,如果使用sudo,必须关闭requiretty选项。修改/etc/ansible/ansible.cfg 文件可以开启pipelining

    $ vim /etc/ansible/ansible.cfg
    ........
    pipelining = True
    

    但是要注意的是:
    如果在ansible中使用sudo命令的话(ssh user@host sudo cmd),需要在被控节点的/etc/sudoers中禁用"requiretty"!!!!

    之所以要设置/etc/sudoers中的requiretty,是因为ssh远程执行命令时,它的环境是非登录式非交互式shell,默认不会分配tty,没有ttysshsudo就无法关闭密码回显(使用
    "-tt"选项强制SSH分配tty)。所以出于安全考虑,/etc/sudoers中默认是开启requiretty的,它要求只有拥有tty的用户才能使用sudo,也就是说ssh连接过去不允许执行sudo
    可以通过visudo编辑配置文件,注释该选项来禁用它。

    $ grep requiretty /etc/sudoers  
    # Defaults  requiretty
    

    3、开启SSH长连接

    ansible天然支持openssh,默认连接方式下,它对ssh的依赖性非常强。所以优化ssh连接,在一定程度上也在优化ansible。其中一点是开启ssh的长连接,即长时间保持连接状态。Ansible模式是使用SSH和远程主机进行通信, 所以Ansible对SSH的依赖性非常强, 在OpenSSH 5.6版本以后SSH就支持了Multiplexing(多路复用)。所以如果Ansible中控机的SSH -V版本高于5.6时, 就可以使用ControlPersist来提高ssh连接速度,从而提高ansible执行效率。

    $ ssh -V
    OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
    
    $ vim /etc/ansible/ansible.cfg
    ..........
    ssh_args = -C -o ControlMaster=auto -o ControlPersist=5d
    # 注意:ConrolPersist=5d, 这个参数是设置整个长连接保持时间为5天。
    

    开启此参数的ssh长连接功能后,在会话过期前会一直建立连接,在netstat的结果中会看到ssh连接是一直established状态,且通过SSH连接过的设备都会在当前用户家目录的
    ".ansible/cp"目录下生成一个socket文件,每个会话对应生成一个socket文件。也可以通过netstat命令查看, 会发现有一个ESTABLISHED状态的连接一直与远程设备进行着TCP连接。

    $ ps -ef|grep ssh|grep ansible
    root      26064      1  0 17:32 ?        00:00:00 ssh: /root/.ansible/cp/cb9972d2a5 [mux]
    root      26067      1  0 17:32 ?        00:00:00 ssh: /root/.ansible/cp/baefa88ac8 [mux]
    
    $ ps -ef|grep ssh|grep /root
    root      26064      1  0 17:32 ?        00:00:00 ssh: /root/.ansible/cp/cb9972d2a5 [mux]
    root      26067      1  0 17:32 ?        00:00:00 ssh: /root/.ansible/cp/baefa88ac8 [mux]
    
    $ ls /root/.ansible/cp/
    baefa88ac8  cb9972d2a5
    

    ControlPersist即持久化socket,一次验证,多次通信。并且只需要修改 ssh 客户端就行,也就是 Ansible 机器即可。

    4、设置facts缓存

    使用json文件缓存

    $ vim /etc/ansible/ansible.cfg
    .........
    gathering = smart
    fact_caching_timeout = 86400
    fact_caching = jsonfile
    fact_caching_connection = /dev/shm/ansible_fact_cache
    
    # 正常配置palybook,不需要关闭gathering facts功能
    $ cat test.yml 
    ---
    - hosts: 10.4.7.101
      remote_user: root
      vars:
        - list: [1,2,3]
      tasks:
        - name: this is loop
          debug: msg="{{ item }}"
          with_items: '{{list}}'
    
    查看这个playbook过程,用时6.699s(第一次可能稍微慢点,缓存之后,后面执行就很快了)
    $ time ansible-playbook test.yml 
    
    PLAY [10.4.7.101] *******************************************************************************************************************************
    
    TASK [Gathering Facts] **************************************************************************************************************************
    ok: [10.4.7.101]
    
    TASK [this is loop] *****************************************************************************************************************************
    ok: [10.4.7.101] => (item=1) => {
        "msg": 1
    }
    ok: [10.4.7.101] => (item=2) => {
        "msg": 2
    }
    ok: [10.4.7.101] => (item=3) => {
        "msg": 3
    }
    
    PLAY RECAP **************************************************************************************************************************************
    10.4.7.101                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    
    
    real	0m6.699s
    user	0m1.301s
    sys     0m0.250s
    
    # 如果去掉上面的facts缓存的四行配置,再次执行上面的playbok,发现用时10s左右!!!
    
    # 查看缓存文件
    $ ls /dev/shm/ansible_fact_cache/
    10.4.7.101
    

    使用redis存储facts文件需安装redis,还需要安装python库

    $ yum install redis
    $ yum -y install epel-release
    $ yum install python-pip
    $ pip install redis
    $ vim /etc/ansible/ansible.cfg
    ........
    gathering = smart
    facts_caching_timeout = 86400      #设置缓存过期时间86400秒
    facts_caching = redis              # 使用redis或者 (或者使用memcached,即"facts_caching = memcached")
    fact_caching_connection = 127.0.0.1:6379
    #若redis设置了密码,比如密码为"admin",则配置修改如下:
    # fact_caching_connection = localhost:6379:0:admin
    
    $ systemctl start redis
    $ lsof -i:6379
    COMMAND     PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    redis-ser 26593 redis    4u  IPv4 125427      0t0  TCP localhost:6379 (LISTEN)
    
    $ time ansible-playbook test.yml 
    
    PLAY [10.4.7.101] *******************************************************************************************************************************
    
    TASK [Gathering Facts] **************************************************************************************************************************
    ok: [10.4.7.101]
    
    TASK [this is loop] *****************************************************************************************************************************
    ok: [10.4.7.101] => (item=1) => {
        "msg": 1
    }
    ok: [10.4.7.101] => (item=2) => {
        "msg": 2
    }
    ok: [10.4.7.101] => (item=3) => {
        "msg": 3
    }
    
    PLAY RECAP **************************************************************************************************************************************
    10.4.7.101                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    
    
    real	0m6.720s
    user	0m1.219s
    sys	    0m0.338s
    
    需要注意:
    在使用redis缓存后,如果出现异常(若未出现,请忽略):TypeError: the JSON object must be str, not 'bytes'。
    解决办法:
    $ find / -name ansible
    $ vim /usr/lib/python2.7/site-packages/ansible/plugins/cache/redis.py
    ..........
    self._cache[key] = json.loads(value.decode('utf-8'))     # 修改为这个
        
    查看redis存储情况
    $ redis-cli
    127.0.0.1:6379> keys *
    1) "ansible_facts10.4.7.101"
    2) "ansible_cache_keys"
    

    5、Ansible取消交互

    $ vim /etc/ansible/ansible.cfg
    ........
    host_key_checking = False          # 打开注释即可
        
    # 取消ssh的yes和no的交互:
    $ vim /root/.ssh/config
    UserKnownHostsFile /dev/null
    ConnectTimeout 15
    StrictHostKeyChecking no
        
    或者直接ssh时增加一个参数
    $ ssh -o StrictHostKeyChecking=no -p22 root@10.4.7.101
    

    https://www.cnblogs.com/mauricewei/p/10056458.html  ansible基础-roles

    https://www.zsythink.net/archives/3021  朱双印的ansible合集,十分不错

    https://www.cnblogs.com/mauricewei/tag/ansible/ 个人整理的ansible集合,不错

    https://blog.51cto.com/9019400/2385520  ansible-playbook用法范例总结

  • 相关阅读:
    php pcntl 多进程学习
    php socket 学习
    linux 常用alias
    php 设置一个函数的最大运行时间
    QTableView 一列添加两个按钮
    翻译qmake文档 目录
    翻译qmake文档(四) Building Common Project Types
    算法时间复杂度
    翻译qmake文档(三) Creating Project Files
    Caliburn.Micro学习笔记目录
  • 原文地址:https://www.cnblogs.com/zjz20/p/13951593.html
Copyright © 2011-2022 走看看