(文章目录)


前言

Ansible是一种自动化工具,可用于部署、配置和管理计算机系统。它是基于Python的开源软件,具有易于使用、可靠、灵活和可扩展等特点,被广泛应用于IT管理领域。

Ansible提供了一个简单而强大的语言,用于描述系统如何配置和管理,称为“Playbook”。它使用SSH协议作为通信渠道,无需在目标主机上安装任何特殊的代理程序或软件包,只需要在控制节点上安装Ansible即可。

通过Ansible,用户可以轻松实现诸如软件包安装、服务启动、文件传输、配置文件修改等任务,并可以将它们组合成更复杂的操作流程。除此之外,还可以利用模板和变量来动态生成配置文件,或者利用Facts获取系统的信息。

最重要的是,Ansible是可扩展的,支持插件机制,可以轻松地编写自定义模块、插件和库,以满足不同场景下的需求。同时,Ansible社区也非常活跃,提供了大量的文档和示例,方便用户学习和使用。

ansible组成

host inventory——主机清单

modules——模块

plugins——插件,实现某个功能的库

playbook——剧本

ansible配置

配置免密通道

[root@web1 ~]# ssh-keygen		# 生成密钥
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 	# 不输入,使用默认目录
Created directory '/root/.ssh'.
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:F6D2e20IAtoO46rwfyvwbPioWvRfUi4CJu+s5Ape9Uc root@web1
The key's randomart image is:
+---[RSA 2048]----+
|        .        |
|       . .       |
|    . o   .      |
|   o o .   .     |
|. B ... SE.      |
| *.*. .+.+ o     |
|o.+*+ o.+.o o    |
|**o.=o.+.. .     |
|@==+ooo.         |
+----[SHA256]-----+
[root@web1 ~]# cd /root/.ssh/
[root@web1 .ssh]# ls		# 公钥私钥文件
id_rsa  id_rsa.pub
[root@web1 .ssh]# ssh-copy-id -i id_rsa.pub root@192.168.10.139		# 分发公钥
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "id_rsa.pub"
The authenticity of host '192.168.10.139 (192.168.10.139)' can't be established.
ECDSA key fingerprint is SHA256:ttyWNvrI38R3W95ovlB/4fseSAdmIql3cxM9jA1HxOE.
ECDSA key fingerprint is MD5:83:50:45:4e:7e:76:eb:8c:d1:9d:25:a7:cd:ca:76:a0.
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@192.168.10.139's password: 	# 输入对应服务器密码

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.10.139'"
and check to make sure that only the key(s) you wanted were added.

# 同样分发到所有需要ansible管理的服务器上
# 对Ubuntu系统服务器配置时,如果没开启root远程登录就只能配置其他用户

安装

yum install epel-release -y
yum install ansible -y

配置文件与可执行文件

1、配置与执行文件说明

ansible的主配置文件:/etc/ansible/ansible.cfg

这个文件主要定义了roles_path路径,主机清单路径,连接清单中主机的方式等配置,这些大部分的默认配置已经足够我们平时使用,如需要特别配置可以自行去修改;

默认主机清单配置文件:/etc/ansible/hosts

可通过ansible.cfg重新定义的;

除了以上两个重要的配置文件,还有三个重要的可执行文件都放在/etc/bin/目录下

分别是:

ansible 主执行程序,一般用于命令行下执行

ansible-playbook 执行playbook中的任务

ansible-doc 获取各模块的帮助信息

配置主机清单

写明控制主机的信息,如ip、端口号、用户名、密码、域名等等

[root@nfs .ssh]#  vim /etc/ansible/hosts
[webnodes]
192.168.10.137
192.168.10.138
192.168.10.139
[LBnodes]
192.168.10.129  ansible_ssh_user='root' ansible_ssh_pass='123456' 	# 不配置免密就需要在后面声明用户和密码
192.168.10.143  ansible_ssh_user='root' ansible_ssh_pass='123456'	# 但是明文不安全,而且密码不建议用000000
[dokcerUbu]
192.168.10.133  ansible_ssh_user='zh'   ansible_become_password='000000'	# Ubuntu系统

如果不配置ssh免密登录,明文声明用户和密码后还需先手动远程连接一次,保证客户机的known_hosts文件中有ansible主机的ip记录,因为sshpass 工具不支持此功能

Ubuntu系统默认不允许root用户远程登录,当执行一些需要root权限的命令时,需切换到root用户,这时就需要在主机清单中写明切换用户时使用的密码

ansible-doc 获取帮助信息

ansible模块比较多,可以通过ansible-doc --help 显示帮助信息 ansible-doc -l 获取所有当前版本下的可用模块及简要信息,目前估计有一二千个

ansible-doc -s 模块名 获取指定模块帮助信息说明

ansible 使用格式

ansible HOST-PATTERN [选项]

HOST-PATTERN #匹配主机模式,如all表示所有主机,也可指定为hosts文件中的主机组标签 -m MOD_NAME #模块名 如:ping -a MOD_ARGS #模块执行的参数 -f FORKS #生成几个子进行程执行 -C #(不执行,模拟跑) -u Username #某主机的用户名 -c CONNection #连接方式(default smart)

完整示例:

[root@ansible ~]# ansible all -m shell -a "ifconfig|grep enp0s3"
172.16.3.152 | SUCCESS | rc=0 >>
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

172.16.3.216 | SUCCESS | rc=0 >>
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

ansible使用模块

copy模块

[root@nfs ansible]# ansible webnodes -m copy -a "src=/root/test.sh dest=/root/"

src本地源文件,dest目标目录

注意src= 路径后面带/ 表示带里面的所有内容复制到目标目录下,不带/是目录递归复制过去

script模块

Ansible的script模块可以在远程主机上执行本地主机的脚本。脚本将在控制节点上进行复制,然后通过SSH传输到远程主机并在那里执行。

[root@nfs ansible]# ansible webnodes -m script -a "/root/test.sh"

fetch模块

[root@nfs ansible]# ansible webnodes -m fetch -a "src=/etc/passwd dest=/tmp"

将远程主机文件拿过来

shell模块

[root@ansible ~]# ansible all -m shell -a "ifconfig|grep lo"

能够用其他模块实现的功能不推荐使用shell模块

file模块

设置文件属性/创建文件/删除文件 常用参数: path目标路径 state:directory为目录,link为软链接,touch为文件,hard为硬链接,absent为删除文件 group 目录属组 owner 属主 等,其他参数通过ansible-doc -s file 获取

[root@ansible ~]# ansible all -m file -a "path=/var/tmp/hello.dir state=directory"	# 创建目录

service模块

服务管理模块 常用参数: name:服务名 state:服务状态 started、restarted、stopped、reloaded enabled:是否开机启动 true|false runlevel:启动级别 (systemed方式忽略)

[root@ansible ~]# ansible all -m service -a "name=nginx state=started enabled=true"

yum模块

故名思义就是yum安装软件包的模块; 常用参数说明: enablerepo,disablerepo表示启用与禁用某repo库 name 安装包名 state (present' or installed’, latest')表示安装, (absent’ or `removed’) 表示删除

[root@ansible ~]# ansible all -m yum -a "name=epel-release state=installed"

cron模块

通过cron模块对目标主机生成计划任务 常用参数: 除了分(minute)时(hour)日(day)月(month)周(weekday)外 name: 本次计划任务的名称 state: present 生成(默认) |absent 删除 (基于name)

[root@ansible ~]# ansible all -m cron -a "minute=*/3 job='/usr/sbin/update time.windows.com &>/dev/null'  name=update_time"		# 每三分钟更新时间
[root@nfs tmp]# ansible webnodes -m cron -a "minute=0 hour=8-18 month=5 weekday=1-5 job='bash /root/test.sh' name=ansiblecron"

setup模块

查看ansible在各个主机的内置变量

[root@nfs playbooks]# ansible webnodes -m setup

其它模块还有非常多

Playbook

playbook就是指导手册,或者说是剧本,是基于YAML语言格式配置

1、playbook的核心元素

hosts:playbook配置文件作用的主机 tasks:任务列表 variables: 变量 templates:包含模板语法的文本文件 handlers :由特定条件触发的任务——通过notify触发 roles :用于层次性、结构化地组织playbook。roles 能够根据层次型结构自动装载变量文件、tasks以及handlers等

2、playbook使用方法

  • ansible-playbook --check :只检测可能会发生的改变,但不真执行操作

  • ansible-playbook --list-hosts :列出运行任务的主机

  • ansible-playbook --syntax-check playbook.yaml :语法检测

  • ansible-playbook -t TAGS_NAME playbook.yaml :只执行TAGS_NAME任务

  • ansible-playbook playbook.yaml :运行

3.通过playbook安装epel-release软件源

[root@nfs ansible]# mkdir playbooks
[root@nfs ansible]# cd playbooks/
[root@nfs playbooks]# vim epel_install.yaml
- hosts: webnodes		# 操作主机
  remote_user: root
  tasks:
  - name: install epel		# 操作命名
    yum: name=epel-release state=latest

- hosts: dockerUbu		# Ubuntu系统主机
  remote_user: zh		# 远程连接普通用户
  become: yes			# 开启用户切换
  become_method: su		# 切换方法
  become_user: root		# 切换用户
  tasks:
  - name: install epel
    apt: name=epel-release state=latest		# 安装使用apt模块
语法检测
[root@nfs playbooks]# ansible-playbook --syntax-check epel_install.yaml 

playbook: epel_install.yaml

说明语法没有问题

查看将要执行的主机
[root@nfs playbooks]# ansible-playbook --list-hosts epel_install.yaml

playbook: epel_install.yaml

  play #1 (webnodes): webnodes	TAGS: []
    pattern: [u'webnodes']
    hosts (3):
      192.168.10.137
      192.168.10.138
      192.168.10.139
检测能否成功执行
[root@nfs playbooks]# ansible-playbook --check epel_install.yaml 

PLAY [webnodes] ********************************************************************************

TASK [Gathering Facts] *************************************************************************
ok: [192.168.10.139]
ok: [192.168.10.138]
ok: [192.168.10.137]

TASK [install epel-release] ********************************************************************
changed: [192.168.10.139]
changed: [192.168.10.137]
changed: [192.168.10.138]

PLAY RECAP *************************************************************************************
192.168.10.137             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.10.138             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.10.139             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
执行
[root@nfs playbooks]# ansible-playbook epel_install.yaml 

PLAY [webnodes] ********************************************************************************

TASK [Gathering Facts] *************************************************************************
ok: [192.168.10.139]
ok: [192.168.10.137]
ok: [192.168.10.138]

TASK [install epel-release] ********************************************************************
changed: [192.168.10.138]
changed: [192.168.10.139]
changed: [192.168.10.137]

PLAY RECAP *************************************************************************************
192.168.10.137             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.10.138             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.10.139             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

4.通过playbook安装并配置redis服务

只是以配置redis服务为例,其他服务可以参考进行配置

[root@ansible ~]$ ansible 172.16.3.152 -m fetch -a "src=/etc/redis.conf dest=./"	# 先从别的主机拿一个配置文件
[root@ansible ~]$ mv /root/172.16.3.152/etc/redis.conf  /root/playbooks/redis.conf	# 移动到playcooks目录下
修改bind 0.0.0.0		# 修改配置文件

$ cat redis_second.yaml
- hosts: all                   #所有远程主机
  remote_user: root      #以远程主机上root用户执行
  tasks:                        #任务
  - name: install redis      #任务之安装
    yum: name=redis state=latest        #动作调用yum模块安装
  - name: copy config file     #任务之复制同步配置文件到远程目标主机
    copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf owner=redis #需修改属主,Ubuntu需放在/etc/redis/下
    notify: restart redis      #触发的动作,执行该任务时会触发执行handlers中的对应任务
    tags: configfile         #任务标记名configfile,可通过-t指定执行该命令
  - name: start redis      #任务之启动redis
    service: name=redis state=started    #动作调用sevice模块
  handlers:              #特定情况下,接收到其他任务的通知时被触发
  - name: restart redis
    service: name=redis state=restarted

handlers板块和notify指令的配合使用非常好用

tags的使用也很关键

5.只执行指定任务

[root@ansible playbooks]# ansible-playbook -t configfile redis_second.yaml

以上执行结果就没有了安装与启动的步骤,只有更新和重启!

6.活用var和template

var指定变量,变量可以是数字、字符串、文件路径等等,文件中可以使用ansible setup中的变量或者var中其他的变量

变量使用格式:{{ 变量名 }}

如IP地址使用格式:{{ ansible_facts["ens33"]["ipv4"]["address"] }},对应的是ansible setup中的路径:

192.168.10.137 | SUCCESS => {
    "ansible_facts": {
		……
		"ansible_ens33": {
        	……
            "ipv4": {
                "address": "192.168.10.137", 
                "broadcast": "192.168.10.255", 
                "netmask": "255.255.255.0", 
                "network": "192.168.10.0"
            }, 

template与copy模块差不多,都可以实现将文件从管理节点上传到服务器节点,但是template模块可以在模板文件里可以使用变量

$ cat redis_second.yaml
- hosts: all
  remote_user: root
  vars:		# 定义变量
  -	scredis: /lianxi/playbooks/redis.conf.j2	# 模板文件,当中使用到了内置变量
  -	redis_port: 6399
  tasks:
  - name: install redis
    yum: name=redis state=latest
  - name: copy config file
    template: src={{ scredis }} dest=/etc/redis.conf owner=redis	# 使用在var中定义的变量直接写变量即可