Ansible

一.概述

由于互联网的快速发展导致产品更新换代速度逐渐加快,运维人员每天都要进行大量的维护操作,任按照旧传统方式进行维护使得工作效率低下。这是,部署自动化运维就可以尽可能安全,高效地完成这些工作。

一般,自动化运维工具划分为两类:一类是需要使用代理工具的,也就是基于专用的Agent程序完成管理工作,如:Puppet,Func,Zabbix等;另外一类是不需要配置代理工具的,可以直接基于SSH原理来完成管理功能,如:Ansible,Fabric等

1.Puppet

Puppet基于Rubby开发,支持Linux,Unix,Windows平台,可以针对用户,系统服务,配置文件,软件包,等进行管理,有较强的扩展性,但远程执行命令相对较弱。

2.SaltStack

SaltStack基于python开发,允许管理员对多个操作系统创建统一的管理系统,比Puppet更轻量级。

3.Ansible

Ansible基于python开发,集合了众多优秀运维工具的优点,实现了批量运行命令,部署程序,配置系统等功。默认通过SSH协议进行远程命令执行或下发配置,无需配置任何客户端代理软件,从而使得自动化环境部署变得更加简单。可同时支持多台主机并行管理,是的管理主机更加便捷。

工具

开发语言

结构

配置文件格式

运行任务

Ansible

pthon


YAML

执行命令行

SaltStack

Python

C/S

YAML

支持命令行

Puppet

Ruby

C/S

Ruby语法格式

通过模块实现

二.Ansible核心组件

ansible可以看作是一种基于模块进行工作的框架结构,批量部署能力就是由Ansible所允许的模块实现的。ansible是基于“模块”完成各种“任务”的。其基本框架架构为:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cJ09hcGj-1599490966056)(file:///

linux自动化运维平台 linux 自动化运维工具_运维


)]

Ansible基本框架是由六个部分构成的:

Ansible core核心引擎

Host inventory:用来定义Ansible所管理的主机,默认是在Ansible的hosts配置文件中定义被管理主机,同时也支持自定义动态主机清单和指定其他配置文件的位置

Connection plugins链接插件:负责和被管理主机实现通信。除支持使用ssh链接被管理主机外,Ansible还支持其他的链接方式,所以需要有连接插件将各个主机用连接插件连接到Ansible

Playbooks(yam1,yam2)剧本:用来集中定义Ansible任务的配置文件,即将多个任务定义在一个剧本中由Ansible自动执行,可以由控制主机针对多台被管理主机同时运行多个任务

Core modules核心模块:是Ansible自带的模块,使用这些模块将资源分发到被管理主机,使其执行特定任务或匹配特定的状态。

Custom modules自定义模块:用于完成模块功能的补充,可借助相关插件完成记录日志,发送邮件的功能。

三.安装部署Ansible服务

Ansible自动化运维环境由控制主机与被管理主机组成,由于Ansible是基于SSH协议进行通信的,所以控制主机安装Ansible软件后不需要重启或运行任何程序,被管理主机也不需要安装和运行任何代理程序。

电脑配置不行,就只开了两台centos 7.4主机

角色

主机名

IP地址

控制主机

pc1

192.168.133.138

被管理主机

pc2

192.168.133.141

1.安装Ansible

[root@localhost ~]# yum install epel-release -y #安装epel源

[root@localhost ~]# yum install ansible -y #安装ansible

[root@localhost ~]# ansible --version    #查看版本
ansible 2.9.10
  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)]

2.配置主机清单

Ansible通过读取默认主机清单/etc/ansible/hosts文件,修改主机与组配置后,可同时链接到多个被管理主机上执行任务。比如定义一个webserver组,包含pc2主机,ip:192.168.131.141

[root@localhost ansible]# cat hosts | grep -v -e "#"
i This is the default ansible 'hosts' file.



[webserver]
192.168.131.141

3.设置SSH无密码登录

问题:linux root用户下没有.ssh目录

.ssh 是记录密码信息的文件夹,如果没有登录过root的话,就没有 .ssh 文件夹,因此登录 localhost ,并输入密码就会生成了

ssh localhost

[root@localhost ~]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -N ''
Generating public/private rsa key pair.
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:VBFxrWSiaFFfDZVx7JGFnNcAyX3/7SVZrsLBrWYrXTA root@localhost.localdomain
The key's randomart image is:
+---[RSA 2048]----+
|       .. ===X+B*|
|      .  o.o= O+=|
|       o...+ . +o|
|      o..   E   +|
|     .  S  . + +o|
|            o = =|
|           o + +.|
|          . B . .|
|           +.o   |
+----[SHA256]-----+
[root@localhost ~]# ssh-copy-id root@192.168.133.141

四.Ansible命令应用基础

Ansible可以使用命令行方式进行自动化管理,基础语法:

ansible < host-pattern > [-m module_name] [-a args]

< host-pattern > 对那些主机生效

[-m module_name] 要使用的模块

[-a args] 模块特有的参数

Ansible的命令行管理工具都是由一系列模块,参数所支持的,-h或者–help得到帮助。如使用ansible-doc工具可以通过ansible-doc -h或ansible-doc --help查看帮助信息

ansible自带了很多模块,能够处理执行ansible的各种管理任务。

了解核心模块:

1.command模块

Ansible管理工具使用-m选项来指定使用模块,默认使用Command模块,即-m选项省略时会运行此模块,用于在被管理主机上运行命令

如在被管理主机上执行date命令,显示被管理主机的时间。

[root@localhost ~]# ansible webserver -m command -a 'date'
192.168.133.141 | CHANGED | rc=0 >>
Mon Sep  7 19:40:10 CST 2020
[root@localhost ~]# ansible 192.168.133.141 -m command -a 'date'
192.168.133.141 | CHANGED | rc=0 >>
Mon Sep  7 19:40:48 CST 2020
[root@localhost ~]# ansible all -m command -a 'date'
192.168.133.141 | CHANGED | rc=0 >>
Mon Sep  7 19:41:21 CST 2020

注意:如果省略-m选项,默认运行command模块

[root@localhost ~]# ansible all -a 'tail -1 /etc/passwd'
192.168.133.141 | CHANGED | rc=0 >>
cat7: x:1000:1000:cat7:/home/cat7:/bin/bash

2.cron模块

Ansible中的cron模块用于定义任务计划。其中有两种状态(statr):present表示添加(省略状态时默认使用) absent表示移除

[root@localhost ~]# ansible webserver -m cron -a 'minute="*/1" job="/bin/echo/hello" name="test cron job"'
192.168.133.141 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "envs": [],
    "jobs": [
        "test cron job"
    ]
}
[root@localhost ~]# ansible webserver -a 'crontab -l'
192.168.133.141 | CHANGED | rc=0 >>
#Ansible: test cron job
*/1 * * * * /bin/echo/hello
[root@localhost ~]# ansible webserver -m cron -a 'minute="*/1" job="/bin/echo/hello" name="test cron job state="absent""'
192.168.133.141 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "envs": [],
    "jobs": [
        "test cron job",
        "test cron job state=\"absent\""
    ]
}

[root@localhost ~]# ansible webserver -a 'crontab -l'
192.168.133.141 | CHANGED | rc=0 >>
#Ansible: test cron job
*/1 * * * * /bin/echo/hello
#Ansible: test cron job state="absent"
*/1 * * * * /bin/echo/hello

3.user模块

user模块用于创建用户和更改,删除已存在的用户。其中name选项用来指定创建的用户名称

[root@localhost ~]# ansible webserver -m user -a 'name="cat77"'
192.168.133.141 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "comment": "",
    "create_home": true,
    "group": 1001,
    "home": "/home/cat77",
    "name": "cat77",
    "shell": "/bin/bash",
    "state": "present",
    "system": false,
    "uid": 1001
}

[root@localhost ~]#

[root@localhost ~]# ansible webserver -m user -a 'name="cat77" state=absent'
192.168.133.141 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "force": false,
    "name": "cat77",
    "remove": false,
    "state": "absent"
}

[root@localhost ~]# ansible webserver -a 'tail -1 /etc/passwd'
192.168.133.141 | CHANGED | rc=0 >>
cat7: x:1000:1000:cat7:/home/cat7:/bin/bash

4.group模块

group模块用于对用户组进行管理

[root@localhost ~]# ansible webserver -m group -a 'name=wgroup gid=306 system=yes'
192.168.133.141 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "gid": 306,
    "name": "wgroup",
    "state": "present",
    "system": true
}
[root@localhost ~]# ansible webserver -a 'tail -1 /etc/group'
192.168.133.141 | CHANGED | rc=0 >>
wgroup:x:306:

[root@localhost ~]# ansible webserver -m user -a 'name=stu2 uid=1001 system=yes group=wgroup'
192.168.133.141 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "comment": "",
    "create_home": true,
    "group": 306,
    "home": "/home/stu2",
    "name": "stu2",
    "shell": "/bin/bash",
    "state": "present",
    "system": true,
    "uid": 1001
}

[root@localhost ~]# ansible webserver -a 'groups stu2'
192.168.133.141 | CHANGED | rc=0 >>
stu2 : wgroup

[root@localhost ~]# ansible webserver -m group -a 'name=wgroup gid=305 system=no state=absent'
192.168.133.141 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "msg": "groupdel: cannot remove the primary group of user 'stu2'\n",
    "name": "wgroup"
}

5.copy模块

copy用于实现文件复制和批量下发文件。其中使用src来定义本地源文件路径,使用dest定义被管理主机文件路径,使用content则是通过指定信息内容来生成目标文件

将服务机上内容复制到pc2上并赋予不同文件不同权限

[root@localhost ~]# ansible webserver -m copy -a 'src=/etc/hosts dest=/etc/hosts owner=root mode=640'
192.168.133.141 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "checksum": "57ea0c22bb38854900c9e6c3fc6873fd2147d3f7",
    "dest": "/etc/hosts",
    "gid": 0,
    "group": "root",
    "md5sum": "e206d015008b3c787b8fb3c00077a5d5",
    "mode": "0640",
    "owner": "root",
    "secontext": "system_u:object_r:net_conf_t:s0",
    "size": 169,
    "src": "/root/.ansible/tmp/ansible-tmp-1599480168.99-56681-213686162287559/source",
    "state": "file",
    "uid": 0
}

pc2:

[root@localhost ~]# ls -l /etc/hosts
-rw-r-----. 1 root root 158 Jun  7  2013 /etc/hosts
[root@localhost ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6


testtest

6.File模块

使用file模块来这是文件属性,其中path指定文件路径,使用src定义源文件路径,使用name或dest来替换创建文件的符号链接

eg 1:

[root@localhost ~]# ansible webserver -m file -a 'owner=stu2 group=stu2 mode=544 path=/etc/hosts'
192.168.133.141 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "gid": 0,
    "group": "root",
    "mode": "0640",
    "msg": "chgrp failed: failed to look up group stu2",
    "owner": "stu2",
    "path": "/etc/hosts",
    "secontext": "system_u:object_r:net_conf_t:s0",
    "size": 169,
    "state": "file",
    "uid": 1001
}

-rw-r-----. 1 stu2 root 169 Sep  7 20:02 /etc/hosts
[root@localhost ~]#

eg:2

nk src=/etc/fstab state=link'
192.168.133.141 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "dest": "/mnt/fstab.link",
    "gid": 0,
    "group": "root",
    "mode": "0777",
    "owner": "root",
    "secontext": "unconfined_u:object_r:mnt_t:s0",
    "size": 10,
    "src": "/etc/fstab",
    "state": "link",
    "uid": 0
}
[root@localhost ~]# ansible webserver -a 'ls -l /mnt'
192.168.133.141 | CHANGED | rc=0 >>
total 0
lrwxrwxrwx. 1 root root 10 Sep  7 20:12 fstab.link -> /etc/fstab

7.ping模块

ping模块用于检测指定主机的连通性

[root@localhost ~]# ansible all -m ping
192.168.133.141 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

8.service模块

Ansible中使用service模块来控制管理服务的运行状态。其中,enabled表示开机自启,取值为true或false;使用name定义服务名称;使用state指定服务状态,取值分别为started,stopped,restarted。

[root@localhost ~]# ansible all -a 'systemctl status sshd'          
192.168.133.141 | CHANGED | rc=0 >>                                 
● sshd.service - OpenSSH server daemon                              
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; ve
ndor preset: enabled)                                               
   Active: active (running) since Mon 2020-09-07 11:26:20 CST; 8h ag
o                                                                 
[root@localhost ~]# ansible all -m service -a'enabled=true name=sshd state=started'
192.168.133.141 | SUCCESS => {

9.shell模块

shell模块可以在被管理主机上运行命令,并支持想管道符等功能的复杂命令

[root@localhost ~]# ansible webserver -m user -a 'name=stu3'
192.168.133.141 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"

[root@localhost ~]# ansible webserver -m shell  -a 'echo 123456 | passwd --stdin stu3'
192.168.133.141 | CHANGED | rc=0 >>
Changing password for user stu3.
passwd: all authentication tokens updated successfully.

10.script模块

script模块可以将本地脚本复制到被管理追上进行运行,需要注意,使用相对路径来指定脚本。

[root@localhost ~]# cat test.sh
#!/bin/bash
echo "hello ansible from script" > /mnt/script.ansible

[root@localhost ~]# ansible all -m script -a 'test.sh'
192.168.133.141 | CHANGED => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to 192.168.133.141 closed.\r\n",
    "stderr_lines": [
        "Shared connection to 192.168.133.141 closed."
    ],
    "stdout": "",
    "stdout_lines": []
}

pc2:

[root@localhost ~]# cat /mnt/script.ansible
hello ansible from script

11.yum模块

yum模块复杂在被管理主机上安装与卸载软件包,但是需要在每个节点配置自己的yum仓库。使用name指定要安装的软件包,还需要带上软件包的版本号,否则安装最新的软件包;使用state指定安装软件的状态,present,latest用来表示安装,absent表示卸载

[root@localhost ~]# ansible all -m yum -a 'name=httpd'
192.168.133.141 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "msg": "",
    "rc": 0,
    "results": [
        "httpd-2.4.6-67.el7.centos.x86_64 providing httpd is already installed"
    ]
}
[root@localhost ~]# ansible all  -a 'rpm -qa httpd'

192.168.133.141 | CHANGED | rc=0 >>
httpd-2.4.6-67.el7.centos.x86_64
[root@localhost ~]# ansible all -m yum -a 'name=httpd state=absent'

12.setup模块

setup模块收集 查看被管理主机的facts(facts是ansible采集被管理主机信息的一个功能)。每个被管理主机在接受并运行管理之前,都会将自己的相关信息,(操作系统版本 ip地址等)发送给控制主机。

[root@localhost ~]# ansible all -m setup

五.Ansible中的Inventory(主机清单)

Ansible为了更加便捷地管理主机,在主机清单中将被管理主机进行分组命名,默认的主机清单为/etc/ansible/hosts文件。主机清单可以设置为多个,也可以通过Dynamic Inventory动态生成。

Inventory文件以括号的字符表示为组名,将主机分组管理,也可以将同一主机同时划分到多个不同的组中。如果被管理主机使用非默认的ssh端口,还可以在主机名之后用冒号加端口的方式进行标明。

[webserver] [webserver] [webserver]

192.168.10.1 web1.example.com web[01:05].example.com

192.168.10.2 web2.example.com

Inventory重要概念

1.主机变量

可以在定义主机时添加主机变量,以便在后续的Playbook中使用,如:

www1.zlt.com http_port=80 maxRequestsChild=808

www1.zlt.com http_port=809 maxRequestsChild=909

2.组变量

组变量是指给指定主机设置可以在Playbook中直接使用的变量,如:[server-vars]

ntp_server=ntp.example.org

nfs_server=nfs.example.org

3.组嵌套

在Inventory中的组还可以嵌套其他的组,也可以向组中的主机指定变量。不过这些变量只能在ansible-playbook工具中使用,直接使用Ansible工具并不支持,

[apache]

httpd1.example.org

httpd2.example.org

[nginx]

nginx1.example.org

nginx2.example.org

[webservers:children]

apache

nginx

4.Inventory参数

Ansible基于ssh连接,Inventory中指定被管理主机时,还可以通过参数指定交互方式,参数如下:

ansible_ssh_host:定义hosts ssh地址

ansible_ssh_port:定义hosts ssh端口

ansible_ssh_user:定义hosts ssh认证用户

ansible_ssh_pass:定义hosts ssh认证密码,明文密码不安全

ansible_sudo:定义hosts sudo用户

ansible_sudo_pass:定义hosts sudo密码

ansible_sudo_exe:定义host sudo路径

ansible_connection:定义hosts连接方式,如ssh,local,paramiko

ansible_ssh_private_key_file:定义ssh连接的公钥文件

ansible_shell_type:定义hosts shell类型,默认是sh

ansible_python_interpreter:定义hosts 任务执行python路径

Ansible\_\*\_interpreter:定义hosts其他语言解析路径

如果被配置ssh密钥认证,可以如此对被管理主机进行认证:

#vim /etc/ansible/hosts

[webserver]

192.168.10.1 ansible_ssh_user=root ansible_ssh_pass=123456

六.YAML与playbook介绍

YAML是一种用来表达资料序列的格式,由于参考了多种其他语言,所以具有很高的可计性,YAML是YAML Ain‘t Markup Language的缩写,即YAML不是XML。YAML的意思是 Yet Another Markup Language(仍是一种标记语言),其特性:

1.具有良好的可读性

2.表达能力强

3.和脚本语言的交互性好

4.有一个一致的信息模型

5.可以基于流来处理

Playbook是由一个或多个play组成的列表,主要功能将tas定义好的角色归并为一组进行统一管理,也就是通过task调用Ansible的模板将多个play组织在一个Play中运行

playbook 剧本

play (找谁)

task (干什么)

playbook是由yml语法书写结构清晰,可读性强,所以必须掌握yml基础语法

语法 描述

缩进 yaml使用固定的缩进风格表示层级结构,每个缩进由两个空格组成,不 能使用tab

冒号 以冒号结尾的除外,其他所有冒号后面必须有空格

短横线 表示列表项,使用一个短横线加一个空格。多个项使用同样缩进级别作 为同一列表

eg1:使用ansible安装并配置http服务

[root@localhost ~]# cat http.yaml

  • hosts: webserver
    tasks:
  • name: yum install httpd server
    yum: name=httpd state=present
  • name: configure httpd website
    copy: src=./index.html dest=/var/www/index.html owner=apache group=apache mode=644
  • name: service httpd server
    service: name=httpd state=started enabled=yes
  • name: service firewalld server
    service: name=firewalld state=started
  • name: configure firewalld server
    firewalld: zone=public service=http permanent=yes immediate=yes state=enabled

[root@localhost ~]# ansible-playbook --syntax http.yaml

playbook: http.yaml

测试安装

linux自动化运维平台 linux 自动化运维工具_运维_02

安装

linux自动化运维平台 linux 自动化运维工具_linux_03