Linux:自動化運維之ANSIBLE(一)

運維自動化發展歷程

1、本地部署(On-Premiss) 部署硬件+軟件+操作系統+環境+服務
2、基礎設施即服務(Iaas) 相當於只准備硬件
3、平臺即服務(Paas) 相當於只准備服務
4、軟件即服務(SaaS) 直接使用

企業實際應用場景分析

1、Dev開發環境

使用者:程序員
功能:程序員開發軟件,測試BUG的環境
管理者:程序員

測試環境
使用者:QA測試工程師
功能:測試經過Dev環境測試通過的軟件的功能
管理者:運維
說明:測試環境往往有多套,測試環境滿足測試功能即可,不宜過多
1、測試人員希望測試環境有多套,公司的產品多產品線併發,即多個版本,意味着多個版本同步測試
2、通常測試環境有多少套和產品線數量保持一樣

2、發佈環境:代碼發佈機,有些公司爲堡壘機(安全屏障)

使用者:運維
功能:發佈代碼至生產環境
管理者:運維(有經驗)
發佈機:往往需要有2臺(主備)

3、生產環境

使用者:運維,少數情況開放權限給核心開發人員,極少數公司將權限完全開放給開發人員並其維護
功能:對用戶提供公司產品的服務
管理者:只能是運維
生產環境服務器數量:一般比較多,且應用非常重要。往往需要自動工具協助部署配置應用

4、灰度環境(生產環境的一部分)

使用者:運維
功能:在全量發佈代碼前將代碼的功能面向少量精準用戶發佈的環境,可基於主機或用戶執行灰度發佈
案例:共100臺生產服務器,先發布其中的10臺服務器,這10臺服務器就是灰度服務器
管理者:運維
灰度環境:往往該版本功能變更較大,爲保險起見特意先讓一部分用戶優化體驗該功能,待這部分用戶使用沒有重大問題的時候,再全量發佈至所有服務器

程序發佈

1、程序發佈要求:

不能導致系統故障或造成系統完全不可用
不能影響用戶體驗

2、預發佈驗證:

新版本的代碼先發布到服務器(跟線上環境配置完全相同,只是未接入到調度器)

3、灰度發佈:

基於主機,用戶,業務

4、發佈路徑:放在同一個目錄,通常用軟連接直接指向新版本

/webapp/tuangou
/webapp/tuangou-1.1
/webapp/tuangou-1.2

5、發佈過程:

在調度器上下線一批主機(標記爲maintanance狀態) -->
關閉服務 --> 
部署新版本的應用程序 -->
啓動服務 -->
在調度器上啓用這一批服務器

自動化灰度發佈:腳本、發佈平臺

自動化運維應用場景

文件傳輸
應用部署
配置管理
任務流編排

常用的自動化運維工具

Ansible:python,Agentless,中小型應用環境
分爲控制端,客戶端。藉助於ssh協議,可基於key,無代理,管理中小型

Saltstack:python,一般需部署agent,執行效率更高
被管理端需安裝軟件,需代理程序

ansible

創始人,Michael DeHaan( Cobbler 與 Func 的作者)
2012-03-09,發佈0.0.1版,紅帽收購
2015-10-17,Red Hat宣佈收購 1.5億美金

特性

模塊化:調用特定的模塊,完成特定任務
有Paramiko,PyYAML,Jinja2(模板語言)三個關鍵模塊
支持自定義模塊
基於Python語言實現
部署簡單,基於python和SSH(默認已安裝),agentless
安全,基於OpenSSH
支持playbook編排任務
冪等性:一個任務執行1遍和執行n遍效果一樣,不因重複執行帶來意外情況
無需代理不依賴PKI(無需ssl)
可使用任何編程語言寫模塊
YAML格式,編排任務,支持豐富的數據結構
較強大的多層解決方案

利用ansible實現管理的方式:
Ad-Hoc :ansible命令,主要用於臨時命令使用場景
Ansible-playbook : 主要用於長期規劃好的,大型項目的場景,需要有前提的規劃

注意事項

執行ansible的主機一般稱爲主控端,中控,master或堡壘機
主控端Python版本需要2.6或以上
被控端Python版本小於2.4需要安裝python-simplejson
被控端如開啓SELinux需要安裝libselinux-python
windows不能做爲主控端

配置文件

1./etc/ansible/ansible.cfg 主配置文件,  
如下可變動,其他不用變動
#log_path = /var/log/ansible.log  生成日誌文件
#host_key_checking = False        忽略登錄yes no

Ansible 配置文件/etc/ansible/ansible.cfg (一般保持默認)
[defaults]
#inventory = /etc/ansible/hosts # 主機列表配置文件
#library = /usr/share/my_modules/ # 庫文件存放目錄
#remote_tmp = $HOME/.ansible/tmp #臨時py命令文件存放在遠程主機目錄
#local_tmp = $HOME/.ansible/tmp # 本機的臨時命令執行目錄
#forks = 5 # 默認併發數
#sudo_user = root # 默認sudo 用戶
#ask_sudo_pass = True #每次執行ansible命令是否詢問ssh密碼
#ask_pass = True
#remote_port = 22
#host_key_checking = False # 檢查對應服務器的host_key,建議取消註釋
#log_path=/var/log/ansible.log #日誌文件

2./etc/ansible/hosts 主機清單
3./etc/ansible/roles/ 存放角色的目錄

程序
/usr/bin/ansible 主程序,臨時命令執行工具
/usr/bin/ansible-doc 查看配置文檔,模塊功能查看工具
/usr/bin/ansible-galaxy 下載/上傳優秀代碼或Roles模塊的官網平臺
/usr/bin/ansible-playbook 定製自動化任務,編排劇本工具/usr/bin/ansible-pull 遠程執行命令的工具
/usr/bin/ansible-vault 文件加密工具
/usr/bin/ansible-console 基於Console界面與用戶交互的執行工具

ansible-doc: 顯示模塊幫助

ansible-doc 
-a 顯示所有模塊的文檔
-l, --list 列出可用模塊
-s, --snippet顯示指定模塊的playbook片段
示例:
ansible-doc –l 列出所有模塊
ansible-doc ping 查看指定模塊幫助用法
ansible-doc –s ping 查看指定模塊幫助用法

ansible命令執行過程

1. 加載自己的配置文件 默認/etc/ansible/ansible.cfg
2. 加載自己對應的模塊文件,如command
3. 通過ansible將模塊或命令生成對應的臨時py文件,並將該 文件傳輸至遠程服務器的對應執行用戶$HOME/.ansible/tmp/ansible-tmp-數字/XXX.PY文件
4. 給文件+x執行
5. 執行並返回結果
6. 刪除臨時py文件,sleep 0退出

執行狀態:
綠色:執行成功並且不需要做改變的操作
黃色:執行成功並且對目標主機做變更
紅色:執行失敗

如何使用ansible

1、安裝ansible---基於epel源

[root@centos7 yum.repos.d]#yum install ansible

2、配置主機清單 (非默認ssh協議,後面跟端口號)

[root@centos7 ~]#vim /etc/ansible/hosts
# 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

# If you have multiple hosts following a pattern you can specify
# them like this:

## www[001:006].example.com

# Ex 3: A collection of database servers in the 'dbservers' group

## [dbservers]
## 
## db01.intranet.mydomain.net
## db02.intranet.mydomain.net
## 10.25.1.56
## 10.25.1.57

# Here's another example of host ranges, this time there are no
# leading 0s:

## db-[99:101]-node.example.com               
[websrv]                                
192.168.32.17
192.168.32.6
[appsrv]
192.168.32.[1:2]7

3、基本用法
ansible [-m module_name] [-a args]
跟主機ip或分組名(支持通配符)+模塊名+模塊參數 +-a+需要執行的命令

--version 顯示版本
-m module 指定模塊,默認爲command
-v 詳細過程 –vv -vvv更詳細
--list-hosts 顯示主機列表,可簡寫 --list
-k, --ask-pass 提示輸入ssh連接密碼,默認Key驗證
-K, --ask-become-pass 提示輸入sudo時的口令
-C, --check 檢查,並不執行
-T, --timeout=TIMEOUT 執行命令的超時時間,默認10s
-u, --user=REMOTE_USER 執行遠程執行的用戶
-b, --become 代替舊版的sudo 切換


直接輸入ip地址     基於密碼驗證
[root@centos7 ~]#ansible 192.168.32.6 -m ping -k
SSH password: 
192.168.32.6 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
直接輸入組名       基於密碼驗證
[root@centos7 ~]#ansible websrv -m ping -k            
SSH password: 
192.168.32.6 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.32.17 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
通配符
ansible "*" -m ping
ansible 192.168.1.* -m ping
ansible "*srv" -m ping

邏輯或
ansible "websrvs:appsrvs" -m ping
ansible "192.168.1.10:192.168.1.20" -m ping

邏輯與
ansible "websrv:&dbsrv" –m ping
在websrvs組並且在dbsrvs組中的主機

邏輯非
ansible 'websrv:!dbsrv' –m ping
在websrvs組,但不在dbsrvs組中的主機
注意:此處爲單引號

綜合邏輯
ansible 'websrv:dbsrv:&appsrv:!ftpsrv' –m ping

正則表達式
ansible "websrv.dadda.com:&dbsrv.dadda.com" –m ping
轉換:~ 代表後面要跟的正則表達式
ansible "~(web|db).*\.dadda\.com" –m ping

注:多臺機器管理基於key驗證
如何基於key驗證:

[root@centos7 ~]#ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
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:
SHA256:nIQnThJNBzY0pm14bxLNDjaKvnY2CU9NYYkdFjocVgI root@centos7
The key's randomart image is:
+---[RSA 2048]----+
|  E.=B&=.        |
|   o.%*B         |
|    B.%.=        |
|   . X.@ .       |
|  . .oo S        |
| .. . .o         |
|  .+ .           |
|  ..*            |
| ..o .           |
+----[SHA256]-----+
[root@centos7 ~]#cd .ssh
[root@centos7 .ssh]#ls
id_rsa  id_rsa.pub  known_hosts
[root@centos7 .ssh]#ssh-copy-id 192.168.32.6    多臺可利用腳本
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/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 '192.168.32.6'"
and check to make sure that only the key(s) you wanted were added.
[root@centos7 .ssh]#ssh 192.168.32.6
Last login: Sat Sep 22 22:17:40 2018 from 192.168.32.27
[root@centos7 .ssh]#ansible all -m ping
192.168.32.17 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.32.6 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.32.27 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

使用舉例

1、以本機shine用戶執行ping存活檢測
注意:不是基於key的驗證了需輸入shine的密碼,需帶選項-k

[root@centos7 ~]#ansible all -m ping -u shine -k
SSH password:
192.168.32.17 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.32.27 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.32.6 | UNREACHABLE! => {
"changed": false,
"msg": "Authentication failure.",
"unreachable": true
}

2、以shine sudo至root執行ping存活檢測
注意:sudo需帶選項-b -K ,sudo免口令可不加-K

[root@centos7 ~]#ansible 192.168.32.17 -m ping -u shine -b -K -k
SUDO password:
192.168.32.17 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n",
"unreachable": true
}
失敗是因爲未做sudo授權

授權:切換到(最簡單的是加到配置文件組內)
```bash
[root@centos7-17 ~]#vim /etc/sudoers
...
## Allows people in group wheel to run all commands
#%wheel ALL=(ALL)       ALL              需輸口令
## Same thing without a password
 %wheel ALL=(ALL)       NOPASSWD: ALL    此行免輸口令
...

[root@centos7-17 ~]#getent passwd shine
shine:x:1000:1000:Shine:/home/shine:/bin/bash    
[root@centos7-17 ~]#id shine
uid=1000(shine) gid=1000(shine) groups=1000(shine)

[root@centos7-17 ~]#usermod -aG wheel shine
[root@centos7 ~]#ansible 192.168.32.17 -m ping -u shine -b -K -k   
SSH password: 
SUDO password[defaults to SSH password]: 
192.168.32.17 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

[root@centos7 ~]#ansible 192.168.32.17 -m ping -u shine -b  -k  
SSH password: 
192.168.32.17 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

3、以shine sudo至root用戶執行ls
sudo授權過可以

[root@centos7 ~]#ansible 192.168.32.17 -m command -u shine --become-user=root -a 'ls /root' -b -k -K   
SSH password: 
SUDO password[defaults to SSH password]: 
192.168.32.17 | SUCCESS | rc=0 >>
anaconda-ks.cfg
Desktop
Documents
Downloads
initial-setup-ks.cfg
Music
Pictures
Public
Templates
Videos

沒有sudo授權不可以

[root@centos7-17 ~]#usermod -G '' shine
[root@centos7-17 ~]#id shine
uid=1000(shine) gid=1000(shine) groups=1000(shine)

[root@centos7 ~]#ansible 192.168.32.17 -m command -u shine --become-user=root -a 'ls /root' -b -k -K
SSH password: 
SUDO password[defaults to SSH password]: 
192.168.32.17 | FAILED! => {
    "changed": false, 
    "module_stderr": "Shared connection to 192.168.32.17 closed.\r\n", 
    "module_stdout": "\r\nshine is not in the sudoers file.  This incident will be reported.\r\n", 
    "msg": "MODULE FAILURE", 
    "rc": 1
}

最好還是用root身份基於key最方便

[root@centos7 ~]#ansible 192.168.32.17 -m command -a 'ls /root'
192.168.32.17 | SUCCESS | rc=0 >>
anaconda-ks.cfg
Desktop
Documents
Downloads
initial-setup-ks.cfg
Music
Pictures
Public
Templates
Videos

常用模塊

1、Command:在遠程主機執行命令,默認模塊,可忽略-m選項

[root@centos7 ~]#ansible all -a 'useradd test' 同時創建
192.168.32.17 | SUCCESS | rc=0 >>


192.168.32.27 | SUCCESS | rc=0 >>


192.168.32.6 | SUCCESS | rc=0 >>

[root@centos7 ~]#ansible all -a 'getent passwd test' 同時查看
192.168.32.6 | SUCCESS | rc=0 >>
test:x:502:502::/home/test:/bin/bash

192.168.32.17 | SUCCESS | rc=0 >>
test:x:1001:1001::/home/test:/bin/bash

192.168.32.27 | SUCCESS | rc=0 >>
test:x:1001:1001::/home/test:/bin/bash

[root@centos7 ~]#ansible all -a 'userdel -r test' 同時刪除賬戶及家目錄
192.168.32.17 | SUCCESS | rc=0 >>


192.168.32.27 | SUCCESS | rc=0 >>


192.168.32.6 | SUCCESS | rc=0 >>

此命令不支持 $VARNAME < > | ; & 等,用shell模塊實現

2、Shell:和command相似,用shell執行命令

用command模塊修改密碼:只是輸出內容
[root@centos7 ~]#ansible all -a 'echo dadda |passwd --stdin shine'         
192.168.32.6 | SUCCESS | rc=0 >>
dadda |passwd --stdin shine

192.168.32.17 | SUCCESS | rc=0 >>
dadda |passwd --stdin shine

192.168.32.27 | SUCCESS | rc=0 >>
dadda |passwd --stdin shine

用shell模塊修改密碼:成功
[root@centos7 ~]#ansible all -m shell -a 'echo dadda |passwd --stdin shine'  
192.168.32.17 | SUCCESS | rc=0 >>
Changing password for user shine.
passwd: all authentication tokens updated successfully.

192.168.32.27 | SUCCESS | rc=0 >>
Changing password for user shine.
passwd: all authentication tokens updated successfully.

192.168.32.6 | SUCCESS | rc=0 >>
Changing password for user shine.
passwd: all authentication tokens updated successfully.

更改默認command更換成shell

[root@centos7 ~]#vim /etc/ansible/ansible.cfg 
...
# default module name for /usr/bin/ansible
module_name = shell

[root@centos7 ~]#ansible all -a 'echo dadda |passwd --stdin shine'         
192.168.32.17 | SUCCESS | rc=0 >>
Changing password for user shine.
passwd: all authentication tokens updated successfully.

192.168.32.27 | SUCCESS | rc=0 >>
Changing password for user shine.
passwd: all authentication tokens updated successfully.

192.168.32.6 | SUCCESS | rc=0 >>
Changing password for user shine.
passwd: all authentication tokens updated successfully.

調用bash執行命令 類似 cat /tmp/stanley.md | awk -F‘|’ ‘{print $1,$2}’ &> /tmp/example.txt 這些複雜命令,即使使用shell也可能會失敗,解決辦法:寫到腳本時,copy到遠程,執行,再把需要的結果拉回執行命令的機器

3、Script:運行腳本
注意執行的是本機所在的腳本

[root@centos7 ~]#cat >test.sh
echo ansible
[root@centos7 ~]#cat test.sh 
echo ansible
[root@centos7 ~]#chmod +x test.sh 
[root@centos7 ~]#ansible 192.168.32.17 -m script -a '/root/test.sh' 
192.168.32.17 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.32.17 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.32.17 closed."
    ], 
    "stdout": "ansible\r\n", 
    "stdout_lines": [
        "ansible"
    ]

常用參數
creates 如文件存在,則不執行腳本

[root@centos7 ~]#ansible all -m script -a 'creates=/etc/fstab /root/test.sh' 
192.168.32.27 | SKIPPED
192.168.32.17 | SKIPPED
192.168.32.6 | SKIPPED

removes 如文件存在,則執行腳本

[root@centos7 ~]#ansible 192.168.32.17 -m script -a 'removes=/etc/fstab /root/test.sh' 
192.168.32.17 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.32.17 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.32.17 closed."
    ], 
    "stdout": "ansible\r\n", 
    "stdout_lines": [
        "ansible"
    ]
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章