一、概念
ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
ansible是基于 paramiko 开发的,并且基于模块化工作,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。ansible不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的
Ansible 系统由控制主机对被管节点的操作方式可分为两类,即adhoc和playbook:
ad-hoc模式(点对点模式)
使用单个模块,支持批量执行单条命令。ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令。就相当于bash中的一句话shell。
playbook模式(剧本模式)
是Ansible主要管理方式,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能,如Web服务的安装部署、数据库服务器的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件
二、基本配置
此实验环境为rhel7.3
此处使用yum安装包安装,需要提前下载好相应的安装包和依赖包,此处已经下载好,如下图:
1、安装
ansible安装在中控机,即server1上
[root@server1 ansible]# yum install * -y
[root@server1 ansible]# ansible --version ##查看版本
2、创建一个普通用户
需要在四台主机上都执行
[root@server1 ansible]# useradd devops
[root@server1 ansible]# echo westos|passwd --stdin devops
[root@server2 ~]# useradd devops
[root@server2 ~]# echo westos|passwd --stdin devops
[root@server3 ~]# useradd devops
[root@server3 ~]# echo westos|passwd --stdin devops
[root@server4 ~]# useradd devops
[root@server4 ~]# echo westos|passwd --stdin devops
3、切换到普通用户
[root@server1 ansible]# su - devops
[devops@server1 ~]$ mkdir ansible ##建立ansible目录
#查看相关文件目录
[devops@server1 ~]$ cd ansible/
[devops@server1 ansible]$ pwd
/home/devops/ansible
[devops@server1 ansible]$ cd ..
[devops@server1 ~]$ l.
. .. .ansible .bash_history .bash_logout .bash_profile .bashrc
[devops@server1 ~]$ cd .ansible/
[devops@server1 .ansible]$ ls
tmp
4、修改文件,给主机分组
[devops@server1 ansible]$ pwd
/home/devops/ansible
[devops@server1 ansible]$ vim inventory ##此文件名可任意,但是必须与 ansible.cfg中指定的文件名相同
[dev]
server2
server3
[test]
server3
[prod]
server4
[webservers:children]
dev
test
prod
[devops@server1 ansible]$ ll inventory
-rw-rw-r-- 1 devops devops 91 May 10 17:09 inventory
[devops@server1 ansible]$ vim ansible.cfg
[defaults]
inventory=inventory ##指定文件名
[devops@server1 ansible]$ ansible-inventory --list all ##列出组信息
[devops@server1 ansible]$ ansible dev --list-host ##列出dev组成员
5、测试连接
[devops@server1 ansible]$ vim ansible.cfg
host_key_checking=False
[devops@server1 ansible]$ ansible all -m ping ##会报错
[devops@server1 ansible]$ ansible all -m ping -k ##输密码连接
再次连接,可以连接
[devops@server1 ansible]$ ansible all -m ping
[devops@server1 ansible]$ ansible all -a "hostname"
6、配置免密
[devops@server1 ansible]$ ssh-keygen
[devops@server1 ansible]$ ssh-copy-id server2
[devops@server1 ansible]$ ssh-copy-id server3
[devops@server1 ansible]$ ssh-copy-id server4
三、ad-hoc管理
1、安装apache
要配置的服务机器都要做(ansible可以做,此处因为初学,用于实验环境)
[root@server2 ~]# vim /etc/sudoers
devops ALL=(ALL) NOPASSWD: ALL ##不用密码连接
[root@server3 ~]# vim /etc/sudoer
93:devops ALL=(ALL) NOPASSWD: ALL
[root@server4 ~]# vim /etc/sudoers
93:devops ALL=(ALL) NOPASSWD: ALL
[devops@server1 ansible]$ ansible dev -m yum -a "name=httpd state=present" -b ##安装
[devops@server1 ansible]$ ansible dev -m service -a "name=httpd state=started enabled=yes" -b ##启动
2、开启防火墙
[devops@server1 ansible]$ ansible dev -m service -a "name=firewalld state=started enabled=yes" -b ##开启防火墙
[devops@server1 ansible]$ curl server2
curl: (7) Failed connect to server2:80; No route to host
3、写入防火墙策略
[devops@server1 ansible]$ ansible dev -m firewalld -a "service=http state=enabled permanent=true immediate=true" -b ##将apache添加到防火墙策略中
4、http发布页
[devops@server1 ansible]$ ansible dev -m copy -a 'content="www.westos.org\n" dest=/var/www/html/index.html' -b ##写一个发布页
5、测试
[devops@server1 ansible]$ curl server2 ##测试
www.westos.org
四、playbook,自动部属服务
1、写playbook
[devops@server1 ansible]$ cd
[devops@server1 ~]$ vim .vimrc
autocmd filetype yaml set ai ts=2 sw=2 et ##写table的缩进,yml类型的文件,一个tab键代表两个空格
[devops@server1 ~]$ cd ansible/
[devops@server1 ansible]$ vim playbook.yml ##此文件严格缩进
---
- name: apache playbook
hosts: test ##组,写在inventory 文件下,即针对哪些主机
tasks: ##任务
- name: install httpd ##任务简介
yum:
name: httpd
state: present
- name: start httpd
service:
name: httpd
state: started
enabled: true
- name: enabled firewalld
service:
name: firewalld
state: started
enabled: true
- name: configure firewalld
firewalld:
service: http
state: enabled
permanent: true
immediate: true
- name: copy index.html
copy:
content: "<h1>www.westos.org</h1>\n"
dest: /var/www/html/index.html
[devops@server1 ansible]$ vim ansible.cfg
[privilege_escalation]
become=True
become_method=sudo ##可以用sudo
become_user=root
become_ask_pass=False ##不用密码
2、部署http
[devops@server1 ansible]$ ansible-playbook --syntax-check playbook.yml ##检测语法
playbook: playbook.yml
[devops@server1 ansible]$ ansible-playbook playbook.yml ##执行
3、配置http
[devops@server1 ansible]$ mkdir files ##建立一个目录,
[devops@server1 ansible]$ cd files/
[devops@server1 files]$ scp server3:/etc/httpd/conf/httpd.conf . ##拷贝一份配合子文件到目录下
[devops@server1 files]$ vim httpd.conf ##可以对配置文件进行修改
[devops@server1 files]$ cd ..
[devops@server1 ansible]$ vim playbook.yml ##对playbook进行添加
##写在http安装之后
- name: configure httpd
copy:
src: files/httpd.conf ##文件源
dest: /etc/httpd/conf/httpd.conf ##目的目录
owner: root ##用户
group: root ##组
mode: '0644' ##权限
notify: restart httpd ##动作
handlers: ##触发器
- name: restart httpd
service:
name: httpd
state: restarted
[devops@server1 ansible]$ ansible-playbook --syntax-check playbook.yml
[devops@server1 ansible]$ ansible-playbook playbook.yml
4、虚拟主机
1)写apache配置文件
[devops@server1 ansible]$ cd files/
[devops@server1 files]$ ls
httpd.conf
##写配置文件
[devops@server1 files]$ vim vhosts.conf
<VirtualHost *:80>
DocumentRoot /var/www/html
ServerName server3
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/vhosts/example.com
ServerName server3.example.com
</VirtualHost>
<Directory "/var/www/vhosts/example.com">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
2)在playbook中添加
##写playbook
[devops@server1 files]$ cd ..
[devops@server1 ansible]$ vim playbook.yml
- name: create /var/www/vhosts/example.com ##创建目录
file:
path: /var/www/vhosts/example.com
state: directory
mode: '0755'
- name: create vhost.html ##创建发布页面
copy:
content: "server3.example.com-vhosts\n"
dest: /var/www/vhosts/example.com/vhost.html
- name: copy vhosts.conf ##复制配置文件
copy:
src: files/vhosts.conf
dest: /etc/httpd/conf.d/vhosts.conf
notify: restart httpd
3)对目标主机修改
[devops@server1 ansible]$ ansible-playbook --syntax-check playbook.yml ##检测
[devops@server1 ansible]$ ansible-playbook playbook.yml ##推送
4)做地址解析并测试
[root@server1 ansible]# vim /etc/hosts ##做地址解析,在server1做,而不是普通用户
172.25.47.3 server3 server3.example.com
[root@server1 ansible]# curl server3.example.com/vhost.html ##访问测试,可以看到写的发布页面
server3.example.com-vhosts
五、定义变量
1)调用变量
[devops@server1 ansible]$ vim playbook.yml
4 vars:
5 web_package: httpd
6 web_service: httpd
7 firewalld_service: firewalld
8 tasks:
9 - name: install httpd
10 yum:
11 name: "{{ web_package }}"
12 state: present
24 - name: start httpd
25 service:
26 name: "{{ web_service }}"
27 state: started
28 enabled: true
29
30 - name: enabled firewalld
31 service:
32 name: "{{ firewalld_service }}"
33 state: started
34 enabled: true
65 handlers:
66 - name: restart httpd
67 service:
68 name: "{{ web_service }}"
69 state: restarted
[devops@server1 ansible]$ ansible-playbook --syntax-check playbook.yml
[devops@server1 ansible]$ ansible-playbook playbook.yml
2)调用外部变量
[devops@server1 ansible]$ mkdir vars
[devops@server1 ansible]$ cd vars/
[devops@server1 vars]$ vim web.yml
web_package: httpd
web_service: httpd
firewalld_service: firewalld
[devops@server1 vars]$ cd ..
[devops@server1 ansible]$ vim playbook.yml
3 hosts: test
4 vars_files:
5 - vars/web.yml
[devops@server1 ansible]$ ansible-playbook --syntax-check playbook.yml
[devops@server1 ansible]$ ansible-playbook playbook.yml
3)调用不同的.yml文件,执行不同的任务
[devops@server1 ansible]$ cd vars/
[devops@server1 vars]$ ls
web.yml
[devops@server1 vars]$ cp web.yml ftp.yml
[devops@server1 vars]$ vim ftp.yml
---
ftp_package: vsftpd
ftp_service: vsftpd
firewalld_service: firewalld
[devops@server1 vars]$ cd ..
[devops@server1 ansible]$ cp playbook.yml apache.yml
[devops@server1 ansible]$ cp playbook.yml vsftp.yml
[devops@server1 ansible]$ vim vsftp.yml
---
- name: vsftp playbook
hosts: prod
vars:
firewalld_svc:
- ftp
vars_files:
- vars/ftp.yml
tasks:
- name: install vsftpd
yum:
name: "{{ ftp_package }}"
state: present
- name: configure vsftpd
copy:
src: files/vsftpd.conf
dest: /etc/vsftpd/vsftpd.conf
owner: root
group: root
mode: '0600'
notify: restart vsftpd
- name: start vsftpd
service:
name: "{{ ftp_service }}"
state: started
enabled: true
- name: enabled firewalld
service:
name: "{{ firewalld_service }}"
state: started
enabled: true
- name: configure firewalld
firewalld:
service: "{{ item }}"
state: enabled
permanent: true
immediate: true
loop: "{{ firewalld_svc }}"
handlers:
- name: restart vsftpd
service:
name: "{{ ftp_service }}"
state: restarted
[root@foundation47 ~]# scp /etc/vsftpd/vsftpd.conf server1:/home/devops/ansible/files
[devops@server1 ansible]$ cd files/
[devops@server1 files]$ logout
[root@server1 ansible]# cd /home/devops/ansible/files/
[root@server1 files]# chown devops.devops vsftpd.conf
[root@server1 files]# su - devops
[devops@server1 ~]$ cd ansible/
[devops@server1 ansible]$ ls
ansible.cfg apache.yml files inventory playbook.retry playbook.yml vars vsftp.yml
[devops@server1 ansible]$ vim playbook.ym
---
- import_playbook: apache.yml
- import_playbook: vsftp.yml
[devops@server1 ansible]$ rm -fr playbook.retry
[devops@server1 ansible]$ ansible-playbook --syntax-check playbook.yml
[devops@server1 ansible]$ ansible-playbook playbook.yml
4)在不同组中的主机执行不同的配置
[devops@server1 ansible]$ vim test.yml
---
- name: test
hosts:
- prod
- test
tasks:
- name: deploy apache
yum:
name: httpd
state: latest
when: ansible_hostname in groups['test']
- name: deploy vsftpd
yum:
name: vsftpd
state: present
when: ansible_hostname in groups['prod']
[devops@server1 ansible]$ ansible-playbook --syntax-check test.yml
[devops@server1 ansible]$ ansible-playbook test.yml
5)建立用户
[devops@server1 ansible]$ vim vars/user.yml ##存放用户名和密码的文件
---
userlist:
- name: user1
pass: westos
- name: user2
pass: redhat
[devops@server1 ansible]$ vim test.yml ##写playbook
---
- name: test
hosts:
- test
vars_files:
- vars/user.yml
tasks:
- name: create user
user:
name: "{{ item.name }}"
state: present
password: "{{ item.pass }}"
loop: "{{ userlist }}"
[devops@server1 ansible]$ ansible-playbook --syntax-check test.yml ##检测
[devops@server1 ansible]$ ansible-playbook test.yml ##推送
此处会有警告,因为此时的密码是明文的
解决:
---
- name: test
hosts:
- test
vars_files:
- vars/user.yml
tasks:
- name: create user
user:
name: "{{ item.name }}"
state: present
password: "{{ item.pass |password_hash('sha512','mysalt') }}" ##hash加密
loop: "{{ userlist }}"
[devops@server1 ansible]$ ansible-playbook --syntax-check test.yml
playbook: test.yml
[devops@server1 ansible]$ ansible-playbook test.yml
检测
此时密码已加密