02 Ansible模块

一.Ansible简介

1.什么是Ansible

  • Ansible是一个开源部署工具
  • 开发语言:Python
  • 特点:SSH协议通讯,全平台,无需编译,模块化部署管理

2.Ansible与Chef,Saltstack的不同

  • Chef:Ruby语言编写,C/S架构,配置需要Git依赖,Recipe脚本编写规范需要编程经验
  • Saltstack:Python语言编写,C/S架构,模块化配置管理,YAML脚本编写规范,适合大规模集群部署
  • Ansible:Python语言编写,无Client,模块化配置管理,Playbook脚本编写规范,易于上手,适合中小规模快速部署

二.Ansible的优势和应用场景

1.Ansible的优势

  • 轻量级无客户端Agentless
  • 开源免费,学习成本低,快速上手
  • 使用Playbook作为核心配置架构,统一的脚本格式批量化部署
  • 完善的模块化扩展,支持目前主流的开发场景
  • 强大的稳定性和兼容性
  • 活跃的官方社区问题讨论,方便Trubleshooting与DEBUG问题

三.Ansible安装配置

1.安装配置

  • Python3.7.0+Ansible2.7.1brew install ansible
  • 查看Ansible是否安装完成ansible --version

四.Ansible playbooks入门和编码规范

1.Playbooks框架与格式

  • TestPlaybooks
    • Inventory/ 目录下存放一个或多个Server详细清单目录,用来保存目标部署主机的相关域名或ip地址,及该主机的变量参数。通常我们会采用具体清单与变量声明文件,如dev/qc/prod
      • testenv意味着在testenv的主机部署到testenv环境中
    • roles/ 用于保存我们要部署的详细任务列表,下方可以存放一个或多个role,通常会命名为具体部署的app或项目名称
      • testbox/作为项目名称【详细任务】
        • tasks/用于存放任务内容文件
          • main.yml主任务文件
    • deploy.yml作为Playbook任务入口文件,将调度roles下需要部署的项目,以及该项目下的所有任务,最后将该项目部署到Inventory下定义的目标主机中

2.Playbooks编写规范

  • 详细目录testenv【testenv环境下的server清单】

    [testservers] -> Server组列表
    test.example.com -> 目标部署服务器主机名
    
    [testserver:vars] -> Server组列表参数,用来定义目标主机所用到的所有key/value参数对,作为Server的变量声明
    server_name=test.example.com
    user=root
    output=/root/test.txt
    
  • 主任务文件main.yml【特定role下面具体执行的任务乐章,保存一个或多个task作为音符】

    -name: Print server name and user to remote testbox -> 任务名称,表示task是做什么的
    shell: "echo 'Currently {{user}} is logining {{server_name}}' > {{output}}" -> 执行的任务,使用shell模块(调用Ansible内嵌模块)执行命令,其中的变量使用的是inventory/testenv文件中的变量声明值
    
    以上代码的含义是执行上述的task,通过Ansible的shell模块在目标主机下打印一句话并重定向到目标主机下对应output文件中
    
  • 任务入口文件deploy.yml【作为核心文件直接与Ansible Playbook命令直接对话,将Playbook下所有编排命令全部展示给Ansible进行最终的play演奏,执行到最终的主机中】

    -	hosts: "testservers" -> Server列表对应inventory下的文件中的server主标签,声明要部署的目标主机为test.example.com的主机
    	gather_facts: true -> 获取Server基本信息
    	remote_user: root -> 目标服务器系统用户指定
    	roles:
    		- testbox -> 进入roles/testbox任务目录执行里面的所有tasks
    
  • 在使用Ansible执行命令之前,由于Ansible是使用SSH作为通信协议,为了保证Ansible服务器可以操作目标服务器,我们需要配置Ansible主机与目标主机的密钥认证,保证Ansible主机与目标主机可以实现部署操作

    • 在Ansible主机配置DNS记录,将对应test.example.com域名解析到对应目标主机的ip地址。【配置hosts文件,添加DNS记录如106.54.32.234 test.example.com
    • 配置SSH免密码密钥认证
      • Ansible服务器端创建SSH本地密钥认证对ssh-keygen -t rsa,一路回车创建对应的私钥[id_rsa]和公钥[id_rsa.pub]
      • Ansible服务器端建立与目标部署机器的密钥认证(将Ansible中的密钥传递到目标机器中)ssh-copy-id -i /home/deploy/.ssh/id_rsa.pub [email protected],其中[email protected]表示目标主机用户名@目标主机域名。执行命令后需要输入yes确认连接,且输入目标主机root用户名的密码,输入完密码后就可以将本地的ssh公钥传递到目标主机中,从而建立了Ansible服务器端与目标主机间的密钥认证,实现免密登录
    • 执行Playbooks
    • 部署到testenv环境ansible-playbook -i inventory/testenv ./deploy.yml
    • 确认是否执行成功
      • 命令执行后输出ok个数和changed个数
      • 使用ssh [email protected] 并查看/root/test.txt文件有对应的输出内容

五.Ansible playbooks常用模块介绍

1.File模块

  • 在目标主机创建文件或目录,并赋予其系统权限

  • 实例:使用file模块执行Ansible Task任务

    - name: create a file
      file: 'path=/root/foo.txt state=touch mode=0755 owner=foo group=foo'
    
    • name定义任务名称
    • file声明任务语句调用file模块
      • path定义文本文件在目标主机上的位置
      • state定义要去创建一个文件
      • mode定义要给文件0755的权限
      • owner定义文件的所属用户
      • group定义文件的所属组

2.Copy模块

  • 实现Ansible服务端到目标主机的文件传送

  • 实例:使用copy模块执行Ansible Task任务

    - name: copy a file
      copy: 'remote_src=no src=roles/testbox/files/foo.sh dest=/root/foo.sh mode=0644 force=yes'
    
    • name定义任务名称
    • copy声明任务语句调用copy模块
      • remote_src=no表示要从Ansible主机中的文件传递到目标主机中
      • src声明源文件的路径(Ansible服务器)
      • dest声明目标文件的路径(目标服务器)
      • mode声明目标文件的权限
      • force=yes定义当前的Copy任务强制执行

3.Stat模块

  • 获取远程文件状态信息,并将信息保存到环境变量下供随后使用

  • 实例

    - name: check if foo.sh exists
      stat: 'path=/root/foo.sh'
      register: script_stat
    
    • stat: 'path=/root/foo.sh'表示要获取文件状态信息的路径
    • register: script_stat将stat获取的文件信息传递给script_stat变量

4.Debug模块

  • 打印语句到Ansible执行输出

  • 实例

    - debug: msg="foo.sh exists" -> 定义使用debug模块输出的语句内容为foo.sh exists
      when: script_stat.stat.exists -> when是Ansible内嵌的条件语句,script_stat.stat.exists判断变量中的值是否存在,若存在则打印上述信息
    

5.Command/Shell模块

  • 用来执行Linux目标主机命令行,Shell模块可以调用Linux系统下的/bin/bash,可以使用系统环境变量、重定向符和管道符等

  • 实例

    - name: run the script
      command: "sh /root/foo.sh"
      
    - name: run the script
      shell: "echo 'test' > /root/test.txt" -> 推荐使用shell模块
    

6.Template模块

  • 实现Ansible服务端到目标主机的jinja2模板传送

  • 实例

    - name: write the nginx config file
      template: src=roles/testbox/templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf -> src指定模板文件,dest指定目标文件路径,其中传递过程中会替换对应的变量信息
    

7.Packaging模块

  • 调用目标主机系统包管理工具(yum,apt)进行安装,常用这个模块去安装对应发行版下的app安装包

  • 实例

    - name: ensure nginx is at the latest version
      yum: pkg=nginx state=latest -> 使用yum安装,安装包是nginx包,版本是最新[此方式适用于CentOS/Rethat系统]
      
    - name: ensure nginx is at the latest version
      apt: pkg=nginx state=latest -> 使用apt安装,安装包是nginx包,版本是最新[此方式适用于Debian/Ubuntu系统]
    

8.Service模块

  • 管理目标主机系统服务

  • 实例

    - name: start nginx service
      service: name=nginx state=started -> 启动nginx服务
    

六.Ansible playbooks常用模块案例操作

1.案例操作

  • 到目标服务器上执行如下命令进行预配置工作

    useradd foo
    useradd deploy #添加两个系统用户
    mkdir /etc/nginx #创建目录
    rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm #给yum源添加nginx安装包
    
  • 修改roles/testbox/tasks/main.yml

    - name: create a file
      file: 'path=/root/foo.txt state=touch mode=0755 owner=foo group=foo'
    
  • 执行ansible-playbook执行上述任务创建foo文件

    ansible-playbook -i inventory/testenv ./deploy.yml
    
  • 在role/testbox下添加test目录,并创建foo.sh文件添加文件内容

    mkdir roles/testbox/files
    vi roles/testbox/files/foo.sh
    # 添加文件内容如下
    # echo "This is a test script"
    
  • 在main.yml中添加新的Copy任务

    - name: Create a file
      file: 'path=/root/foo.txt state=touch mode=0755 owner=foo group=foo'
    - name: Copy a file
      copy: 'remote_src=no src=roles/testbox/files/foo.sh dest=/root/foo.sh mode=0644 force=yes'
    
  • 执行ansible-playbook执行上述任务拷贝文件

    ansible-playbook -i inventory/testenv ./deploy.yml
    
  • 在main.yml中添加获取文件状态和判断文件是否存在并打印输出信息任务

    - name: Create a file
      file: 'path=/root/foo.txt state=touch mode=0755 owner=foo group=foo'
    - name: Copy a file
      copy: 'remote_src=no src=roles/testbox/files/foo.sh dest=/root/foo.sh mode=0644 force=yes'
    - name: Check if foo.sh exists
      stat: 'path=/root/foo.sh'
      register: script_stat
    - debug: msg="foo.sh exists"
      when: script_stat.stat.exists
    
  • 执行ansible-playbook执行上述任务进行文件是否存在的判断

    ansible-playbook -i inventory/testenv ./deploy.yml
    
  • 在main.yml中添加执行脚本文件的任务

    - name: Create a file
      file: 'path=/root/foo.txt state=touch mode=0755 owner=foo group=foo'
    - name: Copy a file
      copy: 'remote_src=no src=roles/testbox/files/foo.sh dest=/root/foo.sh mode=0644 force=yes'
    - name: Check if foo.sh exists
      stat: 'path=/root/foo.sh'
      register: script_stat
    - debug: msg="foo.sh exists"
      when: script_stat.stat.exists
    - name: Run the script
      command: "sh /root/foo.sh"
    
  • 执行ansible-playbook运行上述任务执行shell脚本

    ansible-playbook -i inventory/testenv ./deploy.yml
    
  • 添加变量参数到testenv中

    [testservers]
    test.example.com
    
    [testservers:vars]
    server_name=test.example.com
    user=root
    output=/root/test.txt
    port=80
    user=deploy
    worker_processes=4
    max_open_file=65505
    root=/www
    
  • 在roles/testbox下创建templates目录mkdir roles/testbox/templates

  • 在templates文件创建nginx.conf.j2模板文件,使用nginx.conf文件并修改对应字段为{{变量}}

    # For more information on configuration, see: 
    user              {{ user }};  
    worker_processes  {{ worker_processes }};  
      
    error_log  /var/log/nginx/error.log;  
      
    pid        /var/run/nginx.pid;  
      
    events {  
        worker_connections  {{ max_open_file }};
    }
    
    http {  
        include       /etc/nginx/mime.types;  
        default_type  application/octet-stream;  
      
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '  
                          '$status $body_bytes_sent "$http_referer" '  
                          '"$http_user_agent" "$http_x_forwarded_for"';  
      
        access_log  /var/log/nginx/access.log  main;  
      
        sendfile        on;  
        #tcp_nopush     on;  
      
        #keepalive_timeout  0;  
        keepalive_timeout  65;  
      
        #gzip  on;  
          
        # Load config files from the /etc/nginx/conf.d directory  
        # The default server is in conf.d/default.conf  
        #include /etc/nginx/conf.d/*.conf;  
        server {  
            listen       {{ port }} default_server;  
            server_name  {{ server_name }};  
      
            #charset koi8-r;  
      
            #access_log  logs/host.access.log  main;  
      
            location / {  
                root   {{ root }};  
                index  index.html index.htm;  
            }  
      
            error_page  404              /404.html;  
            location = /404.html {  
                root   /usr/share/nginx/html;  
            }  
      
            # redirect server error pages to the static page /50x.html  
            #  
            error_page   500 502 503 504  /50x.html;  
            location = /50x.html {  
                root   /usr/share/nginx/html;  
            }
        }
    }
    
  • 在main.yml中添加传送替换后的nginx.conf文件模板任务、yum安装nginx任务和启动远程nginx服务任务

    - name: Create a file
      file: 'path=/root/foo.txt state=touch mode=0755 owner=foo group=foo'
    - name: Copy a file
      copy: 'remote_src=no src=roles/testbox/files/foo.sh dest=/root/foo.sh mode=0644 force=yes'
    - name: Check if foo.sh exists
      stat: 'path=/root/foo.sh'
      register: script_stat
    - debug: msg="foo.sh exists"
      when: script_stat.stat.exists
    - name: Run the script
      command: "sh /root/foo.sh"
    - name: Write the nginx config file
      template: src=roles/testbox/templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf
    - name: Ensure nginx is at the latest version
      yum: pkg=nginx state=latest
    - name: Start nginx service
      service: name=nginx state=started
    
  • 执行ansible-playbook运行上述模块任务

    ansible-playbook -i inventory/testenv ./deploy.yml
    
  • 进入目标主机查看nginx.conf文件是否成功替换模板,且通过ps -ef | grep nginx命令查看是否启动nginx服务

你可能感兴趣的:(02 Ansible模块)