Ansible

簡介

Ansible是一款爲類Unix系統開發的自由開源的配置和自動化工具。它用Python寫成,類似於saltstack和Puppet,但是有一個不同和優點是我們不需要在節點中安裝任何客戶端。它使用SSH來和節點進行通信。

特點

1.部署簡單,只需在主控端部署Ansible環境,被控端無需做任何操作;
2.默認使用SSH協議對設備進行管理;
3.主從集中化管理;
4.配置簡單、功能強大、擴展性強;
5.支持API及自定義模塊,可通過Python輕鬆擴展;
6.通過Playbooks來定製強大的配置、狀態管理
7.對雲計算平臺、大數據都有很好的支持;

工作機制

在這裏插入圖片描述
Ansible 的組成由 5 個部分組成
Ansible :ansible核心
Modules :包括 Ansible 自帶的核心模塊及自定義模塊
Plugins :完成模塊功能的補充,包括連接插件、郵件插件等
Playbooks :劇本;定義 Ansible 多任務配置文件,由Ansible 自動執行
Inventory :定義 Ansible 管理主機的清單 [ˈɪnvəntri] 清單

安裝

環境

ansible 服務端 test63 192.168.1.63
ansible節點1 test62 192.168.1.62
ansible節點2 test63 192.168.1.63

在test63上安裝ansible

設置EPEL倉庫,Ansible倉庫默認不在yum倉庫中,因此我們需要使用下面的命令啓用epel倉庫。
[root@test63 ~]# yum install epel-release -y
[root@test63 ~]#yum install ansible -y #使用yum安裝Ansible
[root@test63 ~]# ansible –version

ansible命令參數

anisble命令語法: ansible [-i 主機文件] [-f 批次] [組名] [-m 模塊名稱] [-a 模塊參數]
ansible詳細參數:
 -v,–verbose   #  詳細模式,如果命令執行成功,輸出詳細的結果 (-vv –vvv -vvvv)
 -i PATH, -inventory=PATH      #  指定 host 文件的路徑,默認是在 /etc/ansible/hosts 
inventory  [ˈɪnvəntri]  庫存
 -f NUM,-forks=NUM     # NUM 是指定一個整數,默認是 5 ,指定 fork 開啓同步進程的個數。
 -m NAME,-module-name=NAME    #   指定使用的 module 名稱,默認使用 command模塊
 -a,MODULE_ARGS   #指定 module 模塊的參數
 -k,-ask-pass           #提示輸入 ssh 的密碼,而不是使用基於 ssh 的密鑰認證
 -sudo          # 指定使用 sudo 獲得 root 權限
 -K,-ask-sudo-pass             #提示輸入 sudo 密碼,與 -sudo 一起使用
 -u USERNAME,-user=USERNAME          # 指定移動端的執行用戶
 -C,–check             #測試此命令執行會改變什麼內容,不會真正的去執行
ansible-doc詳細參數:
ansible-doc -l           #列出所有的模塊列表
ansible-doc -s 模塊名    #查看指定模塊的參數  -s, --snippet   # [ˈsnɪpɪt]   片斷

定義主機清單

基於端口、密碼訪問主機清單

ansible基於ssh連接-i (inventory)參數後指定的遠程主機時,也可以寫端口,用戶,密碼。

vim  /etc/ansible/hosts   #文件 /etc/ansible/hosts 維護着Ansible中服務器的清單。在文件最後追加以下內容
[web-servers]  #主機組名
192.168.1.63  ansible_ssh_port=22  ansible_ssh_user=root  ansible_ssh_pass=123456
ansible -i /etc/ansible/hosts web-servers -m ping  #測試下主機的連通性, -i 指定 host 文件的路徑,默認是在 /etc/ansible/hosts, -m  指定使用的ping模塊。
192.168.1.63 | FAILED! => {
    "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."
}
ssh [email protected]   #手動連接一下/etc/ansible/hosts主機清單中的主機,這樣就可以在ansible服務器上保存目標主機的fingerprint指紋。後期可以正常連接了
[root@test63 ~]# ansible -i hosts web-servers -m ping    #測試成功
192.168.1.64 | SUCCESS => {   #表示成測試。通信成功。
    "changed": false,   #因爲ping命令不會改變被管理的服務器的狀態。所以是false正常
    "ping": "pong"
}

基於ssh密鑰訪問主機清單

一般來說,使用明文密碼不安全,所以增加主機無密碼訪問。在Ansible服務端生成密鑰,並且複製公鑰到節點中。

[root@test63 ~]# ssh-keygen   #使用ssh-keygen一直回車,不輸入密碼,在/root/.ssh/下會生成私鑰和公鑰
[root@test63 ~]# ssh-copy-id [email protected] #使用ssh-copy-id命令來複制Ansible公鑰到節點:test63和test63
[root@test63 ~]# ssh-copy-id [email protected]
[root@test63 ~]# ssh 192.168.1.64 #測試連接
[root@test64 ~]# exit
[root@test63 ~]# vim /etc/ansible/hosts  #在文件的最後添加以下內容,刪除之前在最後添加的兩行主機清單:
[web-servers]
192.168.1.63
192.168.1.64

在Ansible服務端運行命令

ping模塊檢查網絡連通性
command模塊執行shell命令,command:作爲ansible的默認模塊,可以運行遠程權限範圍內的所有shell命令
例1:使用ping檢查‘web-servers’或者ansible節點的連通性。

[root@test63 ~]# ansible -i /etc/ansible/hosts 'web-servers'  -m ping
或:
[root@test63 ~]# ansible 'web-servers'  -m ping  #不指定,默認使用/etc/ansible/hosts文件
192.168.1.63 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.1.64 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

例2:檢查Ansible節點的運行時間(uptime)

[root@test63 ~]# ansible -m command -a "uptime" 'web-servers'   #也可以把主機清單組名寫到最後,這樣方便閱讀命令
192.168.1.63 | SUCCESS | rc=0 >>
12:45:23 up 32 min,  5 users,  load average: 0.17, 0.11, 0.27

192.168.1.64 | SUCCESS | rc=0 >>
 12:45:23 up 26 min,  2 users,  load average: 0.03, 0.03, 0.10

例3:檢查節點的內核版本

[root@test63 ~]# ansible -m command -a "uname -r" 'web-servers'

例4:給節點增加用戶

[root@test63 ~]# ansible -m command -a "useradd mk123" 'web-servers'
192.168.1.64 | SUCCESS | rc=0 >>
192.168.1.63 | SUCCESS | rc=0 >>
[root@test63 ~]# ansible -m command -a "grep mk123 /etc/passwd" 'web-servers'

例5:將df命令在所有節點執行後,重定向輸出到本機的/tmp/command-output.txt文件中

[root@test63 ~]# ansible -m command -a "df -Th" 'web-servers' > /tmp/command-output.txt
[root@test63 ~]# cat /tmp/command-output.txt

模塊高級用法

3個遠程命令模塊的區別

1.command模塊爲ansible默認模塊,不指定-m參數時,使用的就是command模塊; comand模塊比較簡單,常見的命令都可以使用,但其命令的執行不是通過shell執行的,所以,像這些 “<”, “>”, “|”, and "&"操作都不可以,當然,也就不支持管道; 缺點:不支持管道,沒法批量執行命令;
2.shell模塊:使用shell模塊,在遠程命令通過/bin/sh來執行;所以,我們在終端輸入的各種命令方式,都可以使用。
例1:運行free -m 命令

[root@test63 ~]# ansible -i /etc/ansible/hosts  web-servers -m shell -a "free -m"

注:但是我們自己定義在/.bashrc或/.bash_profile中的環境變量shell模塊由於沒有加載,所以無法識別;如果需要使用自定義的環境變量,就需要在最開始,執行加載自定義腳本的語句;
對shell模塊的使用可以分成兩塊:

  • 如果待執行的語句少,可以直接寫在一句話中
[root@test63 ~]# ansible -i /etc/ansible/hosts  web-servers -m shell -a "source  ~/.bash_profile && df -h | grep sda3"

*如果在遠程待執行的語句比較多,可寫成一個腳本,通過copy模塊傳到遠端,然後再執行;但這樣就又涉及到兩次ansible調用;對於這種需求,ansible已經爲我們考慮到了,script模塊就是幹這事的;
3.scripts模塊
使用scripts模塊可以在本地寫一個腳本,在遠程服務器上執行

[root@test63 ~]# vim /etc/ansible/net.sh
#!/bin/bash
date
hostname
[root@test63 ~]# ansible -i /etc/ansible/hosts  web-servers -m script -a "/etc/ansible/net.sh"

copy模塊

實現主控端向目標主機拷貝文件,類似scp功能
例1:把ansible主機上的/etc/hosts文件複製到主機組中機器的/tmp目錄下

[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m copy -a "src=/etc/hosts dest=/tmp/ owner=root group=root mode=0755"

在這裏插入圖片描述
在test64上查看

[root@test64 ~]# ll /tmp/hosts 
-rwxr-xr-x 1 root root 240 8月  24 16:09 /tmp/hosts

file模塊設置文件屬性。

例如:

[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m file -a "path=/tmp/hosts mode=0777"
驗證:
[root@test63 ~]# ll /tmp/hosts 
-rwxrwxrwx 1 root root 112 Aug 31 04:38 /tmp/hosts

stat模塊獲取遠程文件信息

[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m stat -a "path=/tmp/hosts"

get_url模塊

實現遠程主機下載指定url到本地,支持sha256sum文件校驗。
例如:下載epel-release-latest-7.noarch.rpm到主機清單中的/tmp/目錄下

[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m get_url -a "url=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm  dest=/tmp/ mode=0440 force=yes"

注:url=https://xxx 的等號=前後不能有空格
擴展:查看force=yes的作用

[root@test63 ~]# ansible-doc -s get_url  #在彈出的信息中找到force

如果force=yes,當下載文件時,如果所下的內容和原目錄下的文件內容不一樣,則替換原文件,如果一樣,就不下載了。
如果爲“否”,則僅在目標不存在時才下載文件。 一般來說,只有小型本地文件才應該爲“是”。 在0.6之前,該模塊表現爲默認爲“是”。
查看下載的文件:

[root@test63 ~]# ll /tmp/epel-release-latest-7.noarch.rpm 
-r--r----- 1 root root 15080 8月  24 16:20 /tmp/epel-release-latest-7.noarch.rpm 

測試:下載文件時,當文件不一樣時,會替換原來的文件

[root@test64 ~]# cp /etc/passwd /tmp/epel-release-latest-7.noarch.rpm
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m get_url -a "url=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm  dest=/tmp/ mode=0440 force=yes"
192.168.1.63 | SUCCESS => {
    "changed": false,   #test63上原來的文件和當前的文件一樣,就沒有改變。執行成功,但沒有發生改變,那麼顯示綠色
}
192.168.1.64 | SUCCESS => {
    "changed": true,   #test64上的文件名字一樣,但是內容變,就會重新下載。執行成功,且發生改變,那麼顯示黃色

yum模塊linux平臺軟件包管理。

yum模塊可以提供的status狀態: latest ,present,installed #這3個代表安裝;removed, absent #後面2個是卸載
例子:安裝php軟件

[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m yum -a "name=httpd  state=latest"

cron模塊遠程主機crontab配置。

例如:增加每30分鐘執行ls /tmp

[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m cron -a "name='list dir' minute='*/30' job='ls /tmp'"

在test63上查看

[root@test63 ~]# crontab  -l
#Ansible: list dir
*/30 * * * * ls /tmp

service模塊遠程主機系統服務管理。

service模塊常用參數:
name參數:此參數用於指定需要操作的服務名稱,比如 nginx,httpd。
state參數:此參數用於指定服務的狀態,比如,我們想要啓動遠程主機中的httpd,則可以將 state 的值設置爲 started;如果想要停止遠程主機中的服務,則可以將 state 的值設置爲 stopped。此參數的可用值有 started、stopped、restarted(重啓)、reloaded。
enabled參數:此參數用於指定是否將服務設置爲開機 啓動項,設置爲 yes 表示將對應服務設置爲開機啓動,設置爲 no 表示不會開機啓動。
注:想使用service模塊啓動服務,被啓動的服務,必須可以使用service 命令啓動或關閉

例如:遠程啓動apache服務

[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m service -a "name=httpd state=restarted"

sysctl模塊遠程主機sysctl配置。

例:開啓路由轉發功能

[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m sysctl -a "name=net.ipv4.ip_forward value=1 reload=yes"
驗證:
[root@test63 ~]# cat /proc/sys/net/ipv4/ip_forward
1 

user模塊遠程主機用戶管理

例如:

[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m user -a "name=test6 state=present"
# present  [ˈpreznt]  目前 
驗證:
[root@test63 ~]# id test6
uid=1001(test6) gid=1001(test6) 組=1001(test6)

實戰-使用Playbook批量部署多臺LAMP環境

首先,我們可以在ansible服務器上安裝LAMP環境,然後,再將配置文件通過ansible拷貝到遠程主機上

[root@test63 ~]# yum install httpd –y#安裝httpd軟件
root@test63 ~]# yum install mariadb-server  mariadb  -y #安裝MySQL
[root@test63 ~]# mkdir -p  /mydata/data     #創建目錄作爲數據存放的位置
[root@test63 ~]# chown -R mysql:mysql /mydata/
[root@test63 ~]# vim /etc/my.cnf   #改變數據存放目錄
改:2 datadir=/var/lib/mysql 
爲:2 datadir=/mydata/data    
[root@test63 ~]# systemctl start mariadb
[root@test63 ~]# yum install php php-mysql –y #安裝PHP和php-mysql模塊

[root@test63 ~]# vim /var/www/html/index.php #提供php的測試頁
<?php
    phpinfo();
?>
[root@test63 ~]# systemctl restart httpd啓動httpd服務,在瀏覽器中訪問
[root@test63 ~]# iptables -F

確保已經出現上面的測試頁,而且,要看到MySQL已經被整合進來了,才能進行下一步操作

定義組名

[root@test63 ~]# vim /etc/ansible/hosts  #還使用之前定義好的,這裏不用修改
[web-servers]
192.168.1.63
192.168.1.64

然後,將公鑰信息複製到被控制節點,ansible和兩個節點間通過ssh進行連接。下面3個命令之前已經做過,不用執行了。

[root@test63 ~]# ssh-keygen 
[root@test63 ~]# ssh-copy-id [email protected]
[root@test63 ~]# ssh-copy-id [email protected]

使用playbook創建一個LAMP構建的任務

1.創建相關文件

[root@test63 ~]# mkdir -pv /etc/ansible/lamp/roles/{prepare,httpd,mysql,php}/{tasks,files,templates,vars,meta,default,handlers}
我們將上面搭建成功的LAMP環境的httpd和MySQL的配置文件拷貝到對應目錄下
Playbook常用文件夾作用: 
files:存放需要同步到異地服務器的源碼文件及配置文件; 
handlers:當服務的配置文件發生變化時需要進行的操作,比如:重啓服務,重新加載配置文件; ['hændləz] 處理程序
meta:角色定義,可留空;     ['metə]  元
tasks:需要進行的執行的任務;   #任務
templates:用於執行lamp安裝的模板文件,一般爲腳本;     ['templɪts]  模板
vars:本次安裝定義的變量
[root@test63 ~]# cd /etc/ansible/ 
[root@test63 ~]# cp /etc/httpd/conf/httpd.conf lamp/roles/httpd/files/
[root@test63 ~]# cp /etc/my.cnf lamp/roles/mysql/files/

寫prepare(前期準備)角色的playbooks

[root@test63 ansible]# vim lamp/roles/prepare/tasks/main.yml  #複製以下內容到文件中,配置好yum源
- name: delete yum config
  shell: rm -rf /etc/yum.repos.d/*  #刪除原有的yum配置文件
- name: provide yumrepo file
  shell: wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo   #下載新的yum配置文件
- name: clean the yum repo
  shell: yum clean all    #清除原有的yum緩存信息
- name: clean the iptables
  shell: iptables -F    #清除原有防火牆規則,不然後可能上不了網

2.構建httpd的任務

[root@test63 roles]# cd /etc/ansible/lamp/roles 
[root@test63 roles]# mv /var/www/html/index.php httpd/files/
[root@test63 roles]# vim httpd/tasks/main.yml   #將以下內容複製到文件中
- name: web server install
  yum: name=httpd state=present    #安裝httpd服務
- name: provide test page
  copy: src=index.php dest=/var/www/html    #提供測試頁
- name: delete apache config
  shell: rm -rf  /etc/httpd/conf/httpd.conf  #刪除原有的apache配置文件,如果不刪除,下面的copy任務是不會執行的,因爲當源文件httpd.conf和目標文件一樣時,copy命令是不執行的。如果copy命令不執行,那麼notify將不調用handler。
- name: provide configuration file
  copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf    #提供httpd的配置文件
  notify: restart httpd   #當前面的copy複製成功後,通過notify通知名字爲restart httpd的handlers運行。 

擴展:notify和handlers notify [ˈnəʊtɪfaɪ] 通知
notify: 這個action可用於在每個play的最後被觸發,這樣可以避免多次有改變發生時,每次都執行指定的操作,取而代之,僅在所有的變化發生完成後一次性地執行指定操作。
在notify中列出的操作稱爲handler,也即notify中調用handler中定義的操作。
---- name: test.yml just for test
hosts: testserver
vars:
region: ap-southeast-1
tasks:
- name: template configuration
file template: src=template.j2 dest=/etc/foo.conf
notify:
- restart memcached
- restart apache
handlers:
- name: restart memcached
service: name=memcached state=restarted
- name: restart apache
service: name=apache state=restarted
handlers概述:
Handlers 也是一些 task 的列表,通過名字來引用,它們和一般的 task 並沒有什麼區別。
Handlers 是由通知者進行notify, 如果沒有被 notify,handlers 不會執行。
不管有多少個通知者進行了notify,等到 play 中的所有 task 執行完成之後,handlers 也只會被執行一次。
Handlers 最佳的應用場景是用來重啓服務,或者觸發系統重啓操作.除此以外很少用到了。
3.構建httpd的handlers

[root@test63 roles]# vim httpd/handlers/main.yml
- name: restart httpd
  service: name=httpd enabled=yes state=restarted

4.部署我們的mariadb數據庫
創建MySQL服務的任務,需要安裝MySQL服務,改變屬主信息,啓動MySQL

[root@test63 roles]# cd /etc/ansible/lamp/roles 
[root@test63 roles]# vim mysql/tasks/main.yml
- name: install the mysql
  yum: name=mariadb-server state=present    #安裝mysql服務
- name: mkdir date directory
  shell: mkdir -p /mydata/data    #創建掛載點目錄
- name: provide configration file
  copy: src=my.cnf dest=/etc/my.cnf    #提供mysql的配置文件
- name: chage the owner
  shell: chown -R mysql:mysql /mydata/*    #更改屬主和屬組
- name: start mariadb
  service: name=mariadb enabled=yes state=started    #啓動mysql服務

5.構建PHP的任務

[root@test63 roles]# vim php/tasks/main.yml
- name: install php
  yum: name=php state=present    #安裝php
- name: install php-mysql
  yum: name=php-mysql state=present    #安裝php與mysql交互的插件

6.定義整個的任務

[root@test63 roles]# cd /etc/ansible/lamp/roles
[root@test63 roles]# vim site.yml    #寫入以下內容
- name: LAMP build
  remote_user: root
  hosts: web-servers
  roles:
    - prepare
    - mysql
    - php 
    - httpd

注:所有yml的配置文件中,空格必須嚴格對齊
開始部署:

[root@test63 roles]# ansible-playbook -i /etc/ansible/hosts  /etc/ansible/lamp/roles/site.yml
``
然後,在瀏覽器中訪問這兩臺節點主機,可以直接訪問成功。
http://192.168.1.63/index.php
http://192.168.1.64/index.php

注:
1、默認情況下,首次登陸一臺服務器,系統會提示是否要記住對端的指紋,用ansible也會這樣,這樣會導致需要手工輸入yes或no,ansible 纔可以往下執行。如需避免這種情況,需要在 /etc/ansible/ansible.cfg 文件中設置 host_key_checking = False
例1:

[root@test63 roles]# rm -rf /root/.ssh/known_hosts 
[root@test63 roles]# ansible-playbook -i /etc/ansible/hosts  ./site.yml   #發現需要輸入yes,來保存對端的指紋

解決:

[root@test63 roles]# vim /etc/ansible/ansible.cfg
改:62 #host_key_checking = False   #就是把前面的#號去了
爲:host_key_checking = False  
[root@test63 roles]# rm -rf /root/.ssh/known_hosts 
[root@test63 roles]# ansible-playbook -i /etc/ansible/hosts  ./site.yml   #發現不需要輸入yes,可以自動安裝了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章