Ansible (底層是基于ssh連接的,每次操作其他主機需要輸入密碼 ,所以首先要實現基于key的公鑰驗證)
使用ansible:
ansible "192.168.60.3" -m shell -a 'ls /root' -k (單個用戶在實現基于key的驗證前)
安裝ansible:
yum包的安裝:
yum install ansible (此包依賴于base源和epel源,安裝前確保兩個yum源可以使用)
編譯安裝:
yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
tar xf ansible-1.5.4.tar.gz
cd ansible-1.5.4
python setup.py build
python setup.py install
mkdir /etc/ansible
cp -r examples/* /etc/ansible
相關文件
配置文件
/etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性
/etc/ansible/hosts 主機清單 (將要連接操控的主機IP地址寫在此配置文件的最下方)
/etc/ansible/roles/ 存放角色的目錄
程序
/usr/bin/ansible 主程序,臨時命令執行工具
/usr/bin/ansible-doc 查看配置文檔,模塊功能查看工具
/usr/bin/ansible-galaxy 下載/上傳優秀代碼或Roles模塊的官網平臺
/usr/bin/ansible-playbook 定制自動化任務,編排劇本工具/
usr/bin/ansible-pull 遠 程執行命令的工具
/usr/bin/ansible-vault 文件加密工具
/usr/bin/ansible-console 基于Console界面與用戶交互的執行工具
主機清單inventory (里面列有要操控服務器的IP地址,需要自己手動來添加)
配置文件路徑:/etc/ansible/hosts
格式:可以一連串寫下去,也可分組,組與組之間的所擁有的服務IP地址可重復:
[lvserver] (此為組名為自定義命名)
192.168.60.3
192.168.60.4
webserve] (此為組名為自定義 命名)
192.168.60.3
192.168.60.5
192.168.60.6
將上述IP地址添加到主機清單配置文件的最后一行就可以了。
ansible系列命令 (查看ansible里的各個模塊的使用方法)
ansible-doc: 顯示模塊幫助
-a 顯示所有模塊的文檔
-l, –list 列出可用模塊
-s, –snippet 顯示指定模塊的playbook片段
示例:
ansible-doc –l 列出所有模塊
ansible-doc ping 查看指定模塊(ping)幫助用法
ansible-doc –s ping 查看指定模塊(ping)幫助用法
如何使用ansible
1 實現基于key的公鑰驗證:(基于key的驗證可以在裝系統時寫進腳本,裝完系統后就可以實現了)
生成私鑰對,之后再將其公鑰發送到各臺服務器上的指定位置就可以了:
ssh-keygen -t rsa (生成密鑰)
ssh-copy-id 192.168.60.5 (發送密鑰,如需要批量發送公鑰文件到多臺主機查看第九周的博客)
小結:如果不實現基于key的驗證,則每次使用ansible操作遠程服務器時都需要輸入密碼,而且需要所有服務器的密碼是相同的,如果一組當中有一個服務器的密碼不同,第一次連不上,改成相同的密碼后還是會連不上的,除非單獨先連接一次此IP的地址讓他的密鑰加進/root/.ssh/know_host里面,或者將know_host里的內容刪掉。因為是基于ssh的連接。
ansible <host-pattern> [-m module_name] [-a args]
-m module 指定模塊,默認為command (使用command模塊時可以不用寫commmand )
-v 詳細過程 –vv -vvv更詳細
–list-hosts 顯示主機列表,可簡寫—list
-k, –ask-pass 提示連接密碼,默認Key驗證
-K, –ask-become-pass 提示輸入sudo
-C, –check 檢查,并不執行 (檢查語法是否有錯并不執行,在執行playbook劇本前使用)
-b, –become 代替舊版的sudo 切換
-T, –timeout=TIMEOUT 執行命令的超時時間,默認10s
-u, –user=REMOTE_USER 執行遠程執行的用戶
匹配主機的列表 :
ansible "192.168.60.5" -m command -a 'ls /root' (此為一個命令的示例)
All :表示所有Inventory(主機列表)中的所有主機
ansible all –m ping
* :通配符
ansible “*” -m ping (*代表所有)
ansible 192.168.1.* -m ping (匹配后面的一部分)
ansible “*srvs” -m ping (匹配組名的一部分)
或關系
ansible “websrvs:appsrvs” -m ping (取兩個組的中IP地址的合集)
ansible “192.168.1.10:192.168.1.20” -m ping (兩個IP地址都ping)
與的關系
ansible “websrvs:&dbsrvs” –m ping( 在websrvs組并且在dbsrvs組中的主機)
邏輯非
ansible ‘websrvs:!dbsrvs’ –m ping (在websrvs組,但不在dbsrvs組中的主機 )
ansible命令執行過程 ?
1. 加載自己的配置文件 默認/etc/ansible/ansible.cfg ?
2. 加載自己對應的模塊文件,如command ?
3. 通過ansible將模塊或命令生成對應的臨時py文件,并將該 文件傳輸至遠程服務器 的對應執行用戶$HOME/.ansible/tmp/ansible-tmp-數字/XXX.PY文件 ?
4. 給文件+x執行 ?
5. 執行并返回結果 ?
6. 刪除臨時py文件,sleep 0退出
執行狀態: ?(通過顏色來判斷執行的結果)
綠色:執行成功并且 沒有對目標主機進行更改操作?
黃色:執行成功并且對目標主機做變更 ?
紅色:執行失敗
ansible常用模塊及其具體用法:
1 . Command模塊:在遠程主機執行命令的模塊,此模塊為默認模塊可以不用加 -m選項
此命令不支持 $VARNAME < > | ; & 等,用shell模塊實現
2 . Shell模塊:ansible all -m shell -a '要執行的命令' ,可以執行bash里的所有命令,可添加各種符號。
3 . Script:運行腳本的模塊
ansible all -m script -a f1.sh (腳本加上執行權限后,寫上絕對路徑)
4 . Copy: 從主控端復制文件到眾多的操控端服務器的模塊
ansible all -m copy -a "src=/root/f1.sh dest=/data/f2.sh owner=wang mode=600 backup=yes"
src:為源文件 dest:為要復制到的地方 owner:設置所有者 mode:文件的權限設置
backup=yes 如果不等于yes,如果此處與源文件有相同的文件,則會覆蓋掉;相反的化backup=yes如果此處有與源文件相同的文件,會自動將此文件加上日期并改名后備份,源文件在復制到此處。
4.1 Fetch:從客戶端取文件至服務器端,copy相反,目錄可先用tar打包后再抓取
ansible all -m fetch -a ‘src=/root/(要抓取的文件) dest=/data/(抓取后存放的位置)
5 . Cron:計劃任務任務模塊:
支持時間:minute,hour,day,month,weekday
創建任務 計劃任務:
ansible all -m cron -a “minute=*/5 job=‘/usr/sbin/ntpdate 172.16.0.1 &>/dev/null’ name=jobss1”
其他的時間不寫默認為*(“每”的意思)命令要寫全他在的路徑 例如/bin/touch f1
刪除計劃任務 :
ansible all -m cron -a ‘ name=jobss1 state=absent ’
state=absent (state為狀態 absent 刪除)
name=jobss1 (為要刪除的計劃任務的名字,新建計劃任務定義的名字)
6 . File模塊:設置文件屬性 (對文件來操作,刪除,新建,軟連接)
ansible all -m file -a "name=/root/a.sh state=touch owner=wang mode=755“ :新建文件
ansible all -m file -a ‘src=/app/testfile dest=/app/testfile-link state=link’ 兩個文件建立硬鏈接
state=touch (新建文件)
state=directory (新建文件夾)
state=line (建立鏈接)
stste=absent (刪除文件和文件夾以及鏈接)
具體及詳細信息請查看幫助:ansible-doc -s file (前面為固定模式,后面為模塊的名稱)
7 . Yum模塊:管理包
ansible all -m yum -a ‘name=httpd state=latest’ 使用yum模塊安裝httpd軟件 ?
ansible all -m yum -a ‘name=httpd state=absent’ 使用yum模塊刪除 httpd軟件
ansible all -m yum -a 'name=/data/vftpd 3.0-27………………rpm' 安裝單個rpm包。不依賴于yum倉庫,但需要推送到每個被控端的主機。
8 . Service模塊:管理服務 (啟動,暫停,重啟服務)
ansible all -m service -a 'name=httpd state=stopped' ? (停止服務)
ansible all -m service -a 'name=httpd state=started' ? (開啟服務)
ansible all –m service –a ‘name=httpd state=reloaded’ ?(重新加載此服務)
ansible all -m service -a 'name=httpd state=restarted' ? (重啟此服務)
9 . User模塊:管理用戶 ?
ansible all -m user -a 'name=user1 comment=“test user” uid=2048 home=/app/user1 group=root‘新建用戶 最簡單的用法:ansible all -m user -a 'name=user2'
name:名字 comment: 屬于測試語句可以不用寫的 uid:uid號 home:家目錄 group:屬組
ansible all -m user -a 'name=sysuser1 system=yes home=/app/sysuser1 '?
system=yes:意思時創建系統用戶
ansible all -m user -a 'name=user1 state=absent remove=yes' :刪除用戶
10 . Group:管理組
ansible srv -m group -a "name=testgroup system=yes“ ?
ansible srv -m group -a "name=testgroup state=absent"
11. 解壓文件的模塊
name: Extract invault-wallet.tar.gz to /opt/software/openresty/nginx/html/invault
unarchive:
src: /home/centos/release_static/mainnet/invault-wallet.tar.gz (源文件)
dest: /opt/software/openresty/nginx/html/invault (目標文件)
owner: "{{ file_user }}" (文件的所有者,在執行playbook時傳遞變量的值)
group: "{{ file_user }}" (文件的所有組變量,在執行playbook時傳遞變量的值)
become: true (切換到root去執行此命令)
become_method: su
become_user: root
when: backup_result is succeeded or backup_path_result.stat.exists == True
12. 判斷文件是否存在的模塊:
– name: Check backup path exists or not
stat:
path: /opt/software/openresty/nginx/html/invault{{ ansible_date_time.date }}
register: backup_path_result
become: true
become_method: su
become_user: root
此文件需要切換到root用戶去查看
Ansible-playbook (劇本的介紹和寫法)注意格式的縮進會使playbook報錯。如果找不到報錯的原因注意查看劇本的格式縮進。
playbook的編寫及格式:
首先劇本的名字一般要以.yml為結尾 ;然后內容的開頭第一行應該時3個橫杠 – – – (可以不用寫也行)
具體的格式書寫如下圖:
vim f1.yml
上圖為playbook的書寫方式;(上圖中應該是tasks寫錯了)
執行playbook:
ansible-playbook -C f1.yml (檢查劇本的執行,并不真實的來執行,只做檢查)
ansible-playbook f1.yml : 執行此playbook劇本 (可以不需要加執行權限)
使用#號注釋代碼 ? 縮進必須是統一的,不能空格和tab混用 ?
縮進的級別也必須是一致的,同樣的縮進代表同樣的級別,程序判別配置的級別是通過縮進結 合換行來實現的
執行playbook時傳遞變量參數值:
ssh centos@52.74.137.28 '/usr/bin/ansible-playbook /home/centos/playbook/mainnet/tomcat/release-mainnet.yml –extra-vars \
"targets=tomcat-b-03-group user=centos child_project=invault-account-tomcat war_name=invault-account.war" -f 10'
ssh centos@52.74.137.28 :首先從Jenkins上連接到ansible上去執行已經寫好的劇本,前提是做好免密登錄。
–extra-vars :傳遞參數的設置,后面跟要傳遞的playbook里引用的變量的值
-f 10 : 并行執行的進程數。
具體的各部分信息及介紹:
Hosts 執行的遠程主機列表 ?
playbook中的每一個play的目的都是為了讓某個或某些主機以某個指定的用戶 身份執行任務。hosts用于指定要執行指定任務的主機,須事先定義在主機清 單中 。
Websrvs:dbsrvs 兩個組的并集 ?
Websrvs:&dbsrvs 兩個組的交集 ?
webservers:!phoenix 在websrvs組,但不在dbsrvs組
也可以這樣使用:
ansible lv -m shell -a 'cat /etc/passwd' –limit 192.168.60.2 (只針對lv組中的單個主機來進行操控)
-v 顯示過程 -vv -vvv 更詳細
Tasks 任務集
playbook里的模塊命令如果執行過一次有些情況下不會再次去執行的例如:yum安裝包,如果已經跑過一遍的劇本第二次再執行一遍的話,默認就不會再安裝一遍了。某些服務啟過之后,也不會再次重啟的。
案例:
示例:httpd.yml
– hosts: websrvs
remote_user: root
tasks:
– name: Install httpd
yum: name=httpd state=present (安裝工具包)
– name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/ (復制配置文件)
– name: start service
service: name=httpd state=started enabled=yes (啟動服務)
在此案例中如果將安裝工具的配置文件做了修改后,再次執行此劇本,過程是:包已經安裝過了,不會再安裝了,配置文件更改了會再次執行一次將原來的文件覆蓋掉,最后一步,服務已經起來了,則不會再次執行了,所以問題是:修改的配置文件無法讓其生效了。接下來就需要用到標記的模塊了具體如何使用請看下面的介紹:
handlers和notify結合使用觸發條件 :具體請看下面示例:
httpd.yml
– hosts: websrvs
remote_user: root
tasks:
– name: Install httpd
yum: name=httpd state=present (安裝工具包)
– name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/ (復制配置文件)
notify: restart httpd (在此處用notify做一下標記,如果發現此處再次執行或發生變化時)
– name: start service (會觸發下面的handlers的執行)
service: name=httpd state=started enabled=yes (啟動服務)
handlers: (在上面做的標記的地方 執行下面的命令)
– name: restart httpd
service: name=httpd status=restarted
一個notify對應handlers里的一個執行模塊,可以寫多個標記的notify,但是下面要對應的寫上他的執行模塊命令。
觸發多個:可以連續跟兩個notify,但handlers里的模塊,每個name下面只能跟一個。
tags (標簽)
再cation模塊后添加標簽后,執行劇本可以調用標簽的模塊單獨使用:案例如下:
ansible-playbook -t tags標記的描述 f1.yml (-t 選項時調用tags標簽的action ,-t 后面只跟tags后面的描述就可以了) 可以執行多個標簽,中間用逗號隔開。
Playbook中變量使用
變量名:僅能由字母、數字和下劃線組成,且只能以字母開頭
1 ansible setup facts 遠程主機的所有變量都可直接調用 ?
2 在/etc/ansible/hosts中定義 普通變量:主機組中主機單獨定義,優先級高于公共變量 公共(組)變量:針對主機組中所有主機定義統一變量 ?
3 通過命令行指定變量,優先級最高 ,其次是playbook里,最后是主機列表清單里。
變量的定義及使用:
系統自帶的變量:通過查看系統內部的setup模塊:ansible all -m setup
在文件里定義變量然后調用:
1 . 新建一個name .yml的文件,在里面定義變量如:
var1: hhh
var2: tttt
2. 在新建一個playbook,并調用剛才添加在文件里的變量 : test.yml
– – –
– hosts: all
remote_user: root
var_files: (引用文件的變量,格式單詞必須寫成這樣)
– name.yml (引用定義變量的文件,如果劇本和定義變量的文件在同一個目錄下則不需要寫路徑)
(如果在不同目錄下,引用定義變量的文件需要寫全路徑)
tasks:
-name: touch file (模塊的描述信息)
file: name=/data/{{ var1 }} state=touch (新建文件的模塊命令,新建的文件名調用變量var1的賦值)
執行劇本:ansible-playbook test.yml 執行結果為在all所有被控主機上新建了/data/hhh 的文件
在命令行里的定義和使用:(直接在命令行里定義,和引用)
ansible all -e var1=dddd -m shell -a 'touch /data/{{ var1 }}'
-e 為選項后面只能跟一個定義的變量,如果需要定義多個變量,在后面再添加一個-e然后定義變量就可以
在playbook中定義 變量 :
4 在playbook中定義
vars:
– var1: value1
– var2: value2
引用shell命令結果的變量:
例子:
– hosts: all
remote_user: root
tasks:
– name: Test
shell: date -d "-1 day" +%F (shell命令取值)
register: test1 (將取到的值傳遞給test1)
– name: touch file
shell: touch /data/{{ test1.stdout }}/tets33 (引用test1的變量必須要這種方式來引用)
執行的結果就是可以查找到昨天的日期并在目錄下創建文件
模板templates (templates文件夾下的模板文件不能再單個ansible里調用,只能在playbook里用)
template:算是一個模板的模塊,能夠將自己定義的模板文件復制到,所需要模板文件的地方:
src:為源文件 dest:為目標要復制的文件 (此模塊可以實現復制功能)
使用jinja2的語言,
一般和playbook文件同級的目錄下創建一個模板文件夾(templates),然后將模板文件寫在此文件夾下,并且模板文件的后綴名為.j2
下面一個示例來調用templates文件夾下的模板文件:(以nginx的服務為例)
本機裝好nginx服務并將配置文件推送到被控斷的主機上。
1 . 將nginx的配置文件拷貝到templates文件夾下,然后修改文件名添加后綴.j2
cp /etc/nginx/nginx.conf templates/nginx.conf.j2 (后綴必須添加j2)
2.編寫腳本調用templates里的模板文件:
vim testtemplate.yml
– – –
– hosts: all
remote_user: root
tasks:
– name: install package
yum: name=nginx
– name: copy template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf (調用模板文件,將temlpates下的模板)
– name: start service (文件復制到新裝的nginx下的配置文件)
sevice: name=nginx state=started enabled=yes (啟用服務,且永久啟用)
when :?(條件測試語句)
在task后添加when子句即可使用條件測試;when語句支持Jinja2表達式語法
例如:
執行此劇本的結果是:如果系統的主版本是7則會創建此文件,如果是六的話則會跳過不會創建此文件。
具體執行結果如下圖所示:
register :標記上一次執行結果,作為下一次執行的條件的判斷,執行的結果一般為jesion格式的數據
案例:
– name: set
shell: date -d "-1 day" +%F
register: yesterday
– name: Check today backup path exists or not
stat:
path: /home/{{ user }}/backup/{{ child_project }}/{{ ansible_date_time.date }}/{{ war_name }}
register: backup_path_result (將上面shell模塊執行的結果傳遞到 backup_path_result 里去)
– name: check yestady backup path exit or not (判斷文件是否存在的模塊)
stat:
path: /home/{{ user }}/backup/{{ child_project }}/{{ yesterday.stdout }}/{{ war_name }}
register: yestady_backup_path_result (將上面shell模塊執行的結果傳遞到 backup_path_result 里去)
when: backup_path_result.stat.exits == False (執行此模塊的條件是在backup_path_result.stat.exits為錯誤的時候)
– name: Stop tomcat
shell: setsid /bin/sh -i -c "/opt/{{ child_project }}/bin/stop.sh"
register: stop_result
when: backup_path_result.stat.exists == True or yestady_backup_path_result.stat.exits == True (多個條件的組合判斷)
在命令行傳遞參數,然后在主機列表里添加密碼切換用戶的模塊:
– name: roll-back-today
shell: /usr/bin/mv -f /opt/software/openresty/nginx/html/invault{{ ansible_date_time.date }} /opt/software/openresty/nginx/html/invault
become: true
become_method: su
become_user: root
when: backup_path_result.stat.exists == True
vim /etc/ansible/hosts
ansible-vault edit hosts (另一種打開此文件的方式,由于里面存放密碼所以對文件進行了加密,只有這樣可以打開)
[web-a-group]
web-01 ansible_port=65522 ansible_host=10.0.1.11 ansible_become_user=root ansible_become_pass=UL1PFZoMctplTuW0
[web-b-group]
web-02 ansible_port=65522 ansible_host=10.0.2.11 ansible_become_user=root ansible_become_pass=UL1PFZoMctplTuW0
在劇本里修改文件權限的方法,直接在外邊傳遞playbook的變量參數的值即可:
ssh centos@52.74.137.28 'ansible-playbook /home/centos/playbook/mainnet/wallet/release_wallet.yml –extra-vars "targets=web-a-group user=centos file_user=www" -f 10'
src: /home/centos/release_static/mainnet/invault-wallet.tar.gz
dest: /opt/software/openresty/nginx/html/invault
owner: "{{ file_user }}"
group: "{{ file_user }}"
become: true
become_method: su
become_user: root
(當在playbook里新建或者解壓文件時,切換到root操作,root就有權限來修改文件的所有者,只需在執行playbook時傳遞一個參數來更改文件的所有者就可以了)
迭代:with_items
當有需要重復性執行的任務時,可以使用迭代機制
對迭代項的引用,固定變量名為”item“
要在task中使用with_items給定要迭代的元素列表
列表格式:
字符串
字典
下面為一個案例:
– name: add several users
user: name={{ item }} state=present groups=wheel (創建用戶,及指定組名,引用變量元素列表)
with_items: (此表頭只是就是這樣寫,寫成其他的變量則執行會失?。?/span>
– testuser1
– testuser2
使用迭代讓其循環創建用戶。
迭代嵌套子變量
roles
將各個命令模塊分散單獨存放到一個劇本中,然后組和調用:
這樣做的目的使效率大大提高,重復的的命令模塊不用再次編寫,只需要調用就可以了。
以下具體案例:(官方建議目錄在/etc/ansible/下就有roles文件夾,不強制要求使用)
1 .目錄結構:找個文件夾例如:f1 在里面建一個roles的文件夾
2 .進到roles目錄下在創建目錄nginx(此目錄為安裝此應用單獨分開的)
3 . 進到nginx目錄下在創建各個使用模塊的目錄:tasks和templates的目錄
4 . 進到tasks目錄下去創建單個模塊命令的playbook:
如: group.yml; user.yml; yum.yml ;
vim group.yml
– name: create group (模塊功能描述)
group: name=nginx (創建組)
第一個創建組的劇本就寫好了,如上所示來創建第二個命令模塊,第三個命令模塊,等 ;每個命令模塊只執行一條命令。
vim user.yml
– name: create user
user: name=nginx group=nginx system=yes (system=yes的意思是創建系統賬號,而不是普通賬號)
此創建用戶的劇本也寫完了。
vim
– name: install package
yum: name=nginx
此安裝包的劇本也寫完了。
vim start service
– name: start service
service: name=nginx enabled=yes
此啟動服務的劇本也寫完了
最后在創建總的劇本來決定這些子劇本執行的先后順序:
vim main.yml
– include: group.yml
– include: user.yml
– include: yum.yml
– include: start.yml
此總劇本也創建完了。
最后創建一個playbook調用總劇本,此playbook應該和roles文件夾是平級的。
返回到f1文件夾下,創建nginx的安裝playbook
vim nginxrole.yml
– – –
– hosts: all
retome_user: root
roles:
– role: nginx
開始測試此劇本,安裝nginx服務。到此roles已經完成了。
此目錄結構為:
.
├── nginxroles.yml
└── roles
└── nginx
└── tasks
├── group.yml
├── main.yml
├── start.yml
├── user.yml
└── yum.yml
本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/99680