Ansible之playbook劇本(原來的地方沒有蝴蝶在飛,小野狗也不會飛。) 阿新 • • 發佈:2021-10-24 一、劇本(playbook) 1.1 playbook介紹 ____playbook是ansible用於配置,部署,和管理被控節點的劇本。通過playbook的詳細描述,執行其中的tasks,可以讓遠端主機達到預期的狀態。playbook是由一個或多個”play”組成的列表。 當對一臺機器做環境初始化的時候往往需要不止做一件事情,這時使用playbook會更加適合。通過playbook你可以一次在多臺機器執行多個指令。通過這種預先設計的配置保持了機器的配置統一,並很簡單的執行日常任務。 ____ansible通過不同的模組實現相應的管理,管理的方式通過定義的清單檔案(hosts)所管理的主機包括認證的方式連線的埠等。所有的功能都是通過呼叫不同的模組(modules)來完成不同的功能的。不管是執行單條命令還是play-book都是基於清單檔案。 playbook格式: playbook由YMAL語言編寫。YMAL格式是類似於JSON的檔案格式,便於人理解和閱讀,同時便於書寫。 一個劇本里面可以有多個play,每個play只能有一個tasks,每個tasks可以有多個name。 1.2 playbooks 的組成 Tasks:任務,即通過 task 呼叫 ansible 的模組將多個操作組織在一個playbook 中執行。 Variables:變數 Templates:模板 Handlers:處理器,當 changed 狀態條件滿足時,(notify)觸發執行的操作。 Roles:角色 1.3 案例:編寫httpd的playbook vim test1.yaml --- #yaml檔案以---開頭,以表明這是一個yaml檔案,可省略 - name: first play #定義一個play的名稱,可省略 gather_facts: false #設定不進行facts資訊收集,這可以加快執行速度,可省略 hosts: webservers #指定要執行任務的被管理主機組,如多個主機組用冒號分隔 remote_user: root #指定被管理主機上執行任務的使用者 tasks: #定義任務列表,任務列表中的各任務按次序逐個在hosts中指定的主機上執行 - name: test connection #自定義任務名稱 ping: #使用 module: [options] 格式來定義一個任務 - name: disable selinux command: '/sbin/setenforce 0' #command模組和shell模組無需使用key=value格式 ignore_errors: True #如執行命令的返回值不為0,就會報錯,tasks停止,可使用ignore_errors忽略失敗的任務 - name: disable firewalld service: name=firewalld state=stopped #使用 module: options 格式來定義任務,option使用key=value格式 - name: install httpd yum: name=httpd state=latest - name: install configuration file for httpd copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf #這裡需要一個事先準備好的/opt/httpd.conf檔案 notify: "restart httpd" #如以上操作後為changed的狀態時,會通過notify指定的名稱觸發對應名稱的handlers操作 - name: start httpd service service: enabled=true name=httpd state=started handlers: #handlers中定義的就是任務,此處handlers中的任務使用的是service模組 - name: restart httpd #notify和handlers中任務的名稱必須一致 service: name=httpd state=restarted ① Ansible 管理端編寫好playbook劇本 ② 在webservers端(client1)準備httpd模板配置檔案 ③ 在webservers端(client1)將準備好的httpd模板配置檔案傳送到Ansible管理端 ④ 確認被控制端的httpd服務是否安裝,firewalld處於開啟狀態,本機的httpd模板檔案準備完成並且路 ⑤ 執行playbook劇本 ⑥ 檢查被deservers控制端(client2)192.168.153.70的httpd服務和防火牆狀態以及httpd配置檔案 二、定義、引用變數 - name: second play hosts: dbservers remote_user: root vars: #定義變數 - groupname: mysql #格式為 key: value - username: nginx tasks: - name: create group group: name={{groupname}} system=yes gid=306 #使用 {{key}} 引用變數的值 - name: create user user: name={{username}} uid=306 group={{groupname}} - name: copy file copy: content="{{ansible_default_ipv4}}" dest=/opt/vars.txt #在setup模組中可以獲取facts變數資訊 ansible-playbook test1.yaml -e "username=nginx" #在命令列裡定義變數 //指定遠端主機sudo切換使用者 --- - hosts: dbservers remote_user: zhangsan become: yes #2.6版本以後的引數,之前是sudo,意思為切換使用者執行 become_user: root #指定sudo使用者為root 執行playbook時:ansible-playbook test1.yml -K <密碼> 三、when條件判斷 在Ansible中,提供的唯一一個通用的條件判斷是when指令,當when指令的值為true時,則該任務執行,否則不執行該任務。 when一個比較常見的應用場景是實現跳過某個主機不執行任務或者只有滿足條件的主機執行任務 vim test2.yaml --- - hosts: all remote_user: root tasks: - name: shutdown host command: /sbin/shutdown -r now when: ansible_default_ipv4.address == "192.168.80.12" #when指令中的變數名不需要手動加上 {{}} 或 when: inventory_hostname == "<主機名>" ansible-playbook test2.yaml //迭代 Ansible提供了很多種迴圈結構,一般都命名為with_items,作用等同於 loop 迴圈。 vim test3.yaml --- - name: play1 hosts: dbservers gather_facts: false tasks: - name: create directories file: path: "{{item}}" state: directory with_items: #等同於 loop: - /tmp/test1 - /tmp/test2 - name: add users user: name={{item.name}} state=present groups={{item.groups}} with_items: - name: test1 groups: wheel - name: test2 groups: root 或 with_items: - {name:'test1', groups:'wheel'} - {name:'test2', groups:'root'} ansible-playbook test3.yaml 四、Templates 模組 Jinja是基於Python的模板引擎。Template類是Jinja的一個重要元件,可以看作是一個編譯過的模板檔案,用來產生目標文字,傳遞Python的變數給模板去替換模板中的標記。 1.先準備一個以 .j2 為字尾的 template 模板檔案,設定引用的變數 cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2 vim /opt/httpd.conf.j2 Listen {{http_port}} #42行,修改 ServerName {{server_name}} #95行,修改 DocumentRoot "{{root_dir}}" #119行,修改 2.修改主機清單檔案,使用主機變數定義一個變數名相同,而值不同的變數 vim /etc/ansible/hosts [webservers] 192.168.80.11 http_port=192.168.80.11:80 server_name=www.accp.com:80 root_dir=/etc/httpd/htdocs [dbservers] 192.168.80.12 http_port=192.168.80.12:80 server_name=www.benet.com:80 root_dir=/etc/httpd/htdocs 3.編寫 playbook vim apache.yaml --- - hosts: all remote_user: root vars: - package: httpd - service: httpd tasks: - name: install httpd package yum: name={{package}} state=latest - name: install configure file template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf #使用template模板 notify: - restart httpd - name: create root dir file: path=/etc/httpd/htdocs state=directory - name: start httpd server service: name={{service}} enabled=true state=started handlers: - name: restart httpd service: name={{service}} state=restarted ansible-playbook apache.yaml 五、tags 模組 可以在一個playbook中為某個或某些任務定義“標籤”,在執行此playbook時通過ansible-playbook命令使用–tags選項能實現僅執行指定的tasks。 playbook還提供了一個特殊的tags為always。作用就是當使用always當tags的task時,無論執行哪一個tags時,定義有always的tags都會執行。 vim webhosts.yaml --- - hosts: webservers remote_user: root tasks: - name: Copy hosts file copy: src=/etc/hosts dest=/opt/hosts tags: - only #可自定義 - name: touch file file: path=/opt/testhost state=touch tags: - always #表示始終要執行的程式碼 ansible-playbook webhosts.yaml --tags="only" vim dbhosts.yaml --- - hosts: dbservers remote_user: root tasks: - name: Copy hosts file copy: src=/etc/hosts dest=/opt/hosts tags: - only - name: touch file file: path=/opt/testhost state=touch ansible-playbook dbhosts.yaml --tags="only" //分別去兩臺被管理主機上去檢視檔案建立情況 六、Roles 模組 Ansible為了層次化、結構化地組織Playbook,使用了角色(roles),roles可以根據層次型結構自動裝載變數檔案、task以及handlers等。簡單來講,roles就是通過分別將變數、檔案、任務、模組及處理器放置於單獨的目錄中,並可以便捷地include它們。roles一般用於基於主機構建服務的場景中,但也可以用於構建守護程序等場景中。 //roles 的目錄結構: cd /etc/ansible/ tree roles/ roles/ ├── web/ │ ├── files/ │ ├── templates/ │ ├── tasks/ │ ├── handlers/ │ ├── vars/ │ ├── defaults/ │ └── meta/ └── db/ ├── files/ ├── templates/ ├── tasks/ ├── handlers/ ├── vars/ ├── defaults/ └── meta/ roles 內各目錄含義解釋 ●files:用來存放由 copy 模組或 script 模組呼叫的檔案。 ●templates:用來存放 jinjia2 模板,template 模組會自動在此目錄中尋找 jinjia2 模板檔案。 ●tasks:此目錄應當包含一個 main.yml 檔案,用於定義此角色的任務列表,此檔案可以使用 include 包含其它的位於此目錄的 task 檔案。 ●handlers:此目錄應當包含一個 main.yml 檔案,用於定義此角色中觸發條件時執行的動作。 ●vars:此目錄應當包含一個 main.yml 檔案,用於定義此角色用到的變數。 ●defaults:此目錄應當包含一個 main.yml 檔案,用於為當前角色設定預設變數。 ●meta:此目錄應當包含一個 main.yml 檔案,用於定義此角色的特殊設定及其依賴關係。 在一個 playbook 中使用 roles 的步驟: (1)建立以 roles 命名的目錄 mkdir /etc/ansible/roles/ -p #yum裝完預設就有 (2)建立全域性變數目錄(可選) mkdir /etc/ansible/group_vars/ -p touch /etc/ansible/group_vars/all #檔名自己定義,引用的時候注意 (3)在 roles 目錄中分別建立以各角色名稱命令的目錄,如 httpd、mysql mkdir /etc/ansible/roles/httpd mkdir /etc/ansible/roles/mysql (4)在每個角色命令的目錄中分別建立files、handlers、tasks、templates、meta、defaults和vars目錄,用不到的目錄可以建立為空目錄,也可以不建立 mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta} mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta} (5)在每個角色的 handlers、tasks、meta、defaults、vars 目錄下建立 main.yml 檔案,千萬不能自定義檔名 touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml (6)修改 site.yml 檔案,針對不同主機去呼叫不同的角色 vim /etc/ansible/site.yml --- - hosts: webservers remote_user: root roles: - httpd - hosts: dbservers remote_user: root roles: - mysql (7)執行 ansible-playbook cd /etc/ansible ansible-playbook site.yml 示例: mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta} -p mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta} -p mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta} -p touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yml 案例:編寫httpd模組 寫一個簡單的tasks/main.yml vim /etc/ansible/roles/httpd/tasks/main.yml - name: install apache yum: name={{pkg}} state=latest - name: start apache service: enabled=true name={{svc}} state=started //定義變數:可以定義在全域性變數中,也可以定義在roles角色變數中,一般定義在角色變數中 vim /etc/ansible/roles/httpd/vars/main.yml pkg: httpd svc: httpd -------編寫mysql模組------- vim /etc/ansible/roles/mysql/tasks/main.yml - name: install mysql yum: name={{pkg}} state=latest - name: start mysql service: enabled=true name={{svc}} state=started vim /etc/ansible/roles/mysql/vars/main.yml pkg: - mariadb - mariadb-server svc: mariadb -------編寫php模組----- vim /etc/ansible/roles/php/tasks/main.yml - name: install php yum: name={{pkg}} state=latest - name: start php-fpm service: enabled=true name={{svc}} state=started vim /etc/ansible/roles/php/vars/main.yml pkg: - php - php-fpm svc: php-fpm -----編寫roles示例----- vim /etc/ansible/site.yml --- - hosts: webservers remote_user: root roles: - httpd - mysql - php cd /etc/ansible ansible-playbook site.yml