天天看點

Ansible的安裝部署和使用

ansible簡介

ansible是新出現的自動化運維工具,ansible是一個配置管理和應用部署工具,基于Python開發,集合了衆多運維工具(puppet、cfengine、chef、func、fabric.SaltStack )的優點,實作了批量系統配置、批量程式部署、批量運作指令等功能。ansible是基于子產品工作的,本身沒有批量部署的能力。真正具有批量部署的是ansible所運作的子產品,ansible隻是提供一種架構,根據官方提供的資訊,目前使用ansible的使用者有:

美國國家航空航天局(NASA /ˈnæsə/)

evernote(印象筆記),rackspace(全球三大雲計算中心之一),atlassian,twitter(全球網際網路上通路量最大的十個網站之一)等

ansible在生産環境當中的應用

自動化部署應用

自動化管理配置

自動化持續傳遞

自動化(aws)雲伺服器管理

ansible的優點

ansible糅合了衆多老牌運維工具的優點,基本上pubbet和saltstack能實作的功能全部能實作

輕量級,無需在用戶端安裝agent,更新時,隻需在操作機上進行一次更新即可;

ansible是一個工具,ansible不需要啟動服務,僅僅隻是一個工具,可以輕松的實作分布式擴充

批量任務執行可以寫成腳本,而且不用分發到遠端就可以執行

ansible是一緻性,高可靠性,安全性設計的輕量級自動化工具

使用python編寫,維護更簡單,ruby文法過于複雜;

ansible的基本架構

1.連接配接插件(connectior plugins) 用于連接配接主機 用來連接配接被管理端

2.核心子產品(core modules) 連接配接主機實作操作, 它依賴于具體的子產品來做具體的事情

3.自定義子產品(custom modules) 根據自己的需求編寫具體的子產品

4.插件(plugins) 完成子產品功能的補充

5.playbooks(劇本) ansible的配置檔案,将多個任務定義在劇本中,由ansible自動執行

6.host inventory(主機清單)定義ansible需要操作主機的範圍

最重要的一點是 ansible是子產品化的 它所有的操作都依賴于子產品

https://www.processon.com/mindmap/58d6713be4b0359bbccc00aa 架構圖

Ansible應用場景:

1、檔案傳輸

2、指令執行

- 應用部署

- 配置管理

- 任務流編排

- 自動化持續傳遞

- 自動化雲服務管理

Ansible企業實作應用場景分析:

1、Dev開發環境

使用者:程式員

功能:程式員開發軟體測試BUG的環境

管理者:程式員

2、測試環境

使用者:測試工程師

功能:測試通過Dev環境測試通過的軟體功能

管理者:程式員

3、釋出環境(代碼釋出機,有些公司使用的時堡壘機(安全屏障))

使用者:運維

功能:釋出代碼到生産環境

管理者:有經驗的運維

釋出機:往往需要兩台(主備)

4、生産環境

使用者:運維

功能:對使用者提供公司産品的服務

管理者:運維

5、灰階環境

使用者:運維

功能:在全量釋出代碼前将代碼的功能面向少量精準使用者的釋出環境

管理者:運維

為什麼需要灰階環境:往往是版本的功能更新比較大,為了保險起見特意先讓一部分使用者優先體驗該功能,待這部分使用者使用沒什麼重大問題的時候,再全量釋出到所有的伺服器。

Ansible架構:

Ansible Core

Modules(子產品):

Core Modules 核心子產品

Customed Modules 自定義子產品

Host lventory 主機名清單

Files

CMDB

PlayBooks 劇本

Hosts 主機清單

Roles 角色

connection Olugins: 連接配接插件(主要連接配接至各被管控的主機)

Anstile特性:

子產品化:調用特定的子產品,完成特定的任務

基于Python語言研發,有Paramiko、PyYAML和jinja2三個核心的庫實作

部署簡單:基于agentless

支援自定義子產品,可以使用任意的程式設計語言

強大的PlayBooks機制

幂等性

參數:

-a ‘Arguments‘, --args=‘Arguments‘ 指令行參數

-m NAME, --module-name=NAME 執行子產品的名字,預設使用 command 子產品,是以如果是隻執行單一指令可以不用 -m參數

-i PATH, --inventory=PATH 指定庫存主機檔案的路徑,預設為/etc/ansible/hosts.

-u Username, --user=Username 執行使用者,使用這個遠端使用者名而不是目前使用者

-U --sud-user=SUDO_User sudo到哪個使用者,預設為 root -k --ask-pass 登入密碼,提示輸入SSH密碼而不是假設基于密鑰的驗證

-K --ask-sudo-pass 提示密碼使用sudo -s --sudo sudo運作

-S --su 用 su 指令 -l --list 顯示所支援的所有子產品

-s --snippet 指定子產品顯示劇本片段

-f --forks=NUM 并行任務數。NUM被指定為一個整數,預設是5。 #ansible testhosts -a "/sbin/reboot" -f 10 重新開機testhosts組的所有機器,每次重新開機10台

--private-key=PRIVATE_KEY_FILE 私鑰路徑,使用這個檔案來驗證連接配接

-v --verbose 詳細資訊 all 針對hosts 定義的所有主機執行

-M MODULE_PATH, --module-path=MODULE_PATH 要執行的子產品的路徑,預設為/usr/share/ansible/

--list-hosts 隻列印有哪些主機會執行這個 playbook 檔案,不是實際執行該 playbook 檔案

-o --one-line 壓縮輸出,摘要輸出.嘗試一切都在一行上輸出。

-t Directory, --tree=Directory 将内容儲存在該輸出目錄,結果儲存在一個檔案中在每台主機上。

-B 背景運作逾時時間 -P 調查背景程式時間 -T Seconds, --timeout=Seconds 時間,機關秒s

-P NUM, --poll=NUM 調查背景工作每隔數秒。需要- b

-c Connection, --connection=Connection 連接配接類型使用。可能的選項是paramiko(SSH),SSH和地方。當地主要是用于crontab或啟動。

--tags=TAGS 隻執行指定标簽的任務 例子:ansible-playbook test.yml --tags=copy 隻執行标簽為copy的那個任務

--list-hosts 隻列印有哪些主機會執行這個 playbook 檔案,不是實際執行該 playbook 檔案

--list-tasks 列出所有将被執行的任務

-C, --check 隻是測試一下會改變什麼内容,不會真正去執行;相反,試圖預測一些可能發生的變化

--syntax-check 執行文法檢查的劇本,但不執行它

-l SUBSET, --limit=SUBSET 進一步限制所選主機/組模式 --limit=192.168.0.15 隻對這個ip執行

--skip-tags=SKIP_TAGS 隻運作戲劇和任務不比對這些值的标簽 --skip-tags=copy_start

-e EXTRA_VARS, --extra-vars=EXTRA_VARS 額外的變量設定為鍵=值或YAML / JSON

Ansible安裝和部署

yum install ansible -y

程式:

ansible

ansible-PlayBooks

ansible-doc

配置檔案:

/etc/ansible/ansible.cfg

主機清單:

/etc/ansible/hosts

插件目錄:

/usr/share/ansible-plugins/

Ansible指令:

ansible <host-pattern> [options]

常用選項

-m MOD_NAME -a 子產品參數

配置主機清單:

[[email protected] ansible]# vim /etc/ansible/hosts

# Ex 1: Ungrouped hosts, specify before any group headers. #單個主機方式管理

## 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

## beta.example.org

## 192.168.1.100

## 192.168.1.110

# Ex 3: A collection of database servers in the 'dbservers' group #正則方式定義

## db01.intranet.mydomain.net

## db02.intranet.mydomain.net

## 10.25.1.56

## 10.25.1.57

根據主要端生成ssh密鑰檔案:

[[email protected] ansible]# ssh-keygen -t rsa -P '' #空密碼密鑰檔案的生成

Generating public/private rsa key pair.

Enter file in which to save the key (/root/.ssh/id_rsa):

Created directory '/root/.ssh'.

Your identification has been saved in /root/.ssh/id_rsa.

Your public key has been saved in /root/.ssh/id_rsa.pub.

The key fingerprint is:

d7:dc:43:43:cb:ad:7b:7a:95:78:cb:b3:2c:fb:67:56 [email protected]

The key's randomart image is:

+--[ RSA 2048]----+

| . |

| o o |

| = .|

| o o o |

| S . o = .|

| . . =E|

| + =|

| ..*=|

| .=B+|

+-----------------+

添加信任到用戶端:

[[email protected] ansible]# ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected] 發送公鑰檔案到用戶端

The authenticity of host '172.1.1.11 (172.1.1.11)' can't be established.

ECDSA key fingerprint is 48:6c:db:8c:c7:90:ec:3e:e6:ee:13:ae:cc:cb:a8:7b.

Are you sure you want to continue connecting (yes/no)? yes

/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed

/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys

[email protected]'s password:

Number of key(s) added: 1

Now try logging into the machine, with: "ssh '[email protected]'"

and check to make sure that only the key(s) you wanted were added.

不免密的情況下

[webservers]

119.254.209.197 ansible_ssh_user=root ansible_ssh_pass=xxxxxxx

ansible -h 檢視使用幫助

ansible-doc -l 檢視所有子產品

ansible-doc -s ping 檢視指定子產品的使用幫助

ss -tnl

常用子產品:

ping 查詢主機是否存活

ansible webservers -m ping 對某個主機執行ping子產品操作

command 在遠端主機執行指令

ansible all -m command -a "ip addr" m是執行某個子產品,a是執行的方法

shell 在遠端主機上調用shell解釋器運作指令,支援shell的各種功能,例如管道 (shell和command子產品的核心參數為指令本身,而其他子產品的參數通常為"key=value"格式)

ansible all -m shell -a "echo 'haha'| passwd --stidn centos"

copy 遠端拷貝檔案

ansible all -m copy -a "src=/python/getjpg.py dest=/tmp/getjpg.py mode=644" 拷貝檔案

ansible all -m copy -a "content='hello\nword' dest=/tmp/getjpg.py mode=644" 直接生成内容

file 修改檔案屬性

ansible all -m file -a "path=/tmp/getjpg.py owner=st" path為要修改的檔案路徑,owner為修改屬主

ansible all -m file -a "path=/tmp/getjpg.py state=absent" state為定義檔案狀态 absent為删除檔案

ansible all -m file -a "path=/tmp/getjpg state=directory" directory為建立目錄

ansible all -m file -a "path=/tmp/getjpg.link src=/tmp/getjpg.haha state=link" link為連結檔案

fetch 從遠端主機拷貝檔案到本地

cron 管理周期性任務

- minute 分鐘

- hour 小時

- day 天

- month 月

- weekday 星期

- job 工作

- name 名稱(必給的值)

- user 使用者

ansible all -m cron -a "minute='*/5' job='/usr/sbin/ntpdate 10.1.0.1 &> /dev/null' name='sync time'" 建立name為sync time的定時任務,minute為分鐘

ansible all -m cron -a "name='sync time' state=absent" 删除name為sync time的定時任務(state=present建立|absent删除)

get_url 子產品

該子產品主要用于從http、ftp、https伺服器上下載下傳檔案(類似于wget),主要有如下選項:

– sha256sum:下載下傳完成後進行sha256 check;

– timeout:下載下傳逾時時間,預設10s

– url:下載下傳的URL

– url_password、url_username:主要用于需要使用者名密碼進行驗證的情況

– dest:将檔案下載下傳到哪裡的絕對路徑。如果dest是目錄,則使用伺服器提供的檔案名,或者如果沒有提供,将使用遠端伺服器上的URL的基本名稱。

– headers:以格式“key:value,key:value”為請求添加自定義HTTP标頭。

unarchive子產品

用于解壓檔案,子產品包含如下選項:

– copy:在解壓檔案之前,是否先将檔案複制到遠端主機,預設為yes。若為no,則要求目标主機上壓縮包必須存在。

– creates:指定一個檔案名,當該檔案存在時,則解壓指令不執行

– dest:遠端主機上的一個路徑,即檔案解壓的絕對路徑。

– group:解壓後的目錄或檔案的屬組

– list_files:如果為yes,則會列出壓縮包裡的檔案,預設為no,2.0版本新增的選項

– mode:解壓後檔案的權限

– src:如果copy為yes,則需要指定壓縮檔案的源路徑

– owner:解壓後檔案或目錄的屬主

hostname 設定主機名

- name (必給子產品)

ansible all -m hostname -a "name=zhang"

yum yum包管理器來完成軟體包管理

- name= state=present建立|absent删除

ansible all -m yum -a "name=httpd"

service 設定服務開啟關閉

- name

- enabled 是否開機自動啟動(YES,NO,True,)

- state 判定啟動,停止還是重新開機(started,stoped,restarted)

- runlevel 定義在那些級别下可以開機自啟動

ansible all -m service -a "name=httpd state=started enabled=true"

group 管理組

- name

- state

- system

- gid

user 管理主賬号

- name 用來建立賬号

- group 基本組

- groups 附加組

- shell 指定使用者的shell

- uid 指定使用者的ID号

- system

- createhome

setup 在每一個主機上收集的各種屬性的集合(硬體資訊)

ansible all -m setup

YAML本身是一個資料序列化工具,能夠在多個主機上完成序列化并完成資訊交換,讓對方收到資訊後知道你傳回後的資訊是什麼意義的一種語言格式,更多的資料都是鍵值對

常用的資料結構:

key=value

- ltem1 清單格式

- ltem2

{name:nick,age:21} 清單

PlayBook:

核心元件:

- Tasks 任務(用子產品定義出的的操作清單)

- Variables 變量

- Templates 模闆(即使用模闆文法的檔案檔案)

- Handlers 觸發器(由特定條件出發的任務)

- Roles 角色 有一個主劇本本件site.yaml類似于saltstack中的top檔案,對應下面的角色入口檔案main.yaml

基礎元件:

- hosts 運作指定任務的目标主機

- remote_user 在遠端主機以哪個使用者運作

- sudo_user 非管理者使用者要擁有sudo權限

- tasks 任務清單

子產品、子產品參數:

格式:

(1)action:module arguments

(2)module:arguments(老的方式,用的更廣)

#cat update.yml

---

- hosts: {{ hosts }}

remote_user: {{ user }}

..............

#ansible-playbook update.yml --extra-vars "hosts=vipers user=admin" 傳遞{{hosts}}、{{user}}變量,hosts可以是 ip或組名

-l,--limit 對指定的 主機/組 執行任務 --limit=192.168.0.10,192.168.0.11 或 -l 192.168.0.10,192.168.0.11 隻對這個2個ip執行任務

gather_facts: no -------------設定不擷取主機資訊(預設擷取主機資訊)

vars: --------------設定全局變量

vars_files: ------------- 引用外部檔案的全局變量

register: info ------------把shell執行的結構指派給info變量

debug: msg="{{info}}" ------------列印info變量(可以直接用info.stdout調用傳回值的其中一個值)

在劇本中循環的幾種格式:

debug: msg="{{item}}" ---

with_items: |

- one |-------------用于循環顯示with_items中的變量(類似于for items in whit_items:循環)

- two |

- three |

- four ---

debug: msg="name------>{{item.key}} value--------->{{item.value}}" ---

with_items: |

- {key: "one",value: "VA1"} |-------------用于循環顯示with_items中的字典變量(類似于for items in whit_items:循環)

- {key: "two",value: "VA2"} |

- {key: "three",value: "VA3"} ---

debug: msg="name------>{{item[0]}} value--------->{{item[1]}}" ---

with_nested: |

- ['A','B'] |-------------用于循環顯示with_nested中的清單中的變量(類似于for items in with_nested:循環)

- ['a','b','c'] ---

散列loops:

vars:

user: ---

shan: |

name: haha |-------------用于循環顯示with_items中的字典變量(類似于for items in with_dict:循環)

debug: msg="name------>{{item.key}}" |

with_dict: "{{user}}" ---

指定文本循環:

debug: msg="{{item}}" ---

with_fileglob: |

- /root/*.yml |-------------用于循環顯示with_nested中的清單中的變量(類似于for items in with_fileglob:循環)

---

條件判斷loop

- name: debug loops ---

shell: cat /root/ansible |

register: hosts |-------------5秒執行一次cat /root/ansible将結果register給hosts,然後判斷hosts.stdout.startswith的内容是不是以Master開頭如果成立tasks運作完成,如果條件不成立5秒後重試,5次後還不成立,tasks運作失敗

until: hosts.stdout.startswith("Master") |

retries: 5 | 重試次數

delay: 5 --- 重試間隔

執行結果register多次指派:

tasks: ---

- name: debug loop |

shell: "{{item}}" |

with_items: |

- hostname |------------在劇本中使用jianjia2中的for循環執行個體

- uname |

register: reg |

- name: diskpooy loops |

debug: msg="{% for i in reg.results %} {{ i.stdout }} {% endfor %}" ---

when語句邏輯判斷,符合條件就執行,不符合就不執行

---

- hosts: all

tasks:

- name: host 121.201.24.11 run is task

debug: msg="{{ ansible_default_ipv4.address }}"

when: ansible_default_ipv4.address == "121.201.24.11"

- name: all host run

shell: hostname

register: info

- name: hostname is i-uhf37eg7 run

debug: msg="{{ansible_fqdn}}"

when: info['stdout'] == 'i-uhf37eg7'

- name: hostname is i

debug: msg="{{ ansible_fqdn }}"

when: info['stdout'].startswith('i')

編寫一個簡單的劇本:

touch group.yml

---

- hosts: all

gather_facts: no -------------設定不擷取主機資訊(預設擷取主機資訊)

remote_user: root

vars: --------------設定全局變量

vars_files: ------------- 引用外部檔案的全局變量

- vars.yaml

tasks:

- name: get hostname

shell: hostname

register: info ------------把shell執行的結構指派給info變量

- name: dispaly vars

debug: msg="{{info}}" ------------列印info變量(可以直接用info.stdout調用傳回值的其中一個值)

- name: install a group

group: name=mysgrp system=true

- name: install a user

user: name=user1 group=mygrp uid=888 system=true

- name: install vsftpd package

yum: name=vsftpd

- name: start vsftpd service

service: name=vsftpd state=started enabled=true

執行劇本:ansible-playbook --check --list-hsots group.yml

-C 或 --check表示執行前的測試

--list-hsots檢視會影響到哪些主機

--list-tasks檢視執行劇本的步驟

--list-tags

-t TAGS 或--tags=TAGS 隻運作指定的标簽

--start-at-task=START_AT_TASK 制定從某個任務開始往下運作

--syntax-check做文法檢測

ouch group.yml

---

- hosts: all

gather_facts: no -------------設定不擷取主機資訊(預設擷取主機資訊)

remote_user: root

vars: --------------設定全局變量

vars_files: ------------- 引用外部檔案的全局變量

- vars.yaml

tasks:

- name: register vars

shell: hostname

register: info --------------- register的作用是把上一個子產品執行的值指派給info

- name: dispaly vars

debug: msg= "{{ info.stdout }}" ------------stdout為上一個子產品執行結構的顯示的值的變量名

傳配置檔案的執行個體:

- hosts: all

remote_user: root

tasks:

- name: install httpd package

yum: name=httpd state=present

- name: install conf file

copy: src=/python/Ansible/httpd.conf dest=/etc/httpd/conf/httpd.conf

- name: start httpd service

service: name=httpd state=started

Handlers觸發器的用法執行個體:

- hosts: all

remote_user: root

tasks:

- name: install httpd package

yum: name=httpd state=present

- name: install conf file

copy: src=/python/Ansible/httpd.conf dest=/etc/httpd/conf/httpd.conf

notify: restart httpd service

- name: start httpd service

service: name=httpd state=started

handlers:

- name: restart httpd service

service: name=httpd state=restarted

tags:給指定的任務定義一個使用辨別:

- hosts: all

remote_user: root

tasks:

- name: install httpd package

yum: name=httpd state=present

tags: instpkg

- name: install conf file

copy: src=/python/Ansible/httpd.conf dest=/etc/httpd/conf/httpd.conf

tags: instconf

notify: restart httpd service

- name: start httpd service

service: name=httpd state=started

handlers:

- name: restart httpd service

service: name=httpd state=restarted

ansible-playbook -t instconf,instpkg web.yml (同時調用兩個标簽用法)

Variables:變量在劇本中的用法

類型:

内建:

(1)facts 可直接調用

自定義:

(1)指令行傳遞:

-e VAR=VALUE

(2)在hosts Inventory中為每個主機定義專用變量值

(a)向不同的主機傳遞不同的變量

IP/HOSTNAME variable_name=value

(b)向組内所有的主機傳遞相同的變量

[groupname]

variable_name=value

調用:

{{var_name}}

執行個體:

- hosts: all

remote_user: root

tasks:

- name: install a package

yum: name={{ pkgname }} state=present

ansible-playbook --check -e pkgname=memcached pkg.yml

轉載于:https://www.cnblogs.com/zjqv/p/8999864.html