第10章:深刻淺出Ansible

1.Ansible介紹html

1).Ansible的優勢node

    Ansible是一個簡單的自動化引擎,可完成配置管理、引用部署、服務編排以及其餘各類IT需求python

    Ansible是Python開發並實現的開源軟件,其依賴Jinja2,paramiko和PyYAML這幾個Python庫mysql

    安裝部署簡單linux

    基於SSH進行配置管理nginx

    Ansible不須要守護進程git

    日誌集中存儲sql

    Ansible簡單易用mongodb

    Ansible功能強大shell

    Ansible設計優秀

    Ansible對雲計算和大數據平臺都有很好的支持

2).Ansible與Fabric之間比較

    Fabric像是一個工具箱,提供了不少好用的工具用於在遠程服務器執行命令

    Ansible提供了一套簡單的流程,只須要按照它的流程來作就能輕鬆完成任務

    Fabric是庫,Ansible是框架

    Fabric簡單,Ansible複雜

    Fabric經過SSH執行簡單的命令,Ansible將模塊拷貝到遠程服務器後執行,執行完之後刪除模塊

    Fabric須要Python編程背景,Ansible不須要

    Fabric須要寫代碼,Ansible只須要編寫YAML格式的配置文件來描述要作的事情

    Fabric提供了基本的接口,業務邏輯須要用戶本身實現,Ansible提供了大量模塊,用戶只須要學習模塊的用法便可

3).Ansible與SaltStack之間比較

    Ansible安裝部署簡單,SaltStack須要安裝客戶端接收服務端發過來的命令

    SaltStack相應速度更快,Ansible使用標準SSH鏈接,而SaltStack使用ZeroMQ進行通訊和傳輸

    Ansible更安全,Ansible使用標準SSH鏈接傳輸數據,不須要在遠程主機上啓動守護進程

    SaltStack對Windows支持比較友好

    Ansible自身運維比較簡單,SaltStack須要在Master和Minion主機啓動一個守護進程

 

2.Ansible使用入門

1).安裝Ansible

    pip install ansible

2).Ansible的架構

    Ansible的編排引擎由Inventory、API、Modules(模塊)和Plugins組成

    工程師將須要在遠程服務器執行的操做寫在Ansible Playbook中,而後使用Ansible執行Playbook中的操做

3).Ansible的運行環境

Ansible會默認讀取/etc/ansible/hosts文件中配置的遠程服務器列表
# mkdir /etc/ansible
# cat /etc/ansible/hosts 
[test]
192.168.1.101
192.168.1.102
192.168.1.103

# ansible test -m ping
192.168.1.101 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.1.102 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.1.103 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

4).Ansible的ad-hoc模式

Ansible的ad-hoc模式,經過ansible命令執行操做的方式,稱爲ad-hoc
# ansible test -m command -a "hostname"

# ansible test -m command -a "whoami"

將本地文件拷貝到服務器中:
# ansible test -m copy -a "src=/etc/ansible/hosts dest=/tmp/hosts"

修改文件的全部者和權限:
# ansible all -m file -a "dest=/tmp/hosts mode=500 owner=mysql group=mysql" -become
-become參數相似於Linux命令下的sudo

在遠程服務器中安裝軟件:
# ansible test -m yum -a "name=git state=present" -become

5).使用playbook控制服務器

在實際的生產環境中,咱們通常將遠程服務器須要作的事情寫在一個YAML配置文件中
YAML文件稱爲Ansible Playbook

# cat test_playbook.yaml
---
- hosts : test
  become : yes
  become_method : sudo
  tasks : 
  - name : copy file
    copy : src=/etc/ansible/hosts dest=/tmp/data.txt

  - name : change mode
    file : dest=/tmp/data.txt mode=500 owner=mysql group=mysql

  - name : ensure packages installed
    yum : pkg="{{ item }}" state=present
    with_items : 
    - git

# ansible-playbook test_playbook.yaml

 

3.Inventory管理

1).hosts文件位置

在Ansible中,將可管理的服務器集合稱爲Inventory
Inventory管理即是服務器管理
默認讀取/etc/ansible/hosts文件
經過命令行參數的-i指定hosts文件
經過ansible.cfg文件中的inventory選項指定hosts文件

2).動態Inventory獲取

# cat hosts.py 
import argparse
import json
from collections import defaultdict
from contextlib import contextmanager
import pymysql

def to_json(in_dict):
    return json.dumps(in_dict, sort_keys=True, indent=2)

@contextmanager
def get_conn(**kwargs):
    conn = pymysql.connect(**kwargs)
    try:
        yield conn
    finally:
        conn.close()

def parse_args():
    parser = argparse.ArgumentParser(description='OpenStack Inventory Module')
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('--list', action='store_true', help='List active servers')
    group.add_argument('--host', help='List details about the specific host')
    return parser.parse_args()

def list_all_hosts(conn):
    hosts = defaultdict(list)
    with conn as cur:
        cur.execute('select * from hosts')
        rows = cur.fetchall()
        for row in rows:
            no, host, group, user, port = row
            hosts[group].append(host)
    return hosts

def get_host_detail(conn, host):
    details = {}
    with conn as cur:
        cur.execute("select * from hosts where host='{0}'".format(host))
        rows = cur.fetchall()
        if rows:
            no, host, group, user, port = rows[0]
            details.update(ansible_user=user, ansible_port=port)
    return details

def main():
    parser = parse_args()
    with get_conn(host='127.0.0.1', user='root', passwd='msds007', db='test') as conn:
        if parser.list:
            hosts = list_all_hosts(conn)
            print(to_json(hosts))
        else:
            details = get_host_detail(conn, parser.host)
            print(to_json(details))

if __name__ == '__main__':
    main()

 

4.YAML語法

1).語法規則

YAML文件的第一行爲"---",表示是一個YAML文件
YAML中的字段大小寫敏感
YAML與Python同樣,使用縮進表示層級關係
YAML的縮進不容許使用Tab鍵,只容許使用空格,且空格的數目不重要,只要相同層次的元素左對齊便可
:冒號先後要有空格
#表示註釋,從這個字符一直到行尾都會被解析器忽略

2).支持的數據格式

對象:鍵值對的集合,又稱爲映射,相似於Python中的字典
數組:一組按次序排列的值,又稱爲序列(sequence),相似於Python中的列表
純量:單個的、不可再分的值,如字符串、布爾值於數字

3).解析

pip install PyYAML

使用PyYAML庫解析YAML文件很是簡單
import yaml
with open('data.yaml') as f:
    print(yaml.load(f))

# cat data.yaml 
---
name : Example Developer
job : Developer
skill : Elite
employed : True
foods:
    - Apple
    - Orange
    - Strawberry
    - Mango
languages:
    ruby : Elite
    python : Elite
    dotnet : Lame

 

5.Ansible模塊

1).Ansible的模塊工做原理

1)將模塊拷貝到遠程服務器
2)執行模塊定義的操做,完成對服務器的修改
3)在遠程服務器中刪除模塊

2).經常使用的Ansible模塊

1.ping
2.遠程命令模塊command
3.file
4.copy
5.user/group
6.yum
7.get_url
8.unarchive
9.git

3).模塊的返回值

changed
failed

 

6.Playbook

1).Playbook的定義

    在Ansible中,將各個模塊組合起來的文件是一個YAML格式的配置文件,這個配置文件,在Ansible中稱爲Playbook

    Ansible中的Playbook相似於Linux下的Shell腳本文件

2).使用ansible-playbook

# cat test_playbook.yaml
---
- hosts : test
  become : yes
  become_method : sudo
  tasks : 
  - name : copy file
    copy : src=/py/data.txt dest=/tmp/data.txt

  - name : change mode
    file : dest=/tmp/data.txt mode=500 owner=mysql group=mysql

  - name : ensure packages installed
    yum : pkg="{{ item }}" state=present
    with_items : 
    - git

# ansible-playbook test_playbook.yaml

3).Playbook的詳細語法

1.權限
在Ansible中,默認使用當前用戶鏈接遠程服務器執行操做,咱們能夠在ansible.cfg文件中配置鏈接遠程服務器的默認用戶
2.通知
3.變量
4.Facts變量
Facts變量是Ansible執行遠程部署以前從遠程服務器中獲取的系統信息,包括服務器的名稱、IP地址、操做系統、分區信息、硬件信息等
Facts變量能夠配合Playbook實現更加個性化的功能需求
訪問複雜變量的Playbook:
---
- hosts : test
  gather_facts : yes
  tasks : 
  - shell : echo {{ ansible_eth0 ["ipv4"] ["address"] }}
    register : myecho

  - debug : var=myecho.stdout_lines

  - shell : echo {{ ansible_eth0.ipv4.address }}
    register : myecho

  - debug : var=myecho.stdout_lines
5.循環
# cat test_playbook.yaml 
---
- hosts : test
  become : yes
  become_method : sudo
  tasks : 
  - name : Installed MySQL Package
    yum : pkg="{{ item }}" state=installed
    with_items : 
    - mysql-server
    - MySQL-python
    - libselinux-python
    - libsemanage-python
# ansible-playbook test_playbook.yaml
6.條件
在Playbook中能夠經過when選項執行條件語句,when相似於if語句
7.任務執行策略

4).使用Playbook部署ngix

# cat deploy_nginx.yaml 
---
- hosts: test
  become: yes
  become_method: sudo
  vars:
    worker_processes: 4
    worker_connections: 768
    max_open_files: 65506
  tasks:
    - name: install nginx
      yum: name=nginx update_cache=yes state=present

    - name: copy nginx config file
      template: src=/py/nginx.conf.j2 dest=/etc/nginx/nginx.conf

    - name: copy index.html
      template:
        src: /py/index.html.j2
        dest: /usr/share/nginx/html/index.html
        mode: 0644
      notify: restart nginx

  handlers:
    - name: restart nginx
      service: name=nginx state=restarted

# ansible-playbook depoly_nginx.yml

5).使用Playbook部署MongoDB

# cat mongo.yml 
---
- hosts: test
  become: yes
  become_method: sudo
  vars:
    mongodb_datadir_prefix: /data
    mongod_port: 27018

  tasks:
    - name: Create the mongodb user
      user: name=mongodb comment="MongoDB"

    - name: Create the data directory for the namenode metadata
      file: path={{ mongodb_datadir_prefix }} owner=mongodb group=mongodb state=directory

    - name: Install the mongodb package
      yum: name={{ item }} state=installed
      with_items:
        - mongodb-server
        - mongodb

    - name: create data directory for mongodb
      file:
        path: "{{ mongodb_datadir_prefix }}/mongo-{{ ansible_hostname }}"
        state: directory
        owner: mongodb
        group: mongodb

    - name: create log directory for mongodb
      file: path=/var/log/mongo state=directory owner=mongodb group=mongodb

    - name: Create the mongodb startup file
      template: src=mongod.j2 dest=/etc/init.d/mongod-{{ ansible_hostname }} mode=0655

    - name: Create the mongodb configuration file
      template: src=mongod.conf.j2 dest=/etc/mongod-{{ ansible_hostname }}.conf

    - name: Copy the keyfile for authentication
      copy: src=secret dest={{ mongodb_datadir_prefix }}/secret owner=mongodb group=mongodb mode=0400

    - name: Start the mongodb service
      command: creates=/var/lock/subsys/mongod-{{ ansible_hostname }} /etc/init.d/mongod-{{ ansible_hostname }} start

# ansible-playbook mongo.yml

 

7.role的定義與使用

    role並非某一個具體的東西,而是一個規範與抽象,是一種將複雜的Playbook分割成多個文件的機制

    Ansible從複雜的Playbook中抽象出了role的概念,並在Playbook提供了roles選項來使用role,在命令行提供了ansible-galaxy命令來建立、刪除和查看role

    所謂role,只是一種規範的文件組織方式。每一個Ansible的role都會有一個名字,好比mongodb,與mongodb role相關的文件都存放在/etc/ansible/roles/mongodb目錄下

 

8.Ansible的配置文件

1).配置文件的查找路徑

配置文件的查找路徑
Ansible命令行工具使用的配置文件是/etc/ansible/ansible.cfg文件
通常將全部的role、Playbook、Inventory文件、ansible.cfg文件保存在一個版本控制的庫中

在Ansible中,能夠有多種方式使用ansible.cfg文件。Ansible查找ansible.cfg文件的順序以下:
1)ANSIBLE_CONFIG環境變量指定的配置文件
2)當前目錄下的ansible.cfg文件
3)當前用戶home目錄下的.ansible.cfg文件
4)Ansible默認的/etc/ansible/ansible.cfg文件

2).Ansible中的經常使用配置

1.默認配置
inventory
remote_user
remote_port
private_key_file
roles_path
log_path
host_key_checking
forks
gathering
2.ssh鏈接配置
ssh_args
pipelining
control_path
3.權限提高配置
become
become_method
become_user
become_ask_pass
相關文章
相關標籤/搜索