Ansible简要笔记
参考http://www.ansible.com.cn/docs
主流的自动化运维工具:Puppet、saltstack、ansible chef
Ansible:用Python编写,采用paramiko协议库
Ansible的组成:
1.核心引擎:Ansible
2.核心模块:
3.自定义模块
4.插件:实现日志记录、邮件等功能
5.playbook:记录执行的任务
6.连接插件:现在主要是ssh,还支持其他(ZeroMQ等)
7.主机清单:记录需要配置的节点信息(文件hosts)
Ansible的优点:
1.语法简单
2.不要安装客户端
3.大量内置模块 用 ansible-doc -l | wc -l 统计可用模块
[root@localhost ~]# ansible-doc -l | wc -l
1652
ansible的配置文件:/etc/ansible/ansible.cfg
CentOS7.4的安装:
[root@localhost ~]#yum install -y ansible
[root@localhost ~]# ansible --version
ansible 2.5.0
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
修改配置文件:/etc/ansible/ansible.cfg
#开启日志
log_path = /var/log/ansible.log
#如果ansible没有和被管理节点配置无密码登录时,会提示没有在known_hosts中初始化,如果不想出现这样的提示,可以在配置文件中设置
host_key_checking = False
其他配置基本不用改
基本命令使用:
#查看版本
[root@localhost ~]# ansible --version
#查看所有可用的内置模块
[root@localhost ~]#
ansible-doc -l #查看模式使用帮助
[root@localhost ~]# ansible-doc -s yum
一、安装:
系统要求:Linux ssh
安装方法:通过系统自带的源进行安装(yum install ansible)
Python:python2.6或python2.7
selinux:如果启用,需要安装libselinux-python
二、使用前配置(可选)
配置客户端无密码登陆:
[root@localhost ~]# ssh-keygen
[root@localhost ~]# ssh-copy-id root@10.100.14.102
#########################################################################
三基本配置文件:
(一)inventory文件(客户端主机的IP/域名)
默认文件位置:/etc/ansible/hosts
几种常见的格式:
#1.直接写IP地址
192.168.1.10
#2.把IP分组
[webserver]
192.168.1.11
192.168.1.12
#3.对于不是以22端口连接的主机,可以指定IP地址
[sql]
192.168.1.20:2222
#4.主机别名设置
[jumper]
jumper ansible_ssh_port=5555 ansible_ssh_host=192.168.1.50
#5.对于有规律的一组IP地址可以简写
[dbserver]
192.168.1.[100:102]
db[1:3].example.com
#6.对用非root用户登录或不同登录方式的主机可以指定连接的用户名
[targets]
localhost ansible_connection=local
other1.example.com ansible_connection=ssh ansible_ssh_user=user1
other2.example.com ansible_connection=ssh ansible_ssh_user=user1
#7.给主机定义变量
[apache]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909
#8.给一组主机定义变量
[atlanta]
host1
host2
[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
#9.把一个组作为另一个组的子成员
[group1]
host1
host2
[group2]
host3
host3
[group:children]
group1
group2
此外,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",比如 \*BSD, 或者 /usr/bin/python
不是 2.X 版本的 Python.我们不使用 "/usr/bin/env" 机制,因为这要求远程用户的路径设置正确,且要求 "python" 可执行程序名不可为 python以外的名字(实际有可能名为python26).
与 ansible_python_interpreter 的工作方式相同,可设定如 ruby 或 perl 的路径....
inventory的升级用法:
/etc/ansible/hosts是ansible中默认的被管理节点的IP存放的文件路径,如果想自己定义,或者想把不同类型的主机存在不同的文件中,可以在/etc/ansible/ansible.cfg中更改配置文件即可。比如:
[root@localhost ~]# vim /etc/ansible/ansible.cfg
inventory = /root/myhosts/
[root@localhost ~]# tree /root/myhosts/
/root/myhosts/
├── dbserver
└── httpd
0 directories, 2 files
[root@localhost ~]# ansible all --list-hosts
hosts (2):
10.100.14.102
192.168.1.2
以上的inventory都是静态hosts配置,对于大量的主机在后期添加起来比较麻烦,ansible还支持动态的inventory
即通过外部拉取主机的IP,inventory的脚本需要支持两个参数,--list(-l),--host(-H)然后返回json格式的主机信息。
#########################################################################
(二)playbook配置文件
hosts 中记录的是客户机的IP地址
playbook 中记录的是客户机要进行的操作
Playbooks 的格式是YAML
palybook的简单实例:
---
- hosts: webservers
vars:
http_port: 80
max_clients: 200
remote_user: root #定义连接的用户名
tasks:
- name: ensure apache is at the latest version
yum: pkg=httpd state=latest
- name: write the apache config file
template: src=/srv/httpd.j2 dest=/etc/httpd.conf
notify:
- restart apache
- name: ensure apache is running
service: name=httpd state=started
handlers:
- name: restart apache
service: name=httpd state=restarted
详细解释:
1.主机与用户:
1.2在任务开始之前定义用户
- hosts: webservers #指定操作对象,webserver是在hosts文件中农定义的一组主机的名字
remote_user: root #定义连接的用户名
1.2在每一个任务中定义远程用户
- hosts: webservers
remote_user: root
tasks:
- name: test connection
ping:
remote_user: username
1.3使用sudo切换用户
---
- hosts: webservers
remote_user: yourname
sudo: yes
或者在任务中使用sudo
---
- hosts: webservers
remote_user: username
tasks:
- service: name=nginx state=started
sudo: yes
或者使用sudo切换到其他用户
- hosts: webservers
remote_user: yourname
sudo: yes
sudo_user: postgres
2.任务(tasks)
tasks的格式;
tasks:
- name: 注释部分
模块名称和执行内容
2.1command模块和shell模块格式
tasks:
- name: disable selinux
command: /sbin/setenforce 0
异常的处理:
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand || /bin/true
或者使用ignore_errors: True
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand
ignore_errors: True
2.2其他模块的格式:
tasks:
- name: make sure apache is running
service: name=httpd state=running
3.Handlers的用法:主要用来重启服务
handlers:
- name: restart memcached
service: name=memcached state=restarted
- name: restart apache
service: name=apache state=restarted
playbook的执行
ansible-playbook playbook.yml
4.playbook中变量
4.1变量的命名和其他语言一致
4.2在playbook中定义变量
- hosts: webservers
vars:
http_port: 80
4.3变量的引用:注意需要加双引号
- hosts: app_servers
vars:
app_path: "{{ base_path }}/22"
5.条件选择
5.1when语句(jinja2)
用法1:
tasks:
- name: "shutdown Debian flavored systems"
command: /sbin/shutdown -t now
when: ansible_os_family == "Debian"
tasks:
- shell: echo "only on Red Hat 6, derivatives, and later"
when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6
用法2:如果变量不存在,可以使用defined跳过
tasks:
- shell: echo "I've got '{{ foo }}' and am not afraid to use it!"
when: foo is defined
- fail: msg="Bailing out. this play requires 'bar'"
when: bar is not defined
用法3:在roles 和 includes 上面应用’when’语句
- include: tasks/sometasks.yml
when: "'reticulating splines' in output"
- hosts: webservers
roles:
- { role: debian_stock_config, when: ansible_os_family == 'Debian' }
ansible中的when
tasks:
- command: /bin/false
register: result
ignore_errors: True
- command: /bin/something
when: result|failed
- command: /bin/something_else
when: result|success
- command: /bin/still/something_else
when: result|skipped
5.2变量注册:返回结果保存到一个变量中,比如
- name: test play
hosts: all
tasks:
- shell: cat /etc/motd
register: motd_contents
- shell: echo "motd contains the word hi"
when: motd_contents.stdout.find('hi') != -1
6.循环
6.1标准循环
- name: add several users
user: name={{ item }} state=present groups=wheel
with_items:
- testuser1
- testuser2
或者:
- name: add several users
user: name={{ item }} state=present groups=wheel
with_items:"{{somelist}}"
或者:
- name: add several users
user: name={{ item.name }} state=present groups={{ item.groups }}
with_items:
- { name: 'testuser1', groups: 'wheel' }
- { name: 'testuser2', groups: 'root' }
6.2循环嵌套
- name: give users access to multiple databases
mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
with_nested:
- [ 'alice', 'bob' ]
- [ 'clientdb', 'employeedb', 'providerdb' ]
或者:
- name: here, 'users' contains the above list of employees
mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
with_nested:
- "{{users}}"
- [ 'clientdb', 'employeedb', 'providerdb' ]
6.3对哈希表使用循环
---
users:
alice:
name: Alice Appleworth
telephone: 123-456-7890
bob:
name: Bob Bananarama
telephone: 987-654-3210
tasks:
- name: Print phone records
debug: msg="User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})"
with_dict: "{{users}}"
6.4对文件列表使用循环
---
- hosts: all
tasks:
# first ensure our target directory exists
- file: dest=/etc/fooapp state=directory
# copy each file over that matches the given pattern
- copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600
with_fileglob:
- /playbooks/files/fooapp/*
6.5对并行数据集使用循环(不常用)
---
alpha: [ 'a', 'b', 'c', 'd' ]
numbers: [ 1, 2, 3, 4 ]
tasks:
- debug: msg="{{ item.0 }} and {{ item.1 }}"
with_together:
- "{{alpha}}"
- "{{numbers}}"
6.6对子元素使用循环
---
users:
- name: alice
authorized:
- /tmp/alice/onekey.pub
- /tmp/alice/twokey.pub
mysql:
password: mysql-password
hosts:
- "%"
- "127.0.0.1"
- "::1"
- "localhost"
privs:
- "*.*:SELECT"
- "DB1.*:ALL"
- name: bob
authorized:
- /tmp/bob/id_rsa.pub
mysql:
password: other-mysql-password
hosts:
- "db1"
privs:
- "*.*:SELECT"
- "DB2.*:ALL"
- user: name={{ item.name }} state=present generate_ssh_key=yes
with_items: "{{users}}"
- authorized_key: "user={{ item.0.name }} key='{{ lookup('file', item.1) }}'"
with_subelements:
- users
- authorized
- name: Setup MySQL users
mysql_user: name={{ item.0.user }} password={{ item.0.mysql.password }} host={{ item.1 }} priv={{ item.0.mysql.privs | join('/') }}
with_subelements:
- users
- mysql.hosts
6.7对整数序列循环(不常用)
---
- hosts: all
tasks:
# create groups
- group: name=evens state=present
- group: name=odds state=present
# create some test users
- user: name={{ item }} state=present groups=evens
with_sequence: start=0 end=32 format=testuser%02x
# create a series of directories with even numbers for some reason
- file: dest=/var/stuff/{{ item }} state=directory
with_sequence: start=4 end=16 stride=2
# a simpler way to use the sequence plugin
# create 4 groups
- group: name=group{{ item }} state=present
with_sequence: count=4
6.8随机选择(不常用)
- debug: msg={{ item }}
with_random_choice:
- "go through the door"
- "drink from the goblet"
- "press the red button"
- "do nothing"
6.9Do-Until循环
- action: shell /usr/bin/foo
register: result
until: result.stdout.find("all systems go") != -1
retries: 5
delay: 10
6.10还有很多不常见的用法,具体参考官方文档
四、文件目录
目录结构
production # 关于生产环境服务器的清单文件
stage # 关于 stage 环境的清单文件
group_vars/
group1 # 这里我们给特定的组赋值
group2 # ""
host_vars/
hostname1 # 如果系统需要特定的变量,把它们放置在这里.
hostname2 # ""
library/ # 如果有自定义的模块,放在这里(可选)
filter_plugins/ # 如果有自定义的过滤插件,放在这里(可选)
site.yml # 主 playbook
webservers.yml # 服务器的 playbook
dbservers.yml # 数据库服务器的 playbook
roles/
common/ # 这里的结构代表了一个 "role"
tasks/ #
main.yml # tasks file can include smaller files if warranted
handlers/ #
main.yml # handlers file
templates/ # files for use with the template resource
ntp.conf.j2 # templates end in .j2
files/ #
bar.txt # files for use with the copy resource
foo.sh # script files for use with the script resource
vars/ #
main.yml # variables associated with this role
defaults/ #
main.yml # default lower priority variables for this role
meta/ #
main.yml # role dependencies
webtier/ # same kind of structure as "common" was above, done for the webtier role
monitoring/ # ""
fooapp/ # ""
五 常用命令
来源:oschina
链接:https://my.oschina.net/u/4324881/blog/4006080