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服務

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章