ansible超詳細講解,值得收藏
如果做過運維或者網站開發的朋友,一定接觸過服務部署,那么一般的服務部署流程是什么呢?找一台Linux機器,安裝好運行環境所需要的軟件,然后把服務部署上去。一台機器可以這么做,如果是集群呢?每一台都要這么做。加入我們管理了幾百台機器,突然有一天公司要求在所有機器上都安裝某一款軟件,那么手動顯然是不行的,這個時候就必須要借助自動化腳本來完成這項任務了。
自動化執行的方式有很多種,最原始的就是shell腳本,但是顯然它不能滿足我們的需求。常見自動化配置管理工具有很多種,slatstack和ansible是比較流行的兩種,而且它們都是用python開發的,但是相對來講ansible的優勢更加明顯,主要是因為它擁有大量的模塊和插件,而且你在GitHub和gitee上也可以找到很多別人寫好的編排劇本,基本拿過來就可以使用了。
Ansible簡介
盡管我認為當你看這篇文章的時候,可能對ansible有了至少一丁丁了解,但是簡單的介紹還是要說一下的。Ansible是一個開源配置管理工具,可以使用它來自動化任務,部署應用程序實現IT基礎架構。Ansible可以用來自動化日常任務,比如,服務器的初始化配置、安全基線配置、更新和打補丁系統,安裝軟件包等。
Ansible安裝
- Centos
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum makecache
ansible install -y ansible
- Ubuntu
apt-get install software-properties-common
apt-add-repository ppa:ansible/ansible
apt-get update
apt-get install ansible
- pip安裝
pip install ansible
pip這種方式是最方便的,畢竟我們一般都安裝了Python,但是可能會有一個問題,安裝完以后,我們找不到配置文件,使用ansible --version查看發現config file是none,導致我們沒法正常使用,這是為什么呢?因為ansible加載配置文件的路徑是有順序的。
ansible.cfg文件加載順序
ansible.cfg文件作為配置文件,ansible會在多個路徑下進行讀取,讀取的順序如下:
- ANSIBLE_CONFIG:環境變量
- ansible.cfg:當前執行目錄下
- .ansible.cfg:~/.ansible.cfg
- /etc/ansible/ansible.cfg
所以推薦使用方式是創建一個工程目錄,將所有的配置文件都放置在此目錄下,這樣更方便移植。在ansible.cfg中有如下內容:
[defaults] inventory = ./hosts host_key_checking = False
所以我們使用pip安裝后,在主機上通過find命令查找到ansible.cfg,默認會安裝到python目錄下,將其復制到當前執行目錄即可。
配置文件有三個:
- ansible.cfg --ansible的配置文件,一般我們都使用默認配置,只需要改增加一個host_key_checking=False,不使用指紋驗證。指紋驗證就是當我們在一台Linux機器上ssh登錄另一台Linux時,第一次連接會讓我們輸入Yes/No
- hosts --主機文件清單
- roles --一個配置角色的文件夾,默認里面是空的
配置Ansible主機清單
清單配置中文文檔
主機清單通常用來定義要管理的主機信息,包括IP、用戶、密碼以及SSH key配置。可以分組配置,組與組之間可以配置包含關系,使我們可以按組分配操作主機。配置文件的路徑為:/etc/ansible/hosts
基於密碼的方式連接
vim /etc/ansible/hosts
# 方式一
[web] 192.168.133.111 ansible_ssh_user=root ansible_ssh_pass=123456 192.168.133.112 ansible_ssh_user=root ansible_ssh_pass=123456 192.168.133.123 ansible_ssh_user=root ansible_ssh_pass=123456 # 方式二 [web] 192.168.133.111 192.168.133.112 192.168.133.123 [web:vars] ansible_ssh_user=root ansible_ssh_pass=123456 # 方式三 [web] 192.168.133.111 192.168.133.112 192.168.133.123 # 在/etc/ansible目錄下創建目錄group_vars,然后再創建文件web.yml,以組名命名的yml文件 vim /etc/ansible/group_vars/web.yml # 內容如下 ansible_ssh_user: root ansible_ssh_pass: 123456
測試命令
ansible web -a 'ls /'
基於SSH key方式連接
以下命令均在ansible主機執行,無需到被管理機器操作
# 生成ssh key,一路回車,默認生成在/root/.ssh目錄下id_rsa和id_rsa.pub
ssh-keygen
# 將公鑰拷貝到目標主機
ssh-copy-id root@192.168.143.132
# 執行以上語句,並輸入密碼,會在目標主機生成一個文件/root/.ssh/authorized_keys,之后再連接目標主機就不需要密碼了
ad-hoc命令
ad-hoc是臨時命令,就像我們執行的shell命令一樣,執行完即結束,ad-hoc模式的命令格式如下:
ansible web -m command -a 'df -h'
命令解釋:
- ansible:命令
- web:主機名/IP/分組
- -m:指定模塊(默認是command,所以可以把-m command這個去掉)
- command:模塊名稱
- -a:模塊參數
- ‘df -h’:參數值
執行命令返回的結果顏色代表的含義:
綠色:被管理端沒有被修改
黃色:被管理端發生變更
紅色:執行出現故障
常用模塊介紹
ansible官方存在大量的模塊,我們使用ansible主要使用的也是因為它有大量的模塊和插件,雖然模塊很多,但是我們常用的模塊就那么幾種,下面介紹以下常用模塊:
模塊名 | 說明 |
---|---|
command(默認) | 不支持管道過濾grep |
shell | 支持管道過濾grep |
script | 不用把腳本復制到遠程主機就可以在遠程主機執行腳本 |
yum | 安裝軟件 |
yum_repository | 配置yum源 |
copy | 拷貝文件到遠程主機 |
file | 在遠程主機創建目錄或者文件 |
service | 啟動或停止服務 |
mount | 掛載設備 |
cron | 執行定時任務 |
firewalld | 防火牆設置 |
get_url | 下載軟件或訪問網頁 |
git | 執行git命令 |
yum命令
參數 | 選項 | 含義 |
---|---|---|
name | nginx、git、… | 軟件包名稱或url |
state | present(默認)、absent、latest | 安裝、刪除、最新版 |
enablerepo | epel、base | 允許從哪些倉庫獲取軟件 |
disablerepo | epel、base | 進制從哪些倉庫獲取軟件 |
exclude | kernel、… | 排除哪些軟件包 |
download_only | Yes、no | 僅下載軟件包,不安裝 |
示例:
# 安裝最新版的Apache
ansible web -m yum -a "name=httpd state=latest"
# congepel倉庫安裝罪行的Apache
ansible web -m yum -a "name=httpd state=latest enablerepo=epel"
# 刪除Apache軟件包
ansible web -m yum -a "name=httpd state=absent"
copy命令
參數 | 選項 | 含義 |
---|---|---|
src | 源目錄或文件 | |
dest | 目標目錄或文件 | |
remote_src | True、False | src是遠程主機上還是在當前主機上,僅在mode=preserve有效 |
owner | 所屬用戶 | |
group | 所屬組 | |
mode | 0655、u=rw、u+rw | 設置文件權限 |
backup | yes、no | 是否備份目標文件 |
content | 寫入目標文件的內容 |
示例:
# 拷貝apache配置文件到目標機器
ansible web -m copy -a "src=httpd.conf dest=/etc/httpd/conf/httpd.conf owner=root group=root mode=644"
# 拷貝apache配置文件到目標機器,並備份目標文件
ansible web -m copy -a "src=httpd.conf dest=/etc/httpd/conf/httpd.conf owner=root group=root mode=644 backup=yes"
# 在遠程主機創建一個文件並寫入內容
ansible web -m copy -a "content=HelloWorld dest=/home/index.html"
get_url命令
參數 | 含義 |
---|---|
url | 地址 |
dest | 目標文件 |
mode | 文件權限 |
# 下載文件到本地
ansible web -m get_url -a "url=http://xx.xx.xx/ssss.txt dest=/home/xx.txt mode=655"
file命令
# 創建文件
ansible web -m file -a "path=/home/aaa.txt state=touch"
# 創建目錄
ansible web -m file -a "path=/home/test state=directory"
# 遞歸修改目錄權限
ansible web -m file -a "path=/home owner=nginx group=nginx mode=766 recurse=yes"
git命令
參數 | 含義 |
---|---|
repo | 遠程庫下載地址 |
dest | 更新目錄 |
version | 分支 |
update | yes、no,不更新代碼,只確定庫存在 |
clone | yes、no,不下載代碼,獲取本地已存在倉庫的信息 |
以上是部分常用模塊的解釋與示例,因為ansible的模塊和參數很多,我們就不做詳細解釋了。但是這里要說一個非常非常重要的一點,以上全都是廢話,任何一個模塊,ansible都為我們提供了非常詳細的解釋文檔,例如查看cron模塊的用法,查詢命令如下:ansible-doc cron
不僅有參數解釋,還有執行示例:
如果想查詢都有哪些模塊,ansible-doc -l > ansible.doc
,當然了,執行示例是按照ansible-playbook的方式顯示的,但是我們稍微改一下就可以用ad-doc的方式執行了
報錯處理
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: oldboy
這個問題一般是沒有在ansible.cfg內指定主機清單文件導致的,配置正確的inventory路徑即可,還可以通過在ansible命令后面加-i來指定。
playbook
Playbook
與ad-hoc
相比,是一種完全不同的運用ansible的方式,類似與saltstack
的state
狀態文件。ad-hoc
無法持久使用,playbook
可以持久使用。playbook
是由一個或多個play
組成的列表,play
的主要功能在於將事先歸並為一組的主機裝扮成事先通過ansible
中的task
定義好的角色。從根本上來講,所謂的task
無非是調用ansible
的一個module
。將多個play
組織在一個playbook
中,即可以讓它們聯合起來按事先編排的機制完成某一任務。
Playbook是通過yml語法進行編排的,使用起來非常簡單,我們只需要知道一些基本的關鍵字就可以實現了。
- hosts:
- tasks:
- vars:
- templates:
- handlers:
- tags:
下面給一個簡單的例子:
# httpd.yaml - hosts: web tasks: - name: install httpd server yum: name=httpd state=present - name: configure httpd server copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf - name: configure httpd server copy: src=index.html dest=/var/www/html/index.html - name: service httpd server service: name=httpd state=started enabled=yes
這是一個安裝Apache、配置、啟動的流程,我們看一下其中的關鍵字。
- hosts:需要執行的主機、組、IP
- tasks:執行的任務
- name:任務描述
- yum/copy/service:執行模塊(上面我們介紹過的)
這就是最基礎的Playbook的結構,也是一個Playbook所必備的結構,當然還有更多高級的操作,我們下面通過更多的示例來給大家講解。
搭建nginx服務
- hosts: web vars: hello: Ansible tasks: # 配置軟件源 - name: Configure Yum Repo yum_repository: name: nginx description: nginx repo baseurl: http://nginx.org/packages/centos/7/$basearch/ gpgcheck: yes enabled: yes # 安裝nginx - name: Install Nginx yum: name=ningx state=present # 替換配置文件 - name: Configure Nginx copy: src: nginx.conf dest: /etc/nginx/conf/nginx.conf # 修改首頁 - name: Change Home copy: content: "Hello {{hello}}" dest: /var/www/html/index.html # 啟動nginx - name: Start Nginx service: name: nginx state: started
上面這個例子在模塊使用時,我用了兩種例子
yum: name=nginx state=present
copy: src: nginx.conf dest: /etc/nginx/conf/nginx.conf
這兩種方式都是可以的,只是寫法不同,希望不要有人被誤導,另外在這里例子中我們還引入了下一個知識點-變量
Ansible中的變量
為什么要使用變量?
首先我們要明確為什么使用變量?變量這個詞在編程當中經常用到,我們一直強調在編程中不要使用魔法數字,盡量使用宏或者變量代替,魔法數字一方面意義不夠明確,另外一方面在修改的時候,要涉及到很多地方,會出現紕漏。那么在ansible中使用變量的意義也是一樣的,明確意義、方便修改。
怎么定義變量和使用變量?
- 在playbook文件中的hosts下使用vars進行定義
- 在playbook文件中直接定義變量
- hosts: web vars: web_pack: httpd-2.4.6 ftp_pack: vsftpd # - web_pack: httpd-2.4.6 與上面等同 tasks: - name: Install {{pack_name}} yum: name: - "{{web_pack}}" - "{{ftp_pack}}" state: present
- 額外定義一個變量文件
如果是在多個文件中使用同樣的變量,可以定義一個變量文件,在playbook中使用vars_files中引入即可
# vars.yml web_pack: httpd-2.4.6 ftp_pack: vsftpd
- hosts: web vars_files: - ./vars.yml
- 在主機清單文件中進行定義
- 在主機清單文件中定義
# hosts
[web] 192.168.143.122 [web:vars] pack_name=httpd
# playbook中使用,可以直接使用,如果當前文件中搜索不到,就去主機清單中搜搜 - hosts: web tasks: - name: isntall {{pack_name}} yum: name={{pack_name}} state=present
- 單獨定義group_vars和host_vars目錄
group_vars是為組定義的變量目錄,其下文件名為組名,例如group_vars/web,host_vars是為主機定義的變量目錄,其下文件名為IP,例如host_vars/192.168.143.122。
注意:默認情況下,group_vars目錄中文件名與hosts清單中的組名保持一致,因此在使用的時候,只對本組有效,其他組不能使用,但是系統還提供了一個特殊的組-all,在group_vars新建一個all文件,所有組都可以使用
# web文件
pack_name: httpd
- 執行playbook時使用-e參數指定變量
ansible-playbook httpd.yml -e "pack_name=httpd" -e "hosts=web"
hosts變量通過-e傳遞是比較常見的,我們可以區分測試環境和生產環境,當然你也可以定義不同的文件來區分
ansible 變量的優先級
上面我們介紹了多種變量的定義方式,那么如果在多個地方定義了相同的變量,優先會使用哪個呢?這就涉及到變量優先級的問題了。
-
通過執行命令傳遞的變量
-
在playbook中引入vars_files中的變量
-
在playbook中定義的vars變量
-
在host_vars中定義的變量
-
在group_vars中組名文件中定義的變量
-
在group_vars中all文件中定義的變量
ansible resister注冊變量
在我們使用ansible-playbook的時候,它的輸出是固定的格式的,假如我們啟動了httpd服務以后,想要看一下這個服務的狀態,我們不能登錄到目標主機去查看,那么ansible有什么方式可以查看嗎?
- hosts: web tasks: - name: install httpd server yum: name=httpd state=present - name: service httpd server service: name=httpd state=started enabled=yes - name: check httpd state shell: ps aux|grep httpd register: httpd_status - name: output httpd_status variable debug: msg: "{{httpd_status}}"
上面是輸出了所有的內容,如果需要輸出部分內容,只要用變量.屬性就行了,屬性就是msg下的字典
ansible facts變量的意義
這是我們安裝Apache的打印,可以看到分為幾個過程:PLAY、TASK、PLAY RECAP,在TASK的第一個打印我們看到是Gathering Facts,但是我們並沒有添加這個任務,這是ansible自動為我們添加的,這個任務是做什么用的呢?我們在執行的過程中發現這一塊執行時間還比較長。這個任務的主要作用是獲取目標主機的信息,我們看一下都能獲取哪些信息,可以通過以下語句打印:ansible web -m setup
包括CUP、內存、硬盤、網絡、主機名、綁定信息、系統版本信息等等,非常多的信息,這些信息都可以在playbook中當做變量使用。
- hosts: web tasks: - name: Query Host Info debug: msg: IP address is {{ansible_default_ipv4.address}} in hosts {{ansible_distribution}}
那么這個可以在什么情況下使用呢?例如根據目標主機的CPU數,配置nginx並發進程數量,當然如果不使用,我們也可以關閉它。
- hosts: web gather_facts: no tasks: - name: install httpd server yum: name=httpd state=present - name: service httpd server service: name=httpd state=started enabled=yes
下面看一個例子:安裝memcache
# memcache.yml - hosts: web tasks: - name: install memcached server yum: name=memcached state=present - name: configure memcached server template: src=./memcached.j2 dest=/etc/sysconfig/memcached - name: service memcached server service: name=memcached state=started enabled=yes - name: check memcached server shell: ps aux|grep memcached register: check_mem - name: debug memcached variables debug: msg: "{{check_mem.stdout_lines}}"
# memcached.j2,通過facts獲取的目標主機內存總量
PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="{{ansible_memtotal_mb // 2}}" OPTIONS=""
這里我們用到了一個新的模塊:template,這個相當於Django的模板語法,支持Jinjia2渲染引擎和語法。以上實現了playbook的大部分操作,但是那只是常規操作,還有一些更加靈活的問題需要處理,例如:
我們只想要執行一個playbook中的某個任務?
檢測nginx狀態,如果正常就啟動或重啟,不正常就忽略,執行其他任務
如果nginx的配置文件沒有變化,我們就不執行啟動或重啟命令
以上這些情況都需要進行邏輯判斷,ansible強大的地方也正是這里,下面我們看一下task的任務控制流程
Task任務控制
任務控制包括以下邏輯關鍵字:
- 條件判斷 when
- 循環語句 with_items
- 觸發器 handlers
- 標簽 tags
- 包含 include
- 忽略錯誤 ignore_error
- 錯誤處理 change
條件判斷
假設我們安裝Apache,在centos上安裝的是httpd,在Ubuntu上安裝的是httpd2,因此我們需要判斷主機信息,安裝不同的軟件。
- hosts: web tasks: - name: Install CentOS Httpd yum: name=httpd state=present when: ( ansible_distribution == "CentOS" ) - name: Install Ubuntu Httpd yum: name=httpd2 state=present when: ( ansible_distribution == "Ubuntu" )
給task加上when條件,在執行的時候,就會先判斷條件是否滿足,如果滿足則執行任務,不滿足就不執行此任務。我們再看一個例子:如果Apache服務不正常就重啟,否則跳過。
- hosts: web tasks: - name: check httpd server command: systemctl is-active httpd register: check_httpd - name: httpd restart service: name=httpd state=restarted when: check_httpd.rc == 0
循環命令 with_items
啟動多個服務,例如nginx、httpd
- hosts: web tasks: - name: Service Start service: name={{item}} state=restarted with_items: - nginx - httpd
拷貝多個配置文件
- hosts: web tasks: - name: Copy Configure File copy: src: {{item.src}} dest: {{item.dest}} mode: {{item.mode}} with_items: - { src: './nginx.conf', dest: '/etc/nginx/conf/nginx.conf' } - { src: './httpd.conf', dest: '/etc/httpd/conf/httpd.conf' }
觸發器 handlers
當某個任務發生變化時,觸發另一個任務的執行,例如如果httpd的配置文件發生了變化,就執行重啟任務
- hosts: web tasks: - name: install httpd server yum: name=httpd state=present - name: configure httpd server copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf notify: # 條用名稱為Restart Httpd Server的handlers,可以寫多個 - Restart Httpd Server - name: service httpd server service: name=httpd state=started enabled=yes handlers: - name: Restart Httpd Server service: name=httpd state=restarted
handlers執行的時候需要注意,雖然是在某個任務被觸發的,但是它必須等到所有的task執行完成后,才會執行handlers里面被觸發過的命令,如果在執行前,有另一個task執行失敗了,那么被觸發的handlers也不會執行。
tags標簽
對任務指定標簽后,我們在使用ansible-playbook執行的時候就可以指定標簽來執行任務,不需要執行所有的任務,標簽的設置有三種情況:1. 一個任務設置一個標簽 2.一個任務設置多個標簽 3. 多個任務設置一個標簽
- hosts: web tasks: - name: install httpd server yum: name=httpd state=present tags: install - name: configure httpd server copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf notify: # 條用名稱為Restart Httpd Server的handlers,可以寫多個 - Restart Httpd Server tags: configure - name: service httpd server service: name=httpd state=started enabled=yes tags: start handlers: - name: Restart Httpd Server service: name=httpd state=restarted
執行指定tags的命令:ansible-playbook httpd.yml -t "configure"
跳過指定tags的命令:ansible-playbook httpd.yml --skip-tags "install"
include包含
我們可以把任務單獨寫在一個yaml文件中,然后在其他需要用到的任務中通過include_tasks: xxx.yml引入,舉例如下:
# a.yml - name: restart httpd service service: name=httpd state=restarted
# b.yml - hosts: web tasks: - name: configure httpd server copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf - name: restat httpd include_tasks: ./a.yml
當然我們也可以把兩個完整的playbook合並起來
# a.yml - hosts: web tasks: - name: install httpd server yum: name=httpd state=present
# b.yml - hosts: web tasks: - name: configure httpd server copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
# total.yml - import_playbook: ./a.yml - import_playbook: ./b.yml
在執行total.yml的時候,實際上就是先執行a.yml,然后再執行b.yml,里面的內容實際並不是真正的合並
忽略錯誤ignore_errors
我們知道,在執行playbook的時候,如果其中某個任務失敗了,它下面的任務就不會再執行了,但是有時候我們並不需要所有任務都成功,某些任務是可以失敗的,那么這個時候就需要進行容錯,就是在這個任務失敗的時候,不影響它后面的任務執行。
- hosts: web tasks: - name: check httpd status command: ps aux|grep httpd register: httpd_status ignore_errors: yes # 如果查詢語句執行失敗,繼續向下執行重啟任務 - name: restart httpd service: name=httpd state=restarted
錯誤處理
- force_handlers: yes 強制調用handlers
只要handlers被觸發過,無論是否有任務失敗,均調用handlers
- hosts: web force_handlers: yes tasks: - name: install httpd yum: name=httpd state=present - name: install fuck yum: name=fuck state=present handlers: - name: restart httpd service: name=httpd state=restarted
- change_when
當任務執行的時候,如果被控主機端發生了變化,change就會變化,但是某些命令,比如一些shell命令,只是查詢信息,並沒有做什么修改,但是一直會顯示change狀態,這個時候我們就可以強制把change狀態關掉。
- hosts: web tasks: - name: test task shell: ps aux change_when: false
再看一個例子,加入我們修改配置文件成功了,就執行重啟命令,否則不執行重啟
- hosts: web tasks: - name: install nginx server yum: name=nginx state=present - name: configure nginx copy: src=./nginx.conf dest=/etc/nginx/conf/nginx.conf # 執行nginx檢查配置文件命令 - name: check nginx configure command: /usr/sbin/nginx -t register: check_nginx changed_when: ( check_nginx.stdout.find('successful') ) - name: service nginx server service: name=nginx state=restarted
Jinja模板
jinja模板是類似Django的模板,如果做過Django的同學應該是比較熟悉的,我們使用jinja來配置一下nginx的負載均衡
- hosts: web vars: - http_port: 80 - server_name: web.com tasks: - name: instal nginx server yum: name=nginx state=present - name: configure nginx template: src=./nginx.conf dest=/etc/nginx/conf/nginx.conf - name: start nginx service: name=nginx state=started enabled=yes
要使Jinja語法生效,必須使用template模塊處理,這個模塊和copy類似,但是它支持Jinja語法渲染
# nginx.conf upstream {{server_name}} { {% for i in range(2) %} server 192.168.143.12{{i}}:{{http_port}}; server 192.168.143.12{{i}}:{{http_port}}; {% endfor %} } server { listen {{http_port}}; server_name {{server_name}} location / { proxy_pass http://web.com; include proxy_params; } }
在配置文件中就可以使用playbook中定義的變量,我們在配置MySQL主從復制集群的時候,對於my.cnf文件,master主機和slave主機的配置是不同的,這樣就可以根據主機名,使用Jinja中的if語法進行條件渲染
[mysqld] {% if ansible_fqdn == "mysql_master" %} log-bin=mysql-bin server-id=1 {% else %} server-id=2 {% endif %}
這樣就完成了配置區分,執行同樣的template拷貝命令,在不同的機器上是不同的配置文件。
PS:
ansible_fqdn: 這個是gather_facts任務獲取的變量,我們也可以使用其他變量進行判斷
mysql_master: 這個是需要配置主從復制的master主機hostname,需要提前設置,也是可以用ansible設置的
Ansible Roles
最后我們要講一下ansible中最重要的一個概念-roles,如果前面的你都搞清楚了,那么roles是非常簡單的。總的來說roles就是把我們前面講過的東西進行了一個排版,它規定了嚴格的目錄格式,我們必須按照目錄結構和文件名進行創建,否則它的文件系統就加載不到。目錄格式如下:
- mysql.yml:playbook文件
- mysql:roles目錄,也是角色名
- files:存放文件、壓縮包、安裝包等
- handlers:觸發任務放在這里
- tasks:具體任務
- templates:存放通過template渲染的模板文件
- vars:定義變量
- meta:任務依賴關系
那些main.yml也是必須的,名字必須是這樣,目錄名稱也必須相同,但是不是每個目錄都是必須的,下面我們把httpd的那個例子用roles寫一下:
- hosts: web tasks: - name: install httpd server yum: name=httpd state=present tags: install - name: configure httpd server template: src=httpd.conf dest=/etc/httpd/conf/httpd.conf notify: # 條用名稱為Restart Httpd Server的handlers,可以寫多個 - Restart Httpd Server tags: configure - name: service httpd server service: name=httpd state=started enabled=yes tags: start handlers: - name: Restart Httpd Server service: name=httpd state=restarted
就把上面這一段改成roles的格式,目錄結構如下:
# httpd/handlers/main.yml - name: Restart Httpd Server service: name=httpd state=restarted
# httpd/tasks/config.xml - name: configure httpd server template: src=httpd.conf dest=/etc/httpd/conf/httpd.conf notify: # 條用名稱為Restart Httpd Server的handlers,可以寫多個 - Restart Httpd Server tags: configure
# httpd/tasks/install.yml - name: install httpd server yum: name=httpd state=present tags: install
# httpd/tasks/start.yml - name: service httpd server service: name=httpd state=started enabled=yes tags: start
# httpd/tasks/main.yml - include_tasks: install.yml - include_tasks: config.yml - include_tasks: start.yml
# httpd1.yml - hosts: web roles: - role: nginx # - nginx 與上面是等價的,但是上面的可以增加tags
最后再與httpd1.yml同級目錄下執行ansible-playbook httpd1.yml
即可(我這里實際是httpd2.yml,不要在意這些細節)
Galaxy
最后我們再介紹一個官方網站:Galaxy
這是一個類似GitHub和docker一樣的網站,我的網太爛了,打不開,它上面是別人寫好的roles,比如你想要安裝Nginx,那么在上面搜索nginx,然后會提供一個下載命令:ansible-galaxy install geerlingguy.nginx
,執行以后,會把它蝦藻到/root/.ansible/roles這個目錄下。
到這里,ansible的講解我們就寫完了,ansible是用python開發的,所以我們經常會把它和python結合起來使用,后面我們會把python操作ansible寫一下。