ansible 快速入門筆記(借鑑於博客園某大神)

簡介

高度模塊化,調用特定的模塊,完成特定的任務,基於Yaml,來完成批量任務的模板化,來支持playbook。基於Python語言實現,主要使用Paramiko、PyYAML和JinJa2三個關鍵模塊,部署簡單(agentless),主從模式,支持自定義模塊,支持playbook,冪等性:允許重複執行N次,沒有變化時,只會執行第一次。

特點:

  • 1、Configuration(cfengine,chef,puppet) 配置管理
  • 2、Deployment(Capistrano,Fabric) 部署發佈
  • 3、Ad-Host Task(func) 命令行批量執行
  • 4、Multi-Ter Orchestration(Juju,sort of) 多層次任務編排

PS:集成了上面括號中的工具的主要功能

基本組

主要由模塊、插件、主機羣、以及劇本的組成,各部分含義如下:

1.核心模塊(core modules):Ansible 自帶的模塊。
2.自定義模塊(custom Modules):如果核心模塊不足以完成某種功能,可以自行添加自定義模塊(支持市面上大部分的編程語言)。
3.插件(Plugins):支持使用插件的方式對ansible本身的功能進行擴展。模塊是用來實現任務的,增強ansible平臺自己的功能就需要使用插件(loggin插件記錄日誌,email插件發送郵件)

  • 其中最常用是:連接插件(Connectior Plugins) :ansibile基於連接插件連接到各個主機上,雖然默認情況下ansible使用ssh連接到各個主機上,但它還支持其他的連接方法(mq)。

4.主機羣(Host Inventory): 主機清單,定義ansible管理的主機,還可以存放一下針對不同主機的變量,也可以寫入主機的用戶名和密碼
5.劇本(playbooks):ansible的任務配置文件,將多個任務定義在劇本中,由ansible自動執行

yum install ansible

運行原理:把命令翻譯成shell命令,拷貝到目標主機(/root/.ansible/tmp/下),再執行,執行完畢後刪除tmp文件。

命令介紹

ansible 命令主要參數信息

  • -u : remote user,默認使用root用戶登陸
  • -i : Inventory,指定主機,默認是/etc/ansible/hosts
  • -m :指定模塊的名稱(不指定-m,那麼默認是command模塊)
  • -a : 模塊的參數(比如使用command模塊,那麼-a參數就是要執行的命令)
  • -k : 用來提示輸入遠程主機的密碼(基於用戶密碼登錄)
  • -f : 一次執行幾個進程(併發數量),默認爲5個
  • --sudo : 執行命令時使用 sudo 權限(需要用戶具有sudo權限)
  • --key-file: 建立SSH鏈接的私鑰文件
  • --list-hosts: 列出匹配到的服務器列表
# 基於主機清單:
ansible -i /etc/ansible/hosts test -u root -m command -a 'ls /home' -k (ansible 依賴 sshpass)
|
--> ansible test -a 'ls /home' -k

# 上面兩條命令默認狀態下效果相同

# 我們知道ansible通過ssh的方式來遠程管理多臺主機,所以我們需要使用ssh key的方式來進行ssh認證,當然你也可以使用ansible的時候加上-k,來通過交互式輸入密碼。當有了ssh key以後,那麼我們就可以直接使用ansbile來執行任務了,比如:ansible all -m ping

# 基於主機:
ansible 127.0.0.1 -m ping

Inventory文件介紹

/etc/ansible/hosts:(默認的Inventory)

注意:主機組不要設置爲all,因爲默認all代表所有主機

[test]                    # 用於定義主機組,all表示所有主機,所以儘量避免使用all作爲組名
127.0.0.1                 # 該組的主機列表,可以是主機名(dns解析)或者IP地址,或者用符號來表示連續的主機
192.168.1.[80:88]         # 表示 192.168.1.80 - 192.168.1.88<br><br>[web:children]            # 表示子組<br>nginx                     # nginx組<br>test                      # test組

配置文件中的變量及參數:

[nginx]
127.0.0.1 ansible_ssh_user=root ansible_ssh_host=web1 # 更細緻的配置

    - ansible_ssh_user : 用於指定管理遠程主機的帳號
    - ansible_ssh_host : 用於指定被管理的主機
    - ansible_ssh_port :用於指定ssh的端口
    - ansible_ssh_private_key_file :指定key文件
    - host_key_checking=False :當第一次連接主機時,會提示yes/no,跳過此次環節

Ansible配置文件介紹

ansible 查找 Ansible.cfg 文件遵循以下順序:

  • 1、ANSIBLE_CONFIG環境變量指定的配置文件
  • 2、當前目錄下的ansible.cfg文件
  • 3、當前用戶home目錄下的.ansible.cfg文件
  • 4、Ansible默認的/etc/ansible/ansible.cfg文件

Ansible.cfg中的常用配置:

- inventory:指定inventory文件的路徑
- remote_user:SSH連接時使用的用戶名
- remote_port:SSH連接時使用的端口號
- private_key_file:SSH連接時使用的私鑰文件
- roles_path:查找roles的路徑,可以指定多個查找路徑,多個路徑之間用冒號分隔
- log_path:Ansible的日誌文件路徑
- host_key_checking:類似於ssh命令中的StrictHostKeyChecking選項,當等於False時,不檢查遠程主機是否存在於Konw_hosts文件中
- forks:並行進程的數量
- gathering:控制收集Facts變量的策略

ssh相關

- ssh_args:可以通過這個參數控制Ansible的ssh連接
- pipelining: 多個task之間共享SSH連接,開啓pipelining能夠有效提升Ansible的執行速度
- control_path:保存ControlPath socket的路徑

權限提升相關

- become:是否進行權限提升
- become_method:權限提升的方式,默認爲sudo
- become_user:提升爲哪個用戶的權限,默認爲root
- become_ask_pass:默認爲False,表示權限提升時不需要密碼(設置爲true時,手動輸入密碼,或者配置ansible_become_pass變量)

常用模塊

查看模塊的幫助:

ansible-doc -l # 查看核心的模塊(包含模塊的大致說明,比較慢)
ansible-doc -s 'command' # 執行模塊名,可以列出模塊的用法

setup

用於統計操作系統的相關信息

# 例子
ansible test -m setup
# 參數
  - filter: 過濾要顯示的內容
  - ansible test -m setup -a "filter=ansible_python_version" -k # 只獲取主機ansible_python_version的值
  - 更多的幫助 ansible-doc -s setup

file

設置文件屬性

# 參數
  - force: 在兩種情況下會強制創建軟連接,默認值爲 no
  - 源文件不存在但之後會建立的情況下
  - 目標軟連接已存在,需要先取消之前的軟連,然後創建新的軟鏈
  - group:定義文件的屬組
  - mode:定義文件的權限
  - owner:定義文件的屬主
  - path:必選項,定義文件的路徑
  - recurse:遞歸設置文件的屬性,只對目錄生效(-R)
  - src:要被鏈接的源文件的屬性,只應用於state=link的情況
  - dest:被鏈接到的路徑,只應用與state=link的情況
  - state:
  - directory:如果目錄不存在創建目錄
  - file:即使文件不存在,也不會被創建
  - link:創建軟連接
  - hard:創建硬鏈接
  - touch:如果文件不存在,則會創建一個新的文件,如果文件存在,則會更新其最後修改時間
  - absent:刪除目錄,文件或者取消鏈接文件

# 例子
ansible test -m file -a 'src=/etc/fstab dest=/tmp/fstab state=link'
# 等於 ln -s /etc/fstab /tmp/fstab 
ansible test -m file -a 'path=/tmp/fstab state=absent'
# 刪除文件
ansible test -m file -a 'path=/tmp/lixin.txt state=touch owner=nobody group=nobody mode=666' -k   # 創建文件指定其屬主,屬組,權限

copy

複製文件到遠程主機,每次備份會產生一個md5sum,如果兩次賦值文件的md5sum相同,那麼就不會再次執行復制動作。推薦複製文件,而不是目錄

# 參數
  - backup:在覆蓋之前將原文件備份,備份文件名包含時間信息。有兩個選項:yes | no
  - src:源文件,如果是目錄的話,會遞歸賦值,包括目錄本身,如果目錄爲/,那麼只會複製目錄下的文件
  - dest:目標文件路徑
  - others:所有file模塊裏的選項都可以在這裏使用
  - content:用於替代'src',可以直接設定文件的值
  - directory_mode:遞歸設定目錄的權限,默認爲系統默認權限
  - force:如果目標主機包含該文件,但內容不同,如果設置爲yes,則強制覆蓋,如果爲no,則只有當前目標主機的目標位置不存在該文件時,才複製,默認爲yes。

# 例子:
ansible test -m copy -a "content='hello world' dest=/tmp/tmp.txt" -k    # 在目錄主機上創建tmp.txt文件,內容爲hello world

command

在遠程主機上執行命令。(默認模塊

ps:若獲取命令失敗,結果則顯示failed,否則顯示changed。同shell模塊

# 參數
  - creates:文件名,當該文件存在時,則不執行後面的命令
  - chdir:執行命令前,先修改當前路徑
  - removes:文件名,當文件不存在時,則不執行後面的命令
  - executable:切換shell來執行命令,該執行路徑必須是一個絕對路徑

shell

和command模塊相同,參數也相同。

# command,shell,raw,script模塊同屬於commands類,都是用來執行命令,不同的是:
  - command模塊執行的命令中不能包含:|,<,>,& 符號。
  - shell模塊:可以執行遠程服務器上的shell腳本文件,也支持 管道符等,腳本需要使用絕對路徑。
  - raw模塊和shell模塊相同,可以執行任意命令就像在本機一樣,相當於ssh之直接執行Linux命令,不會進入到ansible的模塊子系統中。
  - script模塊,用來執行一個shell腳本,其實將管理端的shell腳本copy到被管理端上然後執行,相當於 scp + shell 的組合。(需要在腳本所在目錄下執行)
# 官方建議使用command模塊,如果需求不滿足,可以使用raw模塊

service

用於管理服務,service模塊無法直接獲取服務的狀態,但可以使用command模塊來實現

# 參數
  - arguments: 給命令行提供一些選項
  - enable:是否開機啓動 yes | no
  - name:服務名稱
  - pattern:定義一個模式,如果通過status命令來查看服務的狀態時,沒有響應,就會通過ps指令在進程中根據該模式進行查找,如果匹配到,則認爲該服務已經在運行,否則會認爲未啓動( ps aux | grep `pattern` )
  - runlevel:運行級別
  - sleep:如果執行了,restarted,則在 stop 和 start 之間沉睡幾秒鐘
  - state:started、stoped、restarted和reloaded,其中started和stoped是冪等的,也就是說如果服務已經停止,那麼運行stoped不會執行任何操作

# 例子
ansible test -m service -a 'name=nginx state=started enabled=yes' -k                   # 啓動nginx進程,並設置爲開機啓動
ansible test -m service -a 'name=nginx state=stopped' -k                               # 關閉nginx進程
ansible test -m service -a 'name=network state=restarted arguments=eth0' -k            # 重啓network進程,並傳遞eth0 作爲參數,即:重啓eth0網卡
ansible test -m service -a 'name=nginx pattern=/usr/local/nginx state=started' -k      # 如果無法使用 service nginx status查尋到nginx的狀態,那麼會使用 ps 來過濾 pattern指定的關鍵字,如果存在,則表示程序已經正常啓動 

cron

用於管理定時任務(crontab 來操作)

# 參數
  - backup: 對遠程主機上的原計劃內容修改之前做備份
  - cront_file: 如果指定該選項,則用該文件替換遠程主機上的cron.d目錄下的用戶計劃任務
  - day: 日(1-31,*,*/2,......)
  - hour: 小時(0-23,*,*/2,......)
  - minute: 分鐘(0-59,*,*/2,......)
  - mouth: 月(1-12,*,*/2,......)
  - weekday: 周(0-7,*,......)
  - job: 要執行的任務,依賴於state=present
  - name: 該任務的描述,必選項。
  - special_time:指定什麼時候執行(被觸發),參數:reboot,yearly,annually,monthly,weekly,daily,hourly。
  - state:確認該任務計劃是創建還是刪除 Present(啓用) | Absent(停用)
  - user:以哪個用戶的身份執行

# 例子
ansible test -m cron -a "hour=3 month=2 day=1 job='echo hello' name='test' state=present " -k  # 添加一條定時任務,* 3 1 2 * echo hello
ansible test -m cron -a 'name=test state=absent' -k                                            # 刪除name爲test的計劃任務

filesystem

用於在塊設備上創建文件系統。

# 參數
  - dev:目標塊設備
  - force:在一個已有的文件系統的設備上強制創建
  - fstype:文件系統類型
  - opts:傳遞給mkfs命令的選項

yum

使用yum包管理軟件包

ps:present與installed,absent與removed的區別,手冊上他們含義是一樣的。

# 參數
  - config_file:yum的配置文件
  - disable_gpg_check: 關閉gpg_check
  - disablerepo: 不啓用某個源
  - enablerepo:啓用某個源
  - list:列出repo源
  - name:軟件包的名稱,可以爲一個url路徑,或者本地一個rpm包的路徑
  - state:狀態
    # 安裝
    - present
    - installed *
    - latest
    # 刪除
    - absent
    - removed *

# 例子
ansible test -m yum -a 'name=httpd state=installed' -k     # yum 安裝 httpd  

user

用於管理用戶(useradd,userdel) 也可以用command模塊來執行shell命令創建和管理用戶

# 參數
  - home:指定用戶的家目錄
  - createhome: 是否創建用戶家目錄 yes | no
  - groups:用戶的屬組
  - uid:用戶的uid
  - password:用戶的密碼
  - name:用戶的名稱
  - system:是否是系統用戶
  - remove:是否刪除用戶家目錄
  - state:具體的操作, 刪除/添加, present | absent
  - shell: 指定用戶的shell 

synchronize

使用rsync同步文件

ps: 使用該模塊前,本地主機與遠程主機組都需要先安裝rsync軟件。

# 參數
  - archive:是否進行歸檔,默認爲yes,相當於同時開啓recursive,links,perms,times,owner,group -D等選項
  - checksum:是否校驗和
  - copy_links:是否複製鏈接文件
  - delete:刪除源中沒有而目標存在的文件
  - dest_port: 對方用於接收的端口
  - dirs: 非遞歸傳輸目錄
  - mode:模式,推和拉模式, push | pull ,默認爲push(推)
  - src:同步的數據源的位置
  - rsync_opts: 指定rsync的選項,多個選項可以用逗號分隔
  - dest:目標文件
  - compress: 默認爲yes,表示在文件同步過程中是否啓用壓縮<br>
# 例子
# rsync 傳輸文件
ansible test -m synchronize -a 'src=/etc/yum.repos.d/epel.repo dest=/tmp/epel.repo'

ansible test -m synchronize -a 'src=/tmp/123/ dest=/tmp/test/ rsync_opts="-avz,--exclude=passwd"' -k    # 同步文件,添加rsync的參數-avz,並且排除passwd文件
ansible test -m synchronize -a 'src=/tmp/test/abc.txt dest=/tmp/123/ mode=pull' -k                      # 把遠程的文件,拉到本地的/tmp/123/目錄下  
# 傳輸文件目錄
ansible node -m synchronize -a 'src=/tmp/123/ dest=/tmp/123/'
# 傳輸目錄/tmp/123/下,修改或增加的文件或文件目錄。命令同上
ansible node -m synchronize -a 'src=/tmp/123/ dest=/tmp/123/'
# 傳輸目錄/tmp/123/下,修改、增加和刪除的文件及文件目錄,則加 delete參數:
ansible node -m synchronize -a 'src=/tmp/123/ dest=/tmp/123/ delete=yes'
###########
# 推薦使用方法:文件目錄的同步,把參數加上delete!!!

mount

用於磁盤掛載相關操作

# 參數
  - fstype:掛載文件的類型
  - name:掛載點
  - opts:傳遞給mount命令的參數
  - src:要掛載的文件
  - state:
    - present:只會在 fstab 中添加,不會操作磁盤
    - mounted:自動創建掛載點並掛載
    - unmounted:卸載
    - absent:只會在 fstab 中刪除,不會操作磁盤

# 例子
ansible test -m mount -a 'fstype=ext4 src=/dev/loop0 name=/aaa state=mounted' -k   # 掛在/dev/loop0 設備

template

模版,用於將模版文件渲染後,輸出到遠程主機上,模版文件一般以.j2爲結尾,標識其是一個jinja2模版文件

# 參數
  - src:模版文件的路徑
  - dest:拷貝到遠程主機上的位置
  - mode:權限
  - attributes: 特殊權限 類似於 chattr
  - force:存在覆蓋
  - group:屬組
  - owner:屬主

get_url

從互聯網下載數據到本地,作用類似於Linux下的curl命令。

# 參數
  - url:必傳參數,文件的下載地址
  - dest:必傳參數,文件保存的絕對路徑
  - mode:文件的權限mode
  - othes:所有file模塊裏的選項都可以在這裏使用
  - checksum:文件的校驗碼
  - headers:傳遞給下載服務器的 HTTP Headers
  - backup:如果本地已經存在同名的配置文件,先行備份
  - timeout:下載的超時時間

unarchive

用於解壓文件,其作用類似於Linux下的tar命令,默認情況下unarchive的作用是將控制節點的壓縮包拷貝到遠程服務器上,然後進行解壓.

# 參數
  - remote_src: 用來表示需要解壓的文件存在遠程服務器中還是本地服務器中,默認爲no,表示解壓前先將控制節點上的文件複製到遠程主機上中,然後再進行解壓。
  - src:指定壓縮文件的路徑,該選項取決於remote_src的取值,如果remote_src取值爲yes,則src指定的是遠程服務器中壓縮包的地址,如果remote_src取值爲no,則src指向的是控制節點中的路徑
  - dest:該選項指定的是遠程服務器上的絕對路徑,表示壓縮文件解壓的路徑
  - list_files: 默認情況下該選項的取值爲no,如果該選項取值爲yes,也會解壓縮文件,並且在ansible的返回值中列出壓縮包裏的文件;
  - exclude:解壓文件時排出exclude選項指定的文件或目錄列表
  - keep_newer: 默認值爲False,如果該選項爲True,那麼當目標地址中存在同名文件,並且文件比壓縮包中的文件更新時,不進行覆蓋。
  - owner:文件或目錄解壓以後的所有者
  - group: 文件或目錄解壓以後所屬的羣組
  - mode: 文件或目錄解壓以後的權限

git

在遠程服務器上執行git相關操作。依賴於git命令,需要在遠程主機上先進性安裝。

# 參數
  - repo:遠程git庫的地址,可以是一個git協議,ssh協議或者http協議的git庫地址
  - dest:必選參數,git庫clone到本地服務器以後保存的絕對路徑
  - version:克隆遠程git庫的版本,取值可以爲HEAD,分支名稱,tag的名稱,也可以是一個commit的hash值
  - foces:默認爲no,當該選項爲yes時,如果本地git庫有修改,將會拋棄本地的修改(強制覆蓋)
  - accept_hostkey: 當該選項取值爲yes時,如果git庫服務器不再know_hosts中,則添加到know_hosts中,key_file指定克隆遠程git庫地址時使用的私鑰。

stat

用於獲取遠程服務器上的文件信息,類似於Linux下的stat命令

# 參數
  - path:用於指定文件或目錄的路徑 

sysctl

與Linux下的sysctl命令相似,用來控制Linux內核參數

# 參數:
  - name:需要設置的參數
  - value:需要設置的值
  - sysctl_file: sysctl.conf文件的絕對路徑,默認路徑爲/etc/sysctl.conf
  - reload:該選項可以取值爲 yes 或 no,默認爲yes,用於表示設置完以後是否需要實行sysctl -p的操作

# 例子
ansible test -m sysctl -a 'name=vm.overcommit_memory value=1'  # 修改vm.overcommit_memory的值爲1

模塊的返回值

Ansible通過模塊來執行具體的操作,由於模塊功能千差萬別,所以執行模塊操作後,Ansible會根據不同的需要返回不同的結果,Ansible中一些常見的返回值如下:

  • changed:幾乎所有的Ansible模塊都會返回該變量,表示模塊是否對遠程主機進行了操作
  • failed:如果模塊未能執行完成,將返回failed和true
  • msg:模塊執行失敗的原因,常見的錯誤如ssh連接失敗,沒有執行權限等
  • rc:與命令行相關的模塊會返會rc,表示執行Linux名的返回碼
  • stdout:與rc相似,返回的是標準輸出的結果
  • stderr:與rc詳細,返回的是標準差錯誤輸出
  • backup_file:所有存在backup選項的模塊,用來返回備份文件的路徑
  • results:應用在Playbook中存在循環的情況,返回多個結果

YAML簡介

ansible中使用YAML基礎元素:

  • 變量
  • Inventory
  • 條件測試
  • 迭代

變量

變量僅能由字母、數字、下劃線組成,且只能以字母開頭
1.facts
facts是由正在通信的遠程目標主機返回的信息,這些信息被保存在ansible變量中,要獲取指定的遠程主機所所支持的facts,可以使用setup模塊。
2.register(註冊器)
把任務的輸入定義爲變量,然後用於其它任務

task:
- shell:/usr/bin/foo
  register: foo_result
  ignore_errors: True

- name: test
  shell: echo ‘hello world'
  when: foo_result.success    # when條件判斷foo_result

3.通過命令行傳遞變量
在運行playbook的時候也可以傳遞一些變量提供playbook使用:

ansible-playbook test.yaml --extra-vars 'hosts=www user=www'

4.通過roles傳遞變量
當給一個主機角色的時候,可以傳遞變量,然後在角色內使用這些變量

- host: webservers
  roles:
    - common                                                   # common 角色
    - {roles:foo_app_instance,dir:'/var/lib/html',port:8080}   # 傳遞變量參數

Inventory

ansible的主要功能在於批量主機操作,爲了便捷地使用其中的部分主機,可以在Inventory file中講其分組命名,默認的Inventory file爲/etc/ansible/hosts。

1.文件格式
Inventory文件遵循INI文件風格,中括號中的字符表示組名。可以將同一個主機同時歸併到多個不同的組中,此外,當如果目標主機使用了非默認的SSH端口,還可以在主機名稱之後使用冒號加端口號來標明。

192.168.1.1         # 直接列出主機

[web]
192.168.1.2
www.daxin.com

[web]
db[1:3].daxin.com   # 表示 db1.daxin.com db2.daxin.com db3.daxin.com

# 字母或者數字是連續的那麼,可以使用列表的方式進行標識

2.主機變量
可以在 Inventory 中自定義主機時爲其添加主機變量以便於在playbook中使用

[nginx]
127.0.0.1 http_port=8080 user=daxin

PS:定義主機時傳遞的專有的變量,在playbook中可以直接調用

3.組變量
組變量是指賦予給指定組內所有主機上的在playbook中可用的變量。

[nginx]
192.168.1.1
192.168.1.2

[nginx:vars]      # 固定用法                  
ntp_server = ntp1.daxin.com
nfs_server = nfs1.daxin.com 

4.組嵌套
inventory 中,組還可以包含其他組,並且也可以向組中的主機指定變量,不過,這些變量只能在ansible-playbook中使用,而ansible不支持。

[nginx]
192.168.1.1

[apache]
192.168.1.2

[web:children]        # 引用其他組作爲自己組內的主機(子組)
nginx                 # nginx組
apache                # apache組 

5.inenvtory 參數
ansible基於ssh連接inventory中指定的遠程主機時,還可以通過參數指定其交互方式:

- ansible_ssh_user : 用於指定管理遠程主機的帳號
- ansible_ssh_host : 用於指定被管理的主機
- ansible_ssh_port :用於指定ssh的端口
- ansible_ssh_private_key_file :指定key文件
- host_key_checking=False :當第一次連接主機時,會提示yes/no,跳過此次環節
- ansible_ssh_pass : 用於ssh登錄的密碼
- ansible_sudo_pass : 用於用戶sudo時的密碼
- ansible_connection : 連接客戶端的類型(local,ssh,paramiko), 1.2版本以前模式爲paramiko,後面版本爲ssh

條件測試

如果需要根據變量,facts或此前任務的執行結果來做爲某task執行與否的前提時要用到條件測試。

when語句:在task後添加when子句即可使用條件測試:when語句支持Jinja2表達式語法

tasks:
- name: 'shutdown redhat system'
  command: /sbin/shutdown -h now
  when: ansible_os_family == 'redhat'     # ansible_os_family 是 setup中收集到的信息,這裏可以直接進行調用

迭代

當有需要重複性執行的任務時,可以使用迭代機制,其使用格式爲將需要迭代的內容定義爲item變量引用,並通過with_items語句來指明迭代的元素列表即可。

tasks:
  - name: add user
    user: name={{ item }} state=present groups=wheel # 必須要用 {{item}} 來表示迭代。
    with_items:
      - daxin1
      - daxin2

# 等同於:

tasks:
  - name: add user
    user: name=daxin1 state=present groups=wheel
  - name: add user
    user: name=daxin2 state=present groups=wheel

事實上,with_items中還可以使用元素爲hashes,例如:

tasks:
  - name: add users
    user: name={{item.name}} state=parsent groups={{items.group}}
    with_items:
      - {name:'daxin',group='daxin'}
      - {name:'daxin2',group='daxin2'}

注意:with_items中的列表值也可以是字典,但引用時要使用item.key

playbook簡介

playbook是由一個或多個play組成的列表。play的主要功能在於將事先歸併爲一組的主機裝扮成通過ansible中的task定義好的角色。從根本上講,所謂task無非是調用ansible的一個module。將多個play組織在一個playbook中,即可讓他們聯合起來按事先編排的機制完成某一任務。

PS:有一個形象的比如,Ansible中的模塊類似於Linux下的命令,而Ansible的Playbook則類似於Linux下的shell腳本。Shell腳本將各個Linux命令組合起來,以此實現複雜的功能。

在Ansible中,一個play必須包含兩部分內容,hosts,tasks,play配置文件例如:

[root@linux-node2 ~]# cat httpd.yaml
--- #yaml的默認開頭格式
- hosts: test
  user: root
  vars:
    - info: 'hello world'
  tasks:
    - name: setup a infomation # task名稱
      copy: dest=/tmp/info content="{{info}}"
      notify: say something
  handlers:
    - name: say something # handlers名稱
      command: echo 'copy ok'

playbook的一般結構

一個playbook針對配置區域劃分,主要分爲4類:

  1. target section:定義將要執行playbook的遠程主機組
  2. variable section:定義playbook運行時需要使用的變量
  3. task section:定義將要在遠程主機上執行的任務列表
  4. handler section:定義task執行完以後需要調用的任務

細化一點的話playbook的結構爲:

Inventory:操作的主機 *
Modules:使用的模塊 *
Ad Hoc Commands:在主機上指定的命令
Playbooks
  Tasks:任務,即調用模塊完成的某操作 *
  Variables:變量
  Templates:模板
  Handlers:處理器,由某事件觸發完成的操作
  Roles:角色

target 配置項目

- hosts:定義遠程的主機組
- user:執行該任務的用戶
- remote_user: 遠端運行該play的用戶,可以細分到每一個task
- *sudo:如果設置爲yes,執行該任務組的用戶在執行任務的時候,獲取root權限
- *sudo_user: 如果你設置user爲tom,速度設置爲yes,sudo_user爲jerry,則tom用戶則會獲取jerry用戶的權限
- connection:通過什麼方式連接到遠程主機,默認爲ssh
- become:是否提權
- become_method: 提權得方式(sudo)
- notify:當任務執行完畢後,通知handler section 中的任務模塊(出發執行)
- set_fact: 模塊可以自定義facts,這些自定義的facts可以通過template或者變量的方式在playbook中使用。如果你想要獲取一個進程使用的內存的百分比,則必須通過set_fact來進行計算之後得出其值,並將其值在playbook中引用。set_fact: innodb_buffer_pool_size_mb="{{ ansible_memtotal_mb / 2 }}"
- gather_facts:除非你明確說明不需要在遠程主機上執行setup模塊,否則會默認自動執行。如果你的確不需要setup模塊所傳遞過來的變量,你可以啓用該選項
# 可以使用setup獲取到的字典中的key,來渲染對應的值
# 當值的類型爲字典嵌套時,可以使用點來進行深入查找 {{ansible_eth0.ipv4.address}}
# 當值的類型爲列表時,{{ansible[0].xxx}} 

variable 可用的配置項目

- vars:定義一個變量。key:value,多個變量,可以使用{key:value,key2:value2}
- vars_files:定義一個變量文件。這裏列出變量文件的絕對路徑即可。 變量文件中的直接使用key:value定義即可。
- vars_prompt: 通過交互的方式輸入的值
- name:變量的值
- prompt:提示信息
- private:是否爲私有變量,yes | no, yes時輸入的變量不在屏幕上顯示,否則會顯示在屏幕上

task 配置項目

play的主體部分是task list,task list中的各任務被按次序在hosts中 指定的所有主機上運行,即在所有主機上完成第一個任務後再開始第二個。在運行自上而下某個playbook時,如果中途發生錯誤,所有已執行任務都可以能回滾,因此在更正playbook後重新執行一次即可。

task的目的是使用指定的參數運行模塊,而在模塊參數中可以使用變量,模塊執行是冪等的,這意味着多次執行是安全的,因爲其結果一致。

每個task都應該有其name,用於playbook的執行結果輸出,建議其內容儘可能清晰的描述任務執行步驟。如果未提供name,則action的結果將用於輸出。

定義任務的三種方式

# 方式1(action)
- name: task的名稱
  action:要做的操作
# 例如: action: yum name= httpd state=installed

# 方式2(直接寫模塊名)
- name: task的名稱
  copy: src=files/httpd.conf dest=/etc/httpd/conf/httpd.conf

# 方式3(模塊名時,模塊的參數也可以用下列方式使用)
- name: task的名稱
  service:
    name:httpd
    state:restarted

在衆多模塊中只有command和shel模塊僅需要給定一個列表而無需使用key=value格式

tasks:
- name: disable selinux
  command: /sbin/setenforce 0

如果命令或腳本的輸出碼不以0,可以使用如下方式替代

tasks:
- name: run this command and ignore the result
  shell: /usr/bin/somecommand || /bin/true     # 強行成功

或者使用ignore_errors來忽略錯誤信息

tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand
    ignote_errors:True

常用參數:

- ignote_errors: 是否忽略錯誤
- register: 註冊變量,即把當前任務的結果註冊到register指定的變量後,在後續的task中可以進行調用,或者判斷
- when:當when後面的條件爲真時纔會執行當前task,一般配合register來做,當然,when也可以讀取變量

# when支持多條件

# 1、當多個條件是列表時,它們之間是並且的關係
when:
- ansible_distribution == "Centos"
- ansible_distribution == "ubuntu"

# 2、如果要表達更復雜的關係,可以用and/or,
when: (ansible_distribution == "Centos" and ansible_distribution_major_version == "6" ) or (ansible_distribution == "ubuntu")

handler 配置項目

用於通知操作:

  • Handlers 也是一些 task 的列表,通過名字來引用,它們和一般的 task 並沒有什麼區別。
  • Handlers 是由tasks配置中notify進行通知, 如果沒有被通知,則不會執行。
  • 定義多個notify,都需要等到tasks執行完畢後,handlers才執行,且僅一次。
  • Handlers 最佳應用場景:用來重啓服務,或者觸發系統重啓操作。

例子:

tasks:
  - name: template configuration file
    template: src=template.j2 dest=/etc/configuration.conf
    notify:
      - restart memcached

handlers:
  - name: restart memcached
    service: name=memcached state=restart

ansible-playbook命令

playbook需要使用ansible-playbook來運行,它具有ansible的部分參數,以及自己獨有的參數:

  • --list-tasks:列出playbook的任務列表。
  • --step:每執行一個任務後停止,等待用戶確認。(yes/no/continue,yes會繼續下一個task,continue會執行完當前play,下一個play再次等待用戶輸入)
  • --syntax-check:檢查playbook的語法
  • -C --check:檢查當前這個playbook是否會修改遠程服務器,相當於預測playbook的執行結果

其他配置

tags: 在playbook中,可以爲某個任務或某些任務定義一個“標籤”,在執行此playbook時,通過爲ansible-playbook 使用 --tags選項能實現僅指定的tasks,而非所有的。

tasks:
  - name: user add
    user: name='daxin' state=parsent
  - name: config file
    file: src=/tmp/daxin.txt dest=/tmp/daxin.txt
    tags:
    - copyfile

# 運行時
ansible-playbook test.yaml --tags='copyfile'

include:在playbook中,一般情況下,一個yaml文件包含一個play,比如我要同時安裝db.yaml 和 web.yaml,那麼我們可以用include的方式來進行聚合

cat all.yaml
---
- include:db.yaml
- include:web.yaml

這時只需要執行all.yaml即可。 ansible all all.yaml

strategy: free,任務策略
默認情況下,ansible是按照順序執行task的,當匹配到的所有主機執行完task1後,再繼續指定task2。
從Ansible 2.0開始,ansible支持free的任務執行策略,允許較快的遠程服務器提前完成play的部署,不用等待其他遠程服務器一起執行task。

更多知識: https://github.com/lorin/ansible-quickref

Roles

ansible自1.2版本引入的新特性,用於層次性、結構化地組織playbook,roles能夠根據層次型結構自動裝載變量文件、tasks以及handles等。要使用roles,只需要在playbook中使用include指令即可。簡單來講,roles就是通過分別將變量、文件、任務、模塊及處理器放置於單獨的目錄中,並可以便捷的通過include它們的一種機制。角色一般用於基於主機構建服務的場景中,但也可以是用於構建守護進程等場景中。

創建roles的步驟

  • 創建以roles命名的目錄
  • 在roles目錄中分別創建以各角色名稱命名的目錄
  • 在每個角色命名的目錄中,分別創建files,handlers,meta,tasks,templates和vars目錄;用不到的可以創建爲空目錄,或者不創建
  • 在playbook文件中,調用各角色

role內各目錄中的文件說明

tasks目錄:至少應該包含一個main.yml的文件,其定義了此角色的任務列表;此文件可以使用include包含其他的位於此目錄的task文件
files目錄:存放由copy或script等模塊調用的文件
templates目錄:templates模塊會自動在此目錄中尋找Jinja2模版文件
handlers目錄:此目錄中應該包含一個main.yml
yml文件,用於定義此角色用到的各handler,在handler中使用include包含的其他handler文件也應該位於此目錄中
vars目錄:應當包含一個main.yml文件,用於定義此角色用到的變量
meta目錄:應當包含一個main.yml文件,用於定於此角色的特殊設定及依賴關係,ansible1.3 以後才支持
default目錄: 爲當前角色設定默認變量時使用此目錄,應當包含一個main.yml文件

例子:

# 目錄結構:
├── db.yaml
└── roles
└── db
├── files
├── handler
├── tasks
│   └── main.yml
├── templates
│   └── my.cnf.j2
└── vars
└── main.yml

# db.yaml 文件
- hosts: test
  roles:
    - db

# tasks.main.yml 文件
---
- name: Install MySQL
  yum:
    name: mariadb-server
    state: present

- name: copy File
  template:
    src: "my.cnf.j2"
    dest: "/etc/my.cnf"

- name: Start MySQL
  service:
    name: mariadb
    state: started

# vars.main.yml 文件
---
mysql_port: 3307

# templates.my.cnf.j2 文件
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
port = {{ mysql_port }}
bind = {{ ansible_all_ipv4_addresses[0] }}

[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid<br><br># 運行<br>ansible-playbook -i hosts db.yaml

ansible-galaxy 命令

我們可以利用ansible-galaxy來快速創建並初始化一個roles

ansible-galaxy init roles/mysql

我們在galaxy.ansible.com 上找到適合自己的roles時,只需要運行 ansible-galaxy install 作者id.角色包名稱即可完成安裝

# 安裝別人寫好的roles:(galaxy.ansible.com)
ansible-galaxy install -p /etc/ansible/roles bennojoy.mysql
# 安裝到指定目錄
ansible-galaxy -p ./roles install bennojoy.ntp

默認情況下role存放在/etc/ansible/roles目錄,也可以在ansible.cfg 中 使用 roles_path ,來制定roles的目錄

列出已經安裝的roles:

ansible-galaxy list

查看已安裝的roles信息:

ansible-galaxy info bennojoy.mysql

卸載roles:

ansible-galaxy remove bennojoy.mysql

所有巧合的是要麼是上天註定要麼是一個人偷偷的在努力。

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