Ansible 是一款简单且强大的自动化配置管理、应用部署和任务编排工具,在 IT 领域被广泛使用,以下是关于它的详细介绍:
- 基本概念:Ansible 基于 Python 开发,使用 SSH 协议与目标主机进行通信,无需在目标主机上安装额外的客户端软件。它通过 Playbook(剧本)来定义一系列自动化任务,使用 YAML 语言编写,易于理解和编写。同时,它还拥有丰富的模块,可以执行各种系统管理任务,如软件安装、文件操作、服务管理等。
- 主要功能
- 配置管理:能够轻松地对多台服务器进行配置,确保所有服务器的配置一致。比如,可以使用 Ansible 配置服务器的网络参数、用户账户、软件包安装等。
- 应用部署:简化应用程序的部署过程。无论是 Web 应用、数据库还是其他类型的应用,都可以通过 Ansible 快速部署到多台服务器上。例如,将一个 Python 应用部署到多个服务器节点上,实现分布式部署。
- 任务编排:可以按照指定的顺序执行一系列任务,并且可以处理任务之间的依赖关系。比如,在部署应用之前,先安装必要的软件包,然后配置相关的环境变量,最后启动应用服务。
- 批量执行命令:在多台服务器上同时执行命令,提高管理效率。例如,可以同时在多台服务器上查看系统日志、清理临时文件等。
- 核心组件
- Ansible 控制节点:运行 Ansible 命令和 Playbook 的服务器,用于管理目标主机。
- Inventory(清单):定义了 Ansible 要管理的目标主机列表及其相关信息,可以按组进行组织。例如,可以将 Web 服务器分为一组,数据库服务器分为另一组。
- Playbook(剧本):是 Ansible 的配置、部署、编排任务的脚本,由一个或多个 “play” 组成,每个 “play” 定义了一组要在指定主机上执行的任务。
- Module(模块):Ansible 执行具体任务的功能单元,如
yum
模块用于软件包管理,service
模块用于服务管理等。
- 优势特点
- 简单易用:使用 YAML 语言编写 Playbook,语法简洁明了,学习成本低。
- 轻量级:无需在目标主机上安装复杂的客户端软件,减少了系统资源的占用。
- 安全性高:基于 SSH 协议进行通信,支持密钥认证,保证了数据传输的安全性。
- 扩展性强:拥有大量的内置模块,并且用户可以根据需求自定义模块,满足各种复杂的管理需求。
- 幂等性:多次执行同一个 Playbook 的结果是一致的,不会对系统造成额外的影响,确保了自动化任务的可靠性。
Ansible 主要使用 YAML 语言编写 Playbook 来定义自动化任务,下面为介绍一些常见的 Ansible 语法元素:
- Playbook 基本结构:一个 Playbook 由一个或多个
play
组成,每个play
用于定义一组要在特定主机上执行的任务。
---
- name: Example play
hosts: web_servers # 目标主机组
become: yes # 提升权限,如使用 sudo
tasks:
- name: Install a package
yum:
name: httpd
state: present
在这个示例中,---
表示 YAML 文件的开始,name
是对 play
的描述,hosts
指定了要执行任务的目标主机组,become
用于设置是否提升权限,tasks
部分包含了一系列具体的任务。
2. Inventory(清单)语法:Inventory 用于定义 Ansible 要管理的主机和主机组。可以是一个简单的文本文件,也可以使用动态清单。
# 单个主机
webserver1 ansible_host=192.168.1.10 ansible_user=root
# 主机组
[web_servers]
webserver1
webserver2
[db_servers]
dbserver1 ansible_host=192.168.1.20 ansible_user=root
在这个示例中,ansible_host
指定了主机的 IP 地址,ansible_user
指定了连接主机时使用的用户名。主机组用中括号 []
定义。
3. 任务(Tasks)语法:每个任务通常由一个模块及其参数组成。
- name: Create a directory
file:
path: /var/www/html
state: directory
mode: '0755'
这里使用了 file
模块,path
参数指定了目录的路径,state: directory
表示要创建一个目录,mode
参数设置了目录的权限。
- name: Start a service
service:
name: httpd
state: started
enabled: yes
service
模块用于管理系统服务,name
指定服务名称,state
可以是 started
(启动)、stopped
(停止)等,enabled
设置服务是否开机自启。
5. 变量(Variables)语法:可以在 Playbook、Inventory 或单独的变量文件中定义变量,然后在任务中使用。
---
- name: Use variable example
hosts: all
vars:
package_name: nginx # 定义变量
tasks:
- name: Install the package
yum:
name: "{{ package_name }}" # 使用变量
state: present
在这个示例中,vars
部分定义了变量 package_name
,然后在 yum
模块中使用 {{ package_name }}
来引用该变量。
6. 条件语句(Conditional)语法:使用 when
关键字来设置任务执行的条件。
- name: Install a package on specific OS
yum:
name: httpd
state: present
when: ansible_os_family == "RedHat"
这个任务只会在目标主机的操作系统家族为 RedHat
(如 CentOS、RHEL 等)时执行。
7. 循环(Looping)语法:可以使用 with_items
来对列表进行循环操作。
- name: Create multiple users
user:
name: "{{ item }}"
state: present
with_items:
- user1
- user2
- user3
这个任务会为列表中的每个用户名创建一个用户账户。
这些是 Ansible 的一些基本语法,通过组合和扩展这些语法元素,可以实现复杂的自动化任务。
###环境准备两台虚拟机
1.ansible
2.node1
1.双节点编辑hosts文件,进行映射
[root@ansible ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.179.164 node1
192.168.179.160 ansible
2.修改主机名,主控制节点使用ansible来命名,由于ansible可以跨平台实现自动化运维但是这里需要注意的是它不能在windows来作为主节点
[root@ansible ~]# hostnamectl set-hostname ansible && bash
[root@localhost ~]# hostnamectl set-hostname node1 && bash
[root@node1 ~]#
3.双节点关闭防火墙设置selinux模式为Permissive
systemctl disable firewalld --now
setenforce 0
4.主节点配置本地源
[root@ansible ~]# rm -rf /etc/yum.repos.d/*
[root@ansible ~]# cat /etc/yum.repos.d/ftp.repo
[centos]
name=centos
gpgcheck=0
baseurl=file:///opt/centos
[ansible]
name=centos
gpgcheck=0
baseurl=file:///opt/ansible
5.主节点安装vsftpd服务,设置匿名访问,并设置共享目录为opt
1.yum install -y vsftpd
2.echo 'anon_root=/opt'>>/etc/vsftpd/vsftpd.conf
3.systemctl restart vsftpd
6.分发密钥,这里一直回车即可
ssh-keygen -t rsa
7.免密认证
[root@ansible ~]# ssh-copy-id node1
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host 'node1 (192.168.179.164)' can't be established.
ECDSA key fingerprint is SHA256:Yj6nmNXS4FTd1esYP7WLVK2I8kTNqxQ8NVH330dig1Y.
ECDSA key fingerprint is MD5:d7:7b:61:96:45:f8:63:f5:4f:43:7d:ee:99:99:d5:06.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@node1's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'node1'"
and check to make sure that only the key(s) you wanted were added.
8.复制本地源配置,到当前的一个目录下
cp -r /etc/yum.repos.d/ftp.repo /root/example/roles/
9.由于我们配置了ftp服务,所以其它节点是不需要具有本地源的
[root@ansible ~]# cat example/roles/ftp.repo
[centos]
name=centos
gpgcheck=0
baseurl=ftp://ansible/centos
[ansible]
name=centos
gpgcheck=0
baseurl=ftp://ansible/ansible
10.安装ansible服务
[root@ansible ~]# yum install -y ansible
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
软件包 ansible-2.9.10-1.el7.noarch 已安装并且是最新版本
无须任何处理
11. Inventory清单配置
[root@ansible ~]# vi /etc/ansible/hosts
## blue.example.com
## 192.168.100.1
## 192.168.100.10
# Ex 2: A collection of hosts belonging to the 'webservers' group
## [webservers]
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110
# If you have multiple hosts following a pattern you can specify
# them like this:
## www[001:006].example.com
# Ex 3: A collection of database servers in the 'dbservers' group
## [dbservers]
##
## db01.intranet.mydomain.net
## db02.intranet.mydomain.net
## 10.25.1.56
## 10.25.1.57
# Here's another example of host ranges, this time there are no
# leading 0s:
## db-[99:101]-node.example.com
[node1]
192.168.179.164
12.测试连通性,当ping:pong有这个显示,就说明我们配置成功了
[root@ansible ~]# ansible node1 -m ping
192.168.179.164 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
13.编写一些简单的剧本
[root@ansible roles]# ll
总用量 8
-rw-r--r--. 1 root root 125 3月 27 19:06 ftp.repo
drwxr-xr-x. 10 root root 154 3月 27 19:04 mariadb
-rw-r--r--. 1 root root 321 3月 27 19:19 service.yaml
[root@ansible roles]# vi service.yaml
---
- hosts: all
remote_user: root
tasks:
- name: rm old repo
shell: rm -rf /etc/yum.repos.d/*
- name: copy ftp.repo
copy:
src: ftp.repo
dest: /etc/yum.repos.d/
- name: node1 install packges
yum:
name:
- vsftpd
- chrony
state: present
14.执行命令,让受控节点跟着我们的剧本走
[root@ansible roles]# ansible-playbook service.yaml
PLAY [all] ********************************************************************************
TASK [Gathering Facts] ********************************************************************
ok: [192.168.179.164]
TASK [rm old repo] ************************************************************************
[WARNING]: Consider using the file module with state=absent rather than running 'rm'. If
you need to use command because file is insufficient you can add 'warn: false' to this
command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.
changed: [192.168.179.164]
TASK [copy ftp.repo] **********************************************************************
changed: [192.168.179.164]
TASK [node1 install packges] **************************************************************
changed: [192.168.179.164]
PLAY RECAP ********************************************************************************
192.168.179.164 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0