首先要知道ansible是一種輕量級的自動化部署開源軟件,被許多中小型的網站所採用。可以完成配置系統、軟件發佈、高級任務的編排、編排更高級的任務,比如連續部署或零停機時間滾動更新。
ansible的命令格式ansible <host-pattern> [-f forks] [-m module_name] [-a args]
使用命令探測主機
ansible all -m ping -C
192.168.31.201 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.31.203 | SUCCESS => {
"changed": false,
"ping": "pong"
}
查看ansible支持的所有模塊ansible-doc -l
查看模塊的所有參數ansible-doc -s MODULE_NAME
在兩臺主機上創建兩個組
ansible all -m group -a "gid=3000 name=mygrp state=present"
192.168.31.201 | CHANGED => {
"changed": true,
"gid": 3000,
"name": "mygrp",
"state": "present",
"system": false
}
192.168.31.203 | CHANGED => {
"changed": true,
"gid": 3000,
"name": "mygrp",
"state": "present",
"system": false
}
常用的模塊
常用模塊:
command
-a 'COMMAND'
user
-a 'name= state={present|absent} system= uid='
group
-a 'name= gid= state= system='
cron
-a 'name= minute= hour= day= month= weekday= job= user= state='
copy
-a 'dest= src= mode= owner= group='
注意:src是目錄時最後帶/複製目錄內容,不帶/遞歸複製文件本身
file
-a 'path= mode= owner= group= state={directory|link|present|absent} src='
ping
沒有參數
yum
-a 'name= state={present|latest|absent}'
service
-a 'name= state={started|stopped|restarted} enabled='
shell
-a 'COMMAND'
script
-a '/path/to/script'
setup
playbook的核心元素:
- Hosts:主機
- tasks: 任務
- variables: 變量
- templates: 模板包含了模板語法的文本文件
- handlers: 處理器
- roles: 角色
Hosts:運行指定任務的目標主機;
remoute——user:在遠程主機上執行任務的用戶
sudo_user;
tasks:任務列表
模塊,模塊參數;
格式:
(1) action: module arguments
(2) module:arguments
注意: shell和command模塊後面直接跟命令,而非key=value類的參數;
(1) 某任務的狀態在運行後爲change時,可通過"notify"
通知給相應的handlers
(2) 任務可以通過"tags"打標籤,而後可在ansible-playbook
命令上使用-t指定進行調用;
handlers:
任務,在特定條件下觸發;
接收到其他任務的通知時被觸發;
notify:HANDLER TASK NAME
variable:
(1) facts:可直接調用;
注意:ansible命令行下可使用setup模塊直接獲取目標主機的facters;
(2)用戶自定義變量;
ansible-playbook命令的命令行中
-e VARS,--extra-vars=VARS
ansible-playbook -e pkgname=memcached name.yaml
(3) 通過roles傳遞變量
(4) Host Inventory
(a)向不同的主機傳遞不同的變量;
IP/HOSTANME variable=value var2=value2
(b)向組中的主機傳遞相同的變量;
[groupname:vars]
variable=value
注意:invertory參數:
用於定義ansible遠程連接目標主機時使用的參數,而非傳遞給playbook的變量;
- ansible_ssh_host
- ansible_ssh_port
- ansible_ssh_user
- ansible_ssh_pass
- ansible_sudo_pass
templates:模板
文本文件,嵌套有腳本(使用模板編程語言編寫)
Jinja2:
字面量:
字符串:使用單引號或雙引號;
數字:整數,浮點數;
列表:[item1, item2, ...]
元組:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布爾型:true/false
算術運算:
+, -, *, /, //, %, **
比較操作:
==, !=, >, >=, <, <=
邏輯運算:
and, or, not
條件測試
when語句:在task中使用,jinja2的語法格式
tasks:
- name: install conf file to centos7
template: src=files/nginx.conf.c7.j2
when: ansible_distribution_major_version == "7"
- name: install conf file to centos6
template: src=files/nginx.conf.c6.j2
when: ansible_distribution_major_version == "6"
循環
對迭代項的引用,固定變量名爲”item“
而後,要在task中使用with_items給定要迭代的元素列表;
列表方法:
字符串
字典
- name: install some packages
yum: name={{ item }} state=present
with_items:
- nginx
- memcached
- php-fpm
- name: add some users
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- { name: 'user11', group: 'group11' }
- { name: 'user12', group: 'group12' }
- { name: 'user13', group: 'group13' }
roles:角色
每個角色,以特定的層級目錄結構進行組織:
mysql/
files/ :存放由copy或script模塊等調用的文件;
templates/:template模塊查找所需要模板文件的目錄;
tasks/:至少應該包含一個名爲main.yml的文件;其它的文件需要在此文件中通過include進行包含;
handlers/:至少應該包含一個名爲main.yml的文件;其它的文件需要在此文件中通過include進行包含;
vars/:至少應該包含一個名爲main.yml的文件;其它的文件需要在此文件中通過include進行包含;
meta/:至少應該包含一個名爲main.yml的文件,定義當前角色的特殊設定及其依賴關係;其它的文件需要在此文件中通過include進行包含;
default/:設定默認變量時使用此目錄中的main.yml文件;
在playbook調用角色方法1:
- hosts: websrvs
remote_user: root
roles:
- mysql
- memcached
- nginx
在playbook調用角色方法2:傳遞變量給角色
- hosts:
remote_user:
roles:
- { role: nginx, username: nginx }
#鍵role用於指定角色名稱;後續的k/v用於傳遞變量給角色;
#還可以基於條件測試實現角色調用;
roles:
- { role: nginx, when: "ansible_distribution_major_version == '7' " }
現在我們計劃使用role部署一臺nginx兩臺tomcat主機,這就需要兩個角色
首先編輯/etc/ansible/hosts文件,添加需要被控制的主機
[lb]
node2.lvqing.com
[tcservs]
node[3:4].lvqing.com
生成ssh密鑰公鑰對,發送給待管理主機,然後不需要密碼也能ssh登陸了
ssh-keygen -t rsa -P ""
ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
然後創建角色對應的目錄mkdir -pv /etc/ansible/roles/{nginx,tomcat,jdk}/{files,templates,tasks,handlers,vars,meta,default}
首先編輯tasks目錄下的main.yaml文件
- name: install nginx
yum: name=nginx state =present
when: ansible_os_family == "RedHat"
- name: install conf
copy: src=lb.conf dest=/etc/nginx/conf.d/
tags: conf
notify: restart nginx
- name: start nginx
service: name=nginx state=started enabled=yes
因爲定義了notify所以還需要編輯handler文件
- name: restart nginx
service: name=nginx state=restarted
在files下創建需要傳過去的配置文件lb.conf
upstream tcservs {
server node3.lvqing.com;
server node4.lvqing.com;
}
server {
listen 80;
server_name node2.lvqing.com;
location / {
proxy_pass http://tcservs;
}
}
至此nginx角色就簡單的創建完成了,然後定義tomcat的角色
- name: install package
yum: name={{ item }} state=present
with_items:
- tomcat
- tomcat-admin-webapps
- tomcat-webapps
- tomcat-docs-webapp
when: ansible_os_family == "RedHat"
- name: start tomcat
service: name=tomcat state=started enabled=yes
然後因爲tomcat依賴於jdk,我們需要去定義jdk角色
- name: install openjdk
yum: name=java-{{ version }}-openjdk-devel state=present
- name: install env file
copy: name=java.sh dest=/etc/profile.d/
files目錄下java.sh文件
export JAVA_HOME=/usr
然後我們再創建一個playbook來使用這幾個角色
- hosts: lb
remote_user: root
roles:
- nginx
- hosts: tcservs
remote_user: root
roles:
- { role: jdk, version: 1.8.0 }
- tomcat
然後我們運行劇本ansible-playbooks os.yml
PLAY [lb] **************************************************************************************
TASK [Gathering Facts] *************************************************************************
ok: [node2.lvqing.com]
TASK [nginx : install nginx] *******************************************************************
ok: [node2.lvqing.com]
TASK [nginx : install conf] ********************************************************************
changed: [node2.lvqing.com]
TASK [nginx : start nginx] *********************************************************************
changed: [node2.lvqing.com]
RUNNING HANDLER [nginx : restart nginx] ********************************************************
changed: [node2.lvqing.com]
PLAY [tcservs] *********************************************************************************
TASK [Gathering Facts] *************************************************************************
ok: [node2.lvqing.com]
ok: [node3.lvqing.com]
TASK [jdk : install openjdk] *******************************************************************
ok: [node2.lvqing.com]
ok: [node3.lvqing.com]
TASK [jdk : install env file] ******************************************************************
changed: [node2.lvqing.com]
changed: [node3.lvqing.com]
TASK [tomcat : install package] ****************************************************************
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is
deprecated. Instead of using a loop to supply multiple items and specifying `name: {{ item }}`,
please use `name: [u'tomcat', u'tomcat-admin-webapps', u'tomcat-webapps', u'tomcat-docs-
webapp']` and remove the loop. This feature will be removed in version 2.11. Deprecation
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is
deprecated. Instead of using a loop to supply multiple items and specifying `name: {{ item }}`,
please use `name: [u'tomcat', u'tomcat-admin-webapps', u'tomcat-webapps', u'tomcat-docs-
webapp']` and remove the loop. This feature will be removed in version 2.11. Deprecation
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
changed: [node3.lvqing.com] => (item=[u'tomcat', u'tomcat-admin-webapps', u'tomcat-webapps', u'tomcat-docs-webapp'])
changed: [node2.lvqing.com] => (item=[u'tomcat', u'tomcat-admin-webapps', u'tomcat-webapps', u'tomcat-docs-webapp'])
TASK [tomcat : start tomcat] *******************************************************************
changed: [node3.lvqing.com]
changed: [node2.lvqing.com]
PLAY RECAP *************************************************************************************
node2.lvqing.com : ok=10 changed=6 unreachable=0 failed=0
node3.lvqing.com : ok=5 changed=3 unreachable=0 failed=0
可以看到已經成功完成了