Ansible的入門及常見模塊總結實戰

Ansible

幫助獲取:

​ ansible-doc -s 模塊名 ##查看指定模塊的幫助信息

​ ansible-doc -l ##查看支持的所有模塊

常用模塊:

模塊名 用途
file 文件管理,創建文件、目錄或鏈接文件
copy / synchronize 用於傳輸文件或目錄,對於copy傳輸慢建議採用synchronize(rsync封裝)
cron 計劃任務模塊
user 用戶管理
fetch 從客戶端文件系統拉取文件到ansible服務端
service 服務狀態管理
yum 包管理器,安裝卸載軟件
template 模板模塊,該模塊只在playbook中可以使用
setup 用於獲取服務器的信息,可以結合template做變量引用
shell / command 命令代執行模塊,commnad只能執行裸命令(即系統環境中有支持的命令),至於管道之類的功能不支持, shell模塊可以做到

基本使用:

查看模塊幫助
    ansible-doc -l 查看所有模塊
    ansible-doc -s MODULE_NAME 查看指定模塊的詳細幫助

ansible命令應用基礎
    語法: ansible <host-pattern> -f forks [-a args]
            <host-pattern>  在/etc/ansible/hosts中定義的主機組
            -f forks:啓動的併發線程數
            -m module_name: 要使用的模塊
            -a args: 模塊特有的參數
            -u user: 指定用戶執行
            -k passwd: 輸入指定用戶密碼
            -C  假定playbook執行,並非真正的操作文件,只檢測語法和流程

            --list-host 查看主機組裏的主機
            --syntax-check  檢測playbook語法

注:部分模塊參數
    present 可以理解爲True
    absent  可以理解爲False

ansible屬於SSH進行指令下發,所以對一切主機發號施令前請先配置好各主機通訊時的 [主機地址,SSH端口,用戶名,密碼/祕鑰文件],當然你也可以在指令下發時在手動輸入地址和用戶認證信息

方案一:配置好免祕鑰通訊

[root@node1 np]# ssh-keygen -t rsa          ##回車生成證書信息
[root@node1 np]# ssh-copy-id [email protected]  ##將自己的公鑰發給別人
[root@node1 np]# ssh [email protected]     ##查看是否成功免祕鑰

注:當主機過多時可以考慮使用expect腳本來完成,參考我的另一篇內容製作自定交互分發腳本:https://blog.51cto.com/swiki/1978831

使用ansible的第一個模塊ping來檢測服務器狀態信息

[root@node1 np]# ansible 192.168.2.128 -m ping
192.168.2.128 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
[root@node1 np]# ansible 192.168.2.129 -m ping
192.168.2.129 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
注:ping模塊不需要參數所以不用-a,其他需要參數則指定-a

這麼操作也太low了,我如果要獲取一個集羣的狀態豈不是要挨個去ping一次?

解決辦法:在hosts重定義主機組:

[root@node1 np]# cat /etc/ansible/hosts
    [lb]
    192.168.2.128   
    192.168.2.130
    #192.168.2.13[1:9]  ##表示131-139的主機,還有很多表示方式不一一表述

    [db]
    192.168.2.130

注:hosts文件不光可以定義組還可以定義變量,自定義變量

通訊方案二:hosts中設置inventory變量來定製每臺主機的賬號和密碼

[root@node1 np]# cat /etc/ansible/hosts
    [lb]
    192.168.2.128   ansible_ssh_user=root ansible_ssh_pass=root ##默認是22端口
    192.168.2.129   ansible_ssh_user=root ansible_ssh_pass=123  ##默認是22端口

注:如果128和129的賬號和密碼一樣還可以這樣:
    [lb]
    192.168.2.128
    192.168.2.129
    [lb:vars]
    ansible_ssh_user=root
    ansible_ssh_pass=root

不過在hosts中不光可以定義inventory變量還可以定義一些每臺主機自己各不相同的自定義變量,用於playbook使用

你學到這個應該大概知道了在ansible與主機間通訊形式有三種:

1. 免祕鑰
2. inventory變量
3. 參數指定

以下是一些inventory參數:

...
ansible_ssh_host
      將要連接的遠程主機名.與你想要設定的主機的別名不同的話,可通過此變量設置.
ansible_ssh_port
      ssh端口號.如果不是默認的端口號,通過此變量設置.
ansible_ssh_user
      默認的 ssh 用戶名
ansible_ssh_pass
      ssh 密碼(這種方式並不安全,我們強烈建議使用 --ask-pass 或 SSH 密鑰)
ansible_sudo_pass
      sudo 密碼(這種方式並不安全,我們強烈建議使用 --ask-sudo-pass)
...
這裏只列一部分,參考:https://ansible-tran.readthedocs.io/en/latest/docs/intro_inventory.html

這個時候​我們對lb集羣進行ping狀態監測:

[root@node1 np]# ansible lb -m ping
192.168.2.128 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.2.129 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
注:也可以用all表示hosts中所有主機

到這裏基本快速已經完成了基礎,開始學習一些常用的模塊:

這裏模塊總結直接抄的我大表哥的博客總結,不然太費時間了,所以聲明下:https://blog.51cto.com/dyc2005/2070729

1、copy模塊(synchronize和copy使用方法一致)

從本地copy文件分發到目錄主機路徑 
參數說明:
src= 源文件路徑
dest= 目標路徑 
注意src= 路徑後面帶/ 表示帶裏面的所有內容複製到目標目錄下,不帶/是目錄遞歸複製過去
content= 自行填充的文件內容
owner 屬主
group 屬組
mode權限
示例:

ansible all  -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible mode=600"
ansible all -m copy -a "content='hi there\n' dest=/tmp/hi.txt"
到node1上查看
[root@node1 tmp]# ll
-rw------- 1 root root 465 2月   9 14:59 fstab.ansible
-rw-r--r-- 1 root root   9 2月   9 14:58 hi.txt

2、fetch模塊

從遠程主機拉取文件到本地
示例

[root@ansible ~]# ansible all  -m fetch -a "src=/tmp/hi.txt dest=/tmp"
172.16.3.152 | SUCCESS => {
    "changed": true, 
    "checksum": "279d9035886d4c0427549863c4c2101e4a63e041", 
    "dest": "/tmp/172.16.3.152/tmp/hi.txt", 
    "md5sum": "12f6bb1941df66b8f138a446d4e8670c", 
    "remote_checksum": "279d9035886d4c0427549863c4c2101e4a63e041", 
    "remote_md5sum": null
}
.......省略
說明:fetch使用很簡單,src和dest,dest只要指定一個接收目錄,默認會在後面加上遠程主機及src的路徑

3、command模塊

在遠程主機上執行命令,屬於裸執行,非鍵值對顯示;不進行shell解析;
示例1:

[root@ansible ~]# ansible all -m command -a "ifconfig"
172.16.3.152 | SUCCESS | rc=0 >>
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.3.152  netmask 255.255.255.0  broadcast 172.16.3.255
        .....省略.....
172.16.3.216 | SUCCESS | rc=0 >>
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.3.216  netmask 255.255.255.0  broadcast 172.16.3.255
        .....省略.....
示例2:

[root@ansible ~]# ansible all -m command -a "ifconfig|grep lo"
172.16.3.152 | FAILED | rc=2 >>
[Errno 2] 沒有那個文件或目錄

172.16.3.216 | FAILED | rc=2 >>
[Errno 2] 沒有那個文件或目錄
這就是因爲command模塊不是shell解析屬於裸執行導致的
爲了能達成以上類似shell中的解析,ansible有一個shell模塊;

4、shell模塊

由於commnad只能執行裸命令(即系統環境中有支持的命令),至於管道之類的功能不支持,
shell模塊可以做到
示例:

[root@ansible ~]# ansible all -m shell -a "ifconfig|grep lo"
172.16.3.152 | SUCCESS | rc=0 >>
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        loop  txqueuelen 0  (Local Loopback)

172.16.3.216 | SUCCESS | rc=0 >>
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        loop  txqueuelen 0  (Local Loopback)

5、file模塊

設置文件屬性(創建文件)
常用參數:
path目標路徑
state directory爲目錄,link爲軟件鏈接
group 目錄屬組
owner 屬主
等,其他參數通過ansible-doc -s file 獲取
示例1:創建目錄

[root@ansible ~]# ansible all -m file -a "path=/var/tmp/hello.dir state=directory"
172.16.3.152 | SUCCESS => {
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/var/tmp/hello.dir", 
    "size": 6, 
    "state": "directory", 
    "uid": 0
}
172.16.3.216 | SUCCESS => {
    "changed": true, 
     .....省略.....
示例2:創建軟件鏈接

[root@ansible ~]# ansible all -m file -a "src=/tmp/hi.txt path=/var/tmp/hi.link state=link"
172.16.3.152 | SUCCESS => {
    "changed": true, 
    "dest": "/var/tmp/hi.link", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "size": 11, 
    "src": "/tmp/hi.txt", 
    "state": "link", 
    "uid": 0
}
172.16.3.216 | SUCCESS => {
    "changed": true, 
     .....省略.....

6、cron模塊

通過cron模塊對目標主機生成計劃任務
常用參數:
除了分(minute)時(hour)日(day)月(month)周(week)外
name: 本次計劃任務的名稱
state: present 生成(默認) |absent 刪除 (基於name)

示例:對各主機添加每隔3分鐘從time.windows.com同步時間

[root@ansible ~]# ansible all -m cron -a "minute=*/3 job='/usr/sbin/update time.windows.com &>/dev/null'  name=update_time"
172.16.3.152 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "update_time"
    ]
}
172.16.3.216 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "update_time"
    ]
}

#到node1上查看
[root@node1 tmp]# crontab -l
#Ansible: update_time
*/3 * * * * /usr/sbin/update time.windows.com &>/dev/null
示例2:刪除計劃任務

[root@ansible ~]# ansible all -m cron -a "name=update_time state=absent"
172.16.3.152 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
172.16.3.216 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
#node1上查看
[root@node1 tmp]# crontab -l
會發現已經被刪除了

7、yum模塊

故名思義就是yum安裝軟件包的模塊;
常用參數說明:
enablerepo,disablerepo表示啓用與禁用某repo庫
name 安裝包名
state (present' orinstalled', latest')表示安裝, (absent' or `removed') 表示刪除
示例:通過安裝epel擴展源並安裝nginx

[root@ansible ~]# ansible all -m yum -a "name=epel-release state=installed"
[root@ansible ~]# ansible all -m yum -a "name=nginx state=installed"

8、service模塊

服務管理模塊
常用參數:
name:服務名
state:服務狀態
enabled: 是否開機啓動 true|false
runlevel: 啓動級別 (systemed方式忽略)

示例:

[root@ansible ~]# ansible all -m service -a "name=nginx state=started enabled=true"
到node1上查看
[root@node1 tmp]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since 五 2018-02-09 15:54:29 CST; 1min 49s ago
 Main PID: 10462 (nginx)
   CGroup: /system.slice/nginx.service
           ├─10462 nginx: master process /usr/sbin/nginx
           └─10463 nginx: worker process
......省略......

9、script模塊

把本地的腳本傳到遠端執行;前提是到遠端可以執行,不要把Linux下的腳本同步到windows下執行;
直接上示例:
本地ansible上的腳本:

[root@ansible ~]# cat test.sh 
#!/bin/bash
echo "ansible script test!" > /tmp/ansible.txt
[root@ansible ~]# ansible all -m script -a "/root/test.sh"
172.16.3.152 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 172.16.3.152 closed.\r\n", 
    "stdout": "", 
    "stdout_lines": []
}
172.16.3.216 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 172.16.3.216 closed.\r\n", 
    "stdout": "", 
    "stdout_lines": []
}
到node1上查看
[root@node1 tmp]# ls
ansible.txt  fstab.ansible  hi.txt 
[root@node1 tmp]# cat ansible.txt
ansible script test!
script模塊這個功能可以做很多事,就看你怎麼用了~
以上是常用模塊,至於其他模塊的使用可通過官方模塊列表獲得~

playbook

學會了上面的就可以開始搞playbook了:

開搞之前你需要知道爲什麼要用playbook?因爲我們到此之前學的都是單個功能,複製個文件什麼的,這些我想說我在CRT下面開個窗口都能做,那麼playbook到底能做什麼呢?

playbook你可以理解爲一個劇本,就是playbook中,可以定義哪些主機依次分別該幹哪些事,從而完成一項複雜龐大的任務,通常我們用它來部署服務,我們先寫一個簡單的(注意基於yaml語法):

---
- hosts: lb         ##指定lb組的主機做以下的事情
  remote_user: root ##以哪個用戶的身份去執行
  tasks:    ##任務列表
  - name: install nginx     ##第一步,給這個任務命名爲安裝nginx
    yum: name=nginx state=installed ##模塊名: 參數
  - name: installed nginx config  ##第二步,準備配置文件
    copy: src=~/playbook/nginx.conf_v2 dest=/etc/redis.conf owner=redis mode=0640  
  - name: start nginx   ##啓動nginx
    service: name=nginx state=started

如何執行playbook?

[root@node1 np]# ansible-playbook --syntax-check nginx.yml  ##沒有錯誤拋出即可
[root@node1 np]# ansible-playbook nginx.yml    ##執行之前,準備好playbook中需要的配置文件

好了這就是一個簡單的nginx的playbook,以後你給新機器裝nginx就可以這麼搞了,把配置文件搞好每次執行這個文件即可

不行了不行了,今天趕火車實在沒時間了,先排版到這吧,下週一給小夥伴補齊playbook和roles

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章