一、知識剖析
- ansible簡介:
-
ansible是新出現的自動化運維工具,基于Python開發,集合了衆多運維工具(puppet、cfengine、chef、func、fabric)的優點,實作了批量系統配置、批量程式部署、批量運作指令等功能。
ansible是基于子產品工作的,本身沒有批量部署的能力。真正具有批量部署的是ansible所運作的子產品,ansible隻是提供一種架構。
- ansible特性:
-
子產品化:調用特定的子產品,完成特定任務
有Paramiko,PyYAML,Jinja2(模闆語言)三個關鍵子產品
- 支援自定義子產品
- 基于Python語言實作
- 部署簡單,基于python和SSH(預設已安裝),agentless
- 安全,基于OpenSSH
- 支援playbook編排任務
- 幂等性:一個任務執行1遍和執行n遍效果一樣,不因重複執行帶來意外情況
- 無需代理不依賴PKI(無需ssl)
- 可使用任何程式設計語言寫子產品
- YAML格式,編排任務,支援豐富的資料結構
- 較強大的多層解決方案
- Ansible的架構
自動化運維——ansible(部署httpd,zabbix)
由以下幾個核心元件構成:
- ansible(主體):ansible的核心程式,提供一個指令行接口給使用者對ansible進行管理操作;
- Host Inventory(主機清單):為Ansible定義了管理主機的政策。一般小型環境下我們隻需要在host檔案中寫入主機的IP位址即可,但是到了中大型環境我們有可能需要使用靜态inventory或者動态主機清單來生成我們所需要執行的目标主機。
- Core Modules(核心子產品):Ansible執行指令的功能子產品,多數為内置的核心子產品。
- Custom Modules(拓展子產品):如何ansible自帶的子產品無法滿足我麼你的需求,使用者可自定義相應的子產品來滿足自己的需求。
- Connection Plugins(連接配接插件):子產品功能的補充,如連接配接類型插件、循環插件、變量插件、過濾插件等,該功能不常用
- Playbook(任務劇本):編排定義ansible任務集的配置檔案,由ansible順序依次執行,通常是JSON格式的* YML檔案
- API:供第三方程式調用的應用程式程式設計接口
- Ansible工作原理:
- 管理端支援local 、ssh、zeromq 三種方式連接配接被管理端,預設使用基于ssh的連接配接---這部分對應基本架構圖中的連接配接子產品;
- 可以按應用類型等方式進行Host Inventory(主機群)分類,管理節點通過各類子產品實作相應的操作---單個子產品,單條指令的批量執行,我們可以稱之為ad-hoc;
- 管理節點可以通過playbooks 實作多個task的集合實作一類功能,如web服務的安裝部署、資料庫伺服器的批量備份等。playbooks我們可以簡單的了解為,系統通過組合多條ad-hoc操作的配置檔案 。
二、ansible的安裝
-
實驗環境
server1 172.25.19.1
server2 172.24.19.2
- ansible的配置檔案:
/etc/ansible/ansible.cfg 主配置檔案,配置ansible工作特性
/etc/ansible/hosts 主機清單
/etc/ansible/roles/ 存放角色的目錄
- 安裝軟體
[[email protected] ~]# cd ansible/
[[email protected] ansible]# ls
ansible-2.7.8-1.el7.noarch.rpm
ansible-tower-setup-bundle-3.4.2-1.el7.tar.gz
libtomcrypt-1.17-25.el7.x86_64.rpm
libtommath-0.42.0-5.el7.x86_64.rpm
python2-crypto-2.6.1-13.el7.x86_64.rpm
python2-jmespath-0.9.0-1.el7.noarch.rpm
python-httplib2-0.9.2-0.1.el7.noarch.rpm
python-keyczar-0.71c-2.el7.noarch.rpm
python-paramiko-2.1.1-0.9.el7.noarch.rpm
sshpass-1.06-1.el7.x86_64.rpm
[[email protected] ansible]# yum install -y *.rpm
- 配置主機清單
[[email protected] ansible]# cd /etc/ansible/
[[email protected] ansible]# ls
ansible.cfg hosts roles
[[email protected] ansible]# vim hosts ##最後添加
[web] #定義一個主機組
server1 #将主機名加進去
[db]
server2
- 測試ping子產品:先ping——>輸入yes,再加-k參數
[[email protected] ansible]# ansible server1 -m ping ##-m 調用子產品
[[email protected] ansible]# ansible server1 -m ping -k
- 以下是錯誤順序示例
[[email protected] ansible]# ansible server2 -m ping -k ##直接加-k,則報錯
應該先ping——>輸入yes,再加-k參數
[[email protected] ansible]# ansible server2 -m ping ##先允許連接配接
[[email protected] ansible]# ansible server2 -m ping -k ##再加-k參數輸入密碼連接配接
- 制作免密連接配接
[[email protected] ansible]# ssh-keygen ##一路回車即可
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
fb:77:6b:fa:07:30:e3:64:72:e0:5e:23:4e:d0:31:7c [email protected]
The key's randomart image is:
+--[ RSA 2048]----+
| oo. |
| . +.E |
| o o |
| = X |
| S+ O = |
| .o . . |
| . . |
| . . o .|
| ...=oo |
+-----------------+
[[email protected] ansible]#
[[email protected] ansible]# ssh-copy-id server1
[email protected]'s password:
[[email protected] ansible]# ssh-copy-id server2
[email protected]'s password:
- 免密連接配接測試
[[email protected] ansible]# ansible server1 -m ping
[[email protected] ansible]# ansible server2 -m ping
[[email protected] ansible]# ansible all -m ping
[[email protected] ansible]# ansible web -m ping
[[email protected] ansible]# ansible db -m ping
- ansible-doc -l ##列出所有子產品
- ansible-doc user ##檢視user子產品的使用方法
- 測試user子產品:給所有主機添加使用者
[[email protected] ansible]# ansible all -m user -a "name=hui password=westos"
[[email protected] ~]# id hui
uid=1000(hui) gid=1000(hui) groups=1000(hui)
[[email protected] ~]# cat /etc/shadow ##密碼會以明文顯示
hui:westos:17979:0:99999:7:::
##明文的密碼導緻不能做免密認證
[[email protected] ansible]# ssh-copy-id [email protected]
Permission denied, please try again.
##給server1和server2手動更改密碼,再做免密
[[email protected] ansible]# passwd hui
[[email protected] ~]# passwd hui
[[email protected] ansible]# ssh-copy-id [email protected]
[email protected]'s password:
[[email protected] ansible]# ssh-copy-id [email protected]
[email protected]'s password:
##測試免密登陸
[[email protected] ansible]# ssh [email protected]
[[email protected] ~]$ logout
Connection to server1 closed.
[[email protected] ansible]# ssh [email protected]
[[email protected] ~]$ logout
Connection to server2 closed.
##添加使用者授權
[[email protected] ansible]# vim /etc/sudoers
92 hui ALL=(ALL) NOPASSWD: ALL
[[email protected] ansible]# vim /etc/sudoers
92 hui ALL=(ALL) NOPASSWD: ALL
#此時以hui這個使用者登陸,并切換成root使用者成功
[[email protected] ansible]# ansible all -m ping -u hui -b ##-b切換成root使用者
- 測試其他子產品
- 檢視主機
2. 安裝服務
[[email protected] ansible]# ansible server2 -u hui -b -m yum -a "name=httpd state=present"
[[email protected] ~]# rpm -q httpd ##檢視已經安裝上
httpd-2.4.6-45.el7.x86_64
- 開啟服務
[[email protected] ansible]# ansible server2 -u hui -b -m service -a "name=httpd state=started"
[[email protected] ~]# systemctl status httpd
- 拷貝檔案
[[email protected] ansible]# vim index.html
[[email protected] ansible]# cat index.html
www.westos.org
[[email protected] ansible]# ansible server2 -u hui -b -m copy -a "src=index.html dest=/var/www/html/index.html"
[[email protected] ~]# curl 172.25.19.2
www.westos.org
- 建立軟連接配接
[[email protected] ansible]# ansible server2 -u hui -b -m file -a "src=/etc/fstab dest=/tmp/fstab state=link"
[[email protected] ~]# ll /tmp/fstab
lrwxrwxrwx 1 root root 10 Mar 24 10:45 /tmp/fstab -> /etc/fstab
##删除連結
[[email protected] ansible]# ansible server2 -u hui -b -m file -a "dest=/tmp/fstab state=absent"
[[email protected] ~]# ll /tmp/fstab
ls: cannot access /tmp/fstab: No such file or directory
- 建立目錄(遞歸建立)
[[email protected] ansible]# ansible server2 -u hui -b -m file -a "dest=/tmp/dir1/dir2 state=directory mode=755"
[[email protected] ~]# cd /tmp/
[[email protected] tmp]# ls
dir1 systemd-private-e04e5b99a713433d887e04c35a247c48-httpd.service-c4W0KH
[[email protected] tmp]# cd dir1/
[[email protected] dir1]# ls
dir2
##删除目錄
[[email protected] ansible]# ansible server2 -u hui -b -m file -a "dest=/tmp/dir1/dir2 state=absent" ##後面可以加-f參數,指定多少個線程
[[email protected] ~]# cd /tmp
[[email protected] tmp]# cd dir1/
[[email protected] dir1]# ls
[[email protected] dir1]#
- 給server2安裝mysql服務
##安裝MySQL-python和mariadb-server
[[email protected] ~]# ansible server2 -m yum -a "name=MySQL-python state=present"
[[email protected] ~]# ansible server2 -m yum -a "name=mariadb-server state=present"
[[email protected] ~]# ansible server2 -m service -a "name=mariadb state=started"
##添加mysql使用者并授權
[[email protected] ~]# ansible server2 -m mysql_user -a "name=hyg password=westos priv=test.*:ALL state=present"
server2 | CHANGED => {
"changed": true,
"user": "hyg"
}
##測試,可以登入
[[email protected] ~]# mysql -uhyg -pwestos test
MariaDB [test]> quit
Bye
三、 自動化部署httpd服務
- 編寫playbooks
[[email protected] ~]# cd /etc/ansible/
[[email protected] ansible]# mkdir playbooks
[[email protected] ansible]# cd playbooks/
[[email protected] playbooks]# mkdir httpd
[[email protected] playbooks]# cd httpd/
[[email protected] httpd]# vim httpd.yml
---
# httpd部署
- hosts: server2
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
- name: config httpd
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
- name: start httpd
service: name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
- 傳一個httpd.conf檔案(沒有的話安裝一個httpd服務)
[[email protected] conf]# scp /etc/httpd/conf/httpd.conf 172.25.19.1:/etc/ansible/playbooks/httpd
- 進行相關檢測
[[email protected] httpd]# pwd
/etc/ansible/playbooks/httpd
##檢測文法錯誤
[[email protected] httpd]# ansible-playbook httpd.yml --syntax-check
##檢視主機
playbook: httpd.yml
[[email protected] httpd]# ansible-playbook httpd.yml --list-host
playbook: httpd.yml
play #1 (server2): server2 TAGS: []
pattern: [u'server2']
hosts (1):
server2
## 檢視任務
[[email protected] httpd]# ansible-playbook httpd.yml --list-task
playbook: httpd.yml
play #1 (server2): server2 TAGS: []
tasks:
install httpd TAGS: []
config httpd TAGS: []
start httpd TAGS: []
- 執行
[[email protected] httpd]# ansible-playbook httpd.yml
- 以某一個任務開始執行
5. 修改端口(改為8080)
此時兩端檔案的加密串一樣
[[email protected] httpd]# md5sum httpd.conf
f5e7449c0f17bc856e86011cb5d152ba httpd.conf
[[email protected] conf]# pwd
/etc/httpd/conf
[[email protected] conf]# ls
httpd.conf magic
[[email protected] conf]# md5sum httpd.conf
f5e7449c0f17bc856e86011cb5d152ba httpd.conf
對檔案進行修改
[[email protected] httpd]# pwd
/etc/ansible/playbooks/httpd
[[email protected] httpd]# ls
httpd.conf httpd.yml
[[email protected] httpd]# vim httpd.conf
42 Listen 8080 #
測試server1端加密串改變了
[[email protected] httpd]# md5sum httpd.conf
04e9239e7bd5d5b9b85864226d60eee5 httpd.conf
再次執行,就會引發觸發
[[email protected] httpd]# ansible-playbook httpd.yml
server2端口改變了
[[email protected] conf]# netstat -antlp
tcp6 0 0 :::8080 :::* LISTEN 13719/httpd
- server1再次執行,就不會再做任何改變了
自動化運維——ansible(部署httpd,zabbix) - 添加變量,修改端口
[[email protected] httpd]# mv httpd.conf httpd.conf.j2
[[email protected] httpd]# vim httpd.conf.j2
42 Listen {{ http_port }}
[[email protected] httpd]# vim httpd.yml
---
# httpd部署
- hosts: server2
vars: ##添加變量
http_port: 80
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
- name: config httpd
template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf ##添加模闆
notify: restart httpd
- name: start httpd
service: name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
[[email protected] httpd]# ansible-playbook httpd.yml
[[email protected] ~]# netstat -antlp
tcp6 0 0 :::80 :::* LISTEN 15455/httpd
- 直接在/etc/ansible/hosts檔案修改
[[email protected] httpd]# vim /etc/ansible/hosts
[web]
server1 http_port=80
[db]
server2 http_port=8080
[[email protected] httpd]# vim httpd.yml ##删除vars,修改hosts: all
---
# httpd部署
- hosts: all
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
- name: config httpd
template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
- name: start httpd
service: name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
[[email protected] httpd]# ansible-playbook httpd.yml
##server2端口變為8080,server1端口變成80
- 設定監聽主機
- 第一種
[[email protected] httpd]# vim /etc/ansible/hosts
[web]
server1 http_host=172.25.19.1
[db]
server2 http_host=172.25.19.2
[webserver:children]
web
db
[webserver:vars]
http_port=80
[[email protected] httpd]# ansible-playbook httpd.yml
- 第二種
[[email protected] httpd]# vim /etc/ansible/hosts
[web]
server1
[db]
server2
[[email protected] httpd]# vim httpd.conf.j2
Listen {{ ansible_all_ipv4_addresses[0] }}:{{ http_port }}
##或者Listen {{ ansible_eth0['ipv4']['address'] }}:{{ http_port }}
[[email protected] httpd]# vim httpd.yml
---
# httpd部署
- hosts: all
vars:
host_port: 80
remote_user: root
[[email protected] httpd]# ansible-playbook httpd.yml
- 第三種:
[[email protected] httpd]# vim httpd.conf.j2
Listen {{ http_host }}:{{ http_port }}
[[email protected] httpd]# vim /etc/ansible/hosts
[web]
server1
[db]
server2
[all:vars]
http_host={{ ansible_all_ipv4_addresses[0] }}
[[email protected] httpd]# ansible-playbook httpd.yml
如果各節點的系統版本不一樣,又該如何自動化部署服務呢?
- 這裡我們以rhel7.3和rhel6.5兩個版本的主機自動化部署httpd服務為例
-
首先安裝一個rhel6.5的虛拟機server3,做免密
[[email protected] httpd]# ssh-copy-id server3
- 添加server3主機到清單中,測試能否ping通
[[email protected] httpd]# vim /etc/ansible/hosts
[web]
server1
server3
[db]
server2
[all:vars]
http_host={{ ansible_all_ipv4_addresses[0] }}
[[email protected] httpd]# ansible all -m ping
server2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
server1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
server3 | SUCCESS => {
"changed": false,
"ping": "pong"
}
- 給server3安裝httpd服務
[[email protected] httpd]# vim httpd.yml
---
# httpd部署
- hosts: all
vars:
http_port: 80
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
tags: install
- name: config httpd
template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
tags: config
- name: start httpd
service: name=httpd state=started
tags: start
handlers:
- name: restart httpd
service: name=httpd state=restarted
yml
[[email protected] httpd]# ansible-playbook httpd.yml -t install
- 将server3(rhel6.5)的httpd服務配置檔案發給server1,修改對應檔案名
[[email protected] ~]# scp /etc/httpd/conf/httpd.conf server1:/etc/ansible/playbooks/httpd
[[email protected] httpd]# mv httpd.conf httpd.conf6.j2
[[email protected] httpd]# mv httpd.conf.j2 httpd.conf7.j2
- 修改檔案,運作
[[email protected] httpd]# vim httpd.conf6.j2
Listen {{ http_host }}:{{ http_port }}
[[email protected] httpd]# vim httpd.yml
---
# httpd部署
- hosts: all
vars:
http_port: 80
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
tags: install
- name: config httpd
template: src=httpd.conf6.j2 dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
when: ansible_distribution_major_version == "6"
tags: config
- name: config httpd
template: src=httpd.conf7.j2 dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
when: ansible_distribution_major_version == "7"
tags: config
- name: start httpd
service: name=httpd state=started
tags: start
handlers:
- name: restart httpd
service: name=httpd state=restarted
[[email protected] httpd]# ansible-playbook httpd.yml -C
- httpd.yml的第二種寫法
---
# httpd部署
- hosts: all
vars:
http_port: 80
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=present
tags: install
- name: config httpd
template: src=httpd.conf{{ ansible_distribution_major_version }}.j2 dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
tags: config
- name: start httpd
service: name=httpd state=started
tags: start
handlers:
- name: restart httpd
service: name=httpd state=restarted
四、用ansible自動化部署zabbix
- 建立mariadb, zabbix-server角色
[[email protected] roles]# pwd
/etc/ansible/roles
[[email protected] roles]# mkdir mariadb
[[email protected] roles]# cd mariadb/
[[email protected] mariadb]# mkdir files tasks handlers vars templates meta defaults
[[email protected] mariadb]# cd ..
[[email protected] roles]# mkdir zabbix-server/{files,tasks,templates,vars} -p
- 編寫相應的檔案
[[email protected] zabbix4.0]# ls
zabbix-server-mysql-4.0.5-1.el7.x86_64.rpm
zabbix-web-mysql-4.0.5-1.el7.noarch.rpm
zabbix-web-4.0.5-1.el7.noarch.rpm
zabbix-agent-4.0.5-1.el7.x86_64.rpm php-bcmath-5.4.16-42.el7.x86_64.rpm
php-mbstring-5.4.16-42.el7.x86_64.rpm
fping-3.10-1.el7.x86_64.rpm
iksemel-1.4-2.el7.centos.x86_64.rpm
[[email protected] files]# pwd
/etc/ansible/roles/zabbix-server/files
[[email protected] files]# vim zabbix.repo
[zabbix]
name=zabbix4.0
baseurl=http://172.25.19.250/zabbix4.0
gpgcheck=0
[[email protected] files]# vim my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd
#
#
character-set-server=utf8
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
[[email protected] tasks]# pwd
/etc/ansible/roles/mariadb/tasks
[[email protected] tasks]# vim main.yml
- name: install mariadb server
yum: name=mariadb-server,MySQL-python state=present
- name: config mariadb
copy: src=my.cnf dest=/etc/my.cnf
notify: restart mariadb
- name: start mariadb server
service: name=mariadb state=started
[[email protected] handlers]# pwd
/etc/ansible/roles/mariadb/handlers
[[email protected] handlers]# vim main.yml
- name: restart mariadb
service: name=mariadb state=restarted
##server2安裝zabbix-server為了擷取配置檔案
[[email protected] ~]# yum install -y zabbix-server
[[email protected] ~]# scp /etc/zabbix/zabbix_server.conf server1:/etc/ansible/roles/zabbix-server/files
/etc/ansible/roles/zabbix-server/files
[[email protected] files]# vim zabbix_server.conf
DBPassword=zabbix
[[email protected] zabbix-server]# pwd
/etc/ansible/roles/zabbix-server
[[email protected] zabbix-server]# mkdir handlers
[[email protected] zabbix-server]# cd handlers/
[[email protected] handlers]# pwd
/etc/ansible/roles/zabbix-server/handlers
[[email protected] handlers]# vim main.yml
- name: create datbase
mysql_db: name=zabbix state=present
listen: "init zabbix db"
- name: create zabbix user
mysql_user: name=zabbix password=zabbix priv=zabbix.*:ALL state=present
listen: "init zabbix db"
- name: import create.sql.gz
mysql_db: name=zabbix state=import target=/usr/share/doc/zabbix-server-mysql-4.0.5/create.sql.gz
listen: "init zabbix db"
- name: restart zabbix server
service: name=zabbix-server state=restarted
[[email protected] zabbix-server]# cd tasks/
[[email protected] tasks]# ls
[[email protected] tasks]# vim main.yml
- name: copy zabbix.repo
copy: src=zabbix.repo dest=/etc/yum.repos.d/zabbix.repo
- name: install zabbix-server
yum: name=zabbix-server,zabbix-agent state=present
notify: "init zabbix db"
- name: config zabbix server
copy: src=zabbix_server.conf dest=/etc/zabbix/zabbix_server.conf
notify: restart zabbix server
- name: start zabbix server
service: name={{ item }} state=started
with_items:
- zabbix-server
- zabbix-agent
[[email protected] zabbix-server]# cd /etc/ansible/
[[email protected] ansible]# ls
ansible.cfg hosts index.html playbooks roles
[[email protected] ansible]# vim zabbix-server.yml
---
#zabbix-server部署
- hosts: server2
roles:
- mariadb
- zabbix-server
##執行
[[email protected] ansible]# ansible-playbook zabbix-server.yml
- 在server2端檢視zabbix日志,顯示enabling則自動化部署成功
[[email protected] ~]# cat /var/log/zabbix/zabbix_server.log