ansible入门
Ansible是一个配置管理和配置工具,使用SSH连接到服务器并运行配置好的任务,服务器上不需要安装任何其他软件,只需要开启SSH,客户端的ansible会完成所有其他的工作。
首先安装Ansible:
apt-get安装的版本很低,建议使用pip安装:
sudo pip install ansible
可能会提示什么:from pip import main ImportError: cannot import name main
那就使用--user:pip install --user ansible
在虚拟环境virtualenv中安装:
sudo pip install -U virtualenv # 首先安装virtualenv
# 然后进入一个ansible专门的文件夹,创建虚拟环境:
virtualenv .venv
source .venv/bin/activate
# 进入了虚拟环境
pip install ansible
pip install -U ansible # 任何时候都可以这样更新ansible
配置ansible:
在ansible1里面,我们需要用到/etc/ansible里面的默认配置,但是像上面那样在虚拟环境里面安装ansible,那么我们完全不需要这些默认文件,我们可以在非本地路径下创建这些配置文件。
管理服务器:Inventory
我们需要创建一个inventory file用来定义管理哪个server,命名随意,一般为hosts:
[web]
192.168.22.10
192.168.22.11
在web标签下我们需要管理两个server
当我们在server上运行ansible against本地机,我们不需要关心Inventory file里面的内容
当我们本地运行ansible against远程服务器时,Inventory file需要这样编写:
[local]
127.0.0.1
[remote]
192.168.1.2
接下来是建立本地与远程服务器之间连接的命令。
Running Commands
接下来我们针对服务器运行任务tasks,ansible是通过SSH去管理服务器的:
# Run against localhost
ansible -i ./hosts --connection=local local -m ping
# Run against remote server针对远程服务器运行ansible
ansible -i ./hosts remote -m ping
参数说明
--connection=local
的意思是不需要通过ssh连接,因为我们针对的就是本地,还可以是–connection=ssh意思是需要ssh连接。
2.-i ./hosts
指定Inventory file,告诉我们连接到哪里
3.remote,local,all
指明使用哪个标签下面的服务器清单,all表示针对每个服务器运行
4.-m ping
表示使用ping模块,会返回ping结果
然后针对阿里云服务器进行了尝试,运行ansible -i ./hosts remote -m ping
发现报错:
39.107.74.200 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).",
"unreachable": true
}
感觉问题应该是这样的命令没有输入用户名和密码,尝试
ansible -i ./hosts remote -m ping -u root --ask-pass
前提是使用sudo apt-get
安装好了sshpass,然后返回结果:
39.107.74.200 | SUCCESS => {
"changed": false,
"ping": "pong"
}
但是每次敲这么多命令就很复杂,更简单的方法是将用户名密码写入hosts文件里面:
[remotr]
29.107.74.200 ansible_ssh_user=root ansible_ssh_pass=123456
然后就不需要额外的命令了
Modules
ansible使用模块来完成任务,比如安装软件,复制文件以及使用模板。
模块aret the way to use absible, 因为模块可以使用上下文来确定完成任务需要做些什么。
如果没有模块,我们只能运行shell命令,其实是使用的shell模块:
ansible -i ./hosts remote -b --become-user=root all
-m shell -a 'apt-get install nginx’
1.-b
成为另一个用户
2.--become-user=root
以用户root运行命令
3.-m
定义模块,这里使用的是shell模块
4.-a
给模块传递参数
这样做并不好,因为这样只能完成bash脚本能够完成的任务
我们还可以使用apt模块,这样能确保幂等(一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同)
ansible -i ./hosts remote -b --become-user=root
-m apt -a 'name=nginx state=installed update_cache=true'
如果执行后显示的是change:False,就表明已经安装,没有对环境造成任何影响
1.name=nginx
表示需要安装的软件包名
2.state=installed
表示需要的结束状态
3.update_cache=true
表示是否更新软件包储存库缓存
通过模块我们可以做我们想做的事,但是为了更好管理,我们把任务都放到playbook里面,就可以运行多个tasks
Playbooks
playbook可以运行多任务还有一些高级功能,playbook和roles(剧本和角色)都使用YAML文件定义:
nginx.yml
- hosts: remote
become: yes
become_user: root
tasks:
- name: install nginx
apt:
name: nginx
state: present
update_cache: true
YAML文件格式:用缩排方式呈现,结构通过缩进来表示,连续的项目使用-表示,键值对用:表示,不可以使用TAB.
如何使用playbook呢?直接运行:
ansible-playbook -i ./hosts nginx.yml
Handlers
handlers=tasks,处理程序可以做任务可以完成的任何事,但是只有当另一个task调用它的时候才会执行。
我们添加notify指令到上面的playbook中:
- hosts: remote
become: yes
become_user: root
tasks:
- name: Install Nginx
apt:
name: nginx
state: present
update_cache: true
notify:
- Start Nginx
handlers:
- name: Start Nginx
service:
name: nginx
state: started
任务task运行后会通知名为start Nginx的处理程序:该handler处理使用服务service模块,可以启动停止重启等操作。
所以handler和task的唯一区别就是task会自动调用,handler得等着task来调用它
这里还有一个地方需要注意:如果这里nginx已经安装,那么nginx安装任务不会运行,handler也不会被调用。
使用变量:
首先定义变量:
- hosts: local
connection: local
become: yes
become_user: root
vars:
- docroot: /var/www/serversforhackers.com/public
使用变量方法:
file:
path: '{
{ docroot }}'
使用Jinja模板,必须是单引号或者双引号
roles(最终使用方法,比playbook更好配置)
roles角色用于组织多个task并封装成完成这些任务需要的数据,但是真实的配置场景里面,我们需要很多变量,文件,模板之类的东西,虽然可以配合playbook使用,但是roles更好,因为它有一个目录结构来规范
roles
rolename
- files
- handlers
- meta
- templates
- tasks
- vars
我们下面创建一个新的role例子,role的任务有:
1. Add Nginx Repository- 使用apt_repository模块添加Nginx稳定PPA以获取最新的稳定版本的Nginx 。
2. Install Nginx - 使用Apt模块安装Nginx。
3. Create Web Root - 最后创建一个Web根目录。
在每一个子目录中,ansible都会自动找到并读取那个叫main.yml的文件。
创建角色
进入本地ansible-test文件夹,激活虚拟环境:
mkdir nginx # 这里最好就使用roles这个名字
cd nginx
ansible-galaxy init nginx
然后进入nginx,会发现整个role目录已经建立好了。
1. files
里面放置我们需要复制到服务器中的文件
2. handlers
记得放在main.yml文件中:
---
- name: Start Nginx
service:
name: nginx
state: started
- name: Reload Nginx
service:
name: nginx
state: reloaded
前面提到了handler需要被task调用才起作用,我们可以在其他的YAML文件中调用它们
3. meta
这个目录里面的main.yml用于描述角色之间的依赖关系,比如nginx role依赖于ssl role,那么:
---
dependencies:
- {
role: ssl}
这样调用nginx角色时,自动会先调用ssl角色
如果无任何依赖:
dependencies: []
4. Template
这里面不需要有main.yml文件,这里的文件使用的是Jinja2模板引擎的.j2文件
比如我们新建一个文件为serversforhackers.com.conf.j2