簡介展開目錄
- Ansible 是一款基於 python 開發的自動運維工具,實現了批量系統配置、批量運行命令、批量程序部署等功能。
- Ansible 是模塊化工作,它本事沒有部署能力,它只是一個提供了一個框架,真正起作用的是它的模塊。
- Ansible 不需要在遠程主機上安裝任何客戶端或者代理端,因為它是基於 SSH 進行遠程連接。
注意
環境展開目錄
| 主機名 | IP | 系統 | 角色 |
| ansible-1 | 192.168.137.194 | CentOS 7 | Ansible |
| ansible-2 | 192.168.137.195 | CentOS 7 | node |
| ansible-3 | 192.168.137.196 | CentOS 7 | node |
部署展開目錄
- ansible-1 下載 Ansible 工具
-
yum -y install epel-release
-
yum -y install ansible

- ansible 配置文件幾個常用的地方
- #inventory = /etc/ansible/hosts ## 主機列表配置文件
- #library = /usr/share/my_modules/ ## 模塊存放目錄
- #remote_tmp = ~/.ansible/tmp ## 臨時 py 文件存放在遠程主機目錄
- #local_tmp = ~/.ansible/tmp ## 本機的臨時執行目錄
- #forks = 5 ## 默認並發數
- #sudo_user = root ## 默認 sudo 用戶
- #remote_port = 22 ## 遠程主機端口
- #host_key_checking = False ## 跳過檢查主機指紋
- log_path = /var/log/ansible.log ##ansible 日志
主機列表的兩種配置方式展開目錄
- 基於密碼鏈接
注意
- 基於密碼鏈接需要把密碼寫到配置文件,這樣做其實很危險;
- 密碼一般都會定期更換,維護成本高;
- 需要將 ansible.cfg 里面的 '#host_key_checking = False
' 注釋取消掉
-
[root@ansible -1 ~]# sed -i '/host_key_checking/s/#//' /etc/ansible/ansible.cfg
-
[root@ansible -1 ~]# mv /etc/ansible/hosts /etc/ansible/hosts.bak ##養成備份的習慣
-
cat > /etc/ansible/hosts << eof
-
[test]
-
192.168.137.195 ansible_ssh_pass='123456'
-
192.168.137.196 ansible_ssh_pass='123456'
-
eof
- 測試
-
[root@ansible -1 ~]# ansible test -m ping

- 基於密鑰鏈接
- 免密互信
-
[root@ansible -1 ~]# ssh-keygen ##一直回車即可,生成密鑰對
-
[root@ansible -1 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.137.195 ##將公鑰發送給其他服務器
-
[root@ansible -1 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.137.196

- 測試
-
[root@ansible -1 ~]# ansible test -m ping

幫助手冊展開目錄
- 查看所有模塊及其簡介
-
[root@ansible -1 ~]# ansible-doc -l
-
[root@ansible -1 ~]# ansible-doc -l | grep shell ##這里查看shell模塊

- 查看指定模塊比較詳細的說明及舉例
-
[root@ansible -1 ~]# ansible-doc template ##這里查看 'template' 模塊
- 查看指定模塊的參數及簡介
-
[root@ansible -1 ~]# ansible-doc -s template ##這里查看 'template' 模塊
Ansible 命令部分參數介紹展開目錄
- '-h' 參數可以查看 Ansible 所有的參數及對應的介紹
-
[root@ansible -1 ~]# ansible -h
- '-m' 指定模塊,如果不指定模塊默認使用 command
-
[root@ansible -1 ~]# ansible test -m ping

- '-a' 參數指定模塊要執行的具體命令
-
[root@ansible -1 ~]# ansible test -m command -a 'date'

- '-f' 並行任務數,默認為 5
-
[root@ansible -1 ~]# ansible test -m command -a 'date' -f 10

- '-i' 指定主機清單位置,默認為 /etc/ansible/hosts
- 在 /opt 下創建一個新的測試主機清單,只添加一個主機
-
[root@ansible -1 ~]# echo -e '[test2]\n192.168.137.196' > /opt/hosts
-
[root@ansible -1 ~]# ansible -i /opt/hosts test2 -m ping

- '--list-hosts' 列出主機組里的主機
-
[root@ansible -1 ~]# ansible test --list-hosts

- '-o' 將輸出結果壓縮成一行
-
[root@ansible -1 ~]# ansible test -m ping -o

- '-v' '-vv' '-vvv' -'vvvv' 更詳細的輸出結果,v 越多越詳細
-
[root@ansible -1 ~]# ansible test -m ping -vv

Ansible 部分模塊介紹展開目錄
setup 模塊展開目錄
- 用於統計遠程主機的相關信息
-
[root@ansible -1 ~]# ansible -i /opt/hosts test2 -m setup ##因為太多了這里僅查看"ansible-3"的信息

ping 模塊展開目錄
- 用於遠程主機的連通性測試
-
[root@ansible -1 ~]# ansible test -m ping

command 模塊展開目錄
注意
- 該模塊常用命令
- chdir:執行命令前先切換到 chdir 指定的目錄,如果這個目錄不存在則命令不執行並報錯
-
[root@ansible -1 ~]# ansible test -m command -a 'chdir=/opt/test ls' #因為遠程主機上沒有/opt/test目錄,所以如圖顯示報錯
-
[root@ansible -1 ~]# ansible test -m command -a 'chdir=/opt ls' ##遠程主機上有/opt目錄,執行成功,只是里面原本就沒東西

- creates:如果目標文件存在,則后面的命令不執行
-
[root@ansible -1 ~]# ansible test -m command -a 'creates=/opt/a.txt ls /opt' ##因為/opt/a.txt不存在,所以后面的'ls /opt'才能執行
-
[root@ansible -1 ~]# ansible test -m file -a 'path=/opt/a.txt state=touch' ##現在創建/opt/a.txt模擬a.txt存在的情況
-
[root@ansible -1 ~]# ansible test -m command -a 'creates=/opt/a.txt ls /opt' ##可以看到提示/opt/a.txt已經存在,直接跳過后面的命令

- removes:如果目標文件存在,則后面的命令執行
-
[root@ansible -1 ~]# ansible test -m command -a 'removes=/opt/a.txt ls /opt' ##/opt/a.txt存在,則輸出后面的'ls /opt'
-
[root@ansible -1 ~]# ansible test -m file -a 'path=/opt/a.txt state=absent' ##把/opt/a.txt刪掉模擬a.txt不存在的情況
-
[root@ansible -1 ~]# ansible test -m command -a 'removes=/opt/a.txt ls /opt' ##由於a.txt已經被刪了,所以顯示跳過'ls /opt'命令

提醒
shell 模塊展開目錄
- 調用遠程主機的 shell 解釋器,基本上 shell 能用的命令這里都能用,不過 shell 用不了的這里也用不了,比如 'll' 命令
-
[root@ansible -1 ~]# ansible test -m shell -a 'll /opt'

- 不過可以將 'll' 命令替換為 'ls -l'
-
[root@ansible -1 ~]# ansible test -m shell -a 'ls -l /opt'

file 模塊展開目錄
- 常用命令
- path:文件的路徑
- group:定義文件的所屬組
- owner:定義文件的所屬者
- mode:定義文件的權限
- recurse:遞歸,用於目錄上,就是 '-R'
- src:源文件路徑
- dest:目標文件路徑
- state:
~ directory: 如果目錄不存在則創建目錄
~ file:返回目標文件的屬性及狀態,也可以用來判斷文件存在與否
~ link:創建軟連接
~ hard:創建硬鏈接
~ touch:如果目標文件不存在則創建,存在的話就會更新其最近修改時間
~ absent:刪除目標文件
- 舉例
- 在 /opt 下創建一個 test-1.txt
-
[root@ansible -1 ~]# ansible test -m file -a 'path=/opt/test-1.txt state=touch'
-
[root@ansible -1 ~]# ansible test -m shell -a 'ls /opt'

- 更改 /opt/test-1.txt 文件的所屬主,所屬組以及權限
-
[root@ansible -1 ~]# ansible test -m file -a 'path=/opt/test-1.txt group=nobody owner=nobody mode=666'
-
[root@ansible -1 ~]# ansible test -m shell -a 'ls -l /opt'

- 創建軟連接 /opt/fstab 鏈接到 /etc/fstab
-
[root@ansible -1 ~]# ansible test -m file -a 'src=/etc/fstab dest=/opt/fstab state=link'
-
[root@ansible -1 ~]# ansible test -m shell -a 'ls -l /opt'

- 刪除鏈接文件 /opt/fstab
-
[root@ansible -1 ~]# ansible test -m file -a 'path=/opt/fstab state=absent'
-
[root@ansible -1 ~]# ansible test -m shell -a 'ls /opt'

copy 模塊展開目錄
- 常用命令
- src:被復制到遠程主機的本地文件,如果是目錄則會遞歸復制
- dest:將 src 的本地文件復制到遠程主機的目標位置
- content:可以代替 src,類似於 echo,直接將文本內容復制到遠程主機的目標文件上
- backup:備份
~ yes:開啟備份,備份文件名包含時間信息,原文件有變動才會進行備份
~ no:不備份 - directory_mode:遞歸設定目錄的權限
- force:強制覆蓋
~ yes:如果目標位置已經存在同名文件,但內容不同,也進行強制覆蓋
~ no:目標位置不存在該文件才進行覆蓋
- 舉例
- 現在本機 ansible-1 中 /opt 下新建一個 test-2.txt 文件
-
[root@ansible -1 ~]# touch /opt/test-2.txt
- 將本機 ansible-1 中 /opt/test-2.txt 復制到遠程主機上的 /opt 下
[root@ansible-1 ~]# ansible test -m copy -a 'src=/opt/test-2.txt dest=/opt'
[root@ansible-1 ~]# ansible test -m shell -a 'ls /opt'

- 用 'content' 命令將文本 'hello' 覆蓋到遠程主機 /opt/test-2.txt 中並備份原文件
-
[root@ansible -1 ~]# ansible test -m copy -a 'content="hello" dest=/opt/test-2.txt backup=yes'
-
[root@ansible -1 ~]# ansible test -m shell -a 'ls /opt'
-
[root@ansible -1 ~]# ansible test -m shell -a 'cat /opt/test-2.txt'

template 模塊展開目錄
- 這個模塊用於將模版文件渲染后,輸出到遠程主機上,模版文件一般以.j2 為結尾,標識其是一個 jinja2 模版文件
- 常用命令
- src:模板文件路徑
- dest:遠程主機對應文件路徑
- mode:權限
- attributes:特殊權限,類似於 chattr
- force:覆蓋
- owner:所屬者
- group:所屬組
- 舉例
- 現在本地(ansible-1)上 /opt 下創建一個 jinja2 模板文件 test.j2
-
cat > /opt/test.j2 << eof
-
{% if ansible_hostname == a %}
-
我的主機名是: {{ a }}
-
{% elif ansible_hostname == b %}
-
我的主機名是:{{ b }}
-
{% endif %}
-
eof
- 再在 /opt 下創建一個 yml 文件 test.yml
-
cat > /opt/test.yml << eof
-
---
-
-
vars:
-
-
-
tasks:
-
-
template:
-
src: /opt/test.j2
-
dest: /opt/test-3.txt
-
eof
- 執行 yml 文件
-
[root@ansible -1 ~]# ansible-playbook /opt/test.yml

-
[root@ansible -1 ~]# ansible test -m shell -a 'cat /opt/test-3.txt'

fetch 模塊展開目錄
- 該模塊被用來從遠程主機復制文件到本地主機
- 常用命令
- src:源文件,遠程主機上的文件路徑
- dest:目標位置,本地主機上的路徑
- 舉例
- 將遠程主機上 /var/log/messages 日志復制到本地主機 /opt 下
-
[root@ansible -1 ~]# ansible test -m fetch -a 'src=/var/log/messages dest=/opt'
-
[root@ansible -1 ~]# ls /opt

user 模塊展開目錄
- 常用命令
- name:用戶名
- home:指定用戶家目錄
- move_home:將用戶家目錄移動到指定位置
- groups:用戶所屬組
- force:配合 state=absent 強制刪除用戶
- uid:用戶的 uid
- password:用戶密碼
- remove:配合 state=absent 使用,將用戶及用戶目錄下的文件全部刪除
- shell:指定 shell
- comment:用戶信息描述
- system:是否為系統用戶
- state:狀態
~ present:創建用戶,默認為 present
~ absent:刪除用戶
- 舉例
- 創建一個名為 hz,uid 為 6666,密碼為 123456,shell 為 /sbin/nologin 的用戶
-
[root@ansible -1 ~]# ansible test -m user -a 'name=hz uid=6666 password=123456 shell=/sbin/nologin'
-
[root@ansible -1 ~]# ansible test -m shell -a 'cat /etc/passwd | grep hz'

- 將 hz 用戶以及其家目錄的文件刪除
[root@ansible-1 ~]# ansible test -m user -a 'name=hz state=absent remove=yes'
[root@ansible-1 ~]# ansible test -m shell -a 'cat /etc/passwd | grep hz'

yum 模塊展開目錄
- 常用命令
- name:安裝包名
- disable_gpg_check:是否禁止 gpg_check
- disablerepo:臨時禁止某個 yum 源
- enablerepo:臨時使用某個 yum 源
- state:
~ present | installed:安裝
~ latest:安裝最新的
~ absent | removed:卸載
- 舉例
- 安裝 httpd
-
[root@ansible -1 ~]# ansible test -m yum -a 'name=httpd state=present'
-
[root@ansible -1 ~]# ansible test -m shell -a 'rpm -qa | grep httpd'

- 卸載 httpd
-
[root@ansible -1 ~]# ansible test -m yum -a 'name=httpd state=removed'
-
[root@ansible -1 ~]# ansible test -m shell -a 'rpm -qa | grep httpd'

service 模塊展開目錄
- 常用命令
- name:服務名
- enabled:設置開機自啟
- state:
~ started:啟動服務
~ stopped:停止服務
~ restarted:重啟服務
~ reloaded:重載配置
- 舉例
- 關閉防火牆
-
[root@ansible -1 ~]# ansible test -m service -a 'name=firewalld state=stopped'
-
[root@ansible -1 ~]# ansible test -m shell -a 'systemctl status firewalld'

- 打開防火牆
-
[root@ansible -1 ~]# ansible test -m service -a 'name=firewalld state=started'
-
[root@ansible -1 ~]# ansible test -m shell -a 'systemctl status firewalld'

unarchive 模塊展開目錄
- 這個模塊是用來解壓文件的
- 常用命令
- remote_src:默認為 no
~ yes:表示需要解壓的文件在遠程主機上
~ no:將會先將本地主機(ansible-1)上的壓縮包發送到遠程主機上再解壓 - src:源文件路徑,取決於 remote_src 的值,決定 src 是表示遠程主機的路徑還是本地主機的路徑
- dest:解壓到遠程主機的路徑
- exclude:解壓時排除指定的文件或目錄
- owner:指定文件解壓后的所屬者
- group:指定文件解壓后的所屬組
- mode:指定文件解壓后的權限
- 舉例
- 在本地主機(ansible-1)/opt 下准備一個壓縮包
-
[root@ansible -1 ~]# wget -P /opt http://nginx.org/download/nginx-1.20.1.tar.gz
- 發送到遠程主機並解壓到 /opt 下
-
[root@ansible -1 ~]# ansible test -m unarchive -a 'src=/opt/nginx-1.20.1.tar.gz dest=/opt'
-
[root@ansible -1 ~]# ansible test -m shell -a 'ls /opt'

get_url 模塊展開目錄
- 用來從網絡上下載數據
- 常用命令
- url:文件的下載地址
- dest:文件保存的絕對路徑
- mode:文件的權限
- backup:如果本地已有同名的數據,是否備份
- timeout:下載的超時時間
- 舉例
- 在遠程主機上 /opt 下下載 nginx 壓縮包
-
[root@ansible -1 ~]# ansible test -m get_url -a 'url=http://nginx.org/download/nginx-1.20.1.tar.gz dest=/opt'
-
[root@ansible -1 ~]# ansible test -m shell -a 'ls /opt'

PlayBook展開目錄
簡介展開目錄
playbook 由 yaml 語言編寫,ansible 的模塊其實類似於 linux 下的命令,而 playbook 其實就類似於 shell 腳本,這樣就可以將原本一條條的 ansible 命令整合成一個 playbook 以方便解決一些過於復雜的操作。
格式展開目錄
- yaml 腳本對格式有着很嚴格的要求
- YMAL 中的列表元素以”-” 開頭然后緊跟着一個空格,后面為元素內容。
- 同一個列表中的元素應該保持相同的縮進。否則會被當做錯誤處理。
- hosts,variables,roles,tasks 等對象的表示方法都是鍵值中間以 ":" 分隔表示,":" 后面還要增加一個空格。
- 例如:下面是一個 yum 安裝 httpd 然后啟動並設置開機自啟的 yml 腳本,將其放到本地主機(ansible-1)上的 /opt 下並命名為 httpd.yml
注意
-
---
-
- hosts: test #必須指定hosts,可以使用通配符格式,使用 hosts 指示使用哪個主機或主機組來運行下面的 tasks
-
tasks: #指定遠端主機將要執行的一系列動作。tasks 的核心為 ansible 的模塊,前面已經提到模塊的用法。
-
- name: install httpd #name雖然不是必須的,但是為了方便閱讀,還是建議加上去
-
yum:
-
name: httpd
-
state: present
-
- name: start httpd
-
service:
-
name: httpd
-
state: started
-
enabled: yes
- 然后執行
ansible-playbook /opt/httpd.yml可以看到已經運行成功了
ansible-playbook /opt/httpd.yml -C可以預執行命令,可以用來檢查語法,但運行結果並不准確,因為后面的步驟假如需要用到前面步驟作為依賴,預執行又不會實際產生數據,這樣會造成后面的步驟報錯

roles展開目錄
- 簡介
- roles 是為了層次化、結構化地組織 Playbook。
- roles 就是通過分別將變量、文件、任務、模塊及處理器放置於單獨的目錄中,並可以便捷地 include 它們。
- roles 一般用於基於主機構建服務的場景中,在企業復雜業務場景中應用的頻率很高。
- 以特定的層級目錄結構進行組織的 tasks、variables、handlers、templates、files 等;相當於函數的調用把各個功能切割成片段來執行。
- 創建一個名為 test 的 roles
-
[root@ansible -1 ~]# cd /etc/ansible/roles/
-
[root@ansible -1 roles]# ansible-galaxy init test

-
[root@ansible -1 roles]# tree test/ ##roles的結構

提示
- roles 結構的介紹
- default:用於設定默認變量
- files:存儲由 copy 或 script 等模塊調用的文件
- tasks:用於定義各 task
- handlers:用於定義各 handler
- meta:定義當前角色的特殊設定及其依賴關系
- templates:存儲由 template 模塊調用的模板文本
- vars:用於定義各變量
- 模擬用 roles 為遠程主機用二進制安裝方式部署 mysql
- 先下載 mysql 二進制包到 /etc/ansible/roles/files 下
-
[root@ansible-1 test]# wget -P /etc/ansible/roles/test/files https://mirrors.aliyun.com/mysql/MySQL-5.7/mysql-5.7.34-linux-glibc2.12-x86_64.tar.gz
- 編寫 /etc/ansible/roles/tasks/main.yml
-
-
---
-
# tasks file for test
-
-
user:
-
name: mysql
-
state: present
-
-
-
unarchive:
-
src: mysql-5.7.34-linux-glibc2.12-x86_64.tar.gz
-
dest: /usr/local/
-
owner: mysql
-
group: mysql
-
-
-
shell: mv /usr/local/mysql-5.7.34-linux-glibc2.12-x86_64 /usr/local/mysql
-
-
-
file:
-
path: "{{ item }}"
-
state: directory
-
owner: mysql
-
group: mysql
-
recurse: yes
-
with_items:
-
-
-
-
-
-
template:
-
src: mysqlcnf.j2
-
dest: /etc/my.cnf
-
-
-
blockinfile:
-
path: /etc/profile
-
block: "export PATH=/usr/local/mysql/bin:$PATH"
-
notify:
-
-
-
-
shell: /usr/local/mysql/bin/mysqld --initialize-insecure --user=mysql --datadir=/data/mysql --basedir=/usr/local/mysql
-
-
-
shell: cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
-
-
-
file:
-
path: /etc/init.d/mysqld
-
mode: 0777
-
-
-
shell: /etc/init.d/mysqld start
-
eof
- 准備觸發器
這個觸發器是為了刷新環境變量,雖然語法沒問題但是實際沒生效,因為用 shell 解釋器刷新環境變量只會在 shell 解釋過程中生效,解釋完了回到原本的環境就失效了,目前我還沒找到合適的方法解決,就當復習下觸發器了![]()
-
[root@ansible-1 test]# cat > /etc/ansible/roles/test/handlers/main.yml << eof
-
---
-
# handlers file for test
-
- name: 刷新環境變量
-
shell: source /etc/profile
-
eof
- 准備數據庫配置的 jinja2 模板文件
-
[root@ansible-1 test] # cat > /etc/ansible/roles/test/templates/mysqlcnf.j2 << eof
-
{% if ansible_hostname == node1 %}
-
[mysqld]
-
user=mysql
-
basedir=/usr/local/mysql
-
datadir=/data/mysql
-
server_id={{ node1_id }}
-
log-error=/var/log/mysql/error.log #日志
-
port=3306
-
socket=/tmp/mysql.sock
-
[mysql]
-
socket=/tmp/mysql.sock
-
{% elif ansible_hostname == node2 %}
-
[mysqld]
-
user=mysql
-
basedir=/usr/local/mysql
-
datadir=/data/mysql
-
server_id={{ node2_id }}
-
log-error=/var/log/mysql/error.log #日志
-
port=3306
-
socket=/tmp/mysql.sock
-
[mysql]
-
socket=/tmp/mysql.sock
-
{% endif %}
-
eof
- 設置變量
-
[root@ansible-1 test] # cat > /etc/ansible/roles/test/vars/main.yml << eof
-
---
-
# vars file for test
-
node1: ansible-2
-
node2: ansible-3
-
node1_id: 7
-
node2_id: 8
-
eof
- 設置啟動文件
-
[root@ansible-1 test]# cat > /etc/ansible/roles/test/tasks/test.yml << eof
-
---
-
- hosts: test
-
roles:
-
- test
-
eof
- 運行整個 roles
-
[root@ansible -1 tasks]# ansible-playbook /etc/ansible/roles/test/tasks/test.yml

- 到遠程主機 'ansible-2' 檢驗
-
[root@ansible -2 ~]# cat /etc/my.cnf ##查看jinja模板有沒有生效
-
[root@ansible -2 ~]# source /etc/profile ##刷新環境變量,原因在上面
-
[root@ansible -2 ~]# mysql

- 到遠程主機 'ansible-3' 檢驗
-
[root@ansible -3 ~]# cat /etc/my.cnf ##查看jinja模板有沒有生效
-
[root@ansible -3 ~]# source /etc/profile ##刷新環境變量,原因在上面
-
[root@ansible -3 ~]# mysql

- 至此已經成功部署了 mysql
- Ansible 模塊豐富,以后遇到更重要的也會更新在這里![]()
