2019-04-23Day38 ansible自動(dòng)化管理實(shí)踐

0、運(yùn)維發(fā)展歷史

人肉運(yùn)維——自動(dòng)化運(yùn)維——平臺(tái)化——可視化運(yùn)維——智能化運(yùn)維(aiops)
開(kāi)發(fā)自動(dòng)化——開(kāi)發(fā)平臺(tái)(Python/Shell)——開(kāi)發(fā)可視化(Python/Shell)——開(kāi)發(fā)智能化的產(chǎn)品(大數(shù)據(jù)+人工智能)機(jī)器學(xué)習(xí)、深度學(xué)習(xí)

1、ansible軟件知識(shí)介紹

SSH密鑰認(rèn)證+腳本批量管理,特點(diǎn):簡(jiǎn)單、實(shí)用;
但是看起來(lái)比較LOW,需要人工寫(xiě)腳本,類(lèi)似實(shí)時(shí)復(fù)制的inotify工具
MySQL高可用MHA集群,要求所有機(jī)器互相密鑰認(rèn)證。
大數(shù)據(jù)集群也需要。

2、批量管理工具歷史

SSH+腳本 CFEngine、Puppet、 saltstack、 ansible
08年以前 07-08年 10-13年 14-17(python開(kāi)發(fā)) 16-(python開(kāi)發(fā))

3、為什么用ansible?

簡(jiǎn)單、方便、容易學(xué)習(xí)、功能同樣強(qiáng)大。
Ansible有配置文件,可以多線(xiàn)程直接實(shí)現(xiàn)。不需要寫(xiě)腳本,類(lèi)似實(shí)時(shí)復(fù)制的inotify工具

4、什么是ansible?

Ansible是一個(gè)用來(lái)遠(yuǎn)程管理服務(wù)器的工具軟件。這里“遠(yuǎn)程主機(jī)(Remote Host)”是指任何可以通過(guò)SSH登錄的主機(jī),所以它既可以遠(yuǎn)程虛擬機(jī)或物理機(jī),也可以是本地主機(jī)。

Ansible通過(guò)SSH協(xié)議實(shí)現(xiàn)管理節(jié)點(diǎn)與遠(yuǎn)程節(jié)點(diǎn)之間的通信。理論上來(lái)說(shuō),只要能通過(guò)SSH登錄到遠(yuǎn)程主機(jī)來(lái)完成的操作,都可以通過(guò)ansible實(shí)現(xiàn)批量自動(dòng)化操作。

涉及管理操作:復(fù)制文件、安裝服務(wù)、服務(wù)啟動(dòng)停止管理、配置管理等等。

5、為什么要用批量管理工具運(yùn)維?

提高效率,百度幾萬(wàn)臺(tái)服務(wù)器,阿里幾十萬(wàn)臺(tái)服務(wù)器。

6、ansible的特點(diǎn)

Ansible基于python語(yǔ)言實(shí)現(xiàn),由Paramiko和PyYAML兩個(gè)關(guān)鍵模塊構(gòu)建。

Shell、Python是Linux運(yùn)維學(xué)員必會(huì)的兩門(mén)語(yǔ)言。
1)、安裝部署過(guò)程特別簡(jiǎn)單,學(xué)習(xí)曲線(xiàn)很平坦。
2)、不需要單獨(dú)安裝客戶(hù)端,只是利用現(xiàn)有的SSHD服務(wù)(協(xié)議)即可
3)、不需要服務(wù)端(no servers)
4)、ansible playbook ,采用yaml配置,提前編排自動(dòng)化任務(wù)。
5)、ansible功能模塊較多,對(duì)于自動(dòng)化的場(chǎng)景支持豐富

7、Ansible架構(gòu)介紹

1)、連接connectior plugins用于連接主機(jī),用來(lái)連接被管理端
2)、核心模塊core modules連接主機(jī)實(shí)現(xiàn)操作,它依賴(lài)于具體的模塊來(lái)做具體的事情
3)、自定義模塊custom modules,根據(jù)自己的需求編寫(xiě)具體的模塊
4)、插件plugins,完成模塊功能的補(bǔ)充
5)、劇本playbooks,ansible的配置文件,將多個(gè)任務(wù)定義在劇本中,由ansible自動(dòng)執(zhí)行
6)、主機(jī)清單inventor,定義ansible需要操作主機(jī)的范圍
最重要的一點(diǎn)是ansible是模塊化的,它所有的操作都依賴(lài)于模塊


image.png

8、實(shí)踐環(huán)境準(zhǔn)備:

61(m01)====>31(nfs01)
61(m01) ====>41(backup)

9、安裝ansible

m01管理機(jī):
yum install epel-release -y
yum install ansible -y

如果有l(wèi)ibselinux-python就不執(zhí)行下面的命令了。
rpm -qa |grep libselinux-python
yum install libselinux-python -y

其他所有機(jī)器:
rpm -qa |grep libselinux-python
yum install libselinux-python -y

10、主機(jī)列表配置

ssh列表實(shí)現(xiàn)方法:
for n  in 7 8
do 
 echo 172.16.1.$n
done

/etc/ansible/hosts主機(jī)資產(chǎn)清單文件,用于定義被管理主機(jī)的認(rèn)證信息,
例如ssh登錄用戶(hù)名、密碼以及key相關(guān)信息。如何配置Inventory文件
1.主機(jī)支持主機(jī)名通配以及正則表達(dá)式,例如web[1:3].oldboy.com代表三臺(tái)主機(jī)
2.主機(jī)支持基于非標(biāo)準(zhǔn)的ssh端口,例如web1.oldboyedu.com:6666
3.主機(jī)支持指定變量,可對(duì)個(gè)別主機(jī)的特殊配置,如登陸用戶(hù)\密碼
4.主機(jī)組支持指定變量[group_name:vars],同時(shí)支持嵌套組[game:children]

實(shí)踐:

[root@m01~]# cat >/etc/ansible/hosts<<EOF
[oldboy]
172.16.1.31
172.16.1.41

[oldgirl]
172.16.1.31
172.16.1.41
172.16.1.51
EOF
cat /etc/ansible/hosts  < ===查看配置文件

/etc/ansible/ansible.cfg #ansible的配置文件

11.小試牛刀

直接執(zhí)行如下命令或報(bào)錯(cuò)
ansible oldboy -m command -a "free -m"

基于SSH秘鑰認(rèn)證的前提下:

如果沒(méi)有做SSH秘鑰認(rèn)證,可以把用戶(hù)名密碼寫(xiě)到/etc/ansible/hosts

[oldboy_pass]
172.16.1.7 ansible_ssh_user=root ansible_ssh_pass=123456
172.16.1.8 ansible_ssh_user=root ansible_ssh_pass=123456

ansible oldboy -m command -a "free -m" 要想成功,先解決yes/no的問(wèn)題。

1、ssh連接一遍。
2、ssh -o 參數(shù)

上述命令就是sshpass的封裝

ansible關(guān)閉ssh首次連接時(shí)yes/no提示
使用ssh連接時(shí),可以使用-o參數(shù)將StrictHostKeyChecking設(shè)置為no,
避免使用ssh連接時(shí)避免首次連接時(shí)讓輸入yes/no部分的提示。

方法1:修改 /etc/ansible/ansible.cfg中的374行

369 [ssh_connection]
370 
371 # ssh arguments to use
372 # Leaving off ControlPersist will result in poor performance, so use
373 # paramiko on older platforms rather than removing it, -C controls compression use
374 #ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s
374行改為:
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no

方法2:
修改 /etc/ansible/ansible.cfg中的71行

 70 # uncomment this to disable SSH key host checking
 71 #host_key_checking = False
71行的注釋取消:host_key_checking = False

實(shí)驗(yàn):

[root@m01 /server/scripts]# > ~/.ssh/known_hosts 
[root@m01 /server/scripts]# ssh 172.16.1.31
The authenticity of host '172.16.1.31 (172.16.1.31)' can't be established.
ECDSA key fingerprint is SHA256:qZSBkrmOv7xO/63qOU1uLXkPyNVHdkqvrNAcAmXqNEk.
ECDSA key fingerprint is MD5:23:d0:cb:a9:f4:7c:0b:eb:2d:07:00:e1:a3:12:d8:33.
Are you sure you want to continue connecting (yes/no)? ^C
[root@m01 /server/scripts]# ansible oldboy -m command -a "free -m"
172.16.1.31 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            972          88         592          13         291         708
Swap:           767           0         767

172.16.1.41 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            972          89         572          13         310         706
Swap:           767           0         767

目標(biāo):ansible是不是需要免秘鑰認(rèn)證(ssh免秘鑰認(rèn)證)?

[root@m01 ~]# cat /etc/ansible/hosts
[oldboy]
172.16.1.31
172.16.1.7

還原ansible.cfg配置,重啟服務(wù)器

[root@m01 ~]# ansible oldboy -m command -a "free -m"
The authenticity of host '172.16.1.7 (172.16.1.7)' can't be established.
ECDSA key fingerprint is SHA256:qZSBkrmOv7xO/63qOU1uLXkPyNVHdkqvrNAcAmXqNEk.
ECDSA key fingerprint is MD5:23:d0:cb:a9:f4:7c:0b:eb:2d:07:00:e1:a3:12:d8:33.
Are you sure you want to continue connecting (yes/no)? The authenticity of host '172.16.1.31 (172.16.1.31)' can't be established.
ECDSA key fingerprint is SHA256:qZSBkrmOv7xO/63qOU1uLXkPyNVHdkqvrNAcAmXqNEk.
ECDSA key fingerprint is MD5:23:d0:cb:a9:f4:7c:0b:eb:2d:07:00:e1:a3:12:d8:33.
Are you sure you want to continue connecting (yes/no)? 

解決yes/no不需要輸入問(wèn)題:

修改ansible.cfg 374行:

ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no

在執(zhí)行報(bào)錯(cuò):

[root@m01 ~]# ansible oldboy -m command -a "free -m"
172.16.1.7 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Warning: Permanently added '172.16.1.7' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,password).", 
    "unreachable": true
}
172.16.1.31 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Warning: Permanently added '172.16.1.31' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).", 
    "unreachable": true
}

解決公鑰問(wèn)題:

ssh-keygen -f ~/.ssh/id_rsa  -P '' -q
for ip in 7
do
  sshpass -p123456 ssh-copy-id -f -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 172.16.1.$ip
done
#test
ssh 172.16.1.7 "ifconfig eth0"

執(zhí)行ansible命令:

[root@m01 ~]# ansible oldboy -m command -a "free -m"
172.16.1.31 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).", 
    "unreachable": true
}
172.16.1.7 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            972          69         807           7          95         771
Swap:           767           0         767

for ip in 31
do
  sshpass -p123456 ssh-copy-id -f -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 172.16.1.$ip
done
#test
ssh 172.16.1.31 "ifconfig eth0"

[root@m01 ~]# ansible oldboy -m command -a "free -m"
172.16.1.7 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            972          69         807           7          95         771
Swap:           767           0         767

172.16.1.31 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            972          71         804           7          96         768
Swap:           767           0         767

驗(yàn)證:刪除公鑰,是不是不可以了?

重啟后,不行,重啟前可以

[root@m01 ~]# ansible oldboy -m command -a "free -m"
172.16.1.7 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Warning: Permanently added '172.16.1.7' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,password).", 
    "unreachable": true
}
172.16.1.31 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Could not create directory '/root/.ssh'.\r\nWarning: Permanently added '172.16.1.31' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).", 
    "unreachable": true
}

修改Host增加用戶(hù)和密碼:

[root@m01 ~]# cat /etc/ansible/hosts
#[oldboy]
#172.16.1.31
#172.16.1.7

[oldboy_pass]
172.16.1.31 ansible_ssh_user=root ansible_ssh_pass=123456
172.16.1.7 ansible_ssh_user=root ansible_ssh_pass=123456

結(jié)果:

[root@m01 ~]# ansible oldboy_pass -m command -a "free -m"
172.16.1.31 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            972          79         791           7         101         758
Swap:           767           0         767

172.16.1.7 | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            972          69         806           7          95         771
Swap:           767           0         767

結(jié)論:使用SSH連接:

密碼認(rèn)證 host里主機(jī)后面加密碼 Paramiko模塊 重點(diǎn):
秘鑰認(rèn)證:提前發(fā)公鑰,才能用ansible. SSHPASS工具

12.基于SSH秘鑰認(rèn)證的實(shí)踐

一鍵創(chuàng)建及分發(fā)秘鑰:

#!/bin/bash
ssh-keygen -f ~/.ssh/id_rsa  -P '' -q
for ip in 7 8 41 31
do
  sshpass -p123456 ssh-copy-id -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 172.16.1.$ip
done
[root@m01 ~]# cat /etc/ansible/hosts
[oldboy]
172.16.1.31
172.16.1.41
172.16.1.7

[root@m01 ~]# ansible oldboy -m command -a "free -m" 
和前面sh cmd.sh "free -m"

13.ansible命令參數(shù)

-m MODULE_NAME, 模塊名字,默認(rèn)command
-a MODULE_ARGS, 模塊參數(shù)
-f FORKS 并發(fā)進(jìn)程數(shù),默認(rèn)5個(gè)。
-i INVENTORY(default=/etc/ansible/hosts)指定主機(jī)列表文件

14.ansible模塊查看和幫助*****

ansible-doc -s command #Linux命令參數(shù)

14.1 command模塊 *****

1)功能說(shuō)明:

command Executes a command on a remote node
功能說(shuō)明:執(zhí)行一個(gè)命令在遠(yuǎn)程節(jié)點(diǎn)上
操作實(shí)踐:
ansible oldboy -m command -a "free -m"
ansible oldboy -m command -a "df -h"
ansible oldboy -m command -a "ls /root"
ansible oldboy -m command -a "cat redhat-release"
ansible oldboy -m command -a "cat /etc/redhat-release"
最通用的功能。

[root@m01 ~]# ansible oldboy -m command -a "cat /etc/redhat-release"
172.16.1.7 | CHANGED | rc=0 >>
CentOS Linux release 7.6.1810 (Core) 

172.16.1.31 | CHANGED | rc=0 >>
CentOS Linux release 7.6.1810 (Core) 

172.16.1.41 | CHANGED | rc=0 >>
CentOS Linux release 7.6.1810 (Core) 
[root@m01 ~]# cat /server/scripts/cmd.sh 
for n in 31 41
do
   echo "=====172.16.1.$n======"
   ssh 172.16.1.$n "$1"
done
[root@m01 ~]# sh /server/scripts/cmd.sh "cat /etc/redhat-release"
=====172.16.1.31======
CentOS Linux release 7.6.1810 (Core) 
=====172.16.1.41======
CentOS Linux release 7.6.1810 (Core) 

特殊:不支持的東西,例如 > < | &等 $HOME,替代方案用shell模塊
ansible oldboy -m shell -a "ps -ef|grep ssh"
ansible oldboy -m shell -a "echo oldboy >/tmp/a.log"

2)常用參數(shù)說(shuō)明及實(shí)踐

[root@m01 ~]# ansible-doc -s command
- name: Executes a command on a remote node
  command:
      argv:                  # Allows the user to provide the command as a list vs. a string.  Only the
                               string or the list form can be provided, not
                               both.  One or the other must be provided.
      chdir:                 # Change into this directory before running the command.
      creates:               # A filename or (since 2.0) glob pattern. If it already exists, this step
                               *won't* be run.
      free_form:             # (required) The command module takes a free form command to run.  There is no
                               parameter actually named 'free form'. See the
                               examples!
      removes:               # A filename or (since 2.0) glob pattern. If it already exists, this step *will*  be run.
      stdin:                 # Set the stdin of the command directly to the specified value.
      warn:                  # If command_warnings are on in ansible.cfg, do not warn about this particular
                               line if set to `no'.

參數(shù):chdir=/tmp配置相當(dāng)于cd /tmp
[root@m01 ~]# ansible oldboy -m command -a "pwd chdir=/etc"
ansible oldboy -m shell -a "cd /etc/;pwd"

參數(shù):creates=/etc 相當(dāng)于條件測(cè)試 [ -e /etc ]||pwd 和下面removes相反
[root@m01 ~]# ansible oldboy -m command -a "pwd creates=/etc"

參數(shù):removes=/root 相當(dāng)于條件測(cè)試 [ -e /root ]&&ls /root
ansible oldboy -m command -a "ls /root removes=/root"
ansible oldboy -m shell -a "[ -d /etc ]||pwd"
[root@m01 ~]# ansible oldboy -m command -a "cat /etc/hosts removes=/etc/hosts"

參數(shù):warn=False 忽略警告
[root@m01 ~]# ansible oldboy -m command -a "chmod 000 /etc/hosts warn=False"

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容