文章目录
ansible介绍
Ansible是一种集成IT系统的配置管理、应用部署、执行特定任务的开源平台,它是基于python,Agentless语言,由Paramiko和PyYAML两个关键模块构建。集合了众多运维工具的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。Ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是Ansible所运行的模块,Ansible只是提供一种框架。Ansible不需要在远程主机上安装代理工具,因为它们是基于SSH来和远程主机通讯的。
特性
- 模块化:调用特定的模块,完成特定任务,有Paramiko , PyYAML ,jinja2 (模板语言)三个关键模块,支持自定义模块,可使用任何编程语言写模块
- 基于Python语言实现,部署简单,基于python和SSH(默认已安装),agentless 无需代理
- 安全,基于OpenSSH,不依赖PKI (无需ssl )
- 支持playbook编排任务 YAML格式,编排任务,支持丰富的数据结构
- 幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
ansible组成部分
Ansible 在管理节点将 Ansible 模块通过 SSH 协议推送到被管理端执行,执行完后自动删除,可以使用 SVN 等来管理自定义模块及编排。
ANSIBLE PLAYBOOKS :任务剧本(任务集),编排定义Ansible任务集的配置文件,甶Ansible顺序依次执行,通常是JSON格式的YML文件
INVENTORY : Ansible管理主机的清单 /etc/ansible/hosts
MODULES : Ansible执行命令的功能模块,多数为内置核心模块,也可自定义
PlUGINS :模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插 件等,该功能不常用
API:供第三方程序调用的应用程序编程接口
ANSIBLE :是ansible命令核心执行工具
执行ansible的主机一般称为主控端,中控,master或堡垒机
主控端Python版本需要2.6或以上
被控端Python版本小于2.4,需要安装python-simplejson
被控端如开启SELinux需要安装libselinux-python
ansible安装
这里用两台服务器 192.168.90.21 主 192.168.90.23 从
63上安装ansible
[root@localhost ~]# yum -y install epel-release.noarch
[root@localhost ~]# yum install ansible
目录说明
/etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性
/etc/ansible/hosts 主机清单
/etc/ansible/roles/存放角色的目录
/usr/bin/ansible主程序,临时命令执行工具
/usr/bin/ansible-doc查看配置文档,模块功能查看工具
/usr/bin/ansible-galaxy下载/上传优秀代码或Roles模块的官网平台
/usr/bin/ansible-playbook 定制自动化任务,编排剧本工具
/usr/bin/ansible-pull 远程执行命令的工具
/usr/bin/ansible-vault 文件加密工具
/usr/bin/ansible-console基于Console界面与用户交互的执行工具
命令参数
anisble 命令诧法: ansible [-i 主机文件] [-f 批次] [组名] [-m 模块名称] [-a 模块参数]
ansible 详细参数:
-v,-verbose # 详细模式,如果命令执行成功,输出详细的结果 (-vv –vvv -vvvv)
-i PATH, -inventory=PATH # 指定 host 文件的路径,默认是在 /etc/ansible/hosts
-f NUM,-forks=NUM # NUM 是指定一个整数,默认是 5 ,指定 fork 开启同步迚程的个数。
-m NAME,-module-name=NAME # 指定使用的 module 名称,默认使用 command 模块
-a,MODULE_ARGS #指定 module 模块的参数
-k,-ask-pass #提示输入 ssh 的密码,而丌是使用基亍 ssh 的密钥认证
-sudo #指定使用 sudo 获得 root 权限
-K,-ask-sudo-pass #提示输入 sudo 密码,和 -sudo 一起使用
-u USERNAME,-user=USERNAME # 指定执行用户
-C,-check #测试此命令执行会改变什么内容,不会真正的去执行
ansible-doc 详细参数:
ansible-doc -l #列出所有的模块列表
ansible-doc -s 模块名 #查看挃定模块的参数 -s
配置主机清单及操作示例
主机清单配置在/etc/ansible/hosts 文件中
基于端口,用户,密码定义主机清单
配置文件中,可以写端口,用户,密码,
格式:ansible_ssh_port:指定ssh 端口 ansible_ssh_user:指定 ssh 用户 ansible_ssh_pass:指定 ssh用户密码(明文密码不安全) ansible_sudo_pass:指定 sudo 时候的密码
示例如下:
[master]
192.168.90.21 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=root12345
测试ping
[root@localhost ~]# ansible master -m ping
192.168.90.21 | FAILED! => {
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."
}
[root@localhost ~]# ansible -i /etc/ansible/hosts master -m ping
192.168.90.21 | FAILED! => { ----这个报错是因为目标服务器的指纹未保存在当前服务器上, ssh命令连接下目标主机就会自动个保存目标主机指纹。
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."
}
[root@localhost ~]# ssh root@192.168.90.21
The authenticity of host '192.168.90.21 (192.168.90.21)' can't be established.
ECDSA key fingerprint is SHA256:IGamnwLDHVbkYf3CYTNvCDkJtt3dlPczciHGgs8Btww.
ECDSA key fingerprint is MD5:8c:7a:2c:9e:b8:b4:46:ce:e5:e1:7f:aa:0e:0e:53:6b.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.90.21' (ECDSA) to the list of known hosts.
root@192.168.90.21's password:
Last login: Sat Dec 11 16:12:20 2021 from 192.168.90.6
[root@localhost ~]# exit
登出
Connection to 192.168.90.21 closed.
[root@localhost ~]# ansible -i /etc/ansible/hosts master -m ping
192.168.90.21 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
默认情况下,首次登陆一台服务器,系统会提示是否要记住对端的挃纹,用 ansible 也会这样,这样会导致需要手工输入 yes 戒 no,ansible 才可以往下执行。如需避免这种情况,需要在 /etc/ansible/ansible.cfg 文件中设置 host_key_checking = False
基于 ssh 密钥来访问定义主机清单
生成秘钥,并复制到目标机器
[root@localhost ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:IkyNDGcanLB+1TR7rITBvaeaG7maIHPjxcy6Jyyd/ew root@localhost.localdomain
The key's randomart image is:
+---[RSA 2048]----+
|.oo.+..o |
| .oB +=.+ |
|. . +o.+.o |
|. o. ..o. |
| . .o ..S |
| .+ ..o |
|o+oo=oo |
|o+*+++o |
| .+*.=E |
+----[SHA256]-----+
[root@localhost ~]# ssh-copy-id root@102.168.90.21
...
[root@localhost ~]# ssh-copy-id root@102.168.90.21
主机配置文件中增加如下配置
[keyh]
192.168.90.21
192.168.90.23
测试ping 成功
[root@localhost ~]# ansible -i /etc/ansible/hosts keyh -m ping
192.168.90.21 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.90.23 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
操作示例
目标服务器上执行指定命令
[root@localhost ~]# ansible -m command -a "date" keyh
192.168.90.21 | CHANGED | rc=0 >>
2021年 12月 11日 星期六 16:41:46 CST
192.168.90.23 | CHANGED | rc=0 >>
2021年 12月 11日 星期六 16:41:46 CST
常见模块及高级使用
远程命令模块
commond模块
command 模块为 ansible 默认模块,不指定-m 参数时,使用的就是 command 模块; comand 模块比较简单,常见的命令都可以使用,但其命令的执行不是通过 shell 执行的,所以,像这些 “<”, “>”, “|”, and "&"操作都不可以,不支持管道; 缺点:b不支持管道,没法批量执行命令;
shell模块
shell 模块:使用 shell 模块,在远程命令通过/bin/sh 来执行;所以,我们在终端输入的各种命令方式,都可以使用
[root@localhost ~]# ansible keyh -m shell -a "free -m"
192.168.90.21 | CHANGED | rc=0 >>
total used free shared buff/cache available
Mem: 2827 306 2204 9 316 2285
Swap: 3071 0 3071
192.168.90.23 | CHANGED | rc=0 >>
total used free shared buff/cache available
Mem: 2827 182 2409 9 235 2444
Swap: 3071 0 3071
script模块
script模块:如果待执行的语句很少,可以直接写在一句话中采用shell模块来执行,如果待执行的语句比较多时,可写成一个脚本,通过 copy 模块传到目标服务器,然后再执行;这样就又涉及到两次 ansible 调用;这种需求可以使用script 模块
操作示例
编辑脚本
[root@localhost ~]# vi tes.sh
date
hostname
ps -ef|grep resit
[root@localhost ~]# ansible keyh -m script -a "./tes.sh"
192.168.90.21 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.90.21 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.90.21 closed."
],
"stdout": "2021年 12月 11日 星期六 17:03:55 CST\r\nlocalhost.localdomain\r\nroot 7403 7399 0 17:03 pts/6 00:00:00 grep redis\r\n",
"stdout_lines": [
"2021年 12月 11日 星期六 17:03:55 CST",
"localhost.localdomain",
"root 7403 7399 0 17:03 pts/6 00:00:00 grep redis"
]
}
192.168.90.23 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.90.23 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.90.23 closed."
],
"stdout": "2021年 12月 11日 星期六 17:03:55 CST\r\nlocalhost.localdomain\r\nroot 3532 3528 0 17:03 pts/1 00:00:00 grep redis\r\n",
"stdout_lines": [
"2021年 12月 11日 星期六 17:03:55 CST",
"localhost.localdomain",
"root 3532 3528 0 17:03 pts/1 00:00:00 grep redis"
]
}
copy模块
实现主控端向目标主机拷贝文件,类似 scp 功能
[root@localhost ~]# ansible -m copy keyh -a "src=./tes.sh dest=/root/"
192.168.90.23 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "b8604cfc2a36feebe6b2c0191b0d3d553626f205",
"dest": "/root/tes.sh",
"gid": 0,
"group": "root",
"md5sum": "5533452650c95a49fa593af5dda4ce3f",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 32,
"src": "/root/.ansible/tmp/ansible-tmp-1639213669.61-7477-24860246522919/source",
"state": "file",
"uid": 0
}
192.168.90.21 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"checksum": "b8604cfc2a36feebe6b2c0191b0d3d553626f205",
"dest": "/root/tes.sh",
"gid": 0,
"group": "root",
"mode": "0744",
"owner": "root",
"path": "/root/tes.sh",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 32,
"state": "file",
"uid": 0
}
file 模块
用来设置文件属性
[root@localhost ~]# ansible -m file keyh -a "path=/root/tes.sh mode=0777"
192.168.90.21 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"path": "/root/tes.sh",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 32,
"state": "file",
"uid": 0
}
192.168.90.23 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"path": "/root/tes.sh",
"secontext": "system_u:object_r:admin_home_t:s0",
"size": 32,
"state": "file",
"uid": 0
}
state 模块获取远程文件信息
[root@localhost ~]# ansible -m stat keyh -a "path=/root/tes.sh"
192.168.90.21 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"stat": {
"atime": 1639213422.1644905,
"attr_flags": "",
"attributes": [],
"block_size": 4096,
"blocks": 8,
"charset": "us-ascii"
get_url模块实现进程主机下载挃定 url 到本地
支持 sha256sum 文件校验
[root@localhost ~]# ansible -m get_url keyh -a "url=http://mirrors.aliyun.com/repo/Centos-7.repo dest=/root/ mode=0440 force=yes"
192.168.90.21 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum_dest": null,
...
force=yes,弼下载文件时,如果所下的内容和原目录下的文件内容不一样,则替换原文件,如果一样,就不下载了。
如果为“否”,则仁在目标不存在时才下载文件。 一般来说,只有小型本地文件才应该为“是”
yum 模块 实现软件包管理
yum 模块可以提供的 status 状态: latest ,present,installed #这 3 个代表安装;removed, absent 这 2 个是卸载
[root@localhost ~]# ansible -m yum keyh -a "name=httpd state=latest"
192.168.90.23 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"changes": {
"installed": [
"httpd"
],
"updated": []
},
...
cron 模块进程主机 crontab 配置
增加一个计划任务:每 1 分钟执行 echo date>/root/echotest.txt
[root@localhost ~]# ansible -m cron master -a "name=‘echotest’ minute=*/1 job=‘echo date>/root/echotest.txt’ "
192.168.90.21 | CHANGED => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
},
“changed”: true,
“envs”: [],
“jobs”: [
“echotest”
]
}
service 模块进程主机系统服务管理
service 模块常用参数
(1)、name 参数:此参数用于指定需要操作的服务名称,比如 nginx,httpd。
(2)、state 参数:此参数用于指定服务的状态,比如,我们想要启劢进程主机中的 httpd,则可以将 state 的值设置为 started;如果想要停止进程主机中的服务,则可以将 state 的值设置为 stopped。此参数的可用值有started、stopped、restarted(重启)、reloaded。
(2)、enabled 参数:此参数用于指定是否将服务设置为开机 启动项,设置为 yes 表示将对应服务设置为开机启劢,设置为 no 表示丌会开机启劢。
注:想使用 service 模块启劢服务,被启动的服务,必须可以使用 service 命令启动和关闭
[root@localhost ~]# ansible -m service master -a "name=firewalld state=stopped"
192.168.90.21 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"name": "firewalld",
"state": "stopped",
"status": {
"ActiveEnterTimestampMonotonic": "0",
"ActiveExitTimestampMonotonic": "0",
...
sysctl 模块进程主机 sysctl 配置
[root@localhost ~]# ansible -m sysctl master -a "name=nfs.file-max value=1000000 reload=false"
192.168.90.21 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
user 模块进程主机用户管理
添加用户
[root@localhost ~]# ansible -m user master -a "name=test state=present"
192.168.90.21 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1001,
"home": "/home/test",
"name": "test",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1001
}
使用playbooks
playbooks 使用步骤
playbook 就是将上述的模块命令和参数进行组合,从而实现更加复杂的功能。
示例:编排一个安装nginx的剧本并执行
[root@localhost ansible]# vi nginx.yml
- hosts: slave
become: yes
become_user: root
tasks:
- name: install nginx
yum:
name: nginx
state: present
notify:
- Start Nginx
handlers:
- name: Start Nginx
service:
name: nginx
state: started
执行剧本
[root@localhost ansible]# ansible-playbook nginx.yml
PLAY [slave] ************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************
ok: [192.168.90.23]
TASK [install nginx] ****************************************************************************************************
ok: [192.168.90.23]
PLAY RECAP **************************************************************************************************************
192.168.90.23 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
如一个大的操作,安装lump,可以分为prepare、install php 、install mysql等多个部分,可以将多个部分分别定义为角色,每个角色中定义tasks\handlers\files等,最后在剧本中调用角色,完成最终任务。
这里将上述剧本改造为调用角色来完成,目录及文件内容如下:
[root@localhost roles]# tree --roles目录下创建一个目录/角色 nginx,里边包含 tasks handers 等目录,然后通过总的yml 根据需要调用指定角色来完成最终任务
├── installnginx.yml
├── nginx
│ ├── handlers
│ │ └── main.yml
│ └── tasks
│ └── main.yml
[root@localhost tasks]# vi main.yml ----定义nagin 角色的任务
dd:dd- hosts: slave
become: yes
become_user: root
tasks:
- name: install nginx
yum:
name: nginx
state: present
notify:
- Start Nginx
[root@localhost handlers]# vi main.yml ---定义handlers
- name: Start Nginx
service:
name: nginx
state: started
[root@localhost roles]# vi installnginx.yml --定义剧本 调用nginx角色,如果有多个角色则调用多个角色
- name: install nginx
remote_user: root
hosts: slave
roles:
- nginx
[root@localhost roles]# ansible-playbook installnginx.yml
PLAY [install nginx] ****************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************
ok: [192.168.90.23]
TASK [install nginx] ****************************************************************************************************
ok: [192.168.90.23]
PLAY RECAP **************************************************************************************************************
192.168.90.23 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
其他内容后续补充