Ansible自動化運維工具闡述及配置實現

什麼是ansible

ansible是一個輕量級的運維管理工具 , 基於Python研發 。可實現對系統的批量管理配置、程序的批量部署、批量的運行命令等功能。 僅需在任意管理主機安裝 ansible 程序即可實現批量管理被管控主機且被管控的主機無需客戶端。 我們在安裝ansible時一定要依託epel源來安裝(推薦阿里雲),並且在線用yum安裝。它基於python開發所以得解決ansible對python編程的各種依賴。

ansible 特性

1、模塊化:調用特定的模塊,完成特定的任務; 
2、基於Python語言研發主要模塊由Paramiko, PyYAML和Jinja2三個核心庫實現; 
3、部署簡單:agentless; 
4、支持自定義模塊,使用任意編程語言; 
5、強大的playbook機制; 
6、具有冪等性;

ansible 基本架構

Modules:模塊化 
Core Modules 核心模塊 
Customed Modules 自定義模塊 
Host Iventory 主機庫清單,定義要管理的主機 
Files 可以通過配置文件來實現 
CMDB 也可以通過外部存儲來實現 
PlayBooks 劇本,定義每個主機所扮演的角色 
Hosts 哪些主機 
Roles 哪些角色 
Connection Plugins:連接插件,主要連接各管控主機 
Email 
Loggin 
Other

ansible.jpg

注意,ansible不是服務!千萬也不用去想服務的概念

安裝及程序環境: 

程序: 
ansible 
ansible-playbook 
ansible-doc 
配置文件: 
/etc/ansible/ansible.cfg 
主機清單: 
/etc/ansible/hosts 
插件目錄: 
/usr/share/ansible_plugins/ 

主機清單說明

vim /etc/ansible/hosts
# Ex 1: Ungrouped hosts, specify before any group headers.
直接給出主機,IP主機名都可以
## green.example.com
## blue.example.com
## 192.168.100.1
## 192.168.100.10
# Ex 2: A collection of hosts belonging to the 'webservers' group
把幾個主機分組,用中括號定義組名
## [webservers]
## alpha.example.org ...
## 192.168.1.100 ...
# If you have multiple hosts following a pattern you can specify
對主機進行通配001:006表示到一個範圍
## www[001:006].example.com
# Ex 3: A collection of database servers in the 'dbservers' group
定義一組數據庫服務器
## [dbservers]
## db02.intranet.mydomain.net ...
## 10.25.1.56 ...

基本使用入門,獲取模塊列表

ansible -doc -l 獲取模塊列表
ansible-doc -s MOD_NAME 獲取指定模塊幫助信息

以ping模塊爲例,測試

[root@localhost ~]# ansible webserver -m ping 
                   //我是定義了webserver組
   172.16.5.103 | UNREACHABLE! => {
       "changed": false,
       "msg": "Failed to connect to the host via ssh.",
       "unreachable": true
   }
   172.16.5.102 | UNREACHABLE! => {
       "changed": false,
       "msg": "Failed to connect to the host via ssh.",
       "unreachable": true
   }
以上的測試結果提示沒有通過ssh連接到主機,所以我們得配置基於ssh的公鑰認證
因爲ansible是基於ssh進行認證的
也可以這樣:
ansible all -m ping --ask-pass -c paramiko //你懂的

設置 SSH 公鑰認證,並把生成的公鑰拷貝到任意N個主機,實現無密碼操作

在Ansible服務端生成密鑰,並且複製公鑰到節點中。
root@ansible ~]#ssh-keygen //一路回車,文件生成路徑root/.ssh/
使用ssh-copy-id命令來複制Ansible公鑰到節點中。
ssh-copy-id -i root@172.16.5.102/103/105 //見笑了

以ping模塊再次測試

[root@Centos6 ~]# ansible all -m ping
172.16.5.103 | SUCCESS => {
   "changed": false,
   "ping": "pong"
}
172.16.5.102 | SUCCESS => {
   "changed": false,
   "ping": "pong"
}
172.16.5.105 | SUCCESS => {
   "changed": false,
   "ping": "pong"
}
[root@Centos6 ~]#
ok成功......

常用模塊舉例說明1

常用模塊:
ping:探測目標主機是否存活;
   舉例: ansible all -m ping
command:在遠程主機執行命令;
   舉例:ansible all -m command -a "ifconfig"
   舉例:ansible all -m command -a "useradd centos"
shell:在遠程主機上調用shell解釋器運行命令,支持shell的各種功能,如管道等
   舉例:ansible all -m shell -a "echo centos |passwd --stdin centos"
copy:複製文件,給定內容生成文件,mode, owner, group,follow, ...
   拷貝文件
   舉例:ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible mode=640"
   生成文件
   舉例:ansible all -m copy -a "content='hell\nworld\n' dest=/tmp/fstab.ansible mode=640"
file:設置文件屬性
   更改文件屬主
   舉例:ansible all -m file -a "path=/tmp/fstab.ansible owner=centos"
   刪除文件
   舉例:ansible all -m file -a "path=/tmp/fstab.ansible state=absent"
   state 用來定義目標文件狀態的
   創建指定文件空目錄
   舉例:ansible all -m file -a "path=/tmp/dir.ansible state=directory"
   鏈接文件
   舉例:ansible all -m file -a "path=/tmp/test.ansible.link src=/tmp/test.ansible
   state=link"
fetch:從遠程主機拉取一個文件
   ansible是用來管理多節點的,從遠程拉取多個文件到目標主機顯然不近乎仁義。所以用scp就能搞定。略過

常用模塊舉例說明2

cron:用來管理crontab的週期性任務
   定義一個任務
   舉例:ansible all -m cron -a "minute'*/5' job='/usr/sbin/ntpdate 10.1.0.1 &>/dev/null'
        name='sync time'"

        crontab -l
   刪除一個任務
   舉例:ansible all -m cron -a "name='sync time' state=absent"
   只刪除用ansible定義的名
hostname:定義主機名
   舉例:
yum:使用yum包管理器,完成程序包管理
   舉例:ansible all -m yum -a "name=httpd" 安裝
   舉例:ansible all -m yum -a "name=httpd state=absent" 刪除
service:控制服務,控制服務是否開機自動啓動
   舉例:ansible all -m service -a "name=httpd state=started enbaled=true"
group:添加或者刪除組
   舉例:
user:管理組賬號
   舉例:
setup:收集遠程各主機的各種屬性之和
   舉例:ansible all -m setup
以上內容就到這裏,我們該定義一個劇本了
定義一個PlayBook,我們來唱劇本

playbook是由一個或多個”play”組成的列表。play的主要功能在於將事先歸爲一組的主機裝扮成事先通過ansible中的task定義好的角色。從根本上來將,所謂的task無非是調用ansible的一個module。將多個paly組織在一個playbook中,即可以讓他們聯通起來按事先編排的機制同唱一臺大戲。 
YAML是用來寫配置文件的,接下來的配置文件都是以yaml爲後綴

[root@Centos6 ~]# yum info PyYAML
核心元素:
   Tasks:任務,由模塊定義的操作的列表;
   Variables:變量
   Templates:模板,即使用了模板語法的文本文件;
   Handlers:由特定條件觸發的Tasks
   Roles:角色;自包含,有完整獨立實體
playbook的基礎組件:
       Hosts:運行指定任務的目標主機,可多個;
       remote_user:在遠程主機以哪個用戶身份執行;
           sudo_user:非管理員需要擁有sudo權限;
       tasks:給出任務列表,執行完一個,執行第二個
           模塊,模塊參數:
               格式:
                   (1) action: module arguments //任務執行過程
                   (2) module name: arguments //指定運行的模塊

示例;利用playbook指揮三臺主機都創建mygrp組

[root@Centos6 ~]# vim group.yaml 
- hosts: all //任務運行在所有主機
 remote_user: root //在遠程主機以哪個用戶執行
 tasks: //任務列表1
 - name: install a group //任務名
   group: name=mygrp system=true //調用group模塊創建組mygrp
 - name: install a user //任務名
   user: name=user1 group=mygrp system=true //創建user1 組mygrp
- hosts: webserver //任務運行在webserver組內的主機
 remote_user: root //在遠程主機以哪個用戶執行
 tasks: //任務列表2
  - name: install httpd package //任務名
    yum: name=httpd //調用yum模塊安裝httpd
  - name: start httpd service //任務名
    service: name=httpd state=started //調用service模塊啓動服務
   檢查語法,測試運行
annsible-playbook --syntax-check group.yaml
annsible-playbook --list-hosts --list-tasks group.yaml

示例;利用playbook指揮webserver組內主機安裝httpd並監聽8080端口

vim httpd.yaml
- hosts: webserver
 remote_user: root
 tasks:
 - name: install httpd package
   yum: name=httpd state=latest
   tags: installpkg //指明跑某個標籤 -t installpkg
 - name: install conf file
   copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
   tags: installconf //指明跑某個標籤 -t installconf
   notify: restart httpd service  通知給《===httpd
 - name: start httpd service
   service: name=httpd state=started
 handlers: //處理器,也是任務,但是在一定條件下觸發
 - name: restart httpd service //handlers名字
   service: name=httpd state=restarted
語法檢查,測試運行
annsible-playbook --syntax-check  -t installconf  --list-tags httpd.yaml
annsible-playbook --syntax-check httpd.yaml
annsible-playbook --list-hosts --list-tasks httpd.yaml

注意: 
handlers:是指在一定條件下觸發,指明在一個需要讓別人重啓服務才生效的任務上使用notify,通知一定是handlers名字 
tags:只執行playbook中指定的tags標籤,滿足部分需要,多個任務可指明一個同tags 
也可以一次調用兩個標籤,如下 
annsible-playbook -t installconf,installpkg httpd.yaml

自定義變量Variables,可自定義安裝任意程序包

[root@Centos6 ~]# cat name.yaml 
- hosts: webserver
 remote_user: root
 vars:
 - pkgname: memcached //playbook中使用的變量Variables
 tasks:
 - name: install a package
   yum: name=` pakgname ` state=present //自定義變量
[root@Centos6 ~]#
語法測試
ansible-playbook --syntax-check name.yaml
ansible-playbook -e pkgname=httpd/vsftpd/ name.yaml
注意:在執行時命令行中給出的值要優先於playbook內置變量
如:ansible-playbook -e pkgname=httpd name.yaml
檢查:rpm -ql httpd memcached

傳遞給主機單獨變量,實現某些主機安裝不同程序包

編輯主機清單在每個主機後面指定調用變量並賦值
vim /etc/ansible/hosts
[webserver]
172.16.5.102 pkgname=nginx
172.16.5.103 pkgname=httpd
[webserver:vars] //爲一個組內不同主機定義相同變量,效果同上
webserver組內有一組變量vars,其中變量名是pkgname值是memcached
pkgname=memcached
vim name.yaml
   - hosts: webserver
     remote_user: root
     tasks:
     - name: install a package
       yum: name=` pkgname ` state=present
語法測試
ansible-playbook --syntax-check name.yaml

Inventory還可以使用參數: 
用於定義ansible遠程連接目標主機使用的屬性,而非傳遞給playbook的變量 
如: [webserver] 
172.16.5.102 ansible_ssh_user= ansible_ssh_pass ansible_sudo_pass 
不再是傳遞給playbook變量,而是主機本身。

playbook模版

模版本身是文本文件,內部嵌套有模板語言腳本(使用模板語言編寫jinjia2) 
Jinja2 是仿照 Django 模板的 Python 模板語言。 它速度快,被廣泛使用,並且提供了可選的沙箱模板執行環境保證安全。只介紹簡單使用,不過多闡述,語言啊 
jinjia2是用來寫模版文件的,接下來的模版文件都是以j2爲後綴

語法格式:
       支持字面量:
       字符串:使用單引號或雙引號;
       數字:整數、浮點數;
       列表:[item1, item2, ...]
       元組:(item1, item2, ...)
       字典:{key1:value1, key2:value2, ...}
       布爾型:true/false              
       算術運算:
           +, -, *, /, //, %, **
       比較操作:
           ==, !=, >, <, >=, <=    
       邏輯運算:and, or, not

基於模版把nginx配置文件對應的虛擬cpu值改成不是auto

安裝nginx程序包,我們要使用nginx的配置文件當模版 
yum install nginx 
cp /etc/nginx/nginx.conf . 
vim nginx.conf 
worker_processes ` ansible_processor_vcpus `; //由auto改成這樣 
vim nginx.yaml 
– hosts: webserver 
remote_user: root 
tasks: 
– name: copy a nginx file 
template: src=/root/nginx.conf dest=/tmp/nginx.conf 
語法測試 
ansible-playbook –syntax-check nginx.yaml

完整安裝nginx程序,並調用nginx.conf.j2模版

vim nginx.yaml 
– hosts: nginxserver //指定組 
remote_user: root 
tasks: 
– name: install nginx package //安裝nginx程序包 
yum: name=nginx state=latest //調用的yum模塊 
– name: install conf file 
template: src=/root/nginx.conf.j2 dest=/etc/nginx.conf //調用的配置文件模版 
tags: ngxconf //標籤 
notfiy: reload nginx service //通知讓標籤幹什麼 
– name: start nginx service 
service: name=nginx state=started enabled=true //啓動服務,並開機啓動 
handlers: //觸發器,當某個條件滿足時將觸發,也是任務 
– name: reload nginx service 
shell: /usr/sbin/nginx -s reload 
語法測試 
ansible-playbook –syntax-check nginx.yaml

使用when條件判斷語句,判斷基於不同發行版使用不同命令來重啓nginx服務

vim nginx2.yaml
- hosts: all
 remote_user: root
 tasks:
- name: install nginx package
 yum: name=nginx state=latest
- name: start nginx service on CentOS6
 shell: service nginx start
 when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "6"
- name: start nginx service
 shell: systemctl start nginx.service
 when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
語法測試
ansible-playbook --syntax-check nginx2.yaml

基於字符串列表給出元素循環:迭代,需要重複執行的任務; 
對迭代項的引用,固定變量名爲”item”,使用with_item屬性給定要迭代的元素; 
元素列表有兩種:字符串,字典

vim web.yaml
- hosts: webserver
 remote_user: root
 tasks:
 - name: install package
   yum: name=` item ` state=latest
   with_items:
   - httpd
   - php
   - php-mysql
   - php-mbstring
   - php-gd
語法測試
ansible-playbook --syntax-check web.yaml

基於字典列表給出元素循環:迭代,需要重複執行的任務; 
之前我們講過我們要批量在組內的機器上創建用戶是可以的。無非調用user模塊並指明組就可以,但是在不同組內的機器上創建的,可能用戶名與組名都是不相同的,那我們想要它都同樣該怎麼辦呢? 
這個時候我們就可以通過固定變量item來實現 增加兩條name,一個指明用戶,一個指明組名

vim creat.yaml
- hosts: webserver
 remote_user: root
 tasks:
 - name: creat groups //第一個任務
 yum: name=` item ` state=latest
 with_items:
 - groupx1
 - groupx2
 - groupx3
 - name: creat users //第二個任務
user: name={{ item.name }} group={{ item.group }} state=present
 with_items: //元素列表
 - {name: 'userx1', group: 'groupx1'//name鍵值隊
 - {name: 'userx1', group: 'groupx1'//name鍵值隊
 - {name: 'userx1', group: 'groupx1'//name鍵值隊
語法測試:ansible-playbook --check creat.yaml
註釋:
item.name表示調用第一個鍵name裏的值userx1
item.group表示調用第一個鍵group裏的值groupx1

角色(自包含,按照目錄結構來組織)

指定由哪些主機去對應的完成哪個已定義好的角色

roles是以特定的層級目錄結構進行組織的tasks、variables、handlers、templates… 
role_name/ 
files/: 
存儲由copy或script等模塊調用的文件; 
tasks/: 
此目錄中至少應該有一個名爲main.yml的文件,用於定義各task;其它的文件需要由main.yml進行“包含”調用; 
handlers/: 
此目錄中至少應該有一個名爲main.yml的文件,用於定義各handler;其它的文件需要由main.yml進行“包含”調用; 
vars/: 
此目錄中至少應該有一個名爲main.yml的文件,用於定義各variable;其它的文件需要由main.yml進行“包含”調用; 
templates/: 
存儲由template模塊調用的模板文本; 
meta/: 
此目錄中至少應有一個名爲main.yml文件,定義當前角色的特殊設定及其依賴關係;其它文件需要由main.yml進行“包含”調用; 
default/: 
此目錄中至少應該有一個名爲main.yml的文件,用於設定默認變量;

舉例:在webserver組內機器分別各自安裝nginx,memcached,msql-server通過roles調用tasks 
創建目錄 
mkdir -pv ./{nginx,memcached,httpd,mysql}/{files,templates,vars,handlers,meta,tasks,default}

安裝nginx
1、在nginx目錄tasks目錄下創建main.yml文件
   [root@Centos6 tasks]# vim main.yml
   - name: copy nginx package to remote host //先拷貝安裝程序
     copy: src=nginx-1.10.1-1.el7.x86_64.rpm
           dest=/tmp/nginx-nginx-1.10.1-1.el7.x86_64.rpm
     tags: cppkg
   - name: install nginx package //再安裝程序包
     yum: name=/tmp/nginx-1.10.0-1.el7.nginx.x86_64.rpm  state=present
   - name: install conf file nginx.conf //然後提供配置文件
     template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
     tags: nginxconf //加了一個標籤,按需執行
     notify: reload nginx service //通知標籤要幹什麼,我們需要在handlers目錄下創建觸發器
   - name: install conf file default.conf //再提供nginx默認文件
     template: src=default.conf.j2 dest=/etc/nginx/conf.d/default.conf
     tags: nginxconf
     notify: reload nginx service
   - name: start nginix service //啓動服務
     service : name=nginx enabled=true state=started
2、在nginx目錄handlers目錄下創建main.yml文件
     [root@Centos6 handlers]# cat main.yml
       - name: reload nginx service
         service: name=nginx state=restarted
       [root@Centos6 handlers]#
 3、拷貝nginx.conf文件到templates目錄下做模版
       [root@Centos6 roles]# cp /etc/nginx/nginx.conf nginx/templates/nginx.conf.j2
       更改 worker_processes ` ansible_processor_vcps `;
 4、拷貝default.conf文件到templates目錄下做模版
         [root@Centos6 roles]# cp /etc/nginx/conf.d/default.conf nginx/default/default.conf.j2
         更改    listen       ` nginxport `;  //變量定義
 5、nginx/vars目錄下創建main.yml 調用變量
         寫入 nginxport: "8090"
 6、在ansible目錄下創建nginx.yml文件來調用以上各種組織好的nginx角色
         [root@Centos6 roles]# vim nginx.yml
               - hosts: webserver
                 remote_user: root
                 roles: //定義角色
                 - { role: nginx, ngxport: 8080//即能調角色,又能向角色傳變量
                 - nginx //角色調用
 7、編輯ansible.cfg文件啓用roles_path讓roles去找所定義的文件
         [root@Centos6 ansible]# vim ansible.cfg
         啓用把前面註釋去掉 roles_path    = /etc/ansible/roles
8、要注意,避免錯誤,最好定義好文件後各自做個語法測試
9、然後就可以讓劇本跑一遍了
10、確保你的系統selinux是disabled,不然服務起不來
    ansible-playbook --syntax-check nginx.yml
安裝memcached
[root@Centos6 memcached]# ls ../memcached/*
../memcached/handlers:
main.yml
- name: reload memcached
 service: name=memcached state=restarted
../memcached/tasks:
main.yml
- name: install memcached
 yum: name=memcached state=latest
- name: install conf file
 template: src=memcached.j2 dest=/etc/sysconfig/memcached
 tags: mcconf
 notify: reload memcached
- name: start memcached service
 service: name=memcached state=started enabled=true
../memcached/templates:
memcached.j2
   PORT="11211"
   USER="memcached"
   MAXCONN="1024"
   CACHESIZE="{{ ansible_memtotal_mb //4 }}"
   OPTIONS=""
[root@Centos6 memcached]#
安裝mysql
vim mysql/tasks/main.yml
mysql/tasks:
main.yml
- name: install mysql-server
 yum: name=mysql-server state=latest
 when: ansible_distribution == "Centos" and ansible_distribution_major_version == "6"
- name: install mariadb-server
 yum: name=mariadb-server state=latest
 when: ansible_distribution == "Centos" and ansible_distribution_major_version == "7"
- name: start mysql service
 service: name=mysqld state=started
 when: ansible_distribution == "Centos" and ansible_distribution_major_version == "6"
- name: start mariadb service
 service: name=mariadb state=started
 when: ansible_distribution == "Centos" and ansible_distribution_major_version == "7"
[root@Centos6 ansible]# vim mysql.yml
   - hosts: webserver
     remote_user: root
     roles:
     - mysql
語法測試:
ansible-playbook --syntax-check  mysql.yml

done!!!

以上配置環境皆基於CentOS 7.2來實現並完成。

如有錯誤請指出,我們共同學習......

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章