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 模塊參數
配置主機清單:
[root@bogon 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密鑰文件:
[root@bogon 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 root@bogon
The key's randomart image is:
+--[ RSA 2048]----+
| . |
| o o |
| = .|
| o o o |
| S . o = .|
| . . =E|
| + =|
| ..*=|
| .=B+|
+-----------------+
添加信任到客戶端:
[root@bogon ansible]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.1.1.11 發送公鑰文件到客戶端
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
root@172.1.1.11's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@172.1.1.11'"
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