Ansible 简单的说是一个配置管理系统(configuration management system)。
你只需要可以使用 ssh 访问你的服务器或设备就行。它也不同于其他工具,因为它
使用推送的方式,而不是像 puppet 等 那样使用拉取安装agent的方式。你可以将
代码部署到任意数量的服务器上!
ansible可以帮助我们完成一些批量任务,或者完成一些需要经常重复的工作。
比如:同时在100台服务器上安装nginx服务,并在安装后启动它们。
比如:将某个文件一次性拷贝到100台服务器上。
比如:每当有新服务器加入工作环境时,你都要为新服务器部署某个服务,也就是说你需要经常重复的完成相同的工作。
这些场景中我们都可以使用到ansible。
模块化:调用特定的模块,完成特定任务
有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块
支持自定义模块
基于Python语言实现
部署简单,基于python和SSH(默认已安装),agentless
安全,基于OpenSSH
支持playbook编排任务
幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
无需代理不依赖PKI(无需ssl)
可使用任何编程语言写模块
YAML格式,编排任务,支持丰富的数据结构
较强大的多层解决方案
base2 | 172.25.78.12 | ansible服务器 |
---|---|---|
base3 | 172.25.78.13 | 远程客户端 |
[root@base2 ~]# 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
[root@base2 ~]# yum install -y *.rpm
[root@base2 ~]# cd /etc/ansible/
[root@base2 ansible]# ll
total 24
-rw-r--r-- 1 root root 20277 Feb 22 07:04 ansible.cfg # 主配置文件
-rw-r--r-- 1 root root 1016 Feb 22 07:04 hosts # 定义主机变量
drwxr-xr-x 2 root root 6 Feb 22 07:04 roles # 存放角色的文件
[root@base2 ansible]# vim hosts # 添加主机,我是分组存放主机的
[web]
base2
[db]
base3
[root@base2 ansible]# ansible base2 -m ping # -m 调用模块,连接base2
[root@base2 ansible]# ansible base2 -m ping -k # -k表示使用密码
SSH password:
[root@base2 ansible]# ansible base3 -m ping -k
SSH password:
[root@base2 ansible]# ssh-keygen
[root@base2 ansible]# ssh-copy-id base2 # 建立免密
[root@base2 ansible]# ssh-copy-id base3
[root@base2 ansible]# ansible base* -m ping # 测试,不需要密码就可以成功
[root@base2 ansible]# ansible web -m ping
[root@base2 ansible]# ansible db -m ping
[root@base2 ansible]# ansible all -m user -a "name=lala password=redhat" # 给所有节点创建用户
[root@base3 ~]# id lala # 在远程端查看,用户建立成功
uid=1000(lala) gid=1000(lala) groups=1000(lala)
[root@base3 ~]# cat /etc/shadow | tail -n 1
[root@base2 ansible]# ssh-copy-id lala@base2 # 当我们给普通用户免密时,发现自己设置的密码不能使用
[root@base2 ansible]# passwd lala # 所以我们还需要手动修改密码
[root@base3 ~]# passwd lala # 修改远程主机用户密码
[root@base2 ansible]# ssh-copy-id lala@base2 # 免密成功
[root@base2 ansible]# ssh-copy-id lala@base3
[root@base2 ansible]# ansible all -m ping
[root@base2 ansible]# vim /etc/sudoers # 修改普通用户权限
92 lala ALL=(ALL) NOPASSWD: ALL
[root@base3 ~]# vim /etc/sudoers
92 lala ALL=(ALL) NOPASSWD: ALL
注:修改文件时,文件为只读,wq! 退出去即可
[root@base2 ansible]# ansible all -m ping -u lala -b # -b表示切换为超户
[root@base2 ansible]# ansible all -u lala -b -a "hostname"
[root@base2 ansible]# ansible base3 -u lala -b -m yum -a "name=httpd state=present"
name=httpd # 以普通用户的身份登录远程,并用-b切换为超户
[root@base3 ~]# rpm -qa httpd # 远程查看,安装成功
httpd-2.4.6-45.el7.x86_64
[root@base2 ansible]# ansible base3 -u lala -b -m service -a "name=httpd state=started" # 远程开启httpd服务
[root@base3 ~]# netstat -antlp | grep httpd # 查看远程主机,开启成功
[root@base2 ansible]# vim index.html
www.westos.org
[root@base2 ansible]# ansible base3 -u lala -b -m copy -a "src=index.html dest=/var/www/html/index.html" # 远程修改默认发布目录
[root@foundation78 ~]# curl 172.25.78.13 # 测试
www.westos.org
[root@base2 ansible]# ansible base3 -u lala -b -m file -a "src=/etc/fstab dest=/tmp/fstab state=link" # 创建软链接
[root@base3 ~]# ll /tmp/fstab
[root@base2 ansible]# ansible base3 -u lala -b -m file -a "dest=/tmp/fstab state=absent" # 删除软链接
[root@base2 ansible]# ansible base3 -u lala -b -m file -a "dest=/tmp/dir1/dir2 state=directory mode=755" # 递归创建目录
[root@base3 ~]# cd /tmp/ # 查看递归目录建立成功
[root@base3 tmp]# ls
dir1 systemd-private-368b42d09d14493ca8b687f20b5226a9-httpd.service-nt6hdR
[root@base3 tmp]# cd dir1/
[root@base3 dir1]# ls
dir2
[root@base2 ansible]# ansible base3 -u lala -b -m file -a "dest=/tmp/dir1/dir2 state=absent" # 删除递归目录
[root@base2 ansible]# ansible base3 -m yum -a "name=mariadb-server state=present" # 远程安装数据库
[root@base2 ansible]# ansible base3 -m service -a "name=mariadb state=started" # 开启mysql
[root@base2 ansible]# ansible base3 -m mysql_user -a "name=haha password=westos priv=test.*:ALL state=present" # 授权,执行失败,缺少模块
[root@base2 ansible]# ansible base3 -m yum -a "name=MySQL-python state=present" # 安装模块
[root@base2 ansible]# ansible base3 -m mysql_user -a "name=haha password=westos priv=test.*:ALL state=present" # 重新授权
[root@base3 ~]# mysql
MariaDB [(none)]> use mysql
MariaDB [mysql]> select Host,User,Password from user where User="haha";
我们之前的所有模块都是自己一个一个自己加的,这样太麻烦了,所以我们现在用playbooks来整合模块
[root@base2 ansible]# pwd
/etc/ansible
[root@base2 ansible]# mkdir playbooks
[root@base2 ansible]# cd playbooks/
[root@base2 playbooks]# mkdir httpd
[root@base2 playbooks]# cd httpd/
[root@base2 httpd]# vim httpd.yml # 一定要注意缩进
---
# httpd部署
- hosts: base3
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
[root@base2 httpd]# ansible-playbook httpd.yml --syntax-check # 检测语法
[root@base2 httpd]# ansible-playbook httpd.yml --list-host # 查看主机
[root@base2 httpd]# ansible-playbook httpd.yml --list-task # 查看任务列表
[root@base2 httpd]# scp [email protected]:/etc/httpd/conf/httpd.conf /etc/ansible/playbooks/httpd/ # 运行文件
[root@base2 httpd]# ansible base3 -m setup # 查看base3上的所有远程信息
[root@base2 httpd]# md5sum httpd.conf
f5e7449c0f17bc856e86011cb5d152ba httpd.conf
[root@base3 conf]# md5sum httpd.conf
f5e7449c0f17bc856e86011cb5d152ba httpd.conf
[root@base2 httpd]# ansible-playbook httpd.yml --start-at-task="start httpd" # 指定任务执行,仅仅执行了安装的任务
[root@base2 httpd]# vim httpd.conf # 修改端口号
42 Listen 8080
[root@base2 httpd]# md5sum httpd.conf # 检测到文件被篡改
04e9239e7bd5d5b9b85864226d60eee5 httpd.conf
[root@base2 httpd]# ansible-playbook httpd.yml # 执行文件
[root@base3 conf]# netstat -antlp | grep httpd
第一种方法
[root@base2 httpd]# mv httpd.conf httpd.conf.j2 # j2=jinja2
[root@base2 httpd]# vim httpd.conf.j2
42 Listen {{ http_port }} # 调用端口变量
[root@base2 httpd]# vim httpd.yml
---
# httpd部署
- hosts: base3
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
[root@base2 httpd]# ansible-playbook httpd.yml --syntax-check
[root@base2 httpd]# ansible-playbook httpd.yml # 执行成功
[root@base3 conf]# netstat -antlp | grep 80 # 查看端口,修改成功
第二种方法
[root@base2 httpd]# vim /etc/ansible/hosts
[web]
base2 http_port=8080
[db]
base3
[root@base2 httpd]# vim httpd.yml
# httpd部署
- hosts: all
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
[root@base2 httpd]# netstat -antlp | grep 8080
[root@base2 httpd]# netstat -antlp | grep 80
[root@base2 httpd]# pwd
/etc/ansible/playbooks/httpd
[root@base2 httpd]# vim /etc/ansible/hosts
[web]
base2 http_port=8080
[db]
base3 http_port=80
[root@base2 httpd]# vim httpd.yml
---
# 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
[root@base2 httpd]# ansible-playbook httpd.yml --syntax-check
[root@base2 httpd]# ansible-playbook httpd.yml
[root@base2 httpd]# netstat -antlp | grep 8080 # 端口修改成功
第三种方法(识别ip来修改端口)
[root@base2 httpd]# vim httpd.conf.j2
42 Listen {{ http_host }}:{{ http_port}} # 调用ip和端口变量
[root@base2 httpd]# vim /etc/ansible/hosts
[web]
base2 http_host=172.25.78.12
[db]
base3 http_host=172.25.78.13
[webserver:children]
web
db
[webserver:vars]
http_port=80
[root@base2 httpd]# vim httpd.yml
---
# httpd部署
- hosts: all
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
[root@base2 httpd]# ansible-playbook httpd.yml --syntax-check
[root@base2 httpd]# ansible-playbook httpd.yml
[root@base2 httpd]# netstat -antlp | grep httpd
[root@base3 ~]# netstat -antlp | grep httpd
第一种方法(用变量调用ip)
[root@base2 httpd]# vim /etc/ansible/hosts
[web]
base2
[db]
base3
[root@base2 httpd]# ansible base3 -m setup # 查看主机base3的所有远程信息,以下只是部分截图
[root@base2 httpd]# ansible base3 -m setup -a "filter=ansible_all_ipv4_addresses" # 查看主机ip
[root@base2 httpd]# vim httpd.conf.j2
42 Listen {{ ansible_all_ipv4_addresses[0] }}:{{ http_port}} # [0] 表示切片,截取第一段
[root@base2 httpd]# vim httpd.yml
---
# httpd部署
- hosts: all
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
[root@base2 httpd]# ansible-playbook httpd.yml --syntax-check
[root@base2 httpd]# ansible-playbook httpd.yml
[root@base3 ~]# cat /etc/httpd/conf/httpd.conf | grep Listen
[root@base2 httpd]# vim httpd.conf.j2
Listen {{ ansible_eth0['ipv4']['address'] }}:{{ http_port}}
[root@base2 httpd]# vim httpd.yml
---
# httpd部署
- hosts: all
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
[root@base2 httpd]# ansible-playbook httpd.yml --syntax-check
[root@base2 httpd]# ansible-playbook httpd.yml
[root@base3 ~]# cat /etc/httpd/conf/httpd.conf | grep Listen
[root@base2 httpd]# vim /etc/ansible/hosts
[web]
base2
[db]
base3
[all:vars]
http_host={{ ansible_all_ipv4_addresses[0] }}
[root@base2 httpd]# ansible-playbook httpd.yml --syntax-check
[root@base2 httpd]# ansible-playbook httpd.yml
[root@base3 ~]# cat /etc/httpd/conf/httpd.conf | grep Listen
base2 | 172.25.78.12 | ansible服务器 | rhel7 |
---|---|---|---|
base3 | 172.25.78.13 | 远程客户端 | rhel7 |
server1 | 172.25.78.1 | 远程客户端 | rhel6 |
[root@base2 ~]# vim /etc/hosts # 写解析的目的是为了通过域名来访问主机
172.25.78.1 server1
[root@base2 ~]# ssh-copy-id server1 # 做免密
[root@base2 ~]# cd /etc/ansible/playbooks/httpd/
[root@base2 httpd]# ls
httpd.conf.j2 httpd.retry httpd.yml
[root@base2 httpd]# vim /etc/ansible/hosts # 添加主机
[web]
base2
server1
[db]
base3
[root@base2 httpd]# ansible all -m ping # 先检测是否可以进行免密通信
[root@base2 httpd]# ansible base3 -m setup -a "filter=ansible_dis*" # 查看远程主机的版本号
[root@base2 httpd]# ansible server1 -m setup -a "filter=ansible_dis*"
[root@base2 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
[root@base2 httpd]# ansible-playbook httpd.yml --syntax-check
[root@base2 httpd]# ansible-playbook httpd.yml -t install # 执行install模块
[root@server1 ~]# rpm -qa httpd
httpd-2.2.15-29.el6_4.x86_64
[root@base2 httpd]# scp server1:/etc/httpd/conf/httpd.conf .
httpd.conf 100% 34KB 33.6KB/s 00:00
[root@base2 httpd]# ls
httpd.conf httpd.conf.j2 httpd.retry httpd.yml
[root@base2 httpd]# mv httpd.conf httpd6.conf.j2
[root@base2 httpd]# mv httpd.conf.j2 httpd7.conf.j2
[root@base2 httpd]# vim httpd6.conf.j2
136 Listen {{ http_host }}:{{ http_port }}
[root@base2 httpd]# vim /etc/ansible/hosts
[web]
base2
server1
[db]
base3
[all:vars]
http_host={{ ansible_all_ipv4_addresses[0] }}
[root@base2 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=httpd6.conf.j2 dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
when: ansible_distribution_major_version == "6"
tags: config
- name: config httpd
template: src=httpd7.conf.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
[root@base2 httpd]# ansible-playbook httpd.yml
[root@server1 ~]# netstat -antlp | grep httpd
[root@base2 httpd]# pwd
/etc/ansible/playbooks/httpd
[root@base2 httpd]# cd /etc/ansible/
[root@base2 ansible]# ls
ansible.cfg hosts index.html playbooks roles
[root@base2 ansible]# cd roles/
[root@base2 roles]# mkdir mariadb
[root@base2 roles]# cd mariadb/
[root@base2 mariadb]# ls
[root@base2 mariadb]# mkdir files tasks defaults meta templates vars handles
[root@base2 mariadb]# ls
defaults files meta tasks templates vars
[root@base2 mariadb]# cd tasks/
[root@base2 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
[root@base2 tasks]# cd ..
[root@base2 mariadb]# cd files/
[root@base2 files]# cp /etc/my.cnf .
[root@base2 files]# ls
my.cnf
[root@base2 files]# cat 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
[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
[root@base2 files]# cd ..
[root@base2 mariadb]# cd handles/
[root@base2 handles]# vim main.yml
- name: restart mariadb
service: name=mariadb state=restart
[root@base2 tasks]# cd /etc/ansible/roles/
[root@base2 roles]# mkdir -p zabbix-server/{files,tasks,templates,vars,handles}
[root@base2 roles]# ls
mariadb zabbix-server
[root@base2 roles]# cd zabbix-server/
[root@base2 zabbix-server]# cd files
[root@base2 files]# vim zabbix.repo
[rhel7.3]
name=rhel7.3
baseurl=http://172.25.78.254/rhel7.3
gpgcheck=0
[software]
name=software
baseurl=http://172.25.78.254/software
gpgcheck=0
[root@base2 files]# cd ..
[root@base2 zabbix-server]# cd tasks/
[root@base2 tasks]# vim main.yml
- name: copy zabbix.repo
copy: src=zabbix.repo dest=/etc/yum.repos.d/yum.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
[root@base3 ~]# cd /etc/yum.repos.d/
[root@base3 yum.repos.d]# ls
redhat.repo yum.repo
[root@base3 yum.repos.d]# vim yum.repo
[rhel7.3]
name=rhel7.3
baseurl=http://172.25.78.254/rhel7.3
gpgcheck=0
[software]
name=software
baseurl=http://172.25.78.254/software
gpgcheck=0
[root@base3 yum.repos.d]# yum install -y zabbix-server
[root@base3 yum.repos.d]# scp zabbix_server.conf base2:/etc/ansible/roles/zabbix-server/files
[root@base2 zabbix-server]# pwd
/etc/ansible/roles/zabbix-server
[root@base2 zabbix-server]# cd files/
[root@base2 files]# ls
zabbix.repo zabbix_server.conf
[root@base2 files]# vim zabbix_server.conf
115 DBPassword=zabbix
[root@base2 tasks]# cd ..
[root@base2 zabbix-server]# ls
files tasks templates vars handles
[root@base2 zabbix-server]# cd handles/
[root@base2 handles]# 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
[root@base2 zabbix-server]# cd /etc/ansible/
[root@base2 ansible]# vim zabbix-server.yml
---
#zabbix-server部署
- hosts: base3
roles:
- mariadb
- zabbix-server
[root@base2 ansible]# ansible-playbook zabbix-server.yml --syntax-check
[root@base2 ansible]# ansible-playbook zabbix-server.yml