±à¼ÍƼö: |
±¾ÎÄÖ÷Òª½éÉÜÁËansibleÓÃÓÚ×Ô¶¯²¿ÊðºÍ»·¾³ÅäÖõÄʹÓÃÖ¸ÄÏ
£¬ÒÔ¼°´´½¨×Ô¶¨ÒåÄ£¿éºÍDocker£¬Ï£Íû¶ÔÄúµÄѧϰÓÐËù°ïÖú¡£
±¾ÎÄÀ´×ÔÓÚ²©¿ÍÔ°£¬ÓÉ»ðÁú¹ûÈí¼þAlice±à¼¡¢ÍƼö¡£ |
|
1 ΪʲôѡÔñAnsible
ÅäÖùÜÀí¡¢Ó¦Óò¿ÊðµÈ¡£ÅäÖùÜÀí¹¤¾ßÓÐChef, Puppet, SaltµÈ£¬Ó¦Óò¿Ê𣨽«´úÂë±àÒë»ò´ò°üÈ»ºó´«Êäµ½·þÎñÆ÷²¿Êð²¢Æô¶¯·þÎñ£©¹¤¾ßÓÐCapistrano£¬FabricµÈ£¬ansible¼¯Á½ÕßÓÚÒ»Éí£¬²Ù×÷ºÜ¼òµ¥µ«Êǹ¦ÄÜÇ¿´ó¡£´ËÍ⣬»¹¿ÉÒÔ¶Ô¶à¸ö·þÎñÆ÷½øÐзþÎñ±àÅÅ£¬Ö§³Öopenstack£¬amazon
ec2£¬ dockerµÈ¡£
ansibleʹÓÃÁËÒ»¸öDSL£¨domain-specific language£©ÃèÊö·þÎñÆ÷״̬¡£Ö´ÐеÄÎļþ³ÆÎªplaybook£¬Îļþ¸ñʽΪyaml¡£ansible¼òÔ¼¶ø²»¼òµ¥¡£±ÈÆðpuppetµÄ·±ËöµÄÅäÖú͸´ÔÓÓï·¨(
Puppet»ù´¡Æª4-°²×°¡¢ÅäÖò¢Ê¹ÓÃPuppet | PuppetÔËά×Ô¶¯»¯¾Ñé·ÖÏí )£¬¼òÖ±ÊÇÒ»¹ÉÇåÁ÷¡£
ͼ2ÃèÊöÁËansibleÖ´Ðйý³Ì£¬Ö´ÐÐÁËÁ½¸ötaskºÍÒ»¸öhandler£¬ÏÈÊÇʹÓÃÁËÒ»¸öaptÄ£¿éÔÚweb1£¬web2£¬web3ÉÏÃæÖ´ÐÐÁ˰²×°nginxµÄÈÎÎñ£¬ÔÙÊÇÓÃtemplateÄ£¿é¿½±´ÁËÅäÖÃÎļþ¡£ÁíÍ⣬ִÐÐÁËÒ»¸önotify
nginxµÄhandlerÖØÆôÁËnginx¡£
Ö´ÐÐÁ÷³Ì£º
1. ´´½¨Ò»¸öpython½Å±¾ÓÃÓÚ°²×°nginx°ü¡£
2. ¿½±´python½Å±¾µ½web1£¬web2£¬web3¡£
3. ·Ö±ðÔÚweb1£¬web2£¬web3ÉÏÖ´Ðиýű¾¡£
4. µÈ´ý½Å±¾ÔÚËùÓзþÎñÆ÷ÉÏÖ´ÐÐÍê±Ï¡£
5. ½Ó×ÅÖ´ÐÐÏÂÒ»¸ötask¡£
×¢ÒâµÄ¼¸µã£º
1.ÔÚ¸÷¸ö·þÎñÆ÷Ö´Ðнű¾µÄ¹ý³ÌÊDz¢Ðеģ¬Óиöforks²ÎÊý¿ÉÒÔÖ¸¶¨£¬Ä¬ÈÏÊÇ5£¬¼´Ò»´Î¿ÉÒÔÔÚ5¸ö·þÎñÆ÷Éϲ¢ÐÐÖ´Ðнű¾¡£
2.ÒªÔÚËùÓеķþÎñÆ÷¶¼Ö´ÐÐÍêµÚÒ»¸ötaskºó²Å»á½Ó×ÅÖ´Ðеڶþ¸ötask¡££¨Ð°汾ÐÂÔöÁËÒì²½²ÎÊý£¬Ò»¸ö·þÎñÆ÷ÔÚÖ´ÐÐÍêÁËËüµÄÈÎÎñºó¿ÉÒÔ²»µÈÆäËû·þÎñÆ÷Ö´ÐÐÍêÖ±½ÓÖ´ÐÐÏÂÒ»¸ötask£©¡£
3.ansibleÖ´ÐÐÈÎÎñ˳ÐòÓëplaybookÖеÄ˳ÐòÒ»Ö¡£
ÓÅÊÆ£º
Óï·¨Ò×¶Á¡£yaml->jsonºÃ±Èmarkdown->html¡£ansibleµÄplaybook¿ÉÒÔ±»³ÆÖ®Îª¿ÉÒÔÖ´ÐеÄREADME¡£
Ô¶³ÌÖ÷»ú²»ÐèÒª°²×°Èκζ«Î÷¡££¨ÕâÓеã¿ä´óÁË£¬python2.5+(python2.4+simplejsonÄ£¿é)ºÍsshÊDZØÐëµÄ£¬µ±È»ÕâÏÖÔÚÒѾÊÇLinux·þÎñÆ÷±êÅäÁË£©
push-based¡£ÈçchefºÍpuppetÊÇpull-based£¬ÏȽ«ÎļþÐÞ¸ÄÍÆË͵½ÖÐÐÄ·þÎñÆ÷£¬ÆäËû·þÎñÆ÷µÄagent¶¨ÆÚÀȡеÄÅäÖùÜÀí½Å±¾²¢ÔÚ±¾»úÖ´ÐС£¶øÔÚansibleÊÇpush-basedµÄ£¬ÏÈÔÚÖÐÐÄ·þÎñÆ÷ÐÞ¸Äplaybook£¬Ö´ÐиÃplaybook£¬ansible»áÁ¬½Óµ½¸÷¸ö·þÎñÆ÷²¢Ö´ÐÐÄ£¿é¸Ä±ä·þÎñÆ÷״̬¡£push-basedµÄºÃ´¦¾ÍÊÇÖ»ÔÚÐèÒªµÄʱºò²Å²Ù¿ØÈ¥¸Ä±äÄ¿±ê·þÎñÆ÷״̬¡£Èç¹ûÄã¸üÇãÏòÓÚpull-basedģʽ£¬¿ÉÒÔÓÃansible-pull¡£
ansible¿ÉÒԺܷ½±ãµÄscaled down£¬µ¥»ú¸ú¶à»úûÓÐÊ²Ã´Çø±ð¡£
Simple things should be simple, complex things should
be possible ¡£
ºÜÇáÁ¿¼¶µÄ³éÏó¡£²»ÏñpuppetÖ®ÀàµÄ¹¤¾ß£¬ÓкܸߵijéÏ󣬱ÈÈçÓÐpackageÕâ¸ö¸ÅÄÓÃÓÚ²»ÓÃÇø·Ö·þÎñÆ÷°æ±¾À´°²×°Ä£¿é¡£µ«ÊÇÔÚansibleÖУ¬ÌṩµÄÊÇaptºÍyumÄ£¿é£¬ÓÉÄã×Ô¼º²ÉÓ㬲»ÒªÔÙ¶îÍâѧһЩ³éÏóµÄÓï·¨£¬¼ò»¯ÄãµÄѧϰ³É±¾¡£Ò²ÓÐÈ˾õµÃÕâÊÇansibleµÄȱµã£¬ÓÅȱµãÓë·ñ£¬¸÷ÓÐÆÀÅС£
2 °²×°ÅäÖÃ
2.1 °²×°
pip install ansible
ÒÀÀµ»·¾³£ºpython
2.2 ÅäÖÃ
ÅäÖÃansible.cfgÎļþ£¬ansibleÅäÖÃÎļþѰÕÒ·¾¶£º
1. File specified
by the ANSIBLE_CONFIG environment variable
2. ./ansible.cfg (ansible.cfg in the current directory)
3. ~/.ansible.cfg (.ansible.cfg in your home directory)
4. /etc/ansible/ansible.cfg |
ansible.cfgÅäÖÃÎļþʵÀý
[defaults]
hostfile=/etc/ansible/hosts
private_key_file = /Users/ssj/.ssh/id_rsa_ansible
remote_user = ssj
remote_port = 22
host_key_checking = False |
×¢Ò⣬Èç¹ûÊÇÔÚ·þÎñÆ÷ÉÏ£¬²»Òª·ÅÖÃprivate key£¬¿ÉÒÔͨ¹ýssh
forward¡£
2.3 ²âÊÔ
¼òµ¥Ö´ÐÐÃüÁî²âÊÔÊÇ·ñ³É¹¦ ( -vvvv¿ÉÒÔ¿´µ½¸ü¶àϸ½ÚÐÅÏ¢)£¬¡±changed¡±:false±íʾִÐÐpingÄ£¿éûÓиıä·þÎñÆ÷״̬£¬¡±ping¡±:pong±íʾģ¿éÖ´ÐкóÊä³ö½á¹ûΪpong¡£ÄãÒ²¿ÉÒÔ½«pingÄ£¿é¸Ä³Écommand£¬¼ÓÉϲÎÊýÖ´ÐÐÖ¸¶¨ÃüÁî¡£±ÈÈç
ansible testserver -m command -a uptime £¬µ±È»£¬commandÊÇĬÈÏÄ£¿é£¬Òò´Ë»¹¿ÉÒÔ¼ò»¯Îª
ansible testserver -a uptime ¡£
hosts
[testserver]
127.0.0.1
run command£¬-i hosts¿ÉÒÔʡȥ¡£
ssj@ssj-mbp ~/ansible $ ansible testserver -i
hosts -m ping
127.0.0.1 | SUCCESS => { "changed":
false, "ping": "pong"
} |
3 ʵÌå¹ØÏµÍ¼
playbook°üº¬ºÜ¶à¸öplay
playÖаüº¬name£¬tasks£¬hosts£¬vars£¬handlesÊôÐÔ¡£
tasksÖаüº¬¸÷¸öÕæÕýÖ´ÐеÄmodule£¬Èçapt£¬copy£¬file£¬
git£¬ svn£¬service£¬command£¬notify£¬mysqlµÈ¡£¾ßÌåµÄÄ£¿é²ÎÊýºÍʹÓÃÎĵµÔÚÕâÀï
4 Ò»¸öÀý×Ó
- name: Configure
webserver with nginx and tls
hosts: webservers
sudo: True
vars:
key_file: /etc/nginx/ssl/nginx.key
cert_file: /etc/nginx/ssl/nginx.crt
conf_file: /etc/nginx/sites-available/default
server_name: localhost
tasks:
- name: Install nginx
apt: name=nginx update_cache=yes cache_valid_time=3600
- name: create directories for TLS certificates
file: path=/etc/nginx/ssl state=directory
- name: copy TLS key
copy: src=files/nginx.key dest={{ key_file }}
owner=root mode=0600
notify: restart nginx
- name: copy TLS certificate
copy: src=files/nginx.crt dest={{ cert_file }}
notify: restart nginx
- name: copy nginx config file
template: src=templates/nginx.conf.j2 dest={{
conf_file }}
notify: restart nginx
- name: enable configuration
file: dest=/etc/nginx/sites-enabled/default src={{
conf_file }} state=link
notify: restart nginx
- name: copy index.html
template: src=templates/index.html.j2 dest=/usr/share/nginx/html/index.html
mode=0644
handlers:
- name: restart nginx
service: name=nginx state=restarted |
¿ÉÒÔ¿´µ½Óõ½ÁËapt£¬file£¬copy£¬template£¬notify£¬serviceµÈÄ£¿é¡£
×¢Ò⼸¸öÓï·¨µã£º
YAML truthy
true, True, TRUE, yes, Yes, YES, on, On, ON, y,
Y
YAML falsey
false, False, FALSE, no, No, NO, off, Off, OFF,
n, N |
trueºÍyes£¬on»òÕß1¶¼ÊÇÒ»ÑùµÄÒâ˼£¬Ò»°ãÔÚÄ£¿é²ÎÊýÀïÃæÓÃyesºÍno£¬trueºÍfalseÔÚplaybookÖÐÆäËûµØ·½¡£
ÁíÍ⣬±ÈÈçÏÂÃæµÄÄ£¿é²ÎÊý·ÖÐÐд£¬¿ÉÒÔÔÚµÚÒ»ÐÐд > £¬ ºóÃæ¼¸Ðиú²ÎÊýÀ´ÊµÏÖ¡£
×¢ÒânotifyÊÇÑϸñ°´ÕÕËüÔÚplayÖж¨ÒåµÄ˳ÐòÖ´Ðе쬶ø²»ÊÇnotifyµ÷ÓõÄ˳ÐòÖ´Ðеġ£±ÈÈçÏÂÃæµÄplaybook£¬¾¡¹ÜÏÈnotifyµÄÊÇ
handler test2 £¬Êµ¼ÊÖ´ÐÐʱʱ°´ÕÕplayÖÐhandlers¶¨ÒåµÄ˳Ðò£¬Ò²¾ÍÊÇÏÈÖ´ÐÐ handler
test1¡£
!/usr/bin/env
ansible-playbook
- name: test handlers
hosts: webservers
tasks:
- name: assure file exist
file: >
path=/tmp/test.conf
state=touch owner=ssj mode=0644
- name: task1
command: date
notify: handler test2
- name: task2
command: echo 'task2'
notify: handler test1
handlers:
- name: handler test1
command: echo 'handler test1'
- name: handler test2
command: echo 'handler test2' |
5 ¸ü¶àϸ½Ú
5.1 inventory¸ñʽºÍÅäÖÃ
inventory¸ñʽ
[webserver]
127.0.0.1
dbserver1 ansible_ssh_host=127.0.0.1 ansible_ssh_port=22
color=red
dbserver2 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2200
color=green
>www.example.com
[dbserver] group
dbserver1
dbserver2<
[forum:children] groups of groups
webserver
dbserver |
¿ÉÒÔÓ÷Ö×éµÄ·½Ê½£¬¿ÉÒÔÖ±½ÓÓÃÓòÃû(www.example.com)£¬Ò²¿ÉÒÔÓñðÃû(Èçtestserver2)+±äÁ¿Ö¸¶¨sshµÄipµØÖ·ºÍ¶Ë¿Ú£¬±ÈÈçansible_ssh_hostºÍcolor±äÁ¿¡£ÃüÁî
ansible testserver2 -a date £¬Í¨³£ÎÒÃÇÒª¿ØÖƶą̀·þÎñÆ÷£¬ÓÚÊÇ¿ÉÒÔ·Ö×é·þÎñÆ÷£¬ÒªÔÚËùÓзþÎñÆ÷Ö´ÐпÉÒÔÓÃall¡£
ansible all -a date¡£
inventory³ýÁË¿ÉÒÔÖ¸¶¨Ö÷»úµÄ±äÁ¿ÈçÉÏÃæµÄcolorÖ®Í⣬»¹¿ÉÒÔ½«±äÁ¿·Ö×飬Ҳ¿ÉÒÔ¶ÔÖ÷»ú±äÁ¿µ¥¶À´æ´¢µ½Ò»¸öÎļþÖУ¬¸ñʽÈçÏ£¬×¢ÒâÈç¹ûhost_varsÖкÍgroup_varsÖÐÓÐÏàͬ±äÁ¿£¬ÔòÒÔhost_varsÖеÄΪ׼¡£host_vars±äÁ¿Ö»Äܱ¾Ö÷»úʹÓã¬group_varsÊDZ¾group¶¼¿ÉÒÔʹÓá£
group_vars/dbserver
-----------------------
db:
user: bbsdbuser
password: bbsdbpasswd
port: 3306
name: bbs
replica:
host: slavedb
port: 3307
host_vars/dbserver1
---------------------
db:
user:server1dbuser
password: server1password
master: true
ssj@ssj-mbp ~/ansible $ ansible dbserver1 -i hosts
-a 'echo {{db.user}}' host_varsÓÅÏȼ¶¸ß
dbserver1 | SUCCESS | rc=0 >>
server1dbuser
----------------------------------------------------------
ssj@ssj-mbp ~/ansible $ ansible dbserver2 -i hosts
-a 'echo {{db.master}}' dbserver2ËùÔÚµÄ×é±äÁ¿ÎļþûÓÐdb.master±äÁ¿£¬±¨´í¡£
dbserver2 | FAILED | rc=0 >>
the field 'args' has an invalid value, which appears
to include a variable that is undefined. The error
was: 'dict object' has no attribute 'master' |
ÉõÖÁÖ§³Ö£º
[web]
web[1:20].example.com
web-[a-t].example.com |
inventoryÎļþ»¹Ö§³Ö¶¯Ì¬µÄ£¬Í¨¹ý -i inventory
¿ÉÒÔÖ¸¶¨Ä¿Â¼»òÕßÎļþ£¬ÕâÑùĿ¼ÏÂÃæ¿ÉÒÔ·ÅÒ»¸öpython½Å±¾£¬ÓÃÀ´¶¯Ì¬»ñÈ¡Ö÷»úÁÐ±í¡£python½Å±¾Òª¿ÉÖ´ÐУ¬Í¬Ê±ÊµÏÖÏÂÃæÁ½¸öÃüÁ
--host=<hostname>
for showing host details
--list for listing groups |
×îºó£¬»¹¿ÉÒÔͨ¹ýadd_hostsÄ£¿éÔÚÔËÐÐʱÔö¼ÓhostÅäÖã¬Ê¹ÓÃgroup_byÄ£¿éÔÚÔËÐÐʱ´´½¨group¡£±ÈÈçͨ¹ý
ansible_distributionÀ´¸ù¾Ý²Ù×÷ϵͳ´´½¨²»Í¬µÄ×飬ÔÙ·Ö±ð°²×°Èí¼þ¡£
- name: group
hosts by distribution
hosts: myhosts
gather_facts: True
tasks:
- name: create groups based on distro
group_by: key={{ ansible_distribution }}
- name: do something to Ubuntu hosts
hosts: Ubuntu
tasks:
- name: install htop
apt: name=htop
...
- name: do something else to CentOS hosts
hosts: CentOS
tasks:
- name: install htop
yum: name=htop
...
|
inventoryĬÈÏÅäÖÃ
¼¸¸ö²ÎÊý½âÊÍÏ£º
- ansible_connection: sshÁ¬½Ó·½Ê½£¬Ä¬ÈÏÊÇsmart£¬Ò²¾ÍÊÇ¿´±¾µØ»úÆ÷ÊÇ·ñ°²×°ÁËssh¿Í»§¶ËÇÒÖ§³ÖControlPersistÌØÐÔ¡£Èç¹ûÖ§³Ö£¬ÔòʹÓñ¾µØµÄssh¿Í»§¶Ë£¬Èç¹û²»Ö§³Ö£¬ÔòʹÓÃÒ»¸ö»ùÓÚpythonµÄssh¿Í»§¶Ë¿âparamiko¡£
- ansible_shell_type: ansibleÈÏΪµÄÔ¶³Ì·þÎñÆ÷Ö´ÐÐscriptµÄshell£¬Ä¬ÈÏÈÏΪÊÇ/bin/sh£¬µ±È»Ò²¿ÉÒÔÉèÖÃΪcsh£¬fishµÈ£¬Èç¹û·þÎñÆ÷Ö§³ÖµÄ»°¡£
- ansible_python_interpreter: ·þÎñÆ÷python½âÊÍÆ÷µÄ·¾¶¡£Èç¹ûÄãµÄ·þÎñÆ÷python½âÊÍÆ÷²»ÔÚÕâ¸öĿ¼£¬ÕâÒªÐ޸ĸÃÅäÖá£
- ansible_*_interpreter: Èç¹ûÓõÄÊÇÒ»¸ö×Ô¶¨ÒåµÄÄ£¿é£¬²»ÊÇpythonµÄ£¬±ÈÈçruby£¬ÔòÉèÖøÃÖµÖ¸¶¨½âÊÍÆ÷·¾¶£¨±ÈÈç/usr/bin/ruby£©¡£
5.2 ±äÁ¿ºÍFacts
±äÁ¿
±äÁ¿¿ÉÒÔÔÚplayÖÐͨ¹ývarsÀ´Ö¸¶¨£¬Ò²¿ÉÒÔͨ¹ývar_fileÖ¸¶¨Ò»¸öÎļþ£¬ÎļþÖд洢±äÁ¿¡£Èç֮ǰµÄnginxµÄplaybook¿ÉÒԸijÉÕâÑù£º
vars_files:
- nginx.yml
nginx.ymlÎļþÄÚÈÝ
key_file: /etc/nginx/ssl/nginx.key
cert_file: /etc/nginx/ssl/nginx.crt
conf_file: /etc/nginx/sites-available/default
server_name: localhost
|
¿ÉÒÔÔÚplayÖÐʹÓÃdebugÄ£¿é´òÓ¡±äÁ¿µÄÖµ£¬×¢ÒâdebugÖ§³ÖµÄ²ÎÊýÓÐvar£¬msgµÈ£¬varÖеıäÁ¿²»ÒªÊ¹ÓÃ
{{}}°ü¹ü¡£
!/usr/bin/env
ansible-playbook
- name: test name
hosts: webserver
vars:
myvar: testmyvar
tasks:
- debug: var=myvar
- name: capture output of id command
command: id -un
register: login
- debug: var=login |
ʹÓÃregisterÀ´×¢²áÒ»¸ö±äÁ¿ºóÃæÊ¹Óã¬register×¢²áµÄ±äÁ¿ÔÚÕâ¸öplaybookµÄÆäËûplayÖÐÒ²ÊÇ¿ÉÒÔʹÓõ쬲»¾ÖÏÞÓÚÕâÒ»¸öplay¡£±ÈÈçcommandÄ£¿éµÄÊä³öÈçÏÂËùʾ£¬¿ÉÒÔͨ¹ýlogin.stdoutµÃµ½Óû§Ãû¡£×¢Òⲻͬģ¿éµÄÊä³ö¿ÉÄÜÊDz»Ò»ÑùµÄ£¬Í¬Ò»¸öÄ£¿éÔÚ²»Í¬Çé¿öÏÂÒ²²»Ò»Ñù£¬±ÈÈçaptÄ£¿é°²×°nginx£¬Èç¹û»úÆ÷ÒѾ°²×°ÁËnginx£¬ÔòÊä³öÀïÃæchangeΪfalse£¬¶øÇÒ²»»áÓÐstdout£¬stderrºÍstdout_linesÕâЩkey¡£Èç¹ûÄ£¿éÖ´Ðгö´í£¬ÔòÆäËûµÄhostĬÈϲ»»áÔÙÖ´ÐУ¬¿ÉÒÔÉèÖÃ
ignore_erros:True ºöÂÔÄ£¿éµÄ´íÎó¡£
ÆäËûÖ¸¶¨±äÁ¿µÄ·½Ê½Èç host_varsĿ¼£¬group_varsĿ¼µÈ¡£
{ "changed":
true, "cmd": [ "id",
"-un"
], "delta": "0:00:00.007369",
"end": "2016-11-17 15:09:49.061725",
"rc": 0, "start":
"2016-11-17 15:09:49.054356", "stderr":
"", "stdout": "ssj",
"stdout_lines": [ "ssj"
], "warnings": []
} |
Èç¹ûÔÚplaybookÖÐÅäÖÃÁË gather_facts:True£¬Ôò»á¿´µ½ÕæÕýµÄÈÎÎñ¿ªÊ¼Ç°£¬»áÏÈÖ´ÐÐÒ»¸ö[setup]µÄÄ£¿é£¬ÓÃÓÚÊÕ¼¯·þÎñÆ÷ÐÅÏ¢£¬°üÀ¨cpu¼Ü¹¹£¬²Ù×÷ϵͳÀàÐÍ£¬ipµØÖ·µÈÐÅÏ¢¡£ÕâЩÐÅÏ¢´æ´¢ÔÚÌØ¶¨µÄ±äÁ¿ÖУ¬ÎÒÃdzÆÖ®Îªfacts¡£Èç¹ûÄãµÄplaybookÖв»ÐèÒªÕâЩÐÅÏ¢£¬Ò²¿ÉÒÔÉèÖÃgather_facts:FalseÀ´¼Ó¿ìplaybookÖ´ÐÐËÙ¶È£¬ÊÕ¼¯·þÎñÆ÷ÐÅÏ¢ÐèÒª»¨·Ñ²»ÉÙʱ¼äµÄ¡£
ͨ¹ýÃüÁî ansible webserver -m setup ¿ÉÒÔ¿´µ½ansibleµÄgathter_factsµÄÊä³öÄÚÈÝ£¬ÈíÓ²¼þÐÅÏ¢¶¼ÓС£ÒòΪÐÅϢ̫¶à£¬»¹¿ÉÒÔͨ¹ýÔÚsetupÄ£¿é¼ÓÉϲÎÊýfilterÀ´É¸Ñ¡ÄãÐèÒªµÄÄÚÈÝ£¬Èç¹ûÖ»ÐèÒªÍøÂçÐÅÏ¢£¬¿ÉÒÔÕâÑù£º
ansible webserver -m setup -a 'filter=ansible_eth*¡¯
£¬ÆäÖÐansible_factsÕâ¸ökeyÊǹ̶¨µÄ¡£
127.0.0.1 | SUCCESS
=> { "ansible_facts": { "ansible_eth0":
{ "active": true, "device":
"eth0", "ipv4": {
"address": "xxx.xxx.xxx.xxx",
"broadcast": "xxx.xxx.xxx.xxx",
"netmask": "xxx.xxx.xxx.xxx.xxx",
"network": "xxx.xxx.xxx.xxx"
}, "macaddress": "xx.xx.xx.xx.xx.xx",
"module": "bnx2",
"mtu": 1500, "pciid":
"0000:10:00.0", "promisc":
false, "type": "ether"
},
}, "changed": false
} |
¿ÉÒÔÔÚ¶¨Òå±¾µØfacts£¬ÔÚ /etc/ansible/facts.d/
Ŀ¼Ð½¨example.factÎļþ£¬ÄÚÈÝÈçÏ£º
[book]
title=Ansible: Up and Running
author=Lorin Hochstein
publisher=O'Reilly Media |
È»ºóÔÚÔËÐÐplaybookµÄʱºò¾Í¿ÉÒÔͨ¹ý ansible_local¶ÁÈ¡ÕâЩ±äÁ¿ÁË¡£
ÁíÍ⣬»¹¿ÉÒÔͨ¹ý set_fact Ä£¿éÉèÖñäÁ¿£¬±ÈÈç֮ǰµÃµ½ÁËÒ»¸öÃüÁîµÄÊä³ö£¬registerµ½Ò»¸ö±äÁ¿£¬È»ºó°ÑÎÒÃÇÐèÒªµÄ±äÁ¿ÌáÈ¡³öÀ´ÓÃset_fact´æ´¢µ½ÁíÍâÒ»¸ö±äÁ¿ÖУ¬¼ò»¯Á˱äÁ¿µÄÒýÓá£
- name: test name
hosts: webserver
gather_facts: True
tasks:
- name: print ansible_local
debug: var=ansible_local
- name: capture output of id command
command: id -un
register: login
ignore_errors: True
- set_fact: loginuser={{ login.stdout }}
- name: show login user
debug: var=loginuser
|
ÄÚÖñäÁ¿
ÃüÁîÐд«µÝ±äÁ¿
»¹¿ÉÒÔÔÚÔËÐÐplaybookµÄʱºòÔÚÃüÁîÐд«µÝ±äÁ¿¡£Èç¹ûÒª´«µÝÒ»¸ö°üº¬±äÁ¿µÄÎļþ£¬¿ÉÒÔÓÃ
$ ansible-playbook greet.yml -e @greetvars.yml ¡£
- name: pass a
message on the command line
hosts: localhost
vars:
greeting: "you didn't specify a message"
tasks:
- name: output a message
debug: msg="{{ greeting }}"
$ ansible-playbook greet.yml -e greeting=hiya
|
±äÁ¿ÓÅÏȼ¶
ansibleÔÚºÜ¶àµØ·½¿ÉÒÔÉèÖñäÁ¿£¬¾¡Á¿²»ÒªÖØÃû¡£ÓÅÏȼ¶Óɸߵ½µÍÈçÏ£º
- ÃüÁîÐеIJÎÊý£¬ ÉÏÃæµÄ -e greeting=¡®hello¡¯
¡£
- host, groupÖеıäÁ¿£¬²»¹ÜÊÇÔÚinventoryÖл¹ÊÇyamlÎļþÖж¨ÒåµÄ¡£
- Facts±äÁ¿
- roleĿ¼Ï嵀 defaults/main.yml ¡£
5.3 playbook񻵋
ʵÓÃÄ£¿é
Èç¹ûÏëÔÚ¿ØÖÆ»úÆ÷¶ø²»ÊÇÔ¶³Ì»úÆ÷ÔËÐÐÃüÁ¿ÉÒÔÓÃlocal_action¡£
Èç¹û»úÆ÷ûÓÐÆô¶¯ÆðÀ´£¬ÐèÒªÏȵȴý»úÆ÷Æô¶¯ÔÙÖ´ÐÐplay£¬ÓÃwait_forÄ£¿é¡£
- name: Deploy
mezzanine
hosts: web
gather_facts: False
vars & vars_files section not shown here
tasks:
- name: wait for ssh server to be running
local_action: wait_for port=22 host="{{ inventory_hostname
}}" search_regex=OpenSSH
- name: gather facts
setup: |
Èç¹û²»ÏëÒ»´ÎÔÚËùÓеÄhosts¶¼Ö´ÐУ¬¿ÉÒÔÉèÖÃserial²ÎÊýÀ´ÉèÖÃÿ´ÎÖ´Ðм¸¸öhost£¬±ÈÈçÉý¼¶·þÎñÆ÷£¬ÎÒÃDz»ÏëÓ°Ïì·þÎñ£¬»áÒ»¸öÒ»¸öÅÜ¡£¿ÉÒÔÉèÖÃmax_fail_percentageÀ´Ö¸¶¨×î´óʧ°ÜµÄ±ÈÂÊ£¬±ÈÈçÉèÖÃΪ25%£¬ÔòÈç¹ûÓÐ4̨»úÆ÷£¬ÓÐ2̨ÈÎÎñÖ´ÐÐʧ°ÜÔòÖÕÖ¹Õû¸öplay£¬ÆäËûÈÎÎñ²»ÔÙÖ´ÐС£
name: upgrade
packages on servers behind load balancer
hosts: myhosts
serial: 1
max_fail_percentage: 25
tasks:
tasks go here |
һЩÊý¾ÝÈçdbÃÜÂëµÈ²»ÄÜÖ±½ÓÌá½»µ½´úÂë¿â£¬¿ÉÒÔÌá½»Ò»¸ö¼ÓÃܵİ汾¡£¼ÓÃÜÎļþ¿ÉÒÔÓÃansible-vault¹¤¾ß¡£ÔËÐÐplaybookµÄʱºò¼ÓÉϲÎÊý
ansible-vault
encrypt secrets.yml
ansible-vault create secrets.yml
ansible-vault view secrets.yml
$ ansible-playbook test.yml --ask-vault-pass
$ ansible-playbook mezzanine --vault-password-file
~/password.txt
|
¿ÉÒÔÓÃðºÅ:±íʾºÏ²¢·þÎñÆ÷×飬:& Çó½»¼¯µÈ¡£
Ö¸¶¨ÔËÐеÄhosts¿ÉÒÔÔÚÃüÁîÐмÓÉÏ ¡ªlimit ¡£
ansible-playbook -l 'staging:&database'
playbook.yml
ansible-playbook ¡ªlimit 'staging:&database'
playbook.yml
Filters
filter¿ÉÒÔÓÃÔÚºÜ¶à·½Ãæ£¬±ÈÈçĬÈÏÖµfilter¡£Èç¹ûdatabase_hostûÓж¨Ò壬ÔòHOSTµÄÖµÉèÖÃΪlocalhost¡£
"HOST": "{{ database_host
| default('localhost') }}"
Õë¶ÔÈÎÎñ·µ»ØÖµµÄfilter¡£¿ÉÒÔµÄȡֵÓÐ failed£¬changed£¬skipped£¬successµÈ¡£
failed_when: result|failed
Îļþ·¾¶µÄfilter¡£
vars:
homepage: /usr/share/nginx/html/index.html
tasks:
- name: copy home page
copy: src=files/{{ homepage | basename }} dest={{
homepage }} |
×Ô¶¨Òåfilter¡£
дһ¸ö×Ô¶¨ÒåµÄfilter£¬·ÅÔÚÏîÄ¿µÄ filter_plugins
Ŀ¼Ï¼´¿É¡£ÏÂÃæÊÇÒ»¸öÓÃÓÚ×Ö·û´®·Ö¸îµÄfilterÄ£¿é£¬Ê¹ÓÃʱʹÓÃfilterÓï·¨¼´¿É¡£
from ansible import
errors
def split_string(string, seperator=' '):
try:
return string.split(seperator)
except Exception, e:
raise errors.AnsibleFilterError('split plugin
error: %s, string=%s' % str(e),str(string) )
class FilterModule(object):
def filters(self):
return {
'split' : split_string,
}
|
²éÕÒ±äÁ¿¿ÉÒÔͨ¹ýlookupʵÏÖ£¬Ö§³Öfile£¬redis£¬pipe£¬cvsfileµÈ¶àÖÖ¸ñʽ¡££¨redisµÄÐèÒª°²×°pythonµÄredisÄ£¿é£©
¸´ÔÓÑ»·
with_items
with_lines
with_fileglob
with_dict
...
debugÄãµÄplaybook
¼ì²éÓï·¨£ºansible-playbook
--syntax-check playbook.yml
²é¿´hostÁÐ±í£ºansible-playbook --list-hosts playbook.yml
²é¿´taskÁÐ±í£ºansible-playbook --list-tasks playbook.yml
¼ì²éģʽ(²»»áÔËÐÐ): ansible-playbook --check playbook.yml
diffģʽ(²é¿´Îļþ±ä»¯)£º ansible-playbook --check --diff
playbook.yml
´ÓÖ¸¶¨µÄtask¿ªÊ¼ÔËÐУºansible-playbook --start-at-task="install
packages" playbook.yml
Öð¸ötaskÔËÐУ¬ÔËÐÐǰÐèÒªÄãÈ·ÈÏ£ºansible-playbook --step playbook.yml
Ö¸¶¨tags£ºansible-playbook --tags=foo,bar playbook.yml
Ìø¹ýtags£ºansible-playbook --skip-tags=baz,quux playbook.yml |
6 ½ÇÉ«(Roles)
6.1 ½ÇÉ«»ù±¾½á¹¹
roles¿ÉÒÔ¼ò»¯playbook±àд£¬ÈÃplaybook¸üÇåÎúºÍ·½±ã¸´Óá£Ò»¸öÃûΪdatabaseµÄroleµÄĿ¼½á¹¹ÈçÏ£¬ÕâЩĿ¼¶¼ÊÇ¿ÉÑ¡µÄ£¬Èç¹ûÄãµÄ½ÇɫûÓÐÈκÎhandler£¬Ôò²»ÐèÒªhandlersĿ¼¡£rolesµÄ²éÕÒ·¾¶Ä¬ÈÏÊÇ/etc/ansible/roles£¬Ò²¿ÉÒÔÔÚ
/etc/ansible/ansible.cfgµÄroles_pathÖÐÉèÖá£
roles/database/tasks/main.yml
Tasks
roles/database/files/
Holds files to be uploaded to hosts
roles/database/templates/
Holds Jinja2 template files
roles/database/handlers/main.yml
Handlers
roles/database/vars/main.yml
Variables that shouldn¡¯t be overridden
roles/database/defaults/main.yml
Default variables that can be overridden
roles/database/meta/main.yml
Dependency information about a role
|
ÔÚ½ÇɫִÐÐÈÎÎñǰ×öһЩǰÖù¤×÷£¬ÈÎÎñÖ´ÐÐÍêºó×öһЩºóÖô¦Àí¡£
- name: test
hosts: dbserver
vars_files:
- secrets.yml
pre_tasks:
- name: update the apt cache
apt: update_cache=yes
roles:
- role: database
post_tasks:
- name: send email
command: xxx |
6.3 ÒÀÀµ½ÇÉ«
Èç¹ûÅÂÒÅ©һЩÈÎÎñ£¬±ÈÈçÉèÖÃntpÖ®ÀàµÄ£¬¿ÉÒÔʹÓÃÒÀÀµ½ÇÉ«µÄ¹¦ÄÜ¡£ÕâÑùÔÚÖ´ÐÐÄãµÄ½ÇÉ«ÈÎÎñʱ»áÏÈÖ´ÐÐÒÀÀµ½ÇÉ«¡£
roles/database/meta/main.yml
dependencies:
- { role: ntp, ntp_server=ntp.ubuntu.com } |
6.4 Ansible Galaxy
¿ÉÒÔͨ¹ýansible galaxy¹¤¾ß·½±ãµÄ´´½¨Ò»¸ö½ÇɫĿ¼¡£
ansible-galaxy
init -p playbooks/roles database |
Èç¹û²»ÓÃ-pÖ¸¶¨Â·¾¶£¬ÄÇôĬÈÏÊÇ»áÔÚµ±Ç°Ä¿Â¼´´½¨½ÇÉ«µÄĿ¼½á¹¹¡£´´½¨ºóµÄĿ¼½á¹¹ÈçÏ£º
playbook/roles/database
©À©¤©¤ README.md
©À©¤©¤ defaults
©¦ ©¸©¤©¤ main.yml
©À©¤©¤ files
©À©¤©¤ handlers
©¦ ©¸©¤©¤ main.yml
©À©¤©¤ meta
©¦ ©¸©¤©¤ main.yml
©À©¤©¤ tasks
©¦ ©¸©¤©¤ main.yml
©À©¤©¤ templates
©À©¤©¤ tests
©¦ ©À©¤©¤ inventory
©¦ ©¸©¤©¤ test.yml
©¸©¤©¤ vars
©¸©¤©¤ main.yml |
ansible galaxy»¹ÊÇÒ»¸ö¿ªÔ´µÄ½ÇÉ«¿â£¬Äã¿ÉÒÔÔÚÆäÖÐÏÂÔØµ½Ðí¶àÆäËûÈËдºÃµÄ½ÇÉ«´úÂë»òÕßÌá½»×Ô¼ºµÄ½ÇÉ«´úÂë¡£½ÇÉ«²Ö¿âµÄʹÓÃ˵Ã÷ÔÚÕâÀï¡£
6.5 Ansible Tower
ansible towerÊÇansible¹«Ë¾ÌṩµÄÒ»Ì×ÉÌÓõÄweb¹ÜÀíÆ½Ì¨£¬Ò²ÓÐÊÔÓð汾£¬»¹Ã»ÓÐÊÔÓùý£¬ºóÐøÊ¹ÓÃÁËÔÙ²¹³ä¡£
7 ¼ÓËÙÄãµÄansible
7.1 SSH ControlPersist
ControlMaster
auto
ControlPath $HOME/.ansible/cp/ansible-ssh-%h-%p-%r
ControlPersist 60s |
7.2 Pipelining£¨ansibleµÄÌØÐÔ)
ansibleͨ³£Ö´ÐеÄÔÀíÊÇÔÚ ~/.ansibleÏÂÃæ´´½¨Ò»¸öÁÙʱĿ¼(ͨ¹ýssh)£¬È»ºóͨ¹ýsftp»òÕßscp¿½±´python½Å±¾µ½ÁÙʱĿ¼£¬È»ºóÖ´ÐÐÕâ¸ö½Å±¾´úÂ루ÔÙ´Îͨ¹ýssh£©¡£Ê¹ÓÃpipeline¿ÉÒÔʹµÃÕâЩ²Ù×÷Ö»ÒªÒ»¸össhÁ¬½ÓÈ¥Ö´ÐÐpython½Å±¾¡£¼´±ãÊÇ¿ªÆôÁËControlPersist£¬Õâ¸öÐÔÄÜÌáÉýÒ²ºÜ¿É¹Û¡£ÔÚÅäÖÃÎļþÖмÓÈëpipelining=true¼´¿É¿ªÆô¡£
ÐèҪעÒâµÄÊÇ£¬¿ªÆôpipelingÒª¹Ø±Õ·þÎñÆ÷µÄrequiretty¹¦ÄÜ¡£Ôö¼ÓÎļþ/etc/sudoers.d/disable-requiretty£¬ÆäÖеÄÄÚÈÝΪ
Defaults:ansibleuser !requiretty£¬ansibleuserΪÄãµÄÓû§Ãû¡£
7.3 Fact Cache
Èç¹ûÄã²»ÐèÒªÓõ½·þÎñÆ÷ÐÅÏ¢£¬¿ÉÒԹرջñÈ¡factµÄ¹¦ÄÜ£¬ÕâÑùÒ²¿ÉÒÔ¼Ó¿ìplaybookµÄÖ´ÐÐЧÂÊ¡£ÅäÖÃÎļþÖмÓÈë
gathering = explicit¼´¿É£¬ÕâÑùÄãÒª»ñÈ¡·þÎñÆ÷ÐÅÏ¢£¬ÐèÒªÏÔʾµÄÔÚplayÖÐÖ¸¶¨¡£
Èç¹ûÒªÓõ½factÐÅÏ¢£¬¿ÉÒÔʹÓÃfact»º´æ£¬ÕâÑùÿ¸ö»úÆ÷µÄfactÐÅÏ¢Ö»»á»ñȡһ´Î¶ø²»ÊÇÿ´Î¶¼È¥»ñÈ¡¡£fact»º´æÖ§³Öjson£¬redis£¬memcached¡£Èç¹ûÓÃredisÔòÐèÒªÔÚ¿ØÖÆ»úÉϰ²×°pythonµÄredisÄ£¿é£¬×ÔÈ»redisÒ²ÊÇÒª°²×°µÄ¡£
[defaults]
gathering = smart
24-hour timeout, adjust if needed
fact_caching_timeout = 86400
You must specify a fact caching implementation
JSON file implementation
fact_caching = jsonfile //»òÕßredis£¬memcached
fact_caching_connection = /tmp/ansible_fact_cache
|
7.4 Parallelism
¿ÉÒÔÉèÖÃANSIBLE_FORKS»·¾³±äÁ¿»òÕßÔÚÅäÖÃÎļþ¼ÓÉÏforks=nÀ´Ö¸¶¨²¢ÐÐÖ´ÐеÄhostµÄÊýÄ¿¡£
7.5 ¹ØÓÚÒì²½
ansibleµÄ1.7°æ±¾¿ªÊ¼Ôö¼ÓÁËÒì²½²ÎÊý async£¬Ò²¾ÍÊÇ˵ִÐÐÒ»¸öʱ¼äºÜ³¤µÄÈÎÎñʱ£¬¿ÉÒÔ²»ÓõȴýËü½áÊø£¬¶øÊÇÖ±½ÓÏÈÖ´ÐкóÃæµÄÈÎÎñ£¬ÔÚºóÐøµÄplayÖж¨Ê±¼ì²éÈÎÎñÖ´Ðнá¹û¼´¿É¡£
Óм¸µã×¢Òâһϣ¬Ò»¸öÊÇasync²ÎÊý£¬ÊÇÖ¸ÈÎÎñÖ´Ðеij¬Ê±Ê±¼ä£¬Èç¹ûÕâ¸öʱ¼äÉèÖõıÈÈÎÎñÖ´ÐÐʱ¼ä¶Ì£¬ÔòÈÎÎñ»á³¬Ê±Ê§°Ü¡£pollֵΪÂÖѯÈÎÎñ״̬µÄʱ¼ä¼ä¸ô£¬Èç¹ûÉèÖÃΪ0£¬±íʾÆô¶¯²¢ºöÂÔ£¬Ò²¾ÍÊÇ˵ÉèÖÃΪ0²ÅÊÇÕæÕýµÄ¿ªÊ¼Òì²½Ö´ÐУ¬Ò²¾ÍÊÇÖ±½ÓÖ´ÐкóÃæµÄtask£¬¶øÎªÁËÖªµÀÒì²½ÈÎÎñÖ´ÐеĽá¹û£¬¿ÉÒÔÓÃasync_statusÀ´ÊµÏÖ¡£Èç¹ûpollÉèÖÃΪ·Ç0Öµ£¬Ôò»¹ÊÇ×èÈûÖ´Ðе쬲¢·ÇÒì²½¡£
- hosts: dbserver
tasks:
- name: simulate long running op (15 sec), wait
for up to 45 sec, poll every 5 sec
command: /bin/sleep 15
async: 20
poll: 0
register: asynctest
- name: check async status
async_status: jid="{{ asynctest.ansible_job_id
}}"
register: job_result
until: job_result.finished
retries: 30
delay: 2
|
8 ´´½¨×Ô¶¨ÒåÄ£¿é
ÔÚijЩÇé¿öÏ£¬¿ÉÄÜansible×Ô´øµÄÄ£¿é²»ÄÜÂú×ãÄãµÄÐèÇó£¬ÐèÒª×Ô¶¨ÒåÄ£¿é¡£¿ÉÒÔͨ¹ýpython»òÕßbashÀ´Ð´×Ô¶¨ÒåÄ£¿é£¬·ûºÏansibleµÄÄ£¿é±àд±ê×¼¼´¿É£¬ÕâÀïÓкÜÏêϸµÄÎĵµ¡£
9 Docker
dockerÊÇĿǰºÜ»ð±¬µÄ¼¼Êõ£¬ËüÌṩÁËÒ»Ì×Ô¶³ÌAPI¹©µÚÈý·½³ÌÐòµ÷Óã¬ansibleµÄdockerÄ£¿é¾ÍÊÇʹÓÃÁËÕâÌ×API¶Ôdocker²Ù×÷¡£ansibleÓÃÔÚdockerÉÏÖ÷ÒªÓÐÁ½µã£ºÒ»ÊDZàÅÅdockerÈÝÆ÷¡£Í¨³£Ò»¸öϵͳÐèÒªºÜ¶à¸ödockerÈÝÆ÷À´Ö§³Ö£¬Ã¿¸öÈÝÆ÷¶¼ÔËÐÐÒ»¸ö·þÎñ¡£·þÎñÖ®¼äÐèÒªÏ໥ͨÐÅ£¬Í¬Ê±ÄãÒ²Òª±£Ö¤ÈÝÆ÷Æô¶¯µÄ˳ÐòµÈ£¬ÔÉúdocker²¢Ã»ÓÐÕâЩ¹¤¾ßÖ§³Ö£¬ansibleÔòÊǷdz£ºÏÊʵÄÒ»¸öÑ¡Ôñ¡£¶þÊÇ´´½¨¾µÏñ¡£¹Ù·½µÄ·½Ê½ÊÇͨ¹ýDockerfileÀ´´´½¨¾µÏñ£¬µ«ÊÇͨ¹ýansibleÀ´ÊµÏÖ¸ü¼Ó¼òµ¥·½±ã¡£
»ùÓÚdockerµÄÓ¦ÓõÄÉúÃüÖÜÆÚÊÇÕâÑùµÄ£º
1. ÔÚ±¾µØ»úÆ÷´´½¨docker¾µÏñ¡£
2. ½«docker¾µÏñpushµ½registry¡£
3. Ô¶³Ì»úÆ÷ÉϽ«¾µÏñ´ÓregistryÉÏpullÏÂÀ´¡£
4. ÔÚÔ¶³Ì»úÆ÷ÉÏÆô¶¯ÈÝÆ÷¡£
ʹÓÃansibleÖ®ºó£¬ÔòÊÇÏÂÃæÕâÑùµÄ£º
1. дºÃÓÃÀ´´´½¨docker¾µÏñµÄplaybook¡£
2. ÔËÐÐplaybookÀ´´´½¨¾µÏñ¡£
3. ½«docker¾µÏñÍÆË͵½registry¡£
4. дºÃÒ»¸öÀÈ¡docker¾µÏñ²¢Æô¶¯ÈÝÆ÷µÄplaybook¡£
5. Ö´ÐÐplaybookÀÈ¡ºÍÆô¶¯ÈÝÆ÷¡£
|