1、Ansible
-
什麼是ansible
Ansible是2013年推出的一款IT自動化和DevOps軟件,目前由Redhat已簽署Ansible收購協議。
其是基於Python研發,糅合了很多老運維工具的優點實現了批量操作系統配置,批量程序的部署,批量運行命令等功能
- Ansilbe可以讓我們實現
- – 自動化部署APP
- – 自動化管理配置項
- – 自動化的持續交付
- – 自動化的(AWS)雲服務管理
-
爲什麼要選Ansilbe
選擇一款配置管理軟件總的來說,無外乎從以下幾點來權衡利弊
- – 活躍度(社區活躍度) 高
- – 學習成本 低
- – 使用成本 低
- – 編碼語言 使用的python shell c 比較通用的
- – 性能 好
- – 使用是否廣泛 廣泛的
優點有
• ansible優點
– 是僅需要ssh和Python即可使用
– 無客戶端
• ansible功能強大,模塊豐富
• 上手容易門檻低
• 基於 python 開發,做二次開發更容易
• 使用公司比較多,社區活躍
缺點是
– 對於幾千臺、上萬臺機器的操作,還不清楚性能、效率情況如何,需要進一步瞭解。
Ansible特性?
• 模塊化設計,調用特定的模塊來完成特定任務
• 基於python語言實現
– paramiko 連接ssh的
– PyYAML (半結構化語言)
– jinja2
• 其模塊支持JSON等標準輸出格式,可採用任何編程語言重寫
• 部署簡單
• 主從模式工作
• 支持自定義模塊
• 支持playbook
• 易於使用
• 支持多層部署
• 支持異構IT環境
工作流程?
Ansible大體執行過程
Ansible安裝
軟件依賴關係
• 對管理主機
– 要求Python 2.6 或 Python 2.7
– ansible 使用了以下模塊,都需要安裝
– paramiko
– PyYAML
– Jinja2
– httplib2
– six
• 對於被託管主機
– Ansible默認通過 SSH 協議管理機器
– 被管理主機要開 ssh 服務,允許 ansible 主機登錄
– 在託管節點上也需要安裝 Python 2.5 或以上的版本
– 如果託管節點上開啓了SElinux,需要安裝libselinux-python
安裝ansible
安裝ansible
• ansible 可以基於源碼運行
• 源碼安裝
– pip,需要配置擴展軟件包源 extras
– git
yum install epel-release
yum install git python2-pip
– pip安裝依賴模塊
pip install paramiko PyYAML Jinja2 httplib2 six
• ansible 源碼下載
– git clone git://github.com/ansible/ansible.git
– yum install python-setuptools python-devel
– python setup.py build
– python setup.py install
• pip 方式安裝
– pip install ansible
• yum 擴展源安裝簡單,自動解決依賴關係(推薦)
– http://mirror.centos.org/.../.../extras/
– yum install ansible
• 安裝完成以後驗證
– ansible -version
練習
• 1、啓動6 臺虛擬機
• 2、禁用 selinux 和 firewalld
• 3、給主機命名,編輯 /etc/hosts
• 4、1臺作爲管理節點,其他爲託管主機
• 5、配置本地 yum 擴展源
• 6、在管理節點安裝 ansible
• 1、啓動6 臺虛擬機
創建虛擬磁盤文件
修改xml文件
定義xml文件
啓動虛擬機
• 2、禁用 selinux 和 firewalld
禁用selinux
停止firewalld
禁止開機自啓動
• 3、給主機命名,編輯 /etc/hosts
/etc/hostname
[root@ansible ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.10 ansible
192.168.1.11 web1
192.168.1.12 web2
192.168.1.13 db1
192.168.1.14 db2
192.168.1.15 cache
• 4、1臺作爲管理節點,其他爲託管主機
• 5、配置本地 yum 擴展源
創建一個目錄創建用於存放ansible的安裝包文件 cd /var/ftp/ansible
拷貝安裝文件到該目錄,後創建索引 createrepo .
配置ansible管理機器,添加repo文件
[ansible]
name=ansible
baseurl=ftp://192.168.4.254/ansible
enabled=1
gpgcheck=0
• 6、在管理節點安裝
在ansible管理機器上
yum clean all
yum install -y ansiblel
安裝完成以後執行,沒有報錯,正確顯示版本即可
ansible --version
ad-hoc主機管理
ad-hoc主機定義與分組
• 安裝好了 Ansible 之後就可以開始一些簡單的任務了
• Ansible配置文件查找順序
1、首先檢測 ANSIBLE_CONFIG 變量定義的配置文件
2、 其次檢查當前目錄下的 ./ansible.cfg 文件
[root@ansible ooxx]# vim ansible.cfg-------自定義配置文件
[defaults]
inventory = myhosts------自定義託管主機地址配置文件
host_key_checking= False----------------遠程時不用再輸入yes確認
- [root@ansible ooxx]# vim myhosts
- [app1]
- web1
- db1
- [app2]
- web2
- db2
- [app]
- cache
- [root@ansible ooxx]# ansible app1 --list-hosts
- hosts (2):
- web1
- db1
3、再次檢查當前用戶家目錄下 ~/ansible.cfg 文件
4、最後檢查 /etc/ansible/ansible.cfg 文件
• /etc/ansible/ansible.cfg -------------默認配置文件路徑
• vim /etc/ansible/ansible.cfg 配置文件
10 [defaults]
11
12 # some basic default values...
14 inventory = /etc/ansible/hosts--------– inventory 是定義託管主機地址配置文件 取消inventory的註釋
15 #library = /usr/share/my_modules/
16 #module_utils = /usr/share/my_module_utils/
17 #remote_tmp = ~/.ansible/tmp
18 #local_tmp = ~/.ansible/tmp
19 #forks = 5
20 #poll_interval = 15
21 #sudo_user = root
22 #ask_sudo_pass = True
23 #ask_pass = True
– 首先編輯 vim /etc/ansible/hosts 文件,寫入一些進程主機的地址。
43 ## db-[99:101]-node.example.com
44 [web]
45 web1
46 web2
47 [db]
48 db1
49 db2
50 [app:children]
51 web
52 db
53 [app:vars]
54 ansible_ssh_user="root"
55 ansible_ssh_pass="1"
56 [other]
57 cache ansible_ssh_user="root" ansible_ssh_pass="1"
• 格式
– # 表示註釋
[組名稱]
主機名稱或ip地址,登錄用戶名,密碼、端口等信息
• 測試
– ansible [組名稱] --list-hosts [組名稱寫到這裏也是可以]
ansible --list-hosts all
ansible cache -m ping
• inventory 參數說明
– 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”
• 分組定義、範圍定義樣例
[web]
web1
web2
[db]
db[1:2]
[cache]
192.168.1.16
[app1:children] 引用子組
web
db
子組怎麼用?
• 分組定義、範圍定義樣例(要打開主配置文件下的host_key_checking = False)
[web]
web[1:2]
[web:vars] 整個組進行定義和賦值
ansible_ssh_user="root" ansible_ssh_pass="pwd“
ansible_ssh_port="22"
[cache]
c01 ansible_ssh_user="root" ansible_ssh_pass="pwd"
• 自定義配置文件
– 創建文件夾 myansible (可以有很多文件夾配置很多ansible.cfg)
– 創建配置文件 ansible.cfg
[defaults]
inventory = myhost
– 配置主機文件
[nginx]
192.168.1.11
192.168.1.12
192.168.1.13
– ansible nginx --list-hosts
課堂練習
• 1、熟悉 ansible 配置文件
• 2、定義主機練習
• 3、定義分組練習
• 4、定義子組練習
• 5、自定義文件,多配置路徑練習
• 1、熟悉 ansible 配置文件
• 2、定義主機練習
• 3、定義分組練習
• 4、定義子組練習
• 5、自定義文件,多配置路徑練習
動態主機
• 無限可能
– Ansible Inventory實際上是包含靜態Inventory和動
態Inventory兩部分,靜態Inventory指的是在文件
/etc/ansible/hosts中指定的主機和組,Dynamic
Inventory指通過外部腳本獲取主機列表,並按照
ansible 所要求的格式返回給ansilbe命令的。
• json
– JSON的全稱是”JavaScript Object Notation”,意
思是JavaScript對象表示法,它是一種基於文本,獨立
於語言的輕量級數據交換格式。
• 注意事項:
– 1、主機部分必須是列表格式的;
– 2、hostdata行,其中的"hosts" 部分可以省略,但如果使用時,必須是"hosts"
• 腳本輸出主機列表
#!/usr/bin/python
import json
hostlist = {} 創建空監製對列表
hostlist["bb"] = ["192.168.1.15", "192.168.1.16"] 定義web組
hostlist["192.168.1.13"] = { 定義db組
"ansible_ssh_user":"root","ansible_ssh_pass":"pwd"
}
hostlist["aa"] = {
"hosts" : ["192.168.1.11", "192.168.1.12"],
"vars" : {
"ansible_ssh_user":"root","ansible_ssh_pass":"pwd"
}
}
print( json.dumps(hostlist))
• 腳本輸出樣例
{
"aa" : {
"hosts" : ["192.168.1.11", "192.168.1.12"],
"vars" : {
"ansible_ssh_user" : "root",
"ansible_ssh_pass" : "pwd"
}
},
"bb" : ["192.168.1.15", "192.168.1.16"],
"192.168.1.13": { "ansible_ssh_user" : "root",
"ansible_ssh_pass" : "pwd"}
}
課堂練習
• 腳本演示講解
• shell 腳本
• python 腳本
ad-hoc批量執行
Ansible命令基礎
• ansible <host-pattern> [options]
- – host-pattern 主機或定義的分組
- – -M 指定模塊路徑
- – -m 使用模塊,默認 command 模塊
- – -a or --args 模塊參數
- – -i inventory 文件路徑,或可執行腳本
- – -k 使用交互式登彔密碼
- – -e 定義變量
- – -v 詳細信息,-vvvv 開啓 debug 模式
• 列出要執行的主機,不執行任何操作
– ansible all --list-hosts
• 批量檢測主機
– ansible all -m ping
• 批量執行命令
– ansible all -m command -a 'id' -k
比如:
153 ansible all -m ping
154 ansible all -m 'command' -a 'uptime'
155 ansible all -m 'command' -a 'df -h'
156 ansible all -m 'command' -a 'free'
批量部署證書文件
• 每次交互輸入密碼比較麻煩
• 密碼寫入配置文件安全性很差
• 不同主機不同密碼,配置文件要上天
• 使用 key 方式認證,是一個不錯的選擇
• 給所有主機部署公鑰
– ansible all -m authorized_key -a "user=root
exclusive=true manage_dir=true key='$(<
/root/.ssh/authorized_keys)'" -k -v
• 1、創建一對密鑰 在管理主機的root/.ssh下 id_rsa是私鑰 id_rsa.pub是公鑰
ssh-keygen -t rsa -b 2048 -N ''---------- -t加密類型
• 2、給所有主機部署
ansible all -m authorized_key -a "user=root exclusive=true manage_dir=true key='$(< /root/.ssh/id_rsa.pub)'" -k
ansible all -m
authorized_key-------模塊
-a "user=root--------以root身份登陸
exclusive=true ------若源先
manage_dir=true------沒有文件就創建
key='$(< /root/.ssh/id_rsa.pub)'" --------將/root/.ssh/id_rsa.pub公鑰內容重定向輸入給key
-k
測試
• 報錯的話
– "msg": "Using a SSH password instead of a key is
not possible because Host Key checking is
enabled and sshpass does not support this.
Please add this host's fingerprint to your
known_hosts file to manage this host."
– 解決方法:
– 修改 ansible.cfg
host_key_checking = False
批量配置管理 所有模塊
• ansible-doc模塊的手冊
– 模塊的手冊,相當與 shell 的 man
– 非常重要,非常重要,非常重要
– ansible-doc -l 列出所有模塊
– ansible-doc modulename 查看幫助
• ping 模塊
– 測試網絡連通性, ping模塊沒有參數
– 注:測試 ssh 的連通性,與ping命令無關
– ansible host-pattern -m ping
• command模塊
– 默認模塊,遠程執行命令
– 用法
– ansible host-pattern -m command -a '[args]'
– 查看所有機器負載
ansible all -m command -a 'uptime'
– 查看日期和時間
ansible all -m command -a 'date +%F_%T'
• command模塊注意事項:
– 該模塊通過-a跟上要執行的命令可以直接執行,不過
命令裏如果有帶有如下字符部分則執行不成功
– "<", ">", "|", "&"
–因爲 該模塊不啓動 shell 直接在 ssh 進程中執行,所有使用
到 shell 特性的命令執行都會失敗
– 下列命令執行會失敗
ansible all -m command -a 'ps aux|grep ssh'
ansible all -m command -a 'set'
• shell | raw 模塊
– shell模塊用法基本和command一樣,區別是 shell模塊是通過/bin/sh進行執行命令,可以執行任意命令
– raw模塊,用法和shell 模塊一樣 ,可以執行任意命令
– 區別是 raw 沒有chdir、creates、removes參數
– 執行以下命令查看結果
ansible t1 -m command -a 'chdir=/tmp touch f1'-------------改變工作目錄chdir=/tmp
ansible t1 -m shell -a 'chdir=/tmp touch f2'
ansible t1 -m raw -a 'chdir=/tmp touch f3'
• script模塊
– 複雜命令怎麼辦?
– ansible 要上天
– 直接在本地寫腳本,然後使用 script 模塊批量執行
– ansible t1 -m script -a 'urscript'
– 友情提示: 該腳本包含但不限於 shell 腳本,只要指
定 Sha-bang 解釋器的腳本都可運行
課堂練習
• 練習使用
• command , shell , raw, script 模塊
• 掌握他們的特性不區別
#!/bin/bash
id zhang3
if [ $? != 0 ];then
adduser -g 100 li4
echo 123456 | passwd --stdin li4
chage -d 0 li4
fi
ansible app1 -m script -a '/root/ansiblescript.sh' 執行
• copy 模塊
– 複製文件到遠程主機
– src:要複製到遠程主機的文件在本地的地址,可以是
絕對路徑,也可以是相對路徑。如果路徑是一個目錄,
它將遞歸複製。在這種情況下,如果路徑使用"/"來結
尾,則只複製目錄裏的內容,如果沒有使用"/"來結尾,
則包含目錄在內的整個內容全部複製,類似於rsync
– dest:必選項。遠程主機的絕對路徑,如果源文件是
一個目錄,那麼該路徑也必須是個目錄
– backup:在覆蓋之前將原文件備份,備份文件包含時
間信息。有兩個選項:yes|no
– force:如果目標主機包含該文件,但內容不同,如果
設置爲yes,則強制覆蓋,如果爲no,則只有當目標主
機的目標位置不存在該文件時,才複製。默認爲yes
– 複製文件
ansible t1 -m copy -a 'src=/root/alog dest=/root/a.log'
– 複製目錄
ansible t1 -m copy -a 'src=urdir dest=/root/'
ansible all -m copy -a 'src=/etc/resolv.conf dest=/etc/resolv.conf'
• lineinfile | replace 模塊
– 類似 sed 的一種行編輯替換模塊
– path 目的文件
– regexp 正則表達式
– line 替換後的結果
ansible t1 -m lineinfile -a 'path="/etc/selinux/config"
regexp="^SELINUX=" line="SELINUX=disabled"'
– 替換指定字符
ansible t1 -m replace -a 'path="/etc/selinux/config" regexp="^(SELINUX=).*" replace="\1disabled"'
- ansible db -m lineinfile -a 'path=/etc/sysconfig/network-scripts/ifcfg-eth0 regexp="^IPV6INIT" line="IPV6INIT=\"yes\""'
- ansible db -m replace -a 'path=/etc/sysconfig/network-scripts/ifcfg-eth0 regexp="(?<=IPV6INIT=).*" replace="\"no\""'
[root@ansible ~]# ansible cache -m lineinfile -a 'path="/etc/sysconfig/network-scripts/ifcfg-eth0" regexp="^BOOTPROTO" line="BOOTPROTO=\"none\""'
cache | SUCCESS => {
"backup": "",
"changed": true,
"msg": "line replaced"
}
[root@ansible ~]# ansible cache -m lineinfile -a 'path="/etc/sysconfig/network-scripts/ifcfg-eth0" regexp="^BOOTPROTO" line="BOOTPROTO=\"static\""'
cache | SUCCESS => {
"backup": "",
"changed": true,
"msg": "line replaced"
}
總結:lineinfile 是將匹配的字符串所在的行的整行內容替換爲替換內容,replace是隻將匹配的字符串替換爲替換內容
課堂練習
• 練習
• 使用 copy 模塊同步數據
• 使用 lineinfile 編輯文件
• 使用 replace 修改文件
• yum模塊
– 使用yum包管理器來管理軟件包
– config_file:yum的配置文件
– disable_gpg_check:關閉gpg_check
– disablerepo:不啓用某個源
– enablerepo:啓用某個源
– name:要進行操作的軟件包的名字,也可以傳遞一個
Url或者一個本地的rpm包的路徑
– state:狀態(present,absent,latest)
– 刪除軟件包
ansible t1 -m yum -a 'name="lrzsz" state=absent'
– 刪除多個軟件包
ansible t1 -m yum -a 'name="lrzsz,lftp" state=absent'
– 安裝軟件包
ansible t1 -m yum -a 'name="lrzsz"'
– 安裝多個軟件包
ansible t1 -m yum -a 'name="lrzsz,lftp"'
• service模塊
– name:必選項,服務名稱
– enabled:是否開機啓動 yes|no
– sleep:如果執行了restarted,在則stop和start之間沉睡幾秒鐘
– state:對當前服務執行啓動,停止、重啓、重新加載等操作(started,stopped,restarted,reloaded)
ansible t1 -m service -a 'name="sshd" enabled="yes" state="started"'
• setup模塊
– 主要用於獲取主機信息,在playbooks裏經常會用到的
一個參數gather_facts就與該模塊相關。setup模塊下
經常使用的一個參數是filter參數
– filter 可以過濾到我們需要的信息
ansible t1 -m setup -a 'filter=ansible_distribution'
課堂練習
• 綜合練習
– 安裝 apache
ansible cache -m yum -a "name=httpd"
– 修改 apache 監聽的端口爲 8080 改配置
ansible cache -m replace -a 'path="/etc/httpd/conf/httpd.conf" regexp="Listen 80" replace="Listen 8080"'
– 爲 apache 增加 ServerName 配置 改配置
firefox http:www.example.com:8080
– 設置默認主頁
ansible cache -m shell -a "echo 1223 > /var/www/html/index.html"
– 啓動服務 – 設置開機自啓動
ansible cache -m service -a 'name="httpd" enabled="yes" state="started"'