1. ansible

ansible是新出现的 自动化 运维工具 , 基于Python研发 。 糅合了众多老牌运维工具的优点实现了批量操作系统配置、批量程序的部署、批量运行命令等功能。 仅需在管理工作站上安装 ansible 程序配置被管控主机的 IP 信息,被管控的主机无客户端。ansible 应用程序存在于 epel( 第三方社区 ) 源,依赖于很多 python 组件

 运维:Operations

系统安装:
    bare metal:pxe, cobbler pxe(预执行环境)
    virtual machine:
Configuration:
    puppet (ruby)
    saltstack (python)
    chef
    cfengine
    ...
Command and Control:
    fabric
    func

程序发布:
    人工智能(手动发布)
    脚本
    发布程序(运维程序)
    
    要求:
        1、不能影响用户体验;
        2、系统不能停机;
        3、不能导致系统故障或造成系统完全不可用;
        
    灰度模型:
        主机
        用户 
    
        发布路径:
            /webapps/tuangou
            /webapps/tuangou-1.1
            /wepapps/tunagou-1.2
            
        在调度器上下线一批主机(标记为维护模式)--> 关闭服务 --> 部署新版本 --> 启动服务 --> 在调度器上启用这一批主机;
    
ansible:
    Configuration
    Command and Control
    
    运维工个的分类:
        agent:puppet, func, ...
        agentless(ssh,):ansible, fabric
        
    特性:
        模块化:调用特定的模块,完成特定任务;
        基于Python语言实现,由Paramiko, PyYAML和Jinja2三个关键模块;
        部署简单:agentless;
        支持自定义模块;
        支持playbook;
        
        幂等性;
        
    安装:
        epel, ansible
            配置文件:/etc/ansible/ansible.cfg
                主机清单:/etc/ansible/hosts
                
            主程序:
                ansible
                ansible-playbook
                ansible-doc
                
            ansible的简单使用格式:
                ansible  HOST-PATTERN  -m MOD_NAME  -a  MOD_ARGS
                ansible-doc -s group
    基于ssh连接:使用秘钥认证
        生成秘钥:
                ssh-keygen -t rsa [-P ''] [-f “/root/.ssh/id_rsa"]
        将公钥copy到要连接的服务器,并在.ssh/authorized_keys
                 ssh-copy-id 172.16.174.160


        ansible的常用模块: 注  “=”一般为必须给的参数
            获取模块列表:
                ansible-doc  -l
                ansible all -m ping
            command模块:在远程主机运行命令;
                模块省略为command  不支持管道
                ansible all -a "useradd testuser"

            shell模块:在远程主机在shell进程下运行命令,支持shell特性,如管道等; 
                ansible all -m shell -a  'echo mageedu |passwd --stdin' 
                一般用到管道 输入输出重定向时 使用shell模块
                    
            copy模块: Copies files to remote locations.
                用法:
                    (1) src=  dest=
                    (2) content=  dest=
                    owner, group, mode 
                    ansible all -m copy -a "src=  mode 600 dest="
                            content='hello \n'
                    ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab1"
                    ansible all -m copy -a "content='hello' dest=/tmp/testfile"
            cron 模块:Manage cron.d and crontab entries.
                minute=
                day=
                month=
                weekday=
                hour=
                job=   '/sbin/ntpdate 172.16.174.100 > /dev/nuxll' name=Synctime
                *name=  必须指明
                cron_file
                state=            
                    present:创建
                    absent:删除
                    minute=*/5 job=   '/sbin/ntpdate 172.16.174.100 > /dev/nuxll' name=Synctime state=present
                实例:    
                        ansible all -m cron -a "minute=*/5 job='/sbin/ntpdate 172.16.174.100 &> /dev/null' name=Synctime"
                        ansible all -m cron -a "state=Sync"

            fetch模块:Fetches a file from remote nodes
                pull 远程  src在远程注意的文件  dest

            file模块: Sets attributes of files
                用法:
                    (1) 创建链接文件:*path=  src=  state=link   path 为 链接后的路径  src= 原文件的路径
                    (2) 修改属性:path=  owner= mode= group= 
                    (3) 创建目录:path=  state=directory
                    src=  path=/etc/file.link state=link  
            hostname模块:Manage hostname
                name=
                变量 基于循环 多个主机命名 

            pip模块:Manages Python library dependencies.
                    远程主机自动安装 运行python所用到的工具

            yum模块:Manages packages with the `yum' package manager
                name=:程序包名称,可以带版本号;  默认最新版本
                state=
                    present(最新), latest
                    absent 删除
                    ansible all -m yum -a "name=httpd state=latest" state=absent
                 conf_file 
                    name=httpd state=latest
                    安装好 把本地配置好的文件copy到其主机

            service模块:管理服务
                *name=
                state=
                    started
                    stopped
                    restarted
                enabled=   开机自动启动
                runlevel=        
             实例:ansible all -m service -a "name=httpd state=started enabled=true"

            uri
                url=    
            user模块:管理用户账号 创建 删除 修改
                *name=
                system=yes|no
                uid=
                shell=
                group=
                groups=  附加组
                comment=    注释信息
                home=
                  remove (删除用户的时候同时删除家目录)   move_home  state=absent
            setup模块:获取facts
                present 创建
             示例:ansible all -m user -a "name=user111 state=present system=yes uid=306"

        
        YAML:yet another markup language        
            YAML:语法格式
                列表 字典:有两个键值对组合而成的就叫做字典(多个kv 对组成)同类的元素:- 可以嵌套(key下 还可以有key)
                    列表     [1,2,3,4] 
                    字典     {1:mon,2:tue}  {1:mon,2:[red,bule,yellow]} 
                packages:
                    - httpd
                    - php
                    - php-mysql
                version:0.1
            
        Playbook的核心元素: 通过读取yaml格式的文件 playbook就是由一个或多个play组成的列表
            Hosts:
            Tasks:任务
            Variables: (自带的,自定义)
            Templates:包含了模板语法的文本文件;
            Handlers:由特定条件触发的任务;
            
            Roles:把hosts剥离出来,playbook 就成了角色
            
            playbook的基础组件:最基础 hosts tasks user
                Hosts:运行指定任务的目标主机; 一个多个冒号分割
                remo  te_user: 在远程主机上执行任务的用户;
                    定义全局 也可以单任务指定 task
                    sudo_user:临时切换 
                tasks:任务列表  任务执行 第一个在所有主机运行完,再运行第二个任务 
                    模块,模块参数;
                    格式:
                        (1) action: module arguments 较新版本
                        (2) module: arguments 通用(建议使用)
                        
                        注意:shell和command模块后面直接跟命令,而非key=value类的参数列表; command: 
                        
                    (1) 某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers;
                    (2) 任务可以通过"tags“打标签,而后可在ansible-playbook命令上使用-t指定进行调用;可以同时多个标签 中间用空格或,号 试一下
                        ansible-playbook -t instconf web3.yaml
                
            运行playbook的方式:
                (1) 测试
                    ansible-playbook  --check
                        只检测可能会发生的改变,但不真正执行操作;
                    ansible-playbook  --list-hosts
                        列出运行任务的主机;
                    ansible 172.16.174.167 -m setup
                (2) 运行
                    ansible-playbook first.yaml
    实例:
                        - hosts: all
                          remote_user: root
                          tasks:
                          - name: createuser3
                            user: name=user3 system=yes uid=308
                          - name: createuser4
                            user: name=user4 system=yes uid=309
    实例:
                        - hosts: websrv
                          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/
                          - name: start httpd service
                            service: name=httpd state=started enabled=true
                          - name: execute ss command
                            shell: ss -tanl |grep :80

    实例
                        - hosts: websrv
                          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: start httpd service
                            service: name=httpd state=started enabled=true
                        #  - name: execute ss command 
                        #    shell: ss -tanl |grep :80
                          handlers:
                          - name: restart httpd
                            service: name=httpd state=restarted


                            可以将shell命令的结果重定向到文件当中。
            handlers:  
                任务,在特定条件下触发;(一般为在配置文件修改时,触发某动作执行)
                接收到其它任务的通知时被触发;
            
            variables:
                (1) facts:可直接调用;setup模块提供的:
                (2) ansible-playbook命令的命令行中的自定义变量:`pname`调用变量
                    -e VARS, --extra-vars=VARS
                    
                (3) 通过roles传递变量;
                (4) Host Inventory (hosts中定义 实现不同主机拥有不同变量)
                    (a) 向不同的主机传递不同的变量;
                        IP/HOSTNAME  varaiable=value var2=value2   hname=www2
                    实例: (1)[websrv]
                                172.16.174.160 hname=www1
                                172.16.174.177 hname=www2
                                [websrv:vars]
                                http_port=80

                          (2)ansible websrv -m hostname -a "name=` hname `"
                    (b) 向组中的主机传递相同的变量;
                        [groupname:vars]
                        variable=value    http_port=8080
                        在 ansible 中 hosts
                    注意:invertory参数:
                        用于定义ansible远程连接目标主机时使用的参数,而非传递给playbook的变量;
                            ansible_ssh_host
                            ansible_ssh_port
                            ansible_ssh_user
                            ansible_ssh_pass
                            ansbile_sudo_pass  **
                        ...
                        
回顾:运维工具,ansible
运维工具:
    OS Provision:pxe, cobbler, 
    Configuration: puppet, saltstack, chef, cfengine, ...
    Command and Control:fabric, func
    Deployment:
    灰度升级 lvs 权重为weight=0 nginx upstreem server  down(注意是否为长连接,查看老的会话是否已经断开连接;keepalive时间超时) 
ansible: agentless, ssh 
        sudo user 注意
    ansible
    ansible-playbook 
    
    模块:command, shell, cron, copy, file, ping, yum, service, user, setup, hostname, group, script
    
    playbook基本组件:
        hosts
        remote_user 以哪个用户的身份运行
        tasks
        handlers
        variables
        templates        
        roles
        
ansible(2)

模块:
    group模块:添加或删除组
        *name=
        state=
        system=
        gid=
        
    script模块:
        -a "/PATH/TO/SCRIPT_FILE"
    将本地的某个脚本传递到远程主机时执行:ansible websrv -m script -a "/.."    
    template模块:基于模板方式生成一个文件复制到远程主机
        *src=
        *dest=
        owner=
        group=
        mode=
        *必备参数
        
playbook的其它组件
    
    变量:
        ansible facts
        ansible-playbook  -e "var=value" (varname=value)
        host variable: host iventory
        group variable 主机组
            [groupname:vars]
            var=value
        roles
           在vars 目录下:usrname: daemon
                使用时在 templates 调用即可
        调用:` variable `
            insible-playbook -t instconf -e"username=adm" --check nginx.xml
        在playbook中定义变量的方法:
        vars:
        - var1: value1
        - var2: value2
        
    模板:templates
        文本文件,嵌套有脚本(使用模板编程语言编写)
            Jinja2(python 的模板编程语言):
                字面量:
                    字符串:使用单引号或双引号;
                    数字:整数,浮点数;
                    列表:[item1, item2, ...] 可变的
                    元组:(item1, item2, ...) 不可变
                    字典:{key1:value1, key2:value2, ...} key不一般为字符串 “keys”
                    布尔型:true/false
                    
                算术运算:
                    +, -, *, /, //(除完只留商), %, **(次方)
                    
                比较操作:
                    ==, !=, >, >=, <, <=
                    
                逻辑运算:
                    and, or, not 
                    
            示例:    
            - 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                    
                    
                模板配置文件 :nginx.conf.j2
                worker_processes ` ansible_processor_vcpus `;
                listen ` http_port `;
                
    条件测试:
        when语句:在task中使用,jinja2的语法格式(字符串加引号;数字不加引号)
            tasks: 
            - name: install conf file to centos7
              template: src=files/nginx.conf.c7.j2
              when: ansible_distribution_major_version ==     "7"
            - name: install conf file to centos6
              template: src=files/nginx.conf.c6.j2
              when: ansible_distribution_major_version == "6"                
    
    循环:迭代,需要重复执行的任务;
        对迭代项的引用,固定变量名为”item“
        而后,要在task中使用with_items给定要迭代的元素列表;
            列表方法:
                字符串
                字典:key value
                                
        - name: install some packages
          yum: name=` item ` state=present
          with_items:
          - nginx
          - memcached
          - php-fpm
          
        - name: add some groups
          group: name=` item ` state=present
          with_items:
          - group11
          - group12
          - group13
        - name: add some users
          user: name=` item`.`name ` group=` item`.`group ` state=present
          with_items:
          - { name: 'user11', group: 'group11' }
          - { name: 'user12', group: 'group12' }
          - { name: 'user13', group: 'group13' }
          
角色(roles):
    角色集合:
        roles/ 角色名就是目录名
            mysql/
            httpd/
            nginx/
            memcached/
            
    每个角色,以特定的层级目录结构进行组织: 角色是与主机分离的,谁用谁调用,只代表一种功能
        mysql/
            files/ :存放由copy或script模块等调用的文件;
            templates/:template模块查找所需要模板文件的目录;
            tasks/:至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含;
            handlers/:至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含;
            vars/:至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含;
            meta/:至少应该包含一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系;其它的文件需要在此文件中通过include进行包含;
            default/:设定默认变量时使用此目录中的main.yml文件;
            
    在playbook调用角色方法1:
        - hosts: websrvs
          remote_user: root
          roles:
          - mysql
          - memcached
          - nginx
        
    在playbook调用角色方法2:传递变量给角色(可以覆盖vars下同名的变量)
        - hosts: 
          remote_user:
          roles:
          - { role: nginx, username: nginx }
            键role用于指定角色名称;后续的k/v用于传递变量给角色;
            
        还可以基于条件测试实现角色调用;
        roles:
        - { role: nginx, when: "ansible_distribution_major_version == '7' " }