Ansilbe 管理員節點和遠程主機節點經過 SSH 協議進行通訊。因此 Ansible 配置的時候只須要保證從 Ansible 管理節點經過 SSH 可以鏈接到被管理的遠程的遠程節點。html
每一臺被 ansible 遠程管理的主機,都須要配置基於 key 的 ssh 鏈接python
# Readhat/CentOS Linux, Ansible 目前放在 epel 源中 yum install -y epel-release yum install -y ansible # Mac brew install ansible
安裝 ansible 在管理節點,那麼,須要配置管理節點->遠程主機之間基於 key 的免密訪問:nginx
# 生成 ssh key,若是你以前配置過 Git,那麼已經生成過一個了 ssh-keygen -t rsa -C "649168982@qq.com" # 拷貝 ssh key 至遠程主機,下次管理節點就能夠免密訪問遠程主機了 ssh-copy-id remote_user@remote_server # ssh 的時候不會提示是否保存 key ssh-keyscan remote_servers >> ~/.ssh/known_hosts
這時候在管理節點登陸遠程節點時,就不會輸入密碼也不會提醒你存儲key,以前寫過一篇文章,記錄設置免密登陸的文章Linux 雙向 SSH 免密登陸:git
ssh remote_user@remote_server
Host Inventory 是配置文件,用來告訴Ansible須要管理哪些主機。而且把這些主機根據按需分類。github
能夠根據用途分類:數據庫節點,服務節點,nginx 節點、構建機器節點shell
默認的配置文件在:/etc/ansible/hosts
,能夠經過 -i
參數指定配置文件的,參考問題:數據庫
ansible 的配置文件有多個位置,查找順序以下:macos
ANSIBLE_CONFIG
所指向的位置ansible.cfg
~/.ansible.cfg
/etc/ansible/ansible.cfg
本文 ansible.cfg:ubuntu
[defaults] # 這個參數表示主機清單 inventory 文件的位置 inventory = ./inventory # 併發鏈接數,默認爲5 forks = 5 remote_user = root # 設置默認執行命令的用戶,~~sudo_user~~ 參數在 ansbile 2.8 版本將會做廢的 become_user = root #指定一個存儲ansible日誌的文件(默認不記錄日誌) log_path = ./ansible.log
指定用戶名除了在 ansible.cfg
中指定 remote_user
以外,還能夠:centos
ansible_user
或 ansible_ssh_user
-u
參數指定用戶名更多 ansbile.cfg
的配置參考連接
inventory: 英 ['ɪnv(ə)nt(ə)rɪ] 美 ['ɪnvəntɔri] n. 存貨,存貨清單;詳細目錄
Ansible 可同時操做屬於一個組的多臺主機,組和主機之間的關係經過 inventory 文件配置。
inventory:
[centos] 192.168.3.43 [centos:vars] ansible_ssh_user=root
[]
中是組名,用於對主機進行分類,便於對不一樣主機進行個別的管理[組名:vars]
定義了「組的變量」拓展:
能夠把一個組做爲另外一個組的子成員,以及分配變量給整個組使用. 這些變量能夠給 /usr/bin/ansible-playbook
使用,但不能給 /usr/bin/ansible
使用
[atlanta] host1 host2 [raleigh] host2 host3 [southeast:children] atlanta raleigh
Inventory 參數能夠控制 ansible 與遠程主機的交互方式:
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) ansible_sudo_exe (new in version 1.8) sudo 命令路徑(適用於1.8及以上版本) ansible_connection 與主機的鏈接類型.好比:local, ssh 或者 paramiko. Ansible 1.2 之前默認使用 paramiko.1.2 之後默認使用 'smart','smart' 方式會根據是否支持 ControlPersist, 來判斷'ssh' 方式是否可行. ansible_ssh_private_key_file ssh 使用的私鑰文件.適用於有多個密鑰,而你不想使用 SSH 代理的狀況. ansible_shell_type 目標系統的shell類型.默認狀況下,命令的執行使用 'sh' 語法,可設置爲 'csh' 或 'fish'. ansible_python_interpreter 目標主機的 python 路徑.適用於的狀況: 系統中有多個 Python, 或者命令路徑不是"/usr/bin/python",好比 \*BSD, 或者 /usr/bin/python 不是 2.X 版本的 Python.咱們不使用 "/usr/bin/env" 機制,由於這要求遠程用戶的路徑設置正確,且要求 "python" 可執行程序名不可爲 python之外的名字(實際有可能名爲python26). 與 ansible_python_interpreter 的工做方式相同,可設定如 ruby 或 perl 的路徑....
參考
ansible 的主要使用形式分爲兩種:
本文就先從 ad-hoc 方式開始學習。
ansible -h
中將命令行工具叫作 Ad-Hoc Commands
,格式是:
Usage: ansible <host-pattern> [options]
ad hoc——臨時的,在ansible中是指須要快速執行,而且不須要保存的命令。說白了就是執行簡單的命令——一條命令。對於複雜的命令後面會說playbook。關於命令中使用的模塊,以後專門詳細再作功課,這裏先簡單意會入門吧。
個人目錄初始化時的組成:
. ├── ansible.cfg └── inventory
這裏的 host-pattern
既能夠是一個具體的主機 IP,也能夠是 inventory 中的組名。
經常使用的命令選項示例:
ansible all --list-hosts
列出全部主機的 IP,這裏的 all
不是組名,而是隻 inventory 中全部的主機在進入下面的小節學習相關模塊簡單用法以前,我們先學習一個命令,這對於從此的使用頗有幫助:
$ansible-doc <module_name>
在未進行批量授信以前,可使用 --ask-pass
參數來進行認證,例如:ansible all -m ping --ask-pass
。可是這樣並不方便,能夠經過將 ansible server 機器上的公鑰複製到遠程主機 ~/.ssh/authorized_keys
文件中,實現免密登陸。機器不少時,這樣作就比較麻煩了,能夠用以下模塊實現:
ansible centos -m authorized_key -a "user=root key='{{ lookup('file', '/Users/michael/.ssh/id_rsa.pub') }}' path=/root/.ssh/authorized_keys manage_dir=yes" --ask-pass
ping 模塊用於測試 ansible server 到 inventory 主機的連通性,這是官網的介紹ping – Try to connect to host, verify a usable python and return pong on success
$ ansible -i inventory centos -m ping -u root 192.168.3.43 | SUCCESS => { "changed": false, "ping": "pong" }
-i
指定了 inventory
文件,後面要接着目標主機名,否則會報錯-m
後面接使用的 module
-u
只以什麼用戶登陸到目標主機下面實例中,沒有加目標主機名,就報錯了:
ansible -i inventory centos -m ping -u root
ERROR! Missing target hosts
下面錯誤示例,指定的用戶名 hh
沒法免密登陸到目標主機:
$ ansible -i inventory centos -m ping -u hh 192.168.3.43 | UNREACHABLE! => { "changed": false, "msg": "Failed to connect to the host via ssh: hh@192.168.3.43: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n", "unreachable": true }
此時,我在這篇文章中看到了這樣的用法也能夠指定登陸遠程主機的用戶名,而且,優先級比 -u
或者在 ansible.cfg
中指定都高:
[centos] 192.168.3.43 [centos:vars] ansible_ssh_user=michael
command模塊爲ansible默認模塊,不指定-m參數時,使用的就是command模塊;comand模塊比較簡單,常見的命令均可以使用,但其命令的執行不是經過shell執行的,因此,像這些 "<", ">", "|", and "&"操做都不能夠,固然,也就不支持管道;
在遠程主機上執行命令 pwd
:
$ ansible centos -a 'pwd' 192.168.3.43 | CHANGED | rc=0 >> /home/michael
缺點:不支持管道,就無法批量執行命令
-i
參數指定 inventory 文件,由於我運行 ansible --version
時,看到了它識別到了我當前目錄下的 ansible.cfg
文件centos
就是必不可少的參數 host-pattern
,讓咱們複習一下用法 ansible <host-pattern> [options]
-a
/--args
模塊參數使用shell模塊,在遠程命令經過/bin/sh
來執行;因此,咱們在終端輸入的各類命令方式,均可以使用; 可是咱們本身定義在.bashrc/.bash_profile
中的環境變量shell模塊因爲沒有加載,因此沒法識別;
若是須要使用自定義的環境變量,就須要在最開始,執行加載自定義腳本的語句;
對shell模塊的使用能夠分紅兩塊:
1.若是待執行的語句少,能夠直接寫在一句話中:
$ ansible all -m shell -a ". ~/.bashrc;ps -fe |grep sa_q" 192.168.3.43 | CHANGED | rc=0 >> root 2849 2844 2 14:58 pts/0 00:00:00 /bin/sh -c . ~/.bashrc;ps -fe |grep sa_q root 2866 2849 0 14:58 pts/0 00:00:00 grep sa_q
2.若是在遠程待執行的語句比較多,可寫成一個腳本,經過 copy
模塊傳到遠端,而後再執行;但這樣就又涉及到兩次ansible調用;對於這種需求,ansible已經爲咱們考慮到了,script模塊就是幹這事的。
使用 scripts
模塊能夠在本地寫一個腳本,在遠程服務器上執行(遠程服務器不須要python環境):
ansible all -m script -a "./test-20190224.sh"
test-20190224.sh
位於當前目錄下,表示在全部的遠程主機上執行 test.sh
腳本,省略了先把文件複製過去的步驟參考
拷貝本地文件 /Users/michael/Code/05-Github-Own/ansible-learn/file_mbp.txt
至遠程主機的 /tmp
目錄下:
ansible centos -m copy -a "src=//Users/michael/Code/05-Github-Own/ansible-learn/file_mbp.txt dest=/tmp/ [owner=root group=root mode=0755]"` ansible centos -m copy -a "src=//Users/michael/Code/05-Github-Own/ansible-learn/file_mbp.txt dest=/tmp/centos.txt [owner=root group=root mode=0755]"
上面 []
中的內容表示非必須。這個 copy
模塊挺智能,若是目標沒有寫文件名,那麼傳過去的文件就同名,若是自定義了文件名,就進行了重命名:
$ ansible centos -m yum -a "name=lrzsz state=latest" 192.168.3.43 | SUCCESS => { "ansible_facts": { "pkg_mgr": "yum" }, "changed": false, "msg": "", "rc": 0, "results": [ "All packages providing lrzsz are up to date", "" ] }
yum
模塊來安裝軟件包name
指定安裝的軟件包的名字state
指定安裝軟件包時的行爲,它有幾個選項值,
installed
/present
它倆是等價的,表示若是遠程主機上有這個包了,則不從新安裝了;latest
顧名思義,會去安裝最新版的,這個對於生產是比較危險的,有可能所以破壞了生產的環境Yum 模塊
state
值得具體區別,參考了這個問題:
ansible centos -m user -a "name=foo password=<crypted password here>" //移除用戶 ansible all -m user -a 'name=foo state=absent'
$ ansible centos -m git -a "repo=https://github.com/Michael728/my-config-files.git dest=/tmp/my-config-files version=HEAD" 192.168.3.43 | CHANGED => { "after": "6faf55b17a1d7c25dfda6f6197839deaa2aa2bd5", "before": null, "changed": true }
repo
是必選參數dest
也是必選參數,指定代碼庫的下載路徑代碼庫地址除了選擇用 https
連接以外,還能夠用 ssh
地址,事實上,公司中大多使用 ssh
地址會更方便:
ansible centos -m git -a "repo=git@github.com:Michael728/my-config-files.git dest=/tmp/my-config-files version=HEAD accept_hostkey=yes"
遠程主機首次使用 git clone
命令時,是須要手動接受 knows_hosts 的,這時候加上 accept_hostkey=yes
能夠避免出錯
參考:
# 啓動服務 ansible centos -m service -a "name=httpd state=started" # 重啓服務,效果相似 stopped+started,若是服務已經中止的,執行完,會重啓 ansible centos -m service -a "name=httpd state=restarted" # 重載服務,不會中斷服務,若是服務以前未啓動,那麼會啓動服務,若是啓動了不必定會使用新的配置文件,仍是推薦重啓 ansible centos -m service -a "name=httpd state=reloaded" # 中止服務 ansible centos -m service -a "name=httpd state=stopped"
state 有幾個可選值(Choices: reloaded, restarted, started, stopped)[Default: (null)]
:
started'/
stopped` are idempotent[冪等] actions that will not run commands unless necessary.restarted
will always bounce the service.reloaded
will always reload. At least one of state and enabled are required. Note that reloaded will start the service if it is not already started, even if your chosen init system wouldn't normally.參考
$ansible centos -a "/sbin/reboot" -f 10
-f
參數會 fork 出 10 個子進程,以並行的方式這個命令雖然顯示是出現問題了,可是我發現虛擬機確實重啓了:
$ ansible all -a "reboot" -f 6 192.168.3.43 | UNREACHABLE! => { "changed": false, "msg": "Failed to connect to the host via ssh: Shared connection to 192.168.3.43 closed.\r\n", "unreachable": true }
ansible all -m setup # 經過 filter 獲取某一個 fact 變量 ansible all -m setup -a 'filter=ansible_*mb'
能夠發現,ansible Ad-Hoc 的命令使用比較簡單,適用於不復雜的場景,若是須要實現複雜的任務,那麼就須要經過 ansible-playbook 的方式執行了,下一篇文章中學習它。
service 模塊的 restarted reload 區別?