安裝ansible
1.yum安裝:
RHEL(Centos)7版本:
rpm -Uvh http://mirrors.zju.edu.cn/epel/7/x86_64/e/epel-release-7-8.noarch.rpm
yum install ansible
2.Apt(Ubuntu)安裝方式:
apt-get install software-properties-common
apt-add-repository ppa:ansible/ansible
apt-get update
apt-get install ansible
3.homebrew (Mac OSX)安裝方式
brew update
brew install Ansible
4.通過pip安裝:
sodu easy_install pip
pip install ansible
如果是在OS X系統(tǒng)上安裝路召,編譯器可能會有警告或出錯,需要設(shè)置CFLAGS、CPPFLAGS環(huán)境變量:
sudo CFLAGS=-Qunused-arguments CPPFLAGS=-Qunused-arguments pip install ansible
配置運行環(huán)境
Ansible環(huán)境
Ansible 配置文件是以.ini格式存儲配置數(shù)據(jù)的,在Ansible中蒋失,幾乎所有的配置項都可以通過Ansible的playbook或環(huán)境變量來重新賦值月匣。在運行Ansible命令式,命令將會按照預(yù)先設(shè)定的順序查找配置文件遭殉,如下所示:
1)ANSIBLE_CONFIG: 首先毡鉴,Ansible命令會檢查環(huán)境變量崔泵,及這個環(huán)境變量指向的配置文件秒赤。
2)./ansible.cfg: 其次,將會檢查當(dāng)前目錄下的ansible.cfg配置文件
3)~/ansible.cfg: 再次憎瘸,將會檢查當(dāng)前用戶home目錄下的.ansible.cfg配置文件
- /etc/ansible/ansible.cfg: 最后入篮,將會檢查再用軟件包管理工具安裝Ansible時自動產(chǎn)生的配置文件。
ansible.cfg常用配置參數(shù)
1.inventory 這個參數(shù)表示資源清單inventory文件的位置幌甘,資源清單就是被管理主機列表潮售。如:inventory = /etc/ansible/hosts
2.forks 設(shè)置默認情況下Ansible最多能有多少個進程同時工作,默認設(shè)置最多5個進程并行處理锅风。如: forks = 5
3.sudo_user 這是設(shè)置默認執(zhí)行命令的用戶酥诽,如: sudo_user = root
4.remote_port 這是制定連接被管節(jié)點的管理端口,默認是22皱埠。除非設(shè)置了特殊的SSH端口肮帐,不然這個參數(shù)一般是不需要修改的。如:reomte_ssh = 22
5.timeout 這是設(shè)置SSH連接的超時間隔边器,單位是秒训枢。配置示例如下:timeout = 60
第一條ansible命令
編輯(或創(chuàng)建)/etc/ansible/hosts文件,在其中加入被管理的遠程主機:
[merge]
10.0.81.31
10.0.81.32
10.0.81.33
注意:你的public SSH key必須在這些系統(tǒng)的“authorized_keys”中
使用list-hosts參數(shù)進行驗證:
現(xiàn)在對你的管理節(jié)點運行一個命令:
inventory文件
主機與組
Ansible 可同時操作屬于一個組的多臺主機,組和主機之間的關(guān)系通過 inventory 文件配置. 默認的文件路徑為 /etc/ansible/hosts
/etc/ansible/hosts 文件的格式與windows的ini配置文件類似:
[webservers]
foo.example.com
bar.example.com
[dbservers]
one.example.com
two.example.com
three.example.com
方括號[]中是組名,用于對系統(tǒng)進行分類,便于對不同系統(tǒng)進行個別的管理忘巧。
一個系統(tǒng)可以屬于不同的組,比如一臺服務(wù)器可以同時屬于 webserver組 和 dbserver組.這時屬于兩個組的變量都可以為這臺主機所用
如果有主機的SSH端口不是標準的22端口,可在主機名之后加上端口號,用冒號分隔恒界,如下:
badwolf.example.com:5309
假設(shè)你有一些靜態(tài)IP地址,希望設(shè)置一些別名,但不是在系統(tǒng)的 host 文件中設(shè)置,又或者你是通過隧道在連接,那么可以設(shè)置如下:
jumper ansible_ssh_port=5555 ansible_ssh_host=192.168.1.50
在這個例子中,通過 “jumper” 別名,會連接 192.168.1.50:5555.
一組相似的 hostname , 可簡寫如下:
[webservers]
www[01:50].example.com
數(shù)字的簡寫模式中,01:50 也可寫為 1:50,意義相同.你還可以定義字母范圍的簡寫模式:
[databases]
db-[a:f].example.com
對于每一個host,你還可以選擇連接類型和連接用戶名:
[targets]
localhost ansible_connection=local
other1.example.com ansible_connection=ssh ansible_ssh_user=mpdehaan
other2.example.com ansible_connection=ssh ansible_ssh_user=mdehaan
主機變量
分配變量給主機的方式:
[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909
組的變量
也可以定義屬于整個組的變量:
[atlanta]
host1
host2
[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
把一個組作為另一個組的子成員
可以把一個組作為另一個組的子成員,以及分配變量給整個組使用. 這些變量可以給 /usr/bin/ansible-playbook 使用,但不能給 /usr/bin/ansible 使用:
[atlanta]
host1
host2
[raleigh]
host2
host3
[southeast:children]
atlanta
raleigh
[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2
[usa:children]
southeast
northeast
southwest
northwest
分文件定義 Host 和 Group 變量
在 inventory 主文件中保存所有的變量并不是最佳的方式.還可以保存在獨立的文件中,這些獨立文件與 inventory 文件保持關(guān)聯(lián). 不同于 inventory 文件(INI 格式),這些獨立文件的格式為 YAML.
假設(shè) inventory 文件的路徑為:
/etc/ansible/hosts
假設(shè)有一個主機名為 ‘foosball’, 主機同時屬于兩個組,一個是 ‘raleigh’, 另一個是 ‘webservers’. 那么以下配置文件(YAML 格式)中的變量可以為 ‘foosball’ 主機所用.依次為 ‘raleigh’ 的組變量,’webservers’ 的組變量,’foosball’ 的主機變量:
/etc/ansible/group_vars/raleigh
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foosball
Tip: Ansible 1.2 及以上的版本中,group_vars/ 和 host_vars/ 目錄可放在 inventory 目錄下,或是 playbook 目錄下. 如果兩個目錄下都存在,那么 playbook 目錄下的配置會覆蓋 inventory 目錄的配置
Parallelism and Shell Commands
目前ansible自帶很多模塊,我們可以使用ansible-doc -l顯示所有自帶模塊砚嘴,還可以通過?ansible-doc "模塊名"十酣,查看模塊的介紹以及案例。
下面舉一些常見的命令:
1.shell命令
-o, --one-line Try to output everything on one line.
2.復(fù)制文件
3.包和服務(wù)管理
playbook
Playbooks 是 Ansible的配置,部署,編排語言.他們可以被描述為一個需要希望遠程主機執(zhí)行命令的方案,或者一組IT程序運行的命令集合.
playbook 文件格式為YAML語法枣宫,在編寫playbook前需要對YAML有一定的了解婆誓,關(guān)于YAML語法可以通過 yaml官網(wǎng)進行學(xué)習(xí)。
playbook 由一個或多個 ‘plays’ 組成.它的內(nèi)容是一個以 ‘plays’ 為元素的列表也颤。在 play 之中,一組機器被映射為定義好的角色.在 ansible 中,play 的內(nèi)容,被稱為 tasks,即任務(wù).在基本層次的應(yīng)用中,一個任務(wù)是一個對 ansible 模塊的調(diào)用,
下面一個 playbook示例,其中僅包含一個 play:
---
- hosts: webservers
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: pkg=httpd state=latest
- name: write the apache config file
template: src=/srv/httpd.j2 dest=/etc/httpd.conf
notify:
- restart apache
- name: ensure apache is running
service: name=httpd state=started
handlers:
- name: restart apache
service: name=httpd state=restarted
在 ansible-examples 中有很多實例,如果你希望深入學(xué)習(xí)可以在單獨的頁面打開它郁轻。
Task
每一個 play 包含了一個 task 列表(任務(wù)列表).一個 task 在其所對應(yīng)的所有主機上(通過 host pattern 匹配的所有主機)執(zhí)行完畢之后,下一個 task 才會執(zhí)行.
playbook變量與引用
1.通過inventory文件定義主機以及主機變量
在/etc/ansible/hosts中定義主機組和組變量如下:
merge]
10.0.81.31
10.0.81.32
10.0.81.33
[merge:vars]
key=test
創(chuàng)建playbook文件test.yaml如下:
---
- hosts: merge
gather_facts: False
tasks:
- name: display Host Variable from hostfile
debug: msg="The key value is {{ key }}"
運行playbook文件:
2.通過文件定義主機以及主機組變量
我們可以通過host_vars和group_vars目錄來針對主機和主機組定義變量翅娶。
使用yum安裝Ansible的配置文件在/etc/ansible/目錄下,我們在該目錄下新建host_vars和group_vars目錄,如下:
3.通過ansible-playbook命令行傳入
可以通過-e 命令傳入變量
ansbile-playbook test.yaml -e "key=test"
ansible-playbook目前還支持YAML和JSON的方式傳入變量
cat var.yaml
---
key: test
cat var.json
{"key": "test"}
4.可以在playbook文件內(nèi)通過vars字段定義變量
5.可以在playbook文件內(nèi)通過vars_files字段引用變量好唯,首先把所有的變量定義在某個文件內(nèi)竭沫,然后再playbook文件內(nèi)使用vars_files參數(shù)引用這個變量文件
6.使用register內(nèi)的變量
Ansible playbook內(nèi)task之間可以互相傳遞數(shù)據(jù),比如第2個task需要獲得第1個task的執(zhí)行結(jié)果骑篙。
我們可以通過下面的方式:
vim test01.yaml
---
- hosts: merge
gather_facts: False
tasks:
- name: register variable
shell: hostname
register: info
- name: display variable
debug: msg="The key value is {{ info }}"
info的結(jié)果是一段python字典數(shù)據(jù)蜕提,里面存儲著很多信息,包括執(zhí)行時間狀態(tài)變化輸出等靶端。
變量的優(yōu)先級
如果同樣名稱的變量在多個地方都有定義,那么采納是有個確定的順序,如下:
1.xtra vars (在命令行中使用 -e)優(yōu)先級最高谎势,如:ansible-playbook -e var=value
2.然后是在inventory中定義的連接變量(比如ansible_ssh_user)
3.接著是大多數(shù)的其它變量(命令行轉(zhuǎn)換,play中的變量,included的變量,role中的變量等)
4.然后是在inventory定義的其它變量
5.然后是由系統(tǒng)發(fā)現(xiàn)的facts
6.然后是 "role默認變量", 這個是最默認的值,很容易喪失優(yōu)先權(quán)
playbook 循環(huán)
1.標準loops
example:
---
- hosts: merge
gather_facts: False
tasks:
- name: debug loops
debug: msg="name ----------> {{ item }}"
with_items:
- one
- two
with_items的值是python list數(shù)據(jù)結(jié)構(gòu)凛膏, 可以理解為每個task會循環(huán)讀取list里面的值,然后key的名稱是item
在copy和tempalate模塊里面,你能夠使用ansible去查找一組的文件.然后默認使用第一個文件.這能夠讓你達到效果是,當(dāng)?shù)谝粋€文件不存在時,會查找第二個文件,如此類推知道最后一個文件還不存在就報fail.使用first_available_file這個關(guān)鍵字便可以到上述效果.
---
- name: Install an Apache config file
hosts: ansibletest
user: root
tasks:
- name: Get the best match for the machine
copy: dest=/etc/apache.conf src={{ item }}
first_available_file:
- files/apache/{{ ansible_os_family }}-{{ ansible_architecture }}.cfg
- files/apache/default-{{ ansible_architecture }}.cfg
- files/apache/default.cfg
2.嵌套loops
---
- hosts: merge
gather_facts: False
tasks:
- name: debug loops
debug: msg="name ----------> {{ item[0] }} ---------> {{ item[1] }}"
with_nested:
- ['A']
- ['a','b','c']
3.條件判斷l(xiāng)oops
有時候執(zhí)行一個task之后脏榆,我們需要檢測這個task的結(jié)果是否達到了預(yù)想狀態(tài)猖毫,如果沒有就需要退出整個playbook執(zhí)行,這個時候我們就需要對某個task結(jié)果一直循環(huán)檢測了须喂,如下所示:
---
- hosts: merge
gather_facts: False
tasks:
- name: debug loops
shell: cat /root/test.txt
register: host
until: host.stdout.startswith("test")
retries: 5
delay: 5
5秒執(zhí)行一次 cat /root/test.txt將結(jié)果register給host吁断,然后判斷host.stdout.startwith的內(nèi)容是不是test字符串開頭,如果條件成立坞生,此task運行完成仔役,如果條件不成立,5秒以后重試是己,5此后還不滿足條件骂因,此task運行失敗。
其他的循環(huán)還有:散列l(wèi)oops赃泡、文件匹配loops寒波、隨機選擇loops、文件優(yōu)先匹配loops升熊、register loops
playbook lookups
Ansible還支持從外部數(shù)據(jù)拉取信息俄烁,比如我們可以從數(shù)據(jù)庫拉取信息,然后賦值給一個變量级野。
1.lookups file
---
- hosts: merge
gather_facts: False
vars:
contents: "{{ lookup('file', '/root/openrc') }}"
tasks:
- name: debug lookups
debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
2.lookups password
lookup('password', 'file_path')
它會對傳入的內(nèi)容進行加密處理
playbook conditionals
目前Ansible所有conditionals方式都是通過使用when進行判斷页屠,when的值是一個條件表達式,如果條件判斷成立蓖柔,這個task就執(zhí)行某個操作辰企,否則,該task不執(zhí)行况鸣。
tasks:
- name: "shutdown Debian flavored systems"
command: /sbin/shutdown -t now
when: ansible_os_family == "Debian"
如果想查看哪些facts變量可以引用,可以在命令行上通過調(diào)用setup module命令可以查看
ansible hostname -m setup
TAGS
如果你有一個很大的playbook牢贸,而你只想run其中的某個task,這個時候tags是你的最佳選擇镐捧。
一潜索、最常見的使用形式:
tasks:
- yum: name={{ item }} state=installed
with_items:
- httpd
- memcached
tags:
- packages
- template: src=templates/src.j2 dest=/etc/foo.conf
tags:
- configuration
此時若你希望只run其中的某個task,這run 的時候指定tags即可:
ansible-playbook example.yml --tags "configuration,packages" #run 多個tags
ansible-playbook example.yml --tags packages # 只run 一個tag
相反懂酱,也可以跳過某個task
ansible-playbook example.yml --skip-tags configuration
二竹习、tags 和role 結(jié)合使用
tags 這個屬性也可以被應(yīng)用到role上,例如:
roles:
- { role: webserver, port: 5000, tags: [ 'web', 'foo' ] }
三列牺、tags和include結(jié)合使用
- include: foo.yml tags=web,foo
這樣整陌,fool.yml 中定義所有task都將被執(zhí)行
四、系統(tǒng)中內(nèi)置的特殊tags:
always、tagged泌辫、untagged随夸、all 是四個系統(tǒng)內(nèi)置的tag,有自己的特殊意義甥郑。
always: 指定這個tag 后逃魄,task任務(wù)將永遠被執(zhí)行,而不用去考慮是否使用了--skip-tags標記
tagged: 當(dāng) --tags 指定為它時澜搅,則只要有tags標記的task都將被執(zhí)行,--skip-tags效果相反
untagged: 當(dāng) --tags 指定為它時伍俘,則所有沒有tag標記的task 將被執(zhí)行,--skip-tags效果相反
all: 這個標記無需指定,ansible-playbook 默認執(zhí)行的時候就是這個標記.所有task都被執(zhí)行
Roles
怎樣組織 playbook 才是最好的方式呢勉躺?簡單的回答就是:使用 roles ! Roles 基于一個已知的文件結(jié)構(gòu)癌瘾,去自動的加載某些 vars_files,tasks 以及 handlers饵溅》镣耍基于 roles 對內(nèi)容進行分組,使得我們可以容易地與其他用戶分享 roles 蜕企。
一個項目的結(jié)構(gòu)如下:
site.yml
webservers.yml
fooservers.yml
roles/
common/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
webservers/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
如果 roles 目錄下有文件不存在咬荷,這些文件將被忽略。比如 roles 目錄下面缺少了 ‘vars/’ 目錄轻掩,這也沒關(guān)系幸乒。
當(dāng)一些事情不需要頻繁去做時晓铆,你也可以為 roles 設(shè)置觸發(fā)條件辛馆,像這樣:
---
- hosts: webservers
roles:
- { role: some_role, when: "ansible_os_family == 'RedHat'" }
Ansible最佳實踐
優(yōu)化Ansible速度
1.開啟SSH長連接
如果被管理機器的SSH -V版本高于5.6時,我們可以直接在ansible.cfg文件中設(shè)置SSH長連接庆锦。設(shè)置參數(shù)如下:
sh_args = -o ControlMaster=auto -o Controlpersist=5d
Controlpersist=5d 設(shè)置整個長連接保持時間為5天
2.開啟pipelining
如果開啟了pipelining ,生成好的本地Python腳本PUT到遠端服務(wù)器的過程會在SSH的會話中進行丐重,這樣可以大大提高整個執(zhí)行效率腔召。在ansible.cfg中設(shè)置:
pipelining = True
3.設(shè)置facts緩存
如果playbook不需要facts信息,可以在playbook中設(shè)置gather_facts:Fasle來提高playbook效率扮惦。但是如果我們既想在每次執(zhí)行playbook的時候能搜集facts,又想加速這個收集過程臀蛛,那么就需要配置facts緩存了。
可以在ansible.cfg中配置fact緩存使用redis:
[defaults]
gathering = smart
fact_caching = redis #jsonfile等径缅,使用json 需要指定fact_caching_connection指定存放路徑
fact_caching_timeout = 86400
灰度發(fā)布與檢測
1.語法檢測
在編寫完playbook或者role之后一定要養(yǎng)成進行語法檢測的習(xí)慣掺栅,直接使用ansible-playbook命令的 --syntax-check參數(shù)即可。
2.灰度發(fā)布
進行預(yù)運行之前纳猪,我們需要把一個或者多個task使用delegate_to參數(shù)指定到一臺設(shè)備上進行測試。
Ansible與openstack
---
- hosts: localhost
gather_facts: False
vars:
auth_url: http://10.0.84.52:35357/v3
login_username: admin
login_tenant_name: admin
login_password:
image_id: 63a7ea8d-2fc4-442b-8455-261b93aeb909
keypair_name: mykey
private_net: 1b3c98f2-7cbb-459f-bb1f-3dbb4facee13
flavor_id: 1
connection: local
tasks:
- name: create compute
nova_compute:
auth_url: "{{ auth_url }}"
login_username: "{{ login_username }}"
login_password: "{{ login_password }}"
login_tenant_name: "{{ login_tenant_name }}"
security_groups: default
state: present
name: "test-xue-01"
image_id: "{{ image_id }}"
key_name: "{{ keypair_name }}"
flavor_id: "{{ flavor_id }}"
region_name: RegionOne
nics:
- net-id: "{{ private_net }}"
register: openstack
- name: pull floating ip address
local_action: floating
auth_url={{ auth_url }} username={{ login_username }} password={{ login_password }} tenant={{ login_tenant_name }}
register: floating_ip
- name: bond flaoting ip to instance
local_action: bondip_openstack
auth_url={{ auth_url }} username={{ login_username }} password={{ login_password }} tenant={{ login_tenant_name }} instance_id={{ openstack.id }}floating_ip={{ floating_ip.res }}
更多資料可以查看:openstack-ansible
幾個實用的ansible命令:
1.管理域名解析器:
- name: Create DNS File
register: config_resolv
template: src=resolv.conf.j2 dest=/etc/resolv.conf
tags: firsthyper_init
由于我使用了role來組織playbook,roleresolv.conf.j2在相應(yīng)role的templates目錄下.
2.安裝常用軟件:
- name: Install ntp,puppet,rsync
register: install_package
yum: name={{item}} state=latest
with_items:
- ntpdate
- puppet
- rsync
3.同步時間
- name: Sync time
register: sync_time
shell: systemctl stop ntpd && sleep 5 && /usr/sbin/ntpdate {{ ntp_server }} 1 >/dev/null 2>&1 && systemctl start ntpd
ntp_server定義在group_vars中.
4.查看數(shù)據(jù)庫日志文件名稱
- name: Fetch Mysql Master Log File
register: master_log_file
shell: mysql -e "show master status" | grep mysql | awk '{print $1}'
delegate_to: "{{ mysql_master }}"