ansible


ansible

一、基礎介紹

運維工具的分類

根據控制端與被控制端進行交互的方式分為兩類,一類需要被控制端啟用功能,另一類中被控制端無須具備代理功能,控制端直接通過ssh協議以系統用戶的身份與被控制端進行連接
agent:puppet, func, ...
agentless(ssh,):ansible, fabric

特性:

模塊化:調用特定的模塊,完成特定任務;
基於Python語言實現,由Paramiko, PyYAML和Jinja2三個關鍵模塊;
部署簡單:agentless;
支持自定義模塊;
支持playbook;
冪等性;

安裝:

依賴epel源,包名為 ansible

配置文件

主配置文件:/etc/ansible/ansible.cfg
主機清單:/etc/ansible/hosts

主程序:
ansible
ansible-playbook
ansible-doc

ansible的簡單使用格式

ansible HOST-PATTERN -m MOD_NAME -a MOD_ARGS -f FORKS -C -u USERNAME -c CONNECTION

二、常用模塊

(1)command模塊

command模塊:在遠程主機運行命令;
chdir:執行命令前切換工作目錄的指定位置
creates:/path/to/somefile 創建該目錄前判斷該目錄是否存在
removes:/path/to/somefile 如果給定的文件或者目錄不存在,則不執行命令
command模塊為ansible的默認模塊,可以不指定直接使用-a

[root@CentOS6 ~]#ansible all -m command -a 'date'
172.18.45.7 | SUCCESS | rc=0 >>
Tue Nov 21 10:47:55 CST 2017
...
#all:指明匹配的主機,可以是特定IP可以是host定義的組名,all表示全部主機
#-m 指定模塊名
#-a 模塊參數

(2)cron 模塊

Manage cron.d and crontab entries.
minute=
day=
month=
weekday=
hour=
job=
*name=
state=
present:創建
absent:刪除
示例:

[root@CentOS6 ~]#ansible webserv -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job"'
172.18.45.8 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "test cron job"
    ]
}
172.18.45.11 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "test cron job"
    ]
}
#默認state=present,如果要刪除該計划任務則添加state=absent
[root@CentOS6 ~]#ansible webserv -a 'crontab -l'
172.18.45.11 | SUCCESS | rc=0 >>
#Ansible: test cron job
*/10 * * * * /bin/echo hello
172.18.45.8 | SUCCESS | rc=0 >>
#Ansible: test cron job
*/10 * * * * /bin/echo hello

(3)user模塊

管理用戶賬號
*name= #指定用戶名
system=
uid=
shell=
group=
groups=
comment=
home=
generate_ssh_key= [true|false]
local=
默認state=present,如果要刪除該用戶則添加state=absent

(4)copy模塊

Copies files to remote locations.
用法:
(1) src= #源路徑 dest=#目標路徑
(2) content= #取代src,直接生成目標文件 dest=
owner, group, mode
示例:

[root@CentOS6 ~]#ansible all -m copy -a 'src=/etc/fstab dest=/root/fstab.ansible owner=root mode=600'
#此處src可用content=“string...”代替

(5)file模塊

Sets attributes of files定義文件屬性
用法:
(1) 創建鏈接文件:*path= src= state=link
(2) 修改屬性:path= owner= mode= group=
(3) 創建目錄:path= state=directory
注意:sate屬性的可用值
file,directory,link,hard,tuoch,absent

[root@CentOS6 ~]#ansible all -m file -a 'path=/root/ansible.link src=/root/fstab.ansible state=link'

(6)ping模塊

測試指定主機是否能連接

(7)service模塊

管理服務
*name= #服務名稱
state=
started
stopped
restarted
enabled= #是否啟用開機啟動取值為“true or false”
runlevel=
示例:

[root@CentOS6 ~]#ansible websrvs -m service -a "name=nginx enabled=true state=started"
#enabled=true 設置開機自動啟動

(8)shell模塊

在遠程主機在shell進程下運行命令,支持shell特性,如管道等;

(9)script模塊

在遠程主機運行一個本地的腳本
僅支持相對路徑
ansible all -m script -a "script.sh"

(10)yum模塊

yum模塊:Manages packages with the '’yum' package manager
name=:程序包名稱,可以帶版本號;
state=
present(安裝), latest(安裝最新版本)
absent(卸載)
示例:

[root@CentOS6 ~]#ansible websrvs -m yum -a "name=nginx state=latest"

(11)setup模塊

收集遠程和主機的facts
可以用於劇本調用,作為變量為每台主機靈活定制配置參數

(12)git模塊

Deploy software (or files) from git checkouts
repo=
dest=
version=

(13)deploy_helper模塊

Manages some of the steps common in deploying projects.

(14)haproxy模塊

Enable, disable, and set weights for HAProxy backend servers using socket commands.
backend=
host=
state=
weight=

三、playbook

(1)語法YAML

YAML(/ˈjæməl/,尾音類似camel駱駝)是一個可讀性高,用來表達數據序列的格式。YAML參考了其他多種語言,包括:C語言、Python、Perl,並從XML、電子郵件的數據格式(RFC 2822)中獲得靈感。Clark Evans在2001年首次發表了這種語言,另外Ingy döt Net與Oren Ben-Kiki也是這語言的共同設計者。目前已經有數種編程語言或腳本語言支持(或者說解析)這種語言。

YAML是"YAML Ain't a Markup Language"(YAML不是一種標記語言)的遞歸縮寫。在開發的這種語言時,YAML 的意思其實是:"Yet Another Markup Language"(仍是一種標記語言),但為了強調這種語言以數據做為中心,而不是以標記語言為重點,而用反向縮略語重命名。

YAML的語法和其他高級語言類似,並且可以簡單表達清單、散列表,標量等數據形態。它使用空白符號縮進和大量依賴外觀的特色,特別適合用來表達或編輯數據結構、各種配置文件、傾印除錯內容、文件大綱(例如:許多電子郵件標題格式和YAML非常接近)。

(2)YAML特點:

可讀性好;
和腳本的交互性好;
有一個一致的信息模型;
易於實現;
可以基於流量來處理;
表達能力強,擴展性好

(3)Playbook的核心組件

Hosts:主機
Tasks:任務列表
Variables:變量
Templates:包含了模板語法的文本文件;
Handlers:由特定條件觸發的任務;

(4)Hosts

運行指定任務的目標主機;

(5)remoute_user

在遠程主機上執行任務的用戶;

(6)sudo_user

用戶身份切換

(7)tasks

任務列表
模塊,模塊參數;
格式:
(1) action: module arguments
(2) module: arguments

注意:shell和command模塊后面直接跟命令,而非key=value類的參數列表;
(1) 某任務的狀態在運行后為changed時,可通過“notify”通知給相應的handlers;
(2) 任務可以通過"tags“打標簽,而后可在ansible-playbook命令上使用-t指定進行調用;
blaybook中通過hosts組件實現執行任務的目標主機或者主機群靈活調用,而tasks組件下的tags元素則實現了各項任務的單獨調用。

(8)notify

觸發器
notify作為觸發器被定義在tasks之下,當標記有notify觸發器的任務被執行時會觸發下文中handlers中定義的任務。
主要用於配置文件修改時觸發服務重新啟動,或者重讀配置文件。

(9)handlers

處理器
handles定義了一個任務,與tasks不同的是handles定義的任務是條件式觸發的,當標記觸發器notify的任務被執行時才會觸發handles定義的任務。

示例:

[root@CentOS6 ~]#vim nginx.yml 
- hosts: websrvs
  remote_user: root
  tasks:
  - name: install nginx pachkage
    yum: name=nginx state=latest
  - name: start nginx service
    service: name=nginx enabled=true state=started

- hosts: dbsrvs
  remote_user: root
  tasks:
  - name: install redis package
    yum: name=redis state=latest
  - name: install conf file
    copy: src=/root/redis.conf dest=/etc/redis.conf owner=redis group=root mode=644
    tags: instconf
    notify: restart redis service	#觸發器
  - name: start redis service
    service: name=redis state=started
  handlers:	#處理器
  - name: restart redis service
    service: name=redis state=restart

四、運行playbook的方式

(1) 測試
ansible-playbook --check #只檢測可能會發生的改變,但不真正執行操作;
ansible-playbook --list-hosts #列出運行任務的主機;
ansible-playbook --list-tasks #列出要運行的任務列表
ansible-playbook --syntax-check #語法檢查

(2) 運行handlers:
任務,在特定條件下觸發;
接收到其它任務的通知時被觸發;
notify: HANDLER TASK NAME

variables

(1) facts:可直接調用;
注意:可使用setup模塊直接獲取目標主機的facters;

(2) 用戶自定義變量:
(a) ansible-playbook命令的命令行中的
-e VARS, --extra-vars=VARS
(b) 在playbook中定義變量的方法:
vars:
- var1: value1
- var2: value2

變量引用:{{ variable }}
示例:

[root@CentOS6 ~]#vim instpkg.yml 
- hosts: websrvs
  remote_user: root
  vars:
  - pkgname: tree	#定義變量
  tasks:
  - name: install {{ pkgname }}
    yum: name={{ pkgname }} state=latest #調用變量
#name 同樣支持變量調用

(3) 通過roles傳遞變量;

(4) Host Inventory
(a) 用戶自定義變量
(i) 向不同的主機傳遞不同的變量;
IP/HOSTNAME varaiable=value var2=value2
(ii) 向組中的主機傳遞相同的變量;
[groupname:vars]
variable=value
(b) invertory參數
用於定義ansible遠程連接目標主機時使用的參數,而非傳遞給

playbook的變量;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansbile_sudo_pass
...

操作

說明:
該試驗實現簡單的ansible-playbook功能,通過一台控制端配置三台web服務器安裝nginx,配置兩台數據庫服務安裝redis同時同一部署redis的配置文件,簡單的將redis的監聽端口改為0.0.0.0意為監聽本機所有IP地址。
(一)配置host文件

[root@CentOS6 ~]#vim /etc/ansible/hosts
[webserv]
172.18.45.11
172.18.45.8
172.18.45.13
[dbserv]
172.18.45.7
172.18.45.12

(二)密鑰驗證
同步時間:ntpdate 172.18.0.1
生成私鑰:

[root@CentOS6 ~]#ssh-keygen -t rsa

復制密鑰給各個host:

ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.18.45.11
ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.18.45.12
...

查看ansible支持的所有模塊:

[root@CentOS6 ~]#ansible-doc -l
a10_server                         Manage A10 Networks AX/SoftAX/Thunder/vThu...
a10_server_axapi3                  Manage A10 Networks AX/SoftAX/Thunder/vThu...
...

查看特定模塊用法:

[root@CentOS6 ~]#ansible-doc -s MODULE_NAME

(三)編輯playbook

[root@CentOS6 ~]#vim nginx.yml		#要求以.yml結尾
- hosts: websrvs
  remote_user: root			#遠程登錄用戶身份
  tasks:
  - name: install nginx pachkage
    yum: name=nginx state=latest
  - name: start nginx service
    service: name=nginx enabled=true state=started
#使用yum安裝nginx啟動服務,並設置開機自動啟動
- hosts: dbsrvs
  remote_user: root
  tasks:
  - name: install redis package
    yum: name=redis state=latest
  - name: install conf file
    copy: src=/root/redis.conf dest=/etc/redis.conf owner=redis group=root mode=644
    #統一部署配置文件,指定配置文件源路徑,目標路徑,屬主,屬組,以及權限
  - name: start redis service
    service: name=redis state=started

(四)的配置文件
在ansible srv端安裝redis,將redis的配置文件復制到playbook中指定的位置既/root目錄之下,並修改監聽端口將bind 127.0.0.1改為bind 0.0.0.0。
(五)測試
檢查配置文件語法錯誤:

[root@CentOS6 ~]#ansible-playbook --syntax-check nginx.yml 
playbook: nginx.yml		#無誤

模擬運行:

[root@CentOS6 ~]#ansible-playbook -C nginx.yml

(六)運行
在測試沒有錯誤的情況下即可運行劇本

五、補充模塊

setup模塊

template模塊

基於模板方式生成一個文件復制到遠程主機
*src=
*dest=
owner=
group=
mode=

                <html>
                    <title></title>
                    <head></head>
                    <body>
                        ...
                        <?php
                            phpinfo();
                        ?>
                    </body>
                </html>

模板:templates
文本文件,嵌套有腳本(使用模板編程語言編寫)
Jinja2:
字面量:
字符串:使用單引號或雙引號;
數字:整數,浮點數;
列表:[item1, item2, ...]
元組:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布爾型:true/false

算術運算

+, -, *, /, //, %,**
比較操作:
==, !=, >, >=, <, <=

邏輯運算

and, or, not
示例:

- hosts: websrvs
  remote_user: root
  tasks:
    - name: install nginx
    yum: name=nginx state=present
    - name: install conf file
    template: src=files/nginx.conf.j2 dest=/etc/nginx/nginx.conf
    notify: restart nginx
    tags: instconf
    - name: start nginx service
    service: name=nginx state=started
    handlers:
    - name: restart nginx
    service: name=nginx state=restarted					

模板配置文件 :nginx.conf.j2

worker_processes {{ ansible_processor_vcpus - 1 }};
listen {{ http_port }};
server_name 

條件測試

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 groups
  group: name={{ item }} state=present
  with_items:
  - group11
  - group12
  - group13
- 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)

角色集合:
roles/
mysql/
httpd/
nginx/
memcached/

每個角色,以特定的層級目錄結構進行組織:

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' " }

更多開源模塊示例可參考:
https://github.com/ansible/ansible-examples


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM