2017 11-17 ansible應用

一.ansible

(1) ansible:

ansible是一款新出現的自動化運維系統,基于python開發并集合了眾多運維工具的優點,實現批量系統配置,具有程序部署,批量運行命令等功能。工作特點是基于模塊化工作,但本身不具有部署能力,真正具有部署能力的是ansible所運行的模塊,ansible只是提供框架且基于ssh驗證實現批量通訊和配置。

(2)特性:

1.模塊化:調用特定的模塊來完成任務
2.基于python語言實現,由paramiko,pyYAML和jinja2三個關鍵模塊組成
3.部署簡單:屬于agentless
4.支持自定義模塊
5.支持playbook
6.冪等性:執行多次操作,不會造成危險后果并且結果相同

(3)安裝

在epel源中下載或去官網下載
配置文件:/etc/ansible/ansible.cfg
主機清單:/etc/ansible/hosts
主程序:ansible,ansible-playbook,ansible-doc

二.ansible常用模塊

  • 獲取模塊列表
    搜狗截圖20171118094011.png

    按分類查詢
    ansible-doc -s shell
    ansible-doc -s command

  • ansible的使用
    使用ansible -h來獲取幫助信息


    搜狗截圖20171118094524.png
  • 常用選項:
    -a:指定命令參數
    -m:指定模式名稱
  • 簡單配置演示
    ansible的使用格式:ansible HOST-PATTERN -m MOD_NAME -a MOD_ARGS
    首先在主機清單中加入要配置的Ip地址


    搜狗截圖20171118093220.png

    然后使用ansible all -m ping——表示測試所有配置的Ip連通性


    搜狗截圖20171117220036.png

    注意:當在Hosts清單中加入一個不存在的ip地址,然后去測試就會出現如圖的結果,顯示主機不可到達
  • 查看清單列表
    查看所有列表
    ansible all --list-hosts


    搜狗截圖20171117220111.png

    按分類進行查詢
    ansible websrvs --list-hosts
    ansible dbsrvs --list-hosts


    搜狗截圖20171118095923.png

常用模塊

1.command:在遠程主機運行命令

chdir=:執行命令前切換工作目錄至指定的位置;
creates=/PATH/TO/SOMEFILE_OR_DIR:如果此處給定的文件或目錄存在,則不執行命令;
removes=/PATH/TO/SOMEFILE_OR_DIR:如果此處給定的文件或目錄不存在,則不執行命令;
意為:令此處給定的文件或目錄存在時方執行命令;
示例:
ansible 172.18.250.89 -m command -a "mkdir mydir chdir=/tmp"——針對172.18.250.89創建一個目錄并且將目錄放在tmp作為子目錄
此時會顯示創建成功,在172.18.250.89的主機上去查看


搜狗截圖20171118100950.png

但是如果已經存在這個目錄后還要創建相同目錄就會報錯


搜狗截圖20171117221138.png

因此引入冪等性只需要在創建的最后加入creates=/tmp/mydir
搜狗截圖20171117221246.png

如上圖所示會告訴用戶該目錄已經存在,但是不會出現報錯
  • 刪除目錄,前提該目錄必須存在
    ansible 172.18.250.89 -m command -a "rmdir mydir chdir=/tmp removes=mydir"


    搜狗截圖20171118102115.png

2.shell模塊——命令解釋器

shell模塊:在遠程主機在shell進程下運行命令,支持shell特性,如管道等;
chdir:執行命令前切換工作目錄至指定的位置;
creates=/PATH/TO/SOMEFILE_OR_DIR:如果此處給定的文件或目錄存在,則不執行命令;
removes=/PATH/TO/SOMEFILE_OR_DIR:如果此處給定的文件或目錄不存在,則不執行命令;
意為:令此處給定的文件或目錄存在時方執行命令;
executable=/PATH/TO/SHELL:指定運行命令使用的shell解釋器;
示例:創建用戶
ansible 172.18.250.89 -m command -a "useradd use1"
為用戶添加密碼
如果不設置命令解釋器結果如下
ansible 172.18.250.89 -m command -a "echo magedu | passwd --stdin user1"


搜狗截圖20171117221838.png

結果將追加密碼的密令識別成字符串,因此使用shell來解決問題
ansible 172.18.250.89 -m shell -a "echo magedu |passwd --stdin user1"


搜狗截圖20171117221937.png

3.user模塊:管理用戶賬號

  • 經常使用的選項
    name=
    system=
    uid=
    shell=
    group=
    groups=
    comment=
    home=
    generate_ssh_key=
    local=


    搜狗截圖20171117222103.png
  • 示例:
    ansible websrvs -m user -a "name=hako groups=ha state=present uid=3000 createhome=yes shell=/bin/tcsh generate_ssh_key=true"


    搜狗截圖20171117223235.png

    解釋:創建一個用戶名為hako,組為ha,狀態為創建,uid=3000,創建家目錄(不寫也可以,本身就會默認創建),指定shell類型,并且生成私鑰文件,以便今后的ssh驗證


    搜狗截圖20171118105255.png

    創建成功
    也可以直接修改,比如修改uid
    直接執行

    ansible websrvs -m user -a "name=hako groups=ha state=present uid=5000 createhome=yes shell=/bin/tcsh generate_ssh_key=true"


    搜狗截圖20171117223307.png

    修改成功
  • 刪除用戶
    ansible websrvs -m user -a "name=hako groups=ha state=absent"


    搜狗截圖20171118110053.png

    如果想要將ssh驗證取消直接將generate_ssh_key=true改為flase

4. group模塊:管理組賬號

name=
state=
system=
gid=

  • 示例:
    ansible websrvs -m group -a "name=ha system=yes state=present"


    搜狗截圖20171117222406.png

5.copy模塊: Copies files to remote locations.

用法:
(1) src= dest=
(2) content= dest=
owner, group, mode


搜狗截圖20171118110951.png

示例:
首先在ansible主機上創建一個文件
vim test.txt
然后執行 ansible all -m copy -a " src=test.txt dest=/tmp owner=daemon group=nobody mode=664"


搜狗截圖20171117224119.png

在客戶端查詢
搜狗截圖20171117224058.png

執行content 是往test.txt中追加內容
搜狗截圖20171117224426.png

查看test.txt
搜狗截圖20171118111750.png

追加內容成功

6.file模塊Sets attributes of files

用法:
(1) 創建鏈接文件:*path= src= state=link
(2) 修改屬性:path= owner= mode= group=
(3) 創建目錄:path= state=directory
注意:state屬性的可用值
file,directory,link,hard,touch,absent
示例:
ansible all -m file -a "path=/tmp/hidir state=directory"


搜狗截圖20171117224832.png

在客戶端查看


搜狗截圖20171118112517.png

添加屬性
ansible all -m file -a "path=/tmp/hidir state=directory owner=nobody mode=770"
搜狗截圖20171117224930.png

查看
搜狗截圖20171118112852.png

創建空文件
ansible all -m file -a "path=/tmp/hifile state=touch owner=nobody mode=770"
搜狗截圖20171117225130.png

查看
搜狗截圖20171118113223.png

創建符號鏈接
ansible all -m file -a "path=/tmp/mytest.txt src=/tmp/text2.txt stste=link"


搜狗截圖20171117225436.png

查看
搜狗截圖20171117225555.png

刪除符號鏈接
搜狗截圖20171117225640.png

7. get_url模塊

Downloads files from HTTP, HTTPS, or FTP to node
常用用法
url=
dest=
sha256sum= 檢驗校驗碼
owner, group, mode
示例:登錄www.redis.io
復制下載鏈接
執行 ansible all -m get_url -a "url=/http://download.redis.io/releases/redis-4.0.2.tar.gz dest=/tmp"

搜狗截圖20171118114600.png

8.cron模塊

管理任務計劃:Manage cron.d and crontab entries.
minute=
day=
month=
weekday=
hour=
job=
name=
state=
present:創建
absent:刪除
示例:
ansible-doc -s cron


搜狗截圖20171118161854.png

可以定義一個周期任務實現用ntpdate來到172.18.0.1上同步時間
ansible all -m cron -a "name='timesync' job='/usr/sbin/ntpdate 172.18.0.1 &> /dve/null' minute='*/5' "
到客戶端查看


搜狗截圖20171118164054.png

如果想禁止該計劃任務可以在后面加上disabled=true
搜狗截圖20171118164243.png

再到客戶端去查看
搜狗截圖20171118164421.png

9.git模塊

作用:Deploy software (or files) from git checkouts
repo=
dest=
version=
首先要yum git
ansible-doc -s git

搜狗截圖20171118164800.png

示例:
www.github.com中搜索fastdfs
搜狗截圖20171118165030.png

在服務器上執行
ansible websrvs -m git -a "repo=https://github.com/happyfish100/fastdfs.git dest=/tmp/fastdfs"
在客戶端上查看
搜狗截圖20171118165158.png

注意在其他客戶端上都要下載git否則無法進行批量復制下載

9.yum模塊

name=:程序包名稱,可以帶版本號;
state=
present, latest, installed
absent, removed
其它的包管理工具:apt(debian), zypper(suse), dnf(fedora), rpm, dpkg, ...
示例:
ansible all -m yum -a "name=nginx state=latest "
可以使用ansible websrvs -a "rpm -q nginx"
來查看


搜狗截圖20171118165914.png

也可以去客戶端去查看

10.service模塊

*name=
state=
started
stopped
restarted
enabled=
runlevel=
示例:開啟nginx服務,并且設為開機自啟
ansible websrvs -m service -a "name=nginx enabled=true state=started"


搜狗截圖20171118170411.png

客戶端的Nginx服務被開啟

三. Playbook

(1).playbook:YAML格式,任務(task)。
將多個操作命令寫到一個文件中,可以同時執行文件中中命令也可以吧playbook叫做"劇本",將編好的內容按劇本進行下去
(2).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非常接近)。
(3).基本數據結構:
標量、數組、關聯數組
(4).Playbook的核心元素:
Hosts:主機
Tasks:任務列表
Variables
Templates:包含了模板語法的文本文件;
Handlers:由特定條件觸發的任務;

示例:

在ansible主機上編寫腳本
vim nginx.yaml

 1 - hosts: websrvs ——websrvs上安裝nginx
  2   remote_user:  root
  3   tasks:
  4   - name: install nginx package——安裝nginx安裝包
  5     yum: name=nginx state=latest——執行yum命令
  6   - name: start nginx service——開啟nginx服務
  7     service: name=nginx enabled=true state=started——設定開機自啟
  8 
  9 - hosts: dbsrvs——在dbsrvs上安裝redis服務
 10   remote_user: root
 11   tasks:
 12   - name: install redis package
 13     yum: name=redis state=latest
 14   - name: install conf file——安裝conf文件
 15     copy: src=/etc/redis.conf dest=/etc/redis.conf owner=redis group=root mode=644——將本地的配置文件復制目標主機上,并設置所有者和所屬組,權限為644
 16    # tags: insconf
 17    # notify: restart redis service
 18   - name: start redis service
 19     service: name=redis state=started
 20     #tags: startredis
 21   #handlers:
 22   #- name: restart redis service
 23   #  service: name=redis state=restarted

使用ansible-playbook --list-hosts nginx.yaml來查看


搜狗截圖20171118173144.png

ansible-playbook --list-tasks nginx.yaml來查看任務


搜狗截圖20171118173221.png

ansible-playbook --syntax-check nginx.yaml語法檢查
搜狗截圖20171118173426.png

ansible-playbook -C nginx.yaml執行任務屬于并行執行


搜狗截圖20171118173636.png

ansible websrvs -m setup 收集客戶端的信息變量
注意:當修改某服務的配置文件,會有什么影響
例:將redis.conf配置文件中認證密碼改為mageduu后再次執行ansible-playbook -C nginx.yaml
結果所有服務都要重跑一次,而且修改的內容也沒有生效
因為服務沒有重啟,不會因為內容的改變而觸發新的變化
首先解決多個任務總是要都重新執行的問題
加標簽:
搜狗截圖20171118175041.png

執行ansible-play --list-tasks nginx.yaml


搜狗截圖20171118175443.png

執行:ansible-playbook -t insconf,startredis nginx.yaml
但是新修改的命令也不會生效,如果想要啟動重啟任務就要加入
搜狗截圖20171118175835.png

再次執行ansible-playbook -t insconf,startredis nginx.yaml
發現重啟命令生效

四. variables——變量

(1) facts:可直接調用;
注意:可使用setup模塊直接獲取目標主機的facters;
(2) 用戶自定義變量:
(a) ansible-playbook命令的命令行中的
-e VARS, --extra-vars=VARS
(b) 在playbook中定義變量的方法:
vars:
-var1: value1
-var2: value2
變量引用:{{ variable }}
(3) 通過roles傳遞變量;
(4) Host Inventory
(a) 用戶自定義變量
(i) 向不同的主機傳遞不同的變量;
IP/HOSTNAME varaiable=value var2=value2
(ii) 向組中的主機傳遞相同的變量;
[groupname:vars]
variable=value

搜狗截圖20171118224216.png

(b) invertory參數
用于定義ansible遠程連接目標主機時使用的參數,而非傳遞給playbook的變量;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansbile_sudo_pass

  • 測試
    vim installpkc.yaml
- hosts: websrvs
  remote_user: root
  vars: ——定義變量
  - pkgname: tree——安裝tree包
  tasks:
  - name: install package {{ pkgname }}——安裝配置格式
    yum: name={{ pkgname }}  state=latest
搜狗截圖20171118222100.png

在執行過程中也可以執行-e memcached命令
首先要配置一個memcahced.yaml文件


搜狗截圖20171118222408.png

ansible-playbook -e "pkgname=memcached" -C installpkc.yaml


搜狗截圖20171118222850.png

這就說明命令行的優先級是高于playbook的優先級
也可以在ansible的清單文件中進行配置
vim /etc/ansible/hosts
搜狗截圖20171118223214.png

再次執行后觀察結果
ansible-playbook -e "pkgname=memcached" -C installpkc.yaml


搜狗截圖20171118223535.png
  • 測試用于定義ansible遠程連接目標主機時使用的參數,而非傳遞給playbook的變量;
    vim /etc/ansible/hosts
    [websrvs]
    172.18.250.89 ansible_ssh_user=root ansible_ssh_pass=mage
    但是通常不建議這么設定,容易暴露密碼會帶來安全隱患
    所以不經常使用該方法

五.模板文件的應用

基于模板方式生成一個文件復制到遠程主機
src=
dest=
owner=
group=
mode=
文本文件,嵌套有腳本(使用模板編程語言編寫)
Jinja2:
字面量:
字符串:使用單引號或雙引號;
數字:整數,浮點數;
列表:[item1, item2, ...]
元組:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布爾型:true/false
算術運算:
+, -, *, /, //, %, **
比較操作:
==, !=, >, >=, <, <=
邏輯運算:
and, or, not

示例:

cp /etc/redis.conf{,.j2}——復制一個以.j2結尾的配置文件
編輯文件vim /etc/redis.conf.j2


搜狗截圖20171118225027.png

以上命令是為了調用內鍵變量來生成一個.j2格式的模板文件
提取172.18.250.223的內存信息


搜狗截圖20171118225132.png

通過模板文件來實現對內存大小進行計算
vim redis_conf.yml
搜狗截圖20171118225837.png

執行ansible-playbook redis_conf.yaml


搜狗截圖20171118230138.png

在172.18.250.223
vim /etc/reids.conf
搜狗截圖20171118230217.png

內存減少一半
  • 一般情況下常用的內鍵變量
    ansible 172.18.21.200 -m setup |grep vcpu
    ansible 172.18.21.200 -m setup |grep fqdn
    ansible 172.18.21.200 -m setup |grep memtotal
    ansible 172.18.21.200 -m setup |grep version
    ansible 172.18.21.7 -m setup|grep -A 2 "default_ipv4"

條件測試:

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"——同上,版本為6就下載到centos6上                

示例:

在ansible主機上vim diff.txt和diff2.txt,分別寫入不同內容
例如在diff.txt中寫入'host1',在diif2.txt寫入'hosts2'
此時vim copyfiles.yaml

- hosts: websrvs
  remote_user: root
  tasks:
  - name: copy file
    copy: src=/root/diff.txt dest=/tmp/
    when: ansible_default_ipv4['address'] == '172.18.250.89'——判斷條件
  - name: copy file 2
    copy: src=/root/diff2.txt dest=/tmp/
    when: ansible_default_ipv4['address'] == '172.18.250.223'——判斷條件
以上腳本內容是為了對不同的內容復制到不同的主機上去,實現分別復制的功能  

執行 ansible-playbook -C copyfiles.yaml


搜狗截圖20171119144446.png

到目標主機上查看結果
172.18.25.89


搜狗截圖20171119144548.png

172.18.250.223
搜狗截圖20171119144636.png

循環測試

迭代,需要重復執行的任務;
對迭代項的引用,固定變量名為”item“
而后,要在task中使用with_items給定要迭代的元素列表;
列表方法:
字符串
字典

示例1:

- name: install some packages
yum: name={{ item }} state=present——循環模式的書寫格式一定要有{{ item }}
with_items:
- nginx
- memcached
- php-fpm

示例2:

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

為了方便理解做幾個示例來加深印象
vim tomcat.yml

1 - hosts: websrvs
2   remote_user: root
3   vars:
4   - jdk_version: 1.8.0
5   tasks:
6   - name: install {{ item }} package
7     yum: name={{ item }} state=latest
8     with_items:
9     - nginx
10   - tomcat
11   - java-{{ jdk_version }}-openjdk
12   - tomcat-webapps
13   - tomcat-docs-webapp
14   - tomcat-admin-webapps

ansible-playbook tomcat.yml


搜狗截圖20171119151613.png

也可以去目標主機去查看結果
實驗2:對一臺主機安裝不同軟件且指出版本

- hosts: 172.18.250.89
  remote_user: root
  tasks:
  - name: install tomcat package
    yum: name={{ item.name }}-{{ item.version }} state=latest—定義子健為版本號 
    with_items:
    - { name: 'nginx',version: '1.12.2' }
    - { name: 'tomcat',version: '7.0.76'   }

實驗3:將同一軟件的不同文件復制到遠程主機上
以tomcat為例
vim tomcat3.yml

 - hosts: websrvs
   remote_user: root
   vars:
   - jdk_version: 1.8.0
   tasks:
   - name: install {{ item }} package
     yum: name={{ item }} state=latest
     with_items:
     - nginx
     - tomcat
     - java-{{ jdk_version }}-openjdk
     - tomcat-webapps
     - tomcat-docs-webapp
     - tomcat-admin-webapps
  
    - name: install conf file
      copy: src={{ item.f1 }} dest={{ item.f2 }}
      with_items:
      - { f1: '/root/server.xml',f2: '/etc/tomcat/server.xml' }
      - { f1: '/root/tomcat-users.xml',f2: '/etc/tomcat/tomcat-users.xml' }

ansible-playbook tomcat3.yml


搜狗截圖20171119155019.png

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

示例:
1.cd /etc/ansible/roles/
mkdir nginx/{vars,hanlers,templates,files,tasks}
2.配置playbook vim mywebserves.yml

- hosts: websrvs
  remote_user: root
  roles:——定義角色
  - nginx——調用nginx

3.配置handlers
vim handlers/main.yml

- name: reload nginx——定義觸發器,啟動重啟服務
  service: name=nginx state=reloaded——調用重啟服務命令

4.配置tasks/main.yml

- name: install nginx packag
  yum: name=nginx state=latest
- name: install conf file module
  template: src=web.conf.j2  dest=/etc/nginx/conf.d/web.conf——啟用模板文件,格式為.j2 復制到目標主機的conf.d下
  notify: reload nginx——定義標志
  tags: instconf——標志名為instconf
- name: install nginx.conf——安裝nginx.conf文件
  copy: src=nginx.conf dest=/etc/nginx/nginx.conf——啟動復制將文件復制到目標主機上
  notify: reload nginx——定義標志,執行mywebserves.yml時只啟動有標志的服務
  tags: instconf——標志名也為instconf
- name: create docroot
  file: path={{ ngx_doc_root }} state=directory——創建目錄靜態文件
- name: start  nginx service
  service: name=nginx enabled=true state=started

5.配置templates.web.conf.j2——定義模板文件

 1 server{
  2 
  3     listen {{ ngx_server_port }};——監聽nginx的端口
  4     server_name {{ ngx_server_name }};——服務名
  5 
  6     location / {
  7             root {{ ngx_doc_root }};——訪問地址
  8   }
  9 }

6.配置vars/main.yml——定義變量

ngx_server_port: 80——定義端口
ngx_server_name: www.magedu.com——主機服務器地址
ngx_doc_root: /webdata——定義目錄

7.配置flies靜態文件
vim files/nginx.conf
scp 172.18.250.89:/etc/nginx/nginx.conf /etc/ansible/roles/nginx/files/

8.配置完成后執行
ansible-playbook mywebserves.yml


搜狗截圖20171119181822.png

如果想修改nginx的服務端口并且只讓指定的服務運行,可以執行
ansible-playbook -t instconf -e "ngx_server_port=10080" mywebserves.yml 即可
也可以在mywebserves.yml修改

  • hosts: websrvs
    remote_user: root
    roles:
    • { roles: ni=ginx,ngx_server_port:8080 }
      再次執行ansible-playbook -t instconf mywebserves.yml 即可
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容