Ansible第一篇:基礎(chǔ)

一、配置文件 ansible.cfg

/etc/ansible/ansible.cfg 是ansible安裝好后的默認(rèn)配置文件,但是配置文件可以存在于多個地方,ansible讀取配置文件的順序依次是:當(dāng)前命令執(zhí)行目錄 ---> **用戶家目錄下的 .ansible.cfg ** ---> /etc/ansible/ansible.cfg,先找到哪個就使用哪個的配置。ansible.cfg中的配置均可在命令行通過參數(shù)傳遞或定義在playbooks中。

以下是[defaults]常用的配置項:

1)inventory 
    該參數(shù)表示資源清單inventory文件的位置,資源清單就是一些Ansible需要連接管理的主機列表 
    inventory = /root/ansible/hosts 

2)library 
    Ansible的操作動作,無論是本地或遠(yuǎn)程,都使用一小段代碼來執(zhí)行,這小段代碼稱為模塊,這個library參數(shù)就是指向存放Ansible模塊的目錄 
    library = /usr/share/ansible 

3)forks 
    設(shè)置默認(rèn)情況下Ansible最多能有多少個進程同時工作,默認(rèn)設(shè)置最多5個進程并行處理。具體需要設(shè)置多少個,可以根據(jù)控制主機的性能和被管理節(jié)點的數(shù)量來確定。 
    forks = 5 

4)sudo_user 
    這是設(shè)置默認(rèn)執(zhí)行命令的用戶,也可以在playbook中重新設(shè)置這個參數(shù)sudo_user = root 
    //注意:新版本已經(jīng)作了修改,如ansible2.4.1下已經(jīng)為: default_sudo_user = root 

5)remote_port 
    這是指定連接被關(guān)節(jié)點的管理端口,默認(rèn)是22,除非設(shè)置了特殊的SSH端口,不然這個參數(shù)一般是不需要修改的 
    remote_port = 22 

6)host_key_checking 
    這是設(shè)置是否檢查SSH主機的密鑰??梢栽O(shè)置為True或False 
    host_key_checking = False 

7)timeout 
    這是設(shè)置SSH連接的超時間隔,單位是秒。 
    timeout = 20 

8)log_path 
    Ansible系統(tǒng)默認(rèn)是不記錄日志的,如果想把Ansible系統(tǒng)的輸出記錄到人i治穩(wěn)健中,需要設(shè)置log_path來指定一個存儲Ansible日志的文件 
    log_path = /var/log/ansible.log 
    另外需要注意,執(zhí)行Ansible的用戶需要有寫入日志的權(quán)限,模塊將會調(diào)用被管節(jié)點的syslog來記錄,口令是不會出現(xiàn)的日志中的 

9)private_key_file 在使用ssh公鑰私鑰登錄系統(tǒng)時候,使用的密鑰路徑。 
    private_key_file=/path/to/file.pem
    
作者: Jeson老師 
鏈接:https://www.imooc.com/article/22513
來源:慕課網(wǎng)

更多配置項請參考官方文檔

二、主機清單(Inventory)文件hosts

2.1 hosts文件定義

默認(rèn)存放在 **/etc/ansible/hosts **,命令行使用時,還可以通過 -i--inventory-file 指定讀取某個hosts文件,如:

//讀取當(dāng)前用戶家目錄下的hosts文件
ansible -i ~/ansible/hosts webs -m ping

如下是hosts文件中的常用常用的定義主機方法:

# 定義單獨的主機
192.168.1.189   //可以直接為IP地址
ntp.cgy.com:2222    //也可以主機名:端口,端口默認(rèn)是22

# 定義主機組
[apache]
httpd1.cgy.com
httpd[10:20].cgy.com    //[10:20]表示10~20之間所有數(shù)字(包括10和20)

# 定義主機變量
[nginx]
ngx-a.cgy.com http_port=808     //自定義這臺主機的nginx端口為808,可以寫多個變量,每個變量用空格間隔即可           
ngx-[b:f].cgy.com   //[b:f]表示b到f之間所有字母

# 定義主機組變量
[nginx:vars]
ntp_server=ntp.cgy.com      //定義nginx組中所有的主機ntp_server值為ntp.cgy.com

# 定義組嵌套及組變量
[webservers:children]
apache
nginx

[webservers:vars]
ntp_server=ntp.cgy.com

2.2 主機匹配

  1. all(全量)匹配,匹配所有主機
// all和 * 號功能相同,但 * 號需要引起來
ansible all -m ping
ansible "*" -m ping

// 匹配192.168.1.0/24網(wǎng)段的主機
ansible 192.168.1.* -m ping

  1. 邏輯或(or)匹配

如果希望同時對多臺主機或多個組同時執(zhí)行,相互之間用:(冒號)分隔即可。

使用方式如下:

ansible "webservers:dbservers" -m ping

  1. 邏輯非(?。┢ヅ?/li>

邏輯非用感嘆號(?。┍硎荆饕槍Χ嘀貤l件的匹配規(guī)則,使用方法如下:

// 所有在nginx組,但不包括ngx-c.cgy.com的主機
ansible "nginx:!ngx-c.cgy.com" -m ping

  1. 邏輯與(&)匹配

與邏輯非一樣,只是邏輯上的判斷不同。

// apache組和nginx組中同時存在的主機
ansible "apache:&nginx" -m ping

  1. 模糊匹配

* 通配符在ansible表示0個或多個任意字符。

ansible "http*.cgy.com" -m ping

  1. 域切割

hosts文件如下:

[webservers]
cobweb
webbing
weber

通過截取數(shù)組下標(biāo)即可以獲取對應(yīng)主機:

webservers[0]       # == cobweb
webservers[-1]      # == weber
webservers[0:1]     # == cobweb, webbing
webservers[1:]      # == webbing, weber

  1. 正則匹配

ansible同樣完整支持正則匹配功能,~ 開始表示正則匹配

ansible "~(beta|web|green)\.example\.(com|org)" -m ping

ansible ~192\.168\.[0-9]\{\2}\.[0-9]\{2,} -m ping

三、Ad-Hoc命令集

Ad-Hoc命令,也就是臨時命令的意思,就是通常在命令行下操作的ansible命令,區(qū)別于ansible-playbook。

Ad-Hoc 注重于解決一些簡單或者平時工作中臨時遇到的任務(wù),相當(dāng)于Linux系統(tǒng)命令行下的Shell命令;

Ansible-playbook 更適合解決復(fù)雜或需要固化下來的任務(wù),相當(dāng)于Linux系統(tǒng)的Shell腳本。

3.1 ansible命令用法

格式:ansible <host-pattern> [options]

可用選項如下:

-v, --verbose:               輸出更詳細(xì)的執(zhí)行過程信息,**-vvv** 可得到所有執(zhí)行過程信息。
-i PATH, --inventory=PATH:   指定inventory信息,默認(rèn)/etc/ansible/hosts。
-f NUM, --forks=NUM:         并發(fā)線程數(shù),默認(rèn)5個線程。
--private-key=PRIVATE_KEY_FILE:  指定密鑰文件。
-m NAME, --module-name=NAME:     指定執(zhí)行使用的模塊。
-M DIRECTORY, --module-path=DIRECTORY:  指定模塊存放路徑,默認(rèn)/usr/share/ansible,也可以通過ANSIBLE_LIBRARY設(shè)定默認(rèn)路徑。
-a 'ARGUMENTS', --args='ARGUMENTS':     模塊參數(shù)。
-k, --ask-pass SSH:           認(rèn)證密碼。
-K, --ask-sudo-pass sudo:     用戶的密碼(—sudo時使用)。
-o, --one-line:               標(biāo)準(zhǔn)輸出至一行。
-s, --sudo:                   相當(dāng)于Linux系統(tǒng)下的sudo命令。
-t DIRECTORY, --tree=DIRECTORY:  輸出信息至DIRECTORY目錄下,結(jié)果文件以遠(yuǎn)程主機名命名。
-T SECONDS, --timeout=SECONDS:   指定連接遠(yuǎn)程主機的最大超時,單位是:秒。
-B NUM, --background=NUM:     后臺執(zhí)行命令,超NUM秒后kill正在執(zhí)行的任務(wù)。
-P NUM, --poll=NUM:           定期返回后臺任務(wù)進度。
-u USERNAME, --user=USERNAME: 指定遠(yuǎn)程主機以USERNAME運行命令。
-U SUDO_USERNAME, --sudo-user=SUDO_USERNAM:  使用sudo,相當(dāng)于Linux下的sudo命令。
-c CONNECTION, --connection=CONNECTION:      指定連接方式,可用選項paramiko (SSH), ssh, local。Local方式常用于crontab 和 kickstarts。
-l SUBSET, --limit=SUBSET:    指定運行主機。
-l ~REGEX, --limit=~REGEX:    指定運行主機(正則)。
--list-hosts:                 列出符合條件的主機列表,不執(zhí)行任何其他命令

3.2 ansible命令執(zhí)行流程圖

ansible命令執(zhí)行流程

3.3 常用模塊介紹

使用ansible-doc -l可以列出所有ansible支持的模塊;
使用ansible-doc 模塊名獲取模塊幫助信息;

/etc/ansible/hosts文件內(nèi)容如下:

[root@LOCALHOST ~]# cat /etc/ansible/hosts
[load-node]
openstack-load1
openstack-load2

[compute-node]
openstack-compute1
openstack-compute2

[control-node]
openstack-control1
openstack-control2

[openstack:children]
load-node
compute-node
control-node

3.3.1 ?command模塊

如果沒有用-m指定一個模塊,則ansible默認(rèn)使用的就是command模塊。如下:

查看load-node組的主機名:

[root@LOCALHOST ~]# <strong>ansible load-node -a "hostname"</strong>
openstack-load2 | SUCCESS | rc=0 >>
openstack-load2

openstack-load1 | SUCCESS | rc=0 >>
openstack-load1.example.com 

注意:command 模塊不支持 shell 變量,也不支持管道等 shell 相關(guān)的東西.如果你想使用 shell相關(guān)的這些東西, 請使用’shell’ 模塊。

特別注意:執(zhí)行ansible命令之前需要將主機清單中所有主機關(guān)閉selinux狀態(tài)置于disabled狀態(tài),就是將/etc/sysconfig/selinux中的SELINUX=disabled,然后重啟生效。


3.3.2 ?shell模塊

示例一(讀取變量):

[root@LOCALHOST ~]# **ansible load-node -m shell -a "echo $TERM"**
openstack-load2 | SUCCESS | rc=0 >>
xterm 

openstack-load1 | SUCCESS | rc=0 >>
xterm

示例二(支持管道):

[root@LOCALHOST ~]# ansible load-node -m shell -a "netstat -tunlp | grep sshd"
openstack-load1 | SUCCESS | rc=0 >>
tcp        0      0 0.0.0.0:2002            0.0.0.0:*               LISTEN      845/sshd            
tcp6       0      0 :::2002                 :::*                    LISTEN      845/sshd            

openstack-load2 | SUCCESS | rc=0 >>
tcp        0      0 0.0.0.0:2002            0.0.0.0:*               LISTEN      853/sshd            
tcp6       0      0 :::2002                 :::*                    LISTEN      853/sshd 

3.3.3 ?copy模塊
[root@LOCALHOST ~]# **ansible load-node -m copy -a "src=/root/upgrade.log dest=/root/"**
openstack-load2 | SUCCESS => {
    "changed": true, 
    "checksum": "792f7f450667adc5c89fbaeb06f778488149b87b", 
    "dest": "/root/upgrade.log", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "1c1a33178d6a6aeb42fb4126ab420ba0", 
    "mode": "0644", 
    "owner": "root", 
    "size": 36, 
    "src": "/root/.ansible/tmp/ansible-tmp-1522073638.68-199717195987657/source", 
    "state": "file", 
    "uid": 0
}
...省略部分輸出...

注意:copy模塊還有一個remote_src參數(shù),不寫此參數(shù),默認(rèn)為:remote_src=no,將控制主機的src復(fù)制到目標(biāo)主機的dest。如果加上參數(shù) remote_src=yes,那么將從遠(yuǎn)程目標(biāo)主機的src復(fù)制到遠(yuǎn)程主機的dest。


3.3.5 ?file模塊

使用file模塊可以做到修改文件的屬主和權(quán)限:

$ ansible webservers -m file -a "dest=/srv/foo/a.txt mode=600"

$ ansible webservers -m file -a "dest=/srv/foo/b.txt mode=600 owner=mdehaan group=mdehaan"

使用file模塊也可以創(chuàng)建目錄,與執(zhí)行mkdir -p 效果類似:

$ ansible webservers -m file -a "dest=/path/to/c mode=755 owner=mdehaan group=mdehaan state=directory"

刪除目錄(遞歸的刪除)和刪除文件:

$ ansible webservers -m file -a "dest=/path/to/c state=absent"

3.3.6 ?yum模塊

安裝軟件包:

$ ansible control-node -m yum -a "name=httpd state=present"

    // 或者state=installed 安裝軟件
    // state=latest 安裝最新版本 

卸載軟件包:

$ ansible control-node -m yum -a "name=httpd state=absent"
    
    // 或者state=removed 卸載軟件包

yum模塊在playbook中的用法:

# 以下只寫出了tasks部分內(nèi)容:

//安裝指定版本的軟件
- name: install one specific version of Apache
  yum:
    name: httpd-2.2.29-1.4.amzn1
    state: present


// 升級所有軟件包
- name: upgrade all packages
  yum:
    name: '*'
    state: latest

// 升級所有軟件包,不包括內(nèi)核和foo相關(guān)的軟件包
- name: upgrade all packages, excluding kernel & foo related packages
  yum:
    name: '*'
    state: latest
    exclude: kernel*,foo*

// 從遠(yuǎn)程倉庫安裝nginx
- name: install the nginx rpm from a remote repo
  yum:
    name: http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
    state: present


// 安裝開發(fā)環(huán)境包組
- name: install the 'Development tools' package group
  yum:
    name: "@Development tools"
    state: present

// 列出指定軟件包信息并注冊至變量result
- name: List ansible packages and register result to print with debug later.
  yum:
    list: ansible
  register: result

3.3.7 ?user模塊

使用 user 模塊可以方便的創(chuàng)建賬戶,刪除賬戶,或是管理現(xiàn)有的賬戶:

// 添加用戶foo
$ ansible all -m user -a "name=foo password=123456"

// 刪除用戶foo
$ ansible all -m user -a "name=foo state=absent"

    // state=absent結(jié)合remove=yes使用,相當(dāng)于shell命令userdel --remove 刪除用戶家目錄及郵件目錄

3.3.8 ?git模塊

可以直接使用git模塊部署webapp:

$ ansible webservers -m git -a "repo=git://foo.example.org/repo.git dest=/srv/myapp version=HEAD"

3.3.9 ?service模塊

service模塊來管理各種服務(wù)的啟停:

// 開啟httpd
$ ansible webservers -m service -a "name=httpd state=started"

// 重啟httpd
$ ansible webservers -m service -a "name=httpd state=restarted"

    // state可以選擇stopped(停止)、reloaded(重載配置)

需要注意的是,startedstopped是 <font color=green size=4>冪等操作</font>,也就是說,如果某項服務(wù)已經(jīng)開啟或關(guān)閉,那么就不再繼續(xù)操作。


3.3.10 ?pip模塊
// 安裝Django
$ ansible app -m pip -a "name=django state=present"

3.3.11 ?mysql_user模塊

mysql_user模塊,是對mysql用戶進行管理的模塊。
事實上,Ansible也支持如Openstack、Mongodb、PostgreSQL、RabbitMQ等應(yīng)用的管理。

新增mysql用戶stanley,密碼123456,對zabbix.*表有所有權(quán)限,命令如下:

$ ansible db -m mysql_user -a "login_host=localhost login_user=root login_password=laksdvcx name=stanley password=123456 priv=zabbix.*:ALL state=present"

注意:上述命令直接將Mysql登錄信息完全暴露在命令行,存在很大的安全隱患。如果在遠(yuǎn)程主機的~/.my.conf文件中定義登錄用戶及密碼,則可以在上述命令中省略登錄相關(guān)信息。

3.3.12? setup模塊

獲取遠(yuǎn)程主機的系統(tǒng)信息,這些系統(tǒng)信息在playbook中可以直接當(dāng)作變量引用,如 {{ ansible_all_ipv4_addresses }}就可以獲取到遠(yuǎn)程主機的所有IP地址[ "10.0.1.105", "43.240.137.105"],這些變量被稱作facts變量。

$ ansible compute-node -m setup
openstack-compute2 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.0.1.105", 
            "43.240.137.105"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::5054:ff:fe13:38cc", 
            "fe80::5054:ff:fe2b:60e5"
        ], 
        "ansible_apparmor": {
            "status": "disabled"
        }, 
        "ansible_architecture": "x86_64", 
        "ansible_bios_date": "01/01/2007", 
        "ansible_bios_version": "0.5.1", 
        "ansible_cmdline": {
            "BOOT_IMAGE": "/vmlinuz-3.10.0-327.el7.x86_64", 
            "LANG": "zh_CN.UTF-8", 
            "biosdevname": "0", 
            "crashkernel": "auto", 
            "net.ifnames": "0", 
            "quiet": true, 
            "rd.lvm.lv": "centos/swap", 
            "rhgb": true, 
            "ro": true, 
            "root": "/dev/mapper/centos-root"
        }, 

... 省略 ...
        "ansible_system_capabilities_enforced": "True", 
        "ansible_system_vendor": "Red Hat", 
        "ansible_uptime_seconds": 313578, 
        "ansible_user_dir": "/root", 
        "ansible_user_gecos": "root", 
        "ansible_user_gid": 0, 
        "ansible_user_id": "root", 
        "ansible_user_shell": "/bin/bash", 
        "ansible_user_uid": 0, 
        "ansible_userspace_architecture": "x86_64", 
        "ansible_userspace_bits": "64", 
        "ansible_virtualization_role": "guest", 
        "ansible_virtualization_type": "kvm", 
        "gather_subset": [
            "all"
        ], 
        "module_setup": true
    }, 
    "changed": false

過濾顯示:

$ ansible compute-node -m setup -a 'filter=ansible_eth[0-1]'


$ ansible compute-node -m setup -a 'gather_subset=network,virtual'


$ ansible compute-node -m setup -a 'gather_subset=!all,!any,network,virtual'

3.3.13 ?cron模塊

cron模塊是用來添加或刪除定時任務(wù)的;

// 添加一個定時任務(wù),每過2分鐘從time.aliyun.com同步一次時間
[root@LOCALHOST ~]# ansible load-node -m cron -a "name='sync time from ntpserver' minute=*/2 job='/sbin/ntpdate time.aliyun.com &> /dev/null'"
openstack-load1 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "sync time from ntpserver"
    ]
}
openstack-load2 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "sync time from ntpserver"
    ]
}

注意:如果 hour、day、month、weekday都沒指定,則都表示 *;
state沒寫,默認(rèn)等于present,就是創(chuàng)建定時任務(wù)。

刪除一個定時任務(wù):

[root@LOCALHOST ~]# ansible load-node -m cron -a "name='sync time from ntpserver' state=absent"
openstack-load1 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
openstack-load2 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": []

3.3.14 ?script模塊

script模塊是將本地腳本先拷貝一份到目標(biāo)主機上去執(zhí)行,執(zhí)行完成后再將目標(biāo)主機上的拷貝刪除。

// 在目標(biāo)主機上執(zhí)行控制機root目錄下的test.sh腳本
[root@LOCALHOST ~]# ansible load-node -m script -a "/root/test.sh"
openstack-load2 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "", 
    "stdout": "", 
    "stdout_lines": []
}
openstack-load1 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "", 
    "stdout": "", 
    "stdout_lines": []
}


// 驗證腳本在目標(biāo)主機是否執(zhí)行成功
[root@LOCALHOST ~]# ansible load-node -m shell -a "cat /tmp/ansible.txt"
openstack-load1 | SUCCESS | rc=0 >>
openstack-load1.example.com: Ansible is very good !!!

openstack-load2 | SUCCESS | rc=0 >>
openstack-load2: Ansible is very good !!!


3.3.15 ?archive和unarchive模塊

archiveunarchive模塊是打包壓縮與解壓縮模塊;

archive模塊默認(rèn)情況下,它假定目標(biāo)主機上存在壓縮源;

$ ansible load-node -m archive -a "path=/tmp/test exclude_path=/tmp/test/sub2 format=bz2 dest=/tmp/test.tar.bz2"
  • path:指定遠(yuǎn)程主機上將要壓縮的目錄或文件;
  • exclude_path:指定要排除的文件或目錄;
  • format:指定壓縮格式,choices:gz、bz2、zip、tar、xz (ansible 2.5支持),默認(rèn)是gz格式;
  • dest:壓縮后的文件名。

unarchive模塊默認(rèn)情況下,它將在解包之前將源文件從本地系統(tǒng)復(fù)制到目標(biāo)主機。設(shè)置remote_src = yes將解包目標(biāo)主機上已有的壓縮包。

$ ansible load-node -m  unarchive -a "src=/tmp/test.tar.bz2 dest=/root list_files=yes remote_src=yes"

常用模塊就介紹這么多,更多模塊學(xué)習(xí)請使用ansible-doc 模塊名稱獲取幫助。

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

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

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