Ansible學習筆記——基礎與配置

Kivinsae發表於2019-03-07

〇、Ansible整體介紹

Ansible是一個當時最為流行的叢集部署與配置工具,在伺服器配置和運維管理的過程中有重要的作用和優勢。本文主要為結合個人的學習心得,向對ansible有興趣的朋友儘可能深入簡出、詳盡的介紹這個工具的原理和用法。

Ansible是由Ansible Inc.和Red Hat共同開發的一款開源叢集配置軟體,編寫語言為python,使用時的配置檔案語言為yaml。核心元件使用了paramiko和PyYaml。其中paramiko是python的ssh支援庫,而PyYaml則用於支援yaml配置檔案的使用和playbook的應用。

Ansible有著非常突出的優點,從而使其在saltstack等叢集配置工具中脫穎而出。優勢如下:

  • 僅需管理主機安裝並配置即可,所有的配置工作都通過ssh連線下發至被管理主機。
  • 輕量化
  • Python編寫,原始碼可讀性強。同時playbook使用yml配置,容易上手
  • 對於叢集和ECS的支援非常完美。
  • 支援大量API接入,並且對於python的擴充套件支援良好。
  • 由於架構出色,理論上在管理主機效能到位的情況下可以同時配置近乎無限的主機。

一、Ansible基本配置和受管主機接入

1、安裝和基本配置

  • 首先是Ansible的安裝配置,以CentOS為例:
$ yum install -y ansible
複製程式碼
  • 其次配置宿主機對受管機的免密登入,如果已經配置可以直接跳過
$ ssh-keygen -t rsa     ##如果之前已經生成過祕鑰了則不需要這一步
$ ssh-copy-id root@<agent_ip>  ##向受管機配置管理機的公鑰,這一步可能需要輸入受管機密碼
複製程式碼
  • 在配置完公鑰之後記得把受管機的IP資訊記錄到/etc/ansible/hosts檔案中,如果你需要使用的是之後的ansible-playbook,則需要在對應的工作資料夾內建立一個hosts檔案記錄受管機IP。以下為一個標準的ansible hosts檔案的格式:
172.26.0.81    ##不分組直接宣告IP
172.26.0.82:54208    ##申明特殊的ssh埠

[fangwei-test]           ##申明瞭受管機的列表和分類名
172.26.0.83        ##直接宣告IP
Printer     ansible_ssh_host=172.26.0.84    ##定義別名和IP
EMR-master  ansible_ssh_host=172.26.0.85
Snipe-it    ansible_ssh_host=172.26.0.86
Kubernetes  ansible_ssh_host=172.26.0.87

[fangwei-test:vars]      ##配置對應的使用者等ansible變數
ansible_user=root
複製程式碼

這裡順便介紹一下hosts檔案中常用的ansible變數宣告:

ansible_ssh_host ##連線目標主機的地址

ansible_ssh_port ##連線目標主機的埠,預設 22 時無需指定

ansible_ssh_user ##連線目標主機預設使用者

ansible_ssh_pass ##連線目標主機預設使用者密碼

ansible_ssh_connection ##目標主機連線型別,可以是 local 、ssh 或 paramiko

ansible_ssh_private_key_file ##連線目標主機的 ssh 私鑰,用於安全要求高的機器。可以使用其他管理主機的公鑰來登入特定的主機。

ansible_*_interpreter ##指定採用非 Python 的其他指令碼語言
複製程式碼
  • 在這一切都配置完畢後,可以對這個類的受管機進行ping測試,具體為:
$ ansible fangwei-test -m ping
複製程式碼

2. Ansible命令引數介紹

ansible本身自帶非常多的引數選項,可以適配幾乎任何叢集部署的需求和各種測試需求。 這些引數在ansible-playbook等延伸指令中往往也通用。

$ ansible --help

Usage: ansible <host-pattern> [options]

Define and run a single task 'playbook' against a set of hosts  ##單純的ansible指令用於對一個或者一組受管機執行一個playbook任務

普通引數:
  -a MODULE_ARGS, --args=MODULE_ARGS
                        #[重要]模組引數
  --ask-vault-pass     # 要求輸入管理密碼
  -B SECONDS, --background=SECONDS
                        #非同步執行,X秒後失敗(預設關閉)
  -C, --check           #不對受管機執行任何改變,但是假設已執行語句並返回結果(用於測試)
  -D, --diff            #當改變小體積檔案的時候,顯示兩者的區別,常常和-C引數一起用(用於測試)
  -e EXTRA_VARS, --extra-vars=EXTRA_VARS
                        #將其他變數設定為key = value或YAML / JSON,如果filename字首為@
  -f FORKS, --forks=FORKS
                        #指定要使用的並行程式數(預設值= 5)
  -h, --help            #顯示此幫助訊息並退出
  -i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY
                        #指定庫存主機路徑或逗號分隔的主機列表。PS: --inventory-file已棄用
  -l SUBSET, --limit=SUBSET
                        #進一步將所選主機限制為其他模式
  --list-hosts          #輸出匹配主機列表;不會執行任何其他操作
  -m MODULE_NAME, --module-name=MODULE_NAME
                        ##[重要]要執行的模組名稱(預設為command)
  -M MODULE_PATH, --module-path=MODULE_PATH
                        ##將冒號分隔的路徑預先新增到模組庫(預設為[u'/root/.ansible/plugins/modules',u'/usr/share/ansible/plugins/modules'])
  -o, --one-line        ##壓縮輸出。
  --playbook-dir=BASEDIR
                        ##由於此工具不使用playbooks,因此將其用作替代playbook目錄。這將設定許多功能的相對路徑,包括roles/group_vars/etc. 也就是變相實現部分playbook功能。
  -P POLL_INTERVAL, --poll=POLL_INTERVAL
                        ##如果使用-B(預設值= 15),則設定輪詢間隔。
  --syntax-check        ##對playbook執行語法檢查,但不執行它.
  -t TREE, --tree=TREE  ##將輸出記錄到此目錄
  --vault-id=VAULT_IDS  ##顯示要使用的保管庫標識
  --vault-password-file=VAULT_PASSWORD_FILES
                        ##保管庫密碼檔案
  -v, --verbose         ##詳細模式(-vvv表示更多,-vvvv表示啟用連線除錯)
  --version             ##顯示ansible版本並退出

  連線相關引數:
    主要關於控制哪些受管機以及如何連線到主機。

    -k, --ask-pass      ##要求輸入受管機密碼
    --private-key=PRIVATE_KEY_FILE, --key-file=PRIVATE_KEY_FILE
                        ##使用特點檔案來認證連結
    -u REMOTE_USER, --user=REMOTE_USER
                        ##以特定user來進行連線。
    -c CONNECTION, --connection=CONNECTION
                        ##要使用的連線型別(預設=智慧)
    -T TIMEOUT, --timeout=TIMEOUT
                        ##以秒為單位覆蓋連線超時(預設值= 10)
    --ssh-common-args=SSH_COMMON_ARGS
                        ##指定傳遞給sftp / scp / ssh的公共引數(例如ProxyCommand)
    --sftp-extra-args=SFTP_EXTRA_ARGS
                        ##指定僅傳遞給sftp的額外引數(例如-f,-l)
    --scp-extra-args=SCP_EXTRA_ARGS
                        ##指定僅傳遞給scp的額外引數(例如-l)
    --ssh-extra-args=SSH_EXTRA_ARGS
                        ##指定僅傳遞給ssh的額外引數(例如-R)

  特權升級引數:
    控制你在目標主機上如果成為或者成為哪個使用者

    -s, --sudo          ##用sudo(nopasswd)執行操作(不推薦,推薦使用--become-method)
    -U SUDO_USER, --sudo-user=SUDO_USER
                        ##所需的sudo使用者(預設= root)(不建議使用,推薦使用--become-method)
    -S, --su            ##用su執行操作 (不建議使用,推薦使用--become-method)
    -R SU_USER, --su-user=SU_USER
                        ##以su作為此使用者執行操作(預設=無)(不建議使用,推薦使用--become-method)
    -b, --become        ##用run執行操作(不顯示密碼提示)
    --become-method=BECOME_METHOD
                        ##要使用的許可權升級方法(預設= sudo),可選項有: [ sudo | su | pbrun | pfexec | doas | dzdo | ksu | runas | pmrun | enable | machinectl ]
    --become-user=BECOME_USER
                        ##以此使用者身份執行操作(預設= root)
    --ask-sudo-pass     ##請求sudo密碼(不推薦使用,推薦使用--become-method)
    --ask-su-pass       ##請求su密碼 (不推薦使用,推薦使用--become-method)
    -K, --ask-become-pass
                        ##要求提供許可權提升密碼
複製程式碼

二、Ansible模組介紹與使用

Ansible內建了海量的原生模組和大量的用於連線第三方API的支援模組,熟練掌握基礎模組,並且活用各種擴充套件模組,是熟練掌握Ansible的必經之路。這一章裡面我們會對Ansible的模組進行基礎的介紹和使用案例分析。至於詳細的模組介紹可以檢視我寫的Ansible支援模組詳表

在ansible中檢視所有的模組只需要一個命令:

$ ansible-doc -l
複製程式碼

如果需要檢視某一個特定的模組的詳細解釋則可以直接查詢,以ping模組為例:

[root@Host ~]# ansible-doc ping
> PING    (/usr/lib/python2.7/site-packages/ansible/modules/system/ping.py)

        A trivial test module, this module always returns `pong' on successful contact. It does not make sense in playbooks, but it is useful from
        `/usr/bin/ansible' to verify the ability...     ##之後省略
複製程式碼

模組的重要性除了本身的強大功能外,熟練地掌握模組也是之後playbook部分的基礎。一個優秀的playbook使用者必然對常用模組的引數瞭如指掌。

0、Ping模組

ping這個模組主要用來測試能否連通目標伺服器。

$ ansible test -m ping
複製程式碼

1. Command模組

Command模組自如其名,就是一個很純粹的命令執行模組,用於在受管機上進行命令的執行,其本身也可以配合很多二級引數和指令進行功能的擴充套件。不支援管道功能。例如最簡單的檢視hostname功能:

[root@Printer ~]# ansible fangwei -m command -a 'hostname'
EMRtest | CHANGED | rc=0 >>
EMR-master

Snipeit | CHANGED | rc=0 >>
localhost.localdomain
複製程式碼

需要注意的是,在沒有特地指定ansible的-m引數的時候,預設呼叫的Module就是command。 下面是command常用的幾個二級引數:

  • creates:判斷,當該檔案存在時,則該命令不執行
  • free_form:需要執行的Linux指令
  • chdir:在執行命令之前,先切換到該指定的目錄
  • removes:判斷,當該檔案不存在時,則該選項不執行
  • executable:切換shell來執行命令,該執行路徑必須是一個絕對路徑 下面為chdir的用法舉例,其他的指令也是類似的用法,可以自行嘗試。具體的格式為: ansible $目標host -a '$二級引數=$目標檔案或路徑 $待執行指令'
[root@Printer ~]# ansible fangwei -a 'chdir=/etc/ansible ls -l'
EMRtest | CHANGED | rc=0 >>
總用量 28
-rw-r--r-- 1 root root 20277 12月 14 13:57 ansible.cfg
-rw-r--r-- 1 root root  1070 12月 26 11:26 hosts
drwxr-xr-x 2 root root  4096 12月 14 13:57 roles
複製程式碼

2. Shell模組(或者Raw模組)

這個模組的主要特點就是囊括了所有的command的功能和二級引數支援,並且支援管道。

[root@Printer ~]# ansible fangwei -m shell -a 'ps -ef | grep crond | grep -v grep'
EMRtest | CHANGED | rc=0 >>
root      6030     1  0  2018 ?        00:00:13 /usr/sbin/crond -n

Snipeit | CHANGED | rc=0 >>
root      1042     1  0 2月12 ?       00:00:04 /usr/sbin/crond -n
複製程式碼

3. File模組

File模組主要是對於檔案的一些簡單操作,主要是建立或者許可權設定,已經檔案的存在判斷等。

  • force:在兩種情況下強制建立軟連結。1、原始檔不存在但之後會建立的情況;2、目標軟體已存在,需要先取消之前的軟連結,然後建立新的軟連結。選項:yes|no
  • group:定義檔案/目錄的屬組
  • mode:定義檔案/目錄的許可權
  • path:必選項,定義檔案/目錄的路徑
  • recurse:遞迴的設定檔案的屬性,只對目錄有效
  • src:要被連結到的路徑,只應用於state=link的情況
  • dest:被連結到的路徑,只應用於state=link的情況
  • state: directory:如果目錄不存在,建立目錄 file:即使檔案不存在,也不會被建立 link:建立軟連結;hard:建立硬連結 touch:如果檔案不存在,則會建立一個新的檔案,如果已存在,則更新其最後修改時間 absent:刪除目錄/檔案或者取消連結檔案
[root@Printer ~]# ansible fangwei -m file -a 'path=/root/ninngenn.cfg state=touch'
Snipeit | CHANGED => {
    "changed": true,
    "dest": "/root/ninngenn.cfg",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "size": 0,
    "state": "file",
    "uid": 0
}
EMRtest | CHANGED => {
    "changed": true,
    "dest": "/root/ninngenn.cfg",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "size": 0,
    "state": "file",
    "uid": 0
}
複製程式碼

4. Copy模組

Copy模組主要用於複製檔案到遠端主機。具體引數如下:

  • backup:在覆蓋之前將原始檔備份,備份檔案包含時間資訊,選項:yes|no
  • content:用於替代”src”,可以直接設定檔案的值
  • directory_node:遞迴的設定目錄許可權,預設為系統預設許可權
  • force:如果目標主機包含該檔案,但內容不同,如果設定為yes,則強制覆蓋;如果設定為no,則只有當目標主機的目標位置不存在該檔案時,才複製。預設為yes
  • others:所有file模組裡的選項都可以在這裡使用
  • src:要複製到遠端主機的檔案在本地的地址,可以是絕對路徑,也可以是相對路徑。如果路徑是一個目錄,它將遞迴複製。在這種情況下,如果路徑使用“/”來結尾,則只複製目錄裡的內容,如果沒有使用“/”來結尾,則包含目錄在內的整個內容全部複製,類似於rsync
[root@Printer ~]# ansible fangwei -m copy -a 'src=/root/ninngenn.cfg dest=/root/ninngenn.cfg force=yes'
EMRtest | CHANGED => {
    "changed": true,
    "checksum": "458bd6a39e16bc1e00255b66c67b5cb92180166b",
    "dest": "/root/ninngenn.cfg",
    "gid": 0,
    "group": "root",
    "md5sum": "cf35206b8cca3e51082bb32ce278ed8d",
    "mode": "0644",
    "owner": "root",
    "size": 56,
    "src": "/root/.ansible/tmp/ansible-tmp-1551949966.41-24885251361529/source",
    "state": "file",
    "uid": 0
}
Snipeit | CHANGED => {
    "changed": true,
    "checksum": "458bd6a39e16bc1e00255b66c67b5cb92180166b",
    "dest": "/root/ninngenn.cfg",
    "gid": 0,
    "group": "root",
    "md5sum": "cf35206b8cca3e51082bb32ce278ed8d",
    "mode": "0644",
    "owner": "root",
    "size": 56,
    "src": "/root/.ansible/tmp/ansible-tmp-1551949966.4-190980703709511/source",
    "state": "file",
    "uid": 0
}
複製程式碼

5. Service模組

用於受管機服務的配置與管理,類似於systemd,常用選項:

  • arguments:為命令提供一些附加引數
  • enabled:是否開機啟動,選項 yes|no
  • name:必選項,服務名稱
  • pattern:定義一個模式,如果通過status指令來檢視服務狀態時,沒有響應,它會通過ps命令在程式中根據該模式進行查詢,如果匹配到,則認為該服務依然執行
  • runlevel:執行級別
  • sleep:如果執行了restarted,則在stop和start之間等待幾秒鐘
  • state:對當前服務執行啟動/停止/重啟/重新載入等操作(started/stopped/restarted/reloaded)
[root@Printer ~]# ansible fangwei -m service -a 'name=sshd state=restarted enabled=yes'
Snipeit | CHANGED => {
    "changed": true,
    "enabled": true,
    "name": "sshd",
    "state": "started"
}
EMRtest | CHANGED => {
    "changed": true,
    "enabled": true,
    "name": "sshd",
    "state": "started"
}
複製程式碼

6. Cron模組

類似於Linux的Crontab功能,用來控制服務或者程式的定時執行功能。常用引數:

  • backup:對遠端主機上的原計劃任務內容修改之前做備份
  • cron_file:如果指定該選項,則用該檔案替換遠端主機上cron.d目錄下的使用者的任務計劃
  • day:日(1-31,,/2,…)
  • hour:小時(0-23,,/2,…)
  • minute:分鐘(0-59,,/2,…)
  • month:月(0-12,*,…)
  • weekday:周(0-7,*,…)
  • job:要執行的任務,依賴於state=present
  • name:該任務的描述
  • special_time:指定什麼時候執行,引數:reboot,yearly,annually,monthly,weekly,daily,hourly
  • state:確認該任務計劃是建立還是刪除
  • user:以哪個使用者身份執行
[root@Printer ~]# ansible fangwei -m cron -a 'name="check home directory" minute=*/10 job="ls -lht /home"'
Snipeit | CHANGED => {
    "changed": true,
    "envs": [],
    "jobs": [
        "check home directory"
    ]
}
EMRtest | CHANGED => {
    "changed": true,
    "envs": [],
    "jobs": [
        "check home directory"
    ]
}
複製程式碼

7. FileSystem

FileSystem模組用於配置受管機的檔案系統。改模組涉及高位操作,請務必小心,常用引數為:

  • dev:目標塊裝置
  • force:在一個已有檔案系統的裝置上強制建立
  • fstype:檔案系統的型別
  • opts:傳遞給mkfs命令的選項
[root@Printer ~]# ansible test_hosts -m filesystem -a 'dev=/dev/sdb fstype=ext4'
172.26.0.84 | SUCCESS => {
    "changed": true
}
複製程式碼

8. Mount模組

Mount模組用於配置受管機的磁碟掛載,高危模組,請慎重使用,下面為常用引數:

  • dump:儲存(見fstab檔案第5列)。注意,如果設定為null並且狀態設定為present,它將停止工作,並且將在後續執行中進行重複條目。對Solaris系統沒有影響。
  • fstype:必選項,檔案系統型別,要求狀態是present或mounted
  • name:必選項,掛載點
  • opts:傳遞給mount命令的引數
  • src:必選項,要掛載的裝置路徑。要求狀態是present或mounted
  • state:必選項。選項如下: present:只處理fstab中的配置 absent:刪除掛載點 mounted:自動建立掛載點並掛載 unmounted:解除安裝
[root@Ansible ~]# ansible test_hosts -m mount -a 'name=/mnt src=/dev/sdb1 fstype=ext4 state=mounted opts=rw'
172.26.0.84 | SUCCESS => {
    "changed": true, 
    "dump": "0", 
    "fstab": "/etc/fstab", 
    "fstype": "ext4", 
    "name": "/mnt", 
    "opts": "rw", 
    "passno": "0", 
    "src": "/dev/sdb1"
複製程式碼

9. Yum模組

如果熟悉CentOS的朋友應該就會知道,這是使用yum包管理器來管理軟體包的模組,引數如下:

  • conf_file:yum的配置檔案
  • disable_gpg_check:關閉gpg_check
  • disablerepo:不啟用某個源
  • enablerepo:啟用某個源
  • list:檢視yum列表
  • name:要進行操作的軟體包名字,也可以傳遞一個url或者一個本地的rpm包的路徑
  • state:狀態(present/installed/absent/removed/latest)
[root@Printer ~]# ansible fangwei -m yum -a 'name=sl state=latest'
Snipeit | CHANGED => {
    "ansible_facts": {
        "pkg_mgr": "yum"
    },
    "changed": true,
    "msg": "",
    "obsoletes": {
        "grub2": {
            "dist": "x86_64",
            "repo": "@anaconda",
            "version": "1:2.02-0.65.el7.centos.2"
        },
        "grub2-tools": {
            "dist": "x86_64",
            "repo": "@anaconda",
            "version": "1:2.02-0.65.el7.centos.2"
        }
    },
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * ius: dfw.mirror.rackspace.com\n * webtatic: uk.repo.webtatic.com\nResolving Dependencies\n--> Running transaction check\n---> Package sl.x86_64 0:5.02-1.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package       Arch              Version                  Repository       Size\n================================================================================\nInstalling:\n sl            x86_64            5.02-1.el7               epel             14 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 14 k\nInstalled size: 17 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : sl-5.02-1.el7.x86_64                                         1/1 \n  Verifying  : sl-5.02-1.el7.x86_64                                         1/1 \n\nInstalled:\n  sl.x86_64 0:5.02-1.el7                                                        \n\nComplete!\n"
    ]
}
EMRtest | CHANGED => {
    "ansible_facts": {
        "pkg_mgr": "yum"
    },
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package sl.x86_64 0:5.02-1.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package       Arch              Version                  Repository       Size\n================================================================================\nInstalling:\n sl            x86_64            5.02-1.el7               epel             14 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 14 k\nInstalled size: 17 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : sl-5.02-1.el7.x86_64                                         1/1 \n  Verifying  : sl-5.02-1.el7.x86_64                                         1/1 \n\nInstalled:\n  sl.x86_64 0:5.02-1.el7                                                        \n\nComplete!\n"
    ]
}
複製程式碼

10. User模組

User模組顧名思義就是用於使用者引數設定的模組。常用引數:

  • home:指定使用者家目錄
  • group:設定使用者主組
  • groups:設定使用者的附屬組
  • uid:設定使用者的UID
  • password:設定使用者的密碼,密碼必須為加密後的值
  • name:建立使用者的使用者名稱
  • createhhome:選項yes|no,值為yes時才建立使用者家目錄
  • system:選項yes|no,預設為no,值為yes時建立的使用者為系統使用者
  • remove:當state=absent時,remove=yes則表示連同家目錄一起刪除,等價於userdel -r
  • state:選項present|absent,建立使用者或刪除使用者
  • shell:設定使用者的shell環境
[root@Ansible ~]# ansible test_hosts -m user -a 'name=user1 uid=1001 group=yfshare createhome=yes home=/home/user1 password="P@ssw0rd" shell=/bin/bash state=present'
172.26.0.84 | SUCCESS => {
    "changed": true, 
    "comment": "", 
    "createhome": true, 
    "group": 1000, 
    "home": "/home/user1", 
    "name": "user1", 
    "password": "NOT_LOGGING_PASSWORD", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": false, 
    "uid": 1001
}
複製程式碼

11. Group模組

顧名思義用於配置Group資訊的模組,引數如下:

  • gid:設定組的GID
  • name:組名
  • state:選項為present|absent,建立組或刪除組
  • system:選項為yes|no,值為yes,則建立系統組 用法與User模組雷同,不再舉例。

12. get_url模組

主要用於從http、ftp、https伺服器上下載檔案(類似於wget),主要引數如下:

  • checksum:檔案下載完成後進行校驗
  • timeout:請求超時時間,預設為10s
  • url:檔案下載地址
  • url_username:使用者名稱,基於HTTP的基本認證
  • url_password:密碼
  • -use_proxy:選項yes|no,預設為yes,即使用代理
  • dest:下載檔案儲存的絕對路徑
[root@Printer ~]# ansible fangwei -m get_url -a 'dest=/root url=http://172.26.0.84/file/drivers/Canon/mac-10-14-canon.dmg'
EMRtest | CHANGED => {
    "changed": true,
    "checksum_dest": null,
    "checksum_src": "eff3bd83c5966373f04d8c4576cbbe610ba0d638",
    "dest": "/root/mac-10-14-canon.dmg",
    "gid": 0,
    "group": "root",
    "md5sum": "59b6a0a3dcb9dd3e6e46d1e8374d9c43",
    "mode": "0644",
    "msg": "OK (23166785 bytes)",
    "owner": "root",
    "size": 23166785,
    "src": "/root/.ansible/tmp/ansible-tmp-1551951882.53-86480089864174/tmp_7guIp",
    "state": "file",
    "status_code": 200,
    "uid": 0,
    "url": "http://172.26.0.84/file/drivers/Canon/mac-10-14-canon.dmg"
}
Snipeit | CHANGED => {
    "changed": true,
    "checksum_dest": null,
    "checksum_src": "eff3bd83c5966373f04d8c4576cbbe610ba0d638",
    "dest": "/root/mac-10-14-canon.dmg",
    "gid": 0,
    "group": "root",
    "md5sum": "59b6a0a3dcb9dd3e6e46d1e8374d9c43",
    "mode": "0644",
    "msg": "OK (23166785 bytes)",
    "owner": "root",
    "size": 23166785,
    "src": "/root/.ansible/tmp/ansible-tmp-1551951882.52-38856232211770/tmpPLN4Wf",
    "state": "file",
    "status_code": 200,
    "uid": 0,
    "url": "http://172.26.0.84/file/drivers/Canon/mac-10-14-canon.dmg"
複製程式碼

13. Setup模組

playbooks自動收集遠端主機上可用變數,這些變數用於playbooks配置。

[root@Ansible ~]# ansible test_hosts -m setup
172.26.0.84 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "172.26.0.84"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80:****:****:fe5c:dc6d"
        ], 
        "ansible_architecture": "x86_64",
複製程式碼

14. Script模組

這個模組用於在受管機上執行sh指令碼。

[root@Ansible ~]# ansible test_hosts -m script -a '/tmp/script.sh'
Enter passphrase for key '/root/.ssh/id_rsa': 
172.26.0.84 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 172.26.0.84 closed.\r\n", 
    "stdout": "", 
    "stdout_lines": []
複製程式碼

三、神器ansible-playbook的使用

1、Yaml語言

Yaml語言是一種配置語言,主要用於配置檔案的設定和資料塊的儲存,作為一種xml語言的進化形態出現。起主要的優勢在於:

  • YAML的可讀性好。
  • YAML和指令碼語言的互動性好。
  • YAML使用實現語言的資料型別。
  • YAML有一個一致的資訊模型。
  • YAML易於實現。

上面5條也就是XML不足的地方。同時,YAML也有XML的下列優點:

  • YAML可以基於流來處理;
  • YAML表達能力強,擴充套件性好。 總之,YAML試圖用一種比XML更敏捷的方式,來完成XML所完成的任務。

更多的內容及規範參見yaml官網。 語法結構通過空格來展示。Sequence裡的項用"-"來代表,Map裡的鍵值對用":"分隔。 這幾乎就是所有的語法了。以下為一個標準的ansible-playbook的yaml配置檔案:

---
- hosts: rotest2
  roles:
    - sshd
    - snmp
    - hostname
    - vim
    - parted
    - authorized_keys
複製程式碼

2、playbook模組

roles:角色(主模組,和主yaml檔案、ansible配置檔案、host檔案同在playbook根目錄,同時在roles資料夾下則是各種自定義的role。在role資料夾下才包括了後續的其他次級模組)

root@Ansible ~/ansible-test $ ls
ansible.cfg  hosts  roles  main.yml
root@Ansible ~/ansible-test/roles $ ls
audit  authorized_keys  hostname  megacli  nrpe  parted  snmp  sshd  telegraf  vim
複製程式碼

在role資料夾下,會呼叫下面的各個子模組,但是除了task以外都不是必須,而是可選項。例如這個telegraf的部署role,下面只包含了files、handlers、tasks三個子模組。在子模組中我們可以呼叫任何ansible支援的模組功能,尤其是上一章我們介紹的那些重要功能模組

root@Ansible ~/ansible-test/roles/telegraf $ ls
files  handlers  tasks
複製程式碼
  • tasks:任務
  • variables:變數
  • templates:模板
  • handlers:處理器
  • files:需要的檔案

3、如何使用playbook

ansible-playbook的使用基本和ansible類似,哪怕呼叫--help指令檢視,也是一樣的引數結果。一般來說由於playbook呼叫的模組較多,配置的內容較豐富,後續的部署影響較大,所以在使用的時候請務必先呼叫-D -C兩個引數進行結果測試,排查報錯,確認一切無誤後再進行推送和部署。例如:

~$ ansible-playbook -i hosts ro.yml -t authorized_keys -DC
~$ ansible-playbook -i hosts ro.yml -t authorized_keys
複製程式碼

4、使用案例

這裡我們就用一個案例來對ansible-playbook進行詳細的解釋。這個案例比較完整,有助於我們方便理解。 這個案例的檔案架構為:

root@Ansible ~/ansible-test $ ls
ansible.cfg  hosts  roles  main.yml
複製程式碼

具體的main.yml檔案為:

root@Ansible ~/ansible-test $ cat main.yml
---
- hosts: test
  roles:
    - sshd
    - snmp
    - hostname
    - vim
    - parted
    - authorized_keys
    - telegraf
    - audit
複製程式碼

我們進入roles資料夾,檢視具體的role內容。

root@Ansible ~/ansible-test/roles $ ls
audit  authorized_keys  hostname  megacli  nrpe  parted  snmp  sshd  telegraf  vim
複製程式碼

如果我們需要在受管機上安裝某個軟體,以telegraf這個role為例:

root@Ansible ~/ansible-test/roles/telegraf $ tree
.
├── files
│   ├── telegraf-1.8.0-1.x86_64.rpm     #安裝包rpm檔案
│   ├── telegraf.conf                   #自定義的配置檔案
│   └── telegraf.conf.bak               #原始預設配置檔案(非必須)
├── handlers
│   └── main.yml                        #處理器配置
└── tasks
    └── main.yml                        #role的任務主配置

3 directories, 5 files
-------------------------------------
root@Ansible ~/ansible-test/roles/telegraf $ cat ./tasks/main.yml
---

- name: install telegraf                #配置npm的下載地址
  yum: name=https://dl.influxdata.com/telegraf/releases/telegraf-1.8.0-1.x86_64.rpm state=present
  tags: telegraf

- name: copy telegraf config            #配置檔案的複製
  copy: src=telegraf.conf dest=/etc/telegraf/
  notify: reload telegraf
  tags: telegraf

- name: ensure service telegraf is started and enabled
  service: name=telegraf state=started enabled=yes
  tags: telegraf                        #確保在受管機上開機啟動telegraf服務
-------------------------------------
root@Ansible ~/ansible-test/roles/telegraf $ cat ./handlers/main.yml
---

- name: reload telegraf                 #異常狀況重新載入
  service: name=telegraf state=reloaded
複製程式碼

而對於部分複雜的配置需求,我們甚至可以使用shell指令碼來對受管機進行相關的處理,例如磁碟掛載或者分配等系統級別的任務。

root@Ansible ~/ansible-test/roles/parted $ ls
files  tasks
-------------------------------------
root@Ansible ~/ansible-test/roles/parted $ tree
.
├── files
│   ├── parted.sh                   #shell指令碼檔案
│   └── parted.sh.bak
└── tasks
    └── main.yml                    #主task配置

2 directories, 3 files
-------------------------------------
root@Ansible ~/ansible-test/roles/parted $ cat files/parted.sh
#!/bin/bash

OPTS="noatime,nobarrier,errors=remount-ro,nofail"

x=b
#for x in {b}
#do
    echo "mkpart /dev/vd${x}"
    parted /dev/vd${x} -s mklabel gpt
    parted /dev/vd${x} -s mkpart primary 1 100%
    echo ">>> mkfs.ext4 /dev/vd${x}1"
    mkfs.ext4 -q /dev/vd${x}1
    if [ $? -eq 0 ]; then
        UUID=$(blkid /dev/vd${x}1 | sed -e 's/.*\(UUID=.*\) TYPE.*/\1/')
        echo -e "${UUID}\t\t/data\t\text4\t\t${OPTS}\t\t0 0" >> /etc/fstab
    fi
    seq=$(($seq+1))
#done                               #通過shell指令碼進行磁碟的分割槽與掛載
-------------------------------------
root@Ansible ~/ansible-test/roles/parted $ cat tasks/main.yml
---
 #parted
- name: copy parted config
  copy: src={{ item }} dest=~ owner=root group=root mode="0777"
  with_items:                       #複製指令碼到受管機並配置chown許可權
    - parted.sh                     #執行shell指令碼
  tags: parted
複製程式碼

關於playbook的其他功能大家可以通過實踐和閱讀其他案例來學習,ansible非常靈活,請務必善於使用。

附錄、參考文獻

  1. 戴爾yaml介紹
  2. Ansible Documents
  3. Ansible中文權威指南
  4. Ansible模組Module

相關文章