0%

ansible

Ansible是一个开源产品,用于自动执行资源的配置管理和应用程序部署。

概述

Ansible是什么?

Ansible作为自动化运维工具,基于Python开发,可实现批量系统配置、批量程序部署、批量运行命令等功能。

Ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。

Ansible特点

  • 部署简单,只需在主控端部署Ansible环境,被控端无需做任何操作;
  • 默认使用SSH协议对设备进行管理;
  • 有大量常规运维操作模块,可实现日常绝大部分操作;
  • 配置简单、功能强大、扩展性强;
  • 支持API及自定义模块,可通过Python轻松扩展;
  • 通过Playbooks来定制强大的配置、状态管理;
  • 轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;
  • 提供一个功能强大、操作性强的Web管理界面和REST API接口——AWX平台。
  • 模块化:调用特定的模块,完成特定任务
  • 有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块
  • 支持自定义模块
  • 基于Python语言实现
  • 部署简单,基于python和SSH(默认已安装),agentless
  • 安全,基于OpenSSH
  • 支持playbook编排任务
  • 幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
  • 无需代理不依赖PKI(无需ssl)
  • 可使用任何编程语言写模块
  • YAML格式,编排任务,支持丰富的数据结构
  • 较强大的多层解决方案

基本概念

在使用Ansible前,您需要了解以下核心概念:

  • Ansible playbook

    Ansible playbook是Ansible的配置、部署和编排语言。它们可以通过YAML的格式描述您希望远程系统执行的一套运维实施策略或一般IT流程中的一系列步骤。

  • Ansible模块

    Ansible 模块是Ansible执行任务的核心。这些模块是独立的代码,可以通过命令行或者Playbook执行。Ansible模块应该具有幂等性。

Ansibel架构图

Ansible任务执行流程

安装

YUM安装

1
2
yum install epel-release -y
yum install ansible –y

配置文件

ansible 的默认配置文件为/etc/ansible/ansible.cfg

常见参数:

1
2
3
4
5
6
7
inventory = /etc/ansible/hosts		#这个参数表示资源清单inventory文件的位置
forks = 5 #并发连接数,默认为5
sudo_user = root #设置默认执行命令的用户
remote_port = 22 #指定连接被管节点的管理端口,默认为22端口,建议修改,能够更加安全
host_key_checking = False #设置是否检查SSH主机的密钥,值为True/False。关闭后第一次连接不会提示配置实例
timeout = 60 #设置SSH连接的超时时间,单位为秒
log_path = /var/log/ansible.log #指定一个存储ansible日志的文件(默认不记录日志)

主机清单

Ansible可同时操作属于一个组的多台主机。组和主机之间的关系通过Inventory文件配置。Ansible Inventory分为静态Inventory和动态Inventory。当被管理主机比较少的情况下,直接在静态Inventory的host文件中管理即可;当主机越来越多,不断变化时,可以通过动态Inventory来管理。


https://docs.ansible.com/ansible/2.8/user_guide/intro_inventory.html

默认清单文件为/etc/ansible/host,也可以使用-i参数指定清单文件,比如

1
ansible -i hosts-tmp all -m ping

主机和组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 不归属于任何组,单独的主机
172.21.5.198
172.21.5.199

# shence 组
[shence]
172.16.250.17
172.16.250.18
172.16.250.19

[k8s-cms-logagent]
172.21.0.157
172.21.2.240
172.21.2.241

非标准端口

1
2
3
badwolf.example.com:5309

jumper ansible_port=5555 ansible_host=192.0.2.50

相似主机

1
2
3
4
5
6
7
8
[zzz]
172.16.250.[17:19]

[webservers]
www[01:50].example.com

[databases]
db-[a:f].example.com

主机变量

1
2
3
[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909

组变量

1
2
3
4
5
6
7
[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

默认组

有两个默认组:allungrouped

all包含每个主机。 ungrouped包含除 之外没有其他组的所有主机all

内置参数

参数 说明
ansible_ssh_host 将要连接的远程主机名
ansible_ssh_port ssh端口号
ansible_ssh_user ssh 用户名
ansible_ssh_pass ssh 密码
ansible_connection 与主机的连接类型,比如docker,localhost
ansible_ssh_private_key_file ssh 使用的私钥文件。如果使用多个密钥并且您不想使用 SSH 代理,则很有用。
ansible_shell_type 目标主机的shell类型,比如csh、fish
ansible_python_interpreter 目标主机的python解释器。

常用命令

命令行工具

https://docs.ansible.com/ansible/2.8/user_guide/command_line_tools.html

ansible-doc

用于获取模块信息、帮助文档

ansible-doc -s MOD_NAME查看模块的帮助文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ansible-doc -s shell

- name: Execute commands in nodes.
shell:
chdir: # cd into this directory before running the command
creates: # a filename, when it already exists, this step will *not* be run.
executable: # change the shell used to execute the command. Should be an absolute path to
the executable.
free_form: # (required) The shell module takes a free form command to run, as a string.
There's not an actual option named "free
form". See the examples!
removes: # a filename, when it does not exist, this step will *not* be run.
stdin: # Set the stdin of the command directly to the specified value.
warn: # if command warnings are on in ansible.cfg, do not warn about this particular
line if set to no/false.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ansible-doc -s command

- name: Executes a command on a remote node
command:
argv: # Allows the user to provide the command as a list vs. a string. Only the
string or the list form can be provided, not
both. One or the other must be provided.
chdir: # Change into this directory before running the command.
creates: # A filename or (since 2.0) glob pattern. If it already exists, this step
*won't* be run.
free_form: # (required) The command module takes a free form command to run. There is no
parameter actually named 'free form'. See the
examples!
removes: # A filename or (since 2.0) glob pattern. If it already exists, this step
*will* be run.
stdin: # Set the stdin of the command directly to the specified value.
warn: # If command_warnings are on in ansible.cfg, do not warn about this particular
line if set to `no'.

ansible

1
ansible <host-pattern> [-f forks] [-m module_name] [-a args]
demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# atlanta组的机器重启,并发数为10
ansible atlanta -a "/sbin/reboot" -f 10

# 指定命名执行的用户
ansible atlanta -a "/usr/bin/foo" -u username

# 文件传输
ansible atlanta -m copy -a "src=/etc/hosts dest=/tmp/hosts"

# 修改文件权限
ansible webservers -m file -a "dest=/srv/foo/a.txt mode=600"
ansible webservers -m file -a "dest=/srv/foo/b.txt mode=600 owner=mdehaan group=mdehaan"

# 创建目录,类似于 mkdir -p
ansible webservers -m file -a "dest=/path/to/c mode=755 owner=mdehaan group=mdehaan state=directory"

# 删除目录(递归)和删除文件
ansible webservers -m file -a "dest=/path/to/c state=absent"

# yum,服务安装
ansible webservers -m yum -a "name=acme state=present" # 安装一个包,但是不更新
ansible webservers -m yum -a "name=acme-1.5 state=present" # 安装指定版本
ansible webservers -m yum -a "name=acme state=latest" # 最新版本
ansible webservers -m yum -a "name=acme state=absent" # 确保未安装

# 用户和组
ansible all -m user -a "name=foo password=<crypted password here>" # 创建账号
ansible all -m user -a "name=foo state=absent" # 删除账号

# git
ansible webservers -m git -a "repo=https://foo.example.org/repo.git dest=/srv/myapp version=HEAD"

# 服务管理
ansible webservers -m service -a "name=httpd state=started" # 启动服务
ansible webservers -m service -a "name=httpd state=restarted" # 重启服务
ansible webservers -m service -a "name=httpd state=stopped" # 停止服务

# 数据采集
ansible all -m setup

ansible web -m setup -a 'filter="*mem*"' # 查看内存

ansible-playbook

demo
1
2
3
4
5
6
7
8
# playbook.yaml

---
- hosts: k8s-veer-logagent
remote_user: root
tasks:
- name : get 'w' info
command: w
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# ansible-playbook playbook.yaml

PLAY [k8s-veer-logagent] ***********************************************************************************

TASK [Gathering Facts] *************************************************************************************
ok: [172.21.2.238]
ok: [172.21.5.198]
ok: [172.21.0.158]
ok: [172.21.2.239]
ok: [172.21.0.159]
ok: [172.21.5.199]

TASK [get 'w' info] ****************************************************************************************
changed: [172.21.0.158]
changed: [172.21.2.238]
changed: [172.21.2.239]
changed: [172.21.0.159]
changed: [172.21.5.198]
changed: [172.21.5.199]

PLAY RECAP *************************************************************************************************
172.21.0.158 : ok=2 changed=1 unreachable=0 failed=0
172.21.0.159 : ok=2 changed=1 unreachable=0 failed=0
172.21.2.238 : ok=2 changed=1 unreachable=0 failed=0
172.21.2.239 : ok=2 changed=1 unreachable=0 failed=0
172.21.5.198 : ok=2 changed=1 unreachable=0 failed=0
172.21.5.199 : ok=2 changed=1 unreachable=0 failed=0
显示输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# cat playbook.yaml

---
- hosts: k8s-veer-logagent
remote_user: root
tasks:
- name : get 'w' info
command: w
register: demoStop
- name: Process Status
debug: var=demoStop.stdout
with_items: demoStop.results

# ansible-playbook playbook.yaml

PLAY [k8s-veer-logagent] ****************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************
ok: [172.21.2.239]
ok: [172.21.0.158]
ok: [172.21.5.198]
ok: [172.21.0.159]
ok: [172.21.2.238]
ok: [172.21.5.199]

TASK [get 'w' info] *********************************************************************************************************
changed: [172.21.2.239]
changed: [172.21.2.238]
changed: [172.21.0.158]
changed: [172.21.0.159]
changed: [172.21.5.198]
changed: [172.21.5.199]

TASK [Process Status] *******************************************************************************************************
ok: [172.21.0.158] => (item=demoStop.results) => {
"demoStop.stdout": " 16:35:45 up 265 days, 18:19, 1 user, load average: 2.72, 2.20, 1.74\nUSER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT\nroot pts/0 172.16.239.23 16:35 1.00s 0.13s 0.02s w",
"item": "demoStop.results"
}
ok: [172.21.0.159] => (item=demoStop.results) => {
"demoStop.stdout": " 16:35:45 up 265 days, 18:19, 1 user, load average: 1.18, 1.40, 2.04\nUSER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT\nroot pts/0 172.16.239.23 16:35 1.00s 0.16s 0.04s w",
"item": "demoStop.results"
}
ok: [172.21.2.238] => (item=demoStop.results) => {
"demoStop.stdout": " 16:35:45 up 265 days, 18:51, 1 user, load average: 1.97, 1.82, 1.53\nUSER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT\nroot pts/0 172.16.239.23 16:35 1.00s 0.12s 0.02s w",
"item": "demoStop.results"
}
ok: [172.21.2.239] => (item=demoStop.results) => {
"demoStop.stdout": " 16:35:45 up 265 days, 18:50, 1 user, load average: 0.52, 0.47, 0.49\nUSER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT\nroot pts/0 172.16.239.23 16:35 1.00s 0.13s 0.02s w",
"item": "demoStop.results"
}
ok: [172.21.5.198] => (item=demoStop.results) => {
"demoStop.stdout": " 16:35:45 up 265 days, 18:24, 1 user, load average: 0.39, 0.46, 0.57\nUSER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT\nroot pts/0 172.16.239.23 16:35 0.00s 0.13s 0.02s w",
"item": "demoStop.results"
}
ok: [172.21.5.199] => (item=demoStop.results) => {
"demoStop.stdout": " 16:35:46 up 265 days, 18:25, 1 user, load average: 1.86, 1.99, 2.06\nUSER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT\nroot pts/0 172.16.239.23 16:35 0.00s 0.14s 0.04s w",
"item": "demoStop.results"
}

PLAY RECAP ******************************************************************************************************************
172.21.0.158 : ok=3 changed=1 unreachable=0 failed=0
172.21.0.159 : ok=3 changed=1 unreachable=0 failed=0
172.21.2.238 : ok=3 changed=1 unreachable=0 failed=0
172.21.2.239 : ok=3 changed=1 unreachable=0 failed=0
172.21.5.198 : ok=3 changed=1 unreachable=0 failed=0
172.21.5.199 : ok=3 changed=1 unreachable=0 failed=0

API

https://docs.ansible.com/ansible/latest/dev_guide/developing_api.html#

https://www.jianshu.com/p/ec1e4d8438e9