自动化运维之ansible的重要模块

自动化运维

任务背景

公司的服务器越来越多, 维护⼀些简单的事情都会变得很繁琐。⽤shell脚本来管理少量服务器效率还⾏, 服务器多了之后, shell脚本⽆法实现⾼效率运维。这种情况下,我们需要引⼊⾃动化运维⼯具, 对多台服务器实现⾼效运维。

任务要求

通过管理服务器能够按照需求灵活⾼效地管理所有应⽤服务器的运维操作

任务拆解

1, 需要⼀台服务器做管理端, 来连接管理所有的应⽤服务器

2, 考虑如果只针对⼀部分应⽤服务器进⾏运维操作如何实现(服务器分组)

3, 学会将平台烂熟于⼼的linux操作命令转化为⾃动化运维的⽅式(常⻅模块的学习)

4, 如果操作⾮常的冗⻓, 学会使⽤playbook和role的⽅式来管理⾃动化运维主要关注的⾯

假如管理很多台服务器,主要关注以下⼏个⽅⾯:

  1. 管理机与被管理机的连接(管理机如何将管理指令发送给被管理机)

  2. 服务器信息收集 (如果被管理的服务器有centos7.5外还有其它linux发⾏版,如suse,ubuntu等。当你要做的事情在不同OS上有所不同,你需要收集信息,并将其分开处理)

  3. 服务器分组(因为有些时候我要做的事情不是针对所有服务器,可能只针对某⼀个分组)

  4. 管理内容的主要分类

(1)⽂件⽬录管理(包括⽂件的创建,删除,修改,查看状态,远程拷⻉等)

(2)⽤户和组管理

(3)cron时间任务管理

(4)yum源配置与通过yum管理软件包

(5)服务管理

(6)远程执⾏脚本

(7)远程执⾏命令

常见的开源⾃动化运维工具比较

  1. puppet(拓展)

基于ruby语⾔,成熟稳定。适合于⼤型架构,相对于ansible和

saltstack会复杂些。

  1. saltstack(拓展)

基于python语⾔。相对简单,⼤并发能⼒⽐ansible要好, 需要维

护被管理端的服务。如果服务断开,连接就会出问题。

  1. ansible

基于python语⾔。简单快捷,被管理端不需要启服务。直接⾛

ssh协议,需要验证所以机器多的话速度会较慢。

Ansible的应用

1、概述:

ansible是⼀种由Python开发的⾃动化运维⼯具,集合了众多运维⼯具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运⾏命令等功能。

2、特点:

部署简单;

默认使⽤ssh进⾏管理,基于python⾥的paramiko模块开发

管理端和被管理端不需要启动服务

配置简单,功能强⼤,扩展性强

能过playbook(剧本)进⾏多个任务的编排

3、环境准备

管理机:m0(192.168.2.176)

被管理机:s0(192.168.2.177) s1(192.168.2.178) s2(192.168.2.179)

4、基础配置:

(1)静态ip

(2)主机名及主机名互相绑定

(3)关闭防⽕墙, selinux

(4)时间同步

(5)确认和配置yum源(需要epel源)

5、配置过程

(1)安装并查看版本

root@m0 \~# yum list installed|grep epel

epel-release.noarch 7-11 @extras

root@m0 \~# yum -y install ansible

root@m0 \~# ansible --version

ansible 2.9.27

root@m0 \~# find /etc/ -name '*ansible*'

/etc/ansible

/etc/ansible/ansible.cfg

(2)实现master对agent的免密登录,只在master上做。(如果这⼀步不做,则在后⾯操作agent时都要加-k参数传密码;或者在主机清单⾥传密码)做免密(anible通过22端口进行管理)

root@m0 \~# ssh-keygen # 一路enter

The key's randomart image is:

+---RSA 2048----+

| E+..o.. .ooo=|

| + o. . + . +.|

|o + o o = . . .|

|oo o o.+ o + |

|.. . .S. . . B|

| . .o . . X.|

| . . + . + *|

| . . . oo|

| .oo oo|

+----SHA256-----+

root@m0 \~# ls ./ssh/

ls: 无法访问./ssh/: 没有那个文件或目录

root@m0 \~# ls ./.ssh/

id_rsa id_rsa.pub known_hosts

root@m0 \~# cat ./.ssh/id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDt3ZM422EYl4Xgu7miNDPfbF6AV9D1hQPFLvjHzZTtr0piDZvKhvt2iXpd42eF6XNpTPdEKC1omdSfJS8dlqNE1ipYNXQoX+YAnDK+brinwC6k8JzPK34p+lP9VCEkpaaqFIQTJCe/pVyUhNjw2uViikWIAxkZfGBy/dKSkooNr6dLUaeB80njavCZEXMn73/aGAlwYxH0EPgMiiyRRg5leuuMuZXFl8xLU2YiJ9/B43Q/JQBTDxzeaIXdgb8yiPiCJpYUnVcjVgmhQwEpFh58EGHxr5WA+L3MiXYHjT26JdBzkMirmggBBbjPbHrSvRQg6ZCiRfDrrpGGEZbTic7z root@m0

root@m0 \~# ssh-copy-id -i 192.168.2.177

root@m0 \~# ssh-copy-id -i 192.168.2.178

(3)定义主机组测试连接性

# 服务器分组

ansible通过⼀个主机清单功能来实现服务器分组。Ansible的默认主机清单配置⽂件为/etc/ansible/hosts。

示例:

示例:

nginx 组名

apache1:10.aaa.com 表示apache1.aaa.com到apache10.aaa.com这10台机器

nginxa:z.aaa.com 表示nginxa.aaa.com到nginxz.aaa.com共26台机器

192.168.2..11:15 表示192.168.2.11到192.168.2.15这5台机器

nginx

192.168.2.13:2222 表示10.1.1.13这台,但ssh端⼝为2222

# 定义1 192.168.2.177 192.168.2.178 这台服务器的别名为 group01

root@m0 \~# vim /etc/ansible/hosts

group01

192.168.2.177

192.168.2.178

group02

192.168.2.177

192.168.2.178

192.168.2.179

root@m0 \~# ansible 192.168.2.177 -m ping

192.168.2.177 | SUCCESS => {

"ansible_facts": {

"discovered_interpreter_python": "/usr/bin/python"

},

"changed": false,

"ping": "pong"

}

root@m0 \~# ansible group01 -m ping

192.168.2.177 | SUCCESS => {

"ansible_facts": {

"discovered_interpreter_python": "/usr/bin/python"

},

"changed": false,

"ping": "pong"

}

192.168.2.178 | SUCCESS => {

"ansible_facts": {

"discovered_interpreter_python": "/usr/bin/python"

},

"changed": false,

"ping": "pong"

}

root@m0 \~# ansible group02 -m ping

The authenticity of host '192.168.2.179 (192.168.2.179)' can't be established.

ECDSA key fingerprint is SHA256:MioezkR2Al25tYmE7gw4La34F5fPGXOIp7+/icCRKjQ.

ECDSA key fingerprint is MD5:5a:c8:de:80:5a:43:e0:9e:6d:52:50:8f:b6:43:3c:13.

Are you sure you want to continue connecting (yes/no)? 192.168.2.178 | SUCCESS => {

"ansible_facts": {

"discovered_interpreter_python": "/usr/bin/python"

},

"changed": false,

"ping": "pong"

}

192.168.2.177 | SUCCESS => {

"ansible_facts": {

"discovered_interpreter_python": "/usr/bin/python"

},

"changed": false,

"ping": "pong"

}

yes # 没做免密

192.168.2.179 | UNREACHABLE! => {

"changed": false,

"msg": "Failed to connect to the host via ssh: Warning: Permanently added '192.168.2.179' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",

"unreachable": true

}

(4)利⽤别名来分组,没有做免密登录的服务器可以指定⽤户名与密码

root@m0 \~# vim /etc/ansible/hosts

other ansible_ssh_host=192.168.2.179 ansible_ssh_po

rt=22 ansible_ssh_user=root ansible_ssh_password=1

group02

192.168.2.177

192.168.2.177

other

root@m0 \~# ansible group02 -m ping

192.168.2.178 | SUCCESS => {

"ansible_facts": {

"discovered_interpreter_python": "/usr/bin/python"

},

"changed": false,

"ping": "pong"

}

192.168.2.177 | SUCCESS => {

"ansible_facts": {

"discovered_interpreter_python": "/usr/bin/python"

},

"changed": false,

"ping": "pong"

}

other | SUCCESS => {

"ansible_facts": {

"discovered_interpreter_python": "/usr/bin/python"

},

"changed": false,

"ping": "pong"

}

root@m0 \~# ansible other -m ping

other | SUCCESS => {

"ansible_facts": {

"discovered_interpreter_python": "/usr/bin/python"

},

"changed": false,

"ping": "pong"

}

如果要查看ping模块的⽤法,使⽤下⾯命令(其它模块以此类推)

ansible-doc ping

## ⼩结:

主机清单的作⽤: 服务器分组。

主机清单的常⻅功能:

  1. 可以通过IP范围来分, 主机名名字的范围来分

  2. 如果ssh端⼝不是22的,可以传⼊新的端⼝。

  3. 没有做免密登录,可以传密码。

****## 练习:****不论你⽤哪种环境(免密或不免密,端⼝是否22), 请最终将两台被管理机器加⼊到group02组即可

vim /ect/ansible/hosts

web01 ansible_ssh_host=192.168.71.200

ansible_ssh_user=root ansible_ssh_pass=root

ansible_ssh_port=22

web02 ansible_ssh_host=192.168.71.201

ansible_ssh_user=root ansible_ssh_pass=root

ansible_ssh_port=2222

group1

web01

web02

Ansbile 主机ip|域名|组名|别名 -m ping|copy|.... '参数'

ansible模块

查看所有支持的模块

root@m0 \~# ansible-doc -l

root@m0 \~# ansible-doc ping

如果要查看ping模块的⽤法,使⽤下⾯命令(其它模块以此类推)

ansible-doc ping

hostname模块

基本格式为: ansible 操作的机器名或组名 -m 模块名 -a "参数1=值1 参数2=值2"

hostname模块⽤于修改主机名(注意: 它不能修改/etc/hosts⽂件)

root@m0 \~# ansible group02 -m hostname -a 'name=ab.huajuan.tangpin'

file模块

字段说明

path 文件的地址 # directory 创建目录 # touch 创建文件 # absent 删除文件

link 创建软连接 # hard创建硬链接 # recure 是否允许递归 # src 文件源

创建目录

root@s0 \~#ansible group02 -m file -a 'path=/tmp/abc state=directory'

root@s0 \~# ls -l /tmp/

总用量 0

drwxr-xr-x. 2 root root 6 8月 16 11:45 abc

drwx------. 3 root root 17 8月 16 10:25 systemd-private-1d58301c85934a19910d218cdd2c7a70-chronyd.service-6vUQVK

创建文件

root@m0 \~# ansible group02 -m file -a 'path=/tmp/abc/def state=touch'

root@ab \~# ls -ld /tmp/abc/def

-rw-r--r--. 1 root root 0 8月 16 14:09 /tmp/abc/def

递归修改 owne r、group、mode

root@m0 \~# ansible group02 -m file -a 'path=/tmp/abc recurse=yes owner=bin group=daemon mode=1777'

root@ab \~# ll /tmp/

总用量 0

drwxrwxrwt. 2 bin daemon 17 8月 16 14:09 abc

drwx------. 3 root root 17 8月 16 10:25 systemd-private-a33925d16cd14fc5bc9b8f0fe5c23f27-chronyd.service-5wcjuI

root@ab \~# ll /tmp/abc

总用量 0

-rwxrwxrwt. 1 bin daemon 0 8月 16 14:09 def

删除⽬录(连同⽬录⾥的所有 文件 )

root@ab \~#ansible group02 -m file -a 'path=/tmp state=absent'

创建⽂件并指定owner,group,mode等

root@ab \~#ansible group1 -m file -a 'path=/tmp/test state=touch owner=bin group=daemon mode=1777'

删除文件

root@m0 \~# ansible group02 -m file -a 'path=/tmp/abc state=absent'

root@ab \~# ll /tmp/abc

ls: 无法访问/tmp/abc: 没有那个文件或目录

软连接指向硬链接,硬链接指向文件

创建软连接文件

root@m0 \~# ansible group02 -m file -a 'src=/etc/fstab path=/tmp/xxx state=link'

root@ab \~# ll /tmp/

lrwxrwxrwx. 1 root root 10 8月 16 14:28 xxx -> /etc/fstab

创建硬连接文件

root@m0 \~# ansible group02 -m file -a 'src=/etc/fstab path=/tmp/yyy state=hard'

root@ab \~# ll /tmp/

-rw-r--r--. 2 root root 501 7月 23 08:58 yyy

state模块 (了解)

获取/etc/fstab文件的状态信息

root@m0 \~#ansible group1 -m stat -a 'path=/etc/fstab'

copy模块 (一主两从

copy模块⽤于对⽂件的远程拷⻉操作(如把本地 的⽂件拷⻉到远程的机器上)

root@m0 \~# ls

anaconda-ks.cfg

mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz

soft

改名

root@m0 \~# mv mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz mysql57.tar.gz

root@m0 \~# ls

anaconda-ks.cfg mysql57.tar.gz soft

上传文件

root@m0 \~# ansible group02 -m copy -a 'src=./mysql57.tar.gz dest=~

查看

root@ab \~# ls ~/

anaconda-ks.cfg mysql57.tar.gz soft

将master文件拷⻉到group02的所有机器上

root@m0 \~#echo master > /tmp/222

root@m0 \~#ansible group1 -m copy -a 'src=/tmp/222 dest=/tmp/333'

root@ab \~# ls /tmp/

333

使⽤content参数直接往远程 文件 ⾥写内容(会覆盖原内容)

root@m0 \~#ansible group02 -m copy -a 'content="haha" dest=/tmp/333'

注意:ansible中-a后⾯的参数⾥也有引号时,记得要单引双引交叉使⽤,如果都为双引会出现问题。

使⽤force参数控制是否强制覆盖,如果⽬标⽂件已经存在,则不覆盖

root@m0 \~#ansible group1 -m copy -a 'src=/tmp/222 dest=/tmp/333 force=no'

如果⽬标⽂件已经存在,则会强制覆盖

root@m0 \~#ansible group1 -m copy -a 'src=/tmp/222 dest=/tmp/333 force=yes'

使 ⽤backup参数控制是否备份⽂件

backup=yes表示如果拷⻉的⽂件内容与原内容不⼀样,则会备份⼀份

group02的机器上会将/tmp/333备份⼀份(备份⽂件命名加上时间),再远程拷⻉新的⽂件为/tmp/333

root@m0 \~#ansible group02 -m copy -a 'src=/etc/fstab dest=/tmp/333 backup=yes owner=daemon group=daemon mode=1777'

copy模块拷⻉时要注意拷⻉⽬录后⾯是否带"/"符号

/etc/yum.repos.d后⾯不带/符号,则表示把/etc/yum.repos.d整个⽬录拷⻉到/tmp/⽬录下

master# ansible group1 -m copy -a

'src=/etc/yum.repos.d dest=/tmp/'

/etc/yum.repos.d/后⾯带/符号,则表示把/etc/yum.repos.d/⽬录⾥的所有⽂件拷⻉到/tmp/⽬录下

在m0上配置好所有的yum源,然后拷⻉到group02的远程机器上(要求⽬录内的内容完全⼀致)

root@s0\~# ansible group02 -m file -a "path=/etc/yum.repos.d/ state=absent"

root@s0\~#ansible group02 -m copy -a "src=/etc/yum.repos.d dest=/etc/"

template模块(与copy模块功能⼏乎⼀样)

template模块⾸先使⽤变量渲染jinja2模板⽂件成普通⽂件,然后再复制过去.⽽copy模块不⽀持.(jinja2是⼀个基于python的模板引擎),注意:template模块不能拷⻉⽬录

root@s0\~# ansible -m template group02 -a "src=/etc/hosts dest=/tmp/hosts"

root@s0\~#ansible -m template group1 -a "src=/etc/yum.repos.d/ dest=/etc/yum.repos.d/"

fetch模块

fetch模块与copy模块类似,但作⽤相反。⽤于把远程 机器的⽂件拷⻉到本地

注意 !!!: fetch模块不能从远程拷⻉⽬录到本地

在两台被管理机上分别创建⼀个同名⽂件(但内容不同)

root@s0\~# echo agent1 > /tmp/1.txt

root@s1 \~#echo agent2 > /tmp/1.txt

从m 0 上fecth⽂件(因为group 02 ⾥有2台机器,为了避免同名⽂件⽂件冲突,它使⽤了不同的⽬录)

root@m0 \~#ansible group02 -m fetch -a 'src=/tmp/1.txt dest=/tmp/'

root@m0 \~#ansible group02 -m fetch -a 'src=/etc/sysconfig/network-scripts/ifcfg-ens33 dest=/tmp'

先删除上⾯fetch过来的, 然后尝试只fetch其中⼀台机器的,也会使⽤名称来做⼦⽬录区分

root@m0 \~#rm /tmp/192.168.2..* -rf

root@m0 \~#ansible 192.168.2.177 -m fetch -a 'src=/tmp/1.txt dest=/tmp/'

192.168.2.177 | CHANGED => {

"changed": true,

"checksum":

"d2911a028d3fcdf775a4e26c0b9c9d981551ae41",

"dest": "/tmp/192.168.2.177/tmp/1.txt", 只fetch⼀个,也会这样命名

"md5sum": "0d59da0b2723eb03ecfbb0d779e6eca5",

"remote_checksum":

"d2911a028d3fcdf775a4e26c0b9c9d981551ae41",

"remote_md5sum": null

}

yum_repository模块( yum_repository模块⽤于配置yum仓库 )

增加⼀个/etc/yum.repos.d/local.repo配置 文件

root@m0 \~# ansible group02 -m yum_repository -a "name=local description=localyum baseurl=file:///mnt/ enabled=yes gpgcheck=no"

注意 !!! ****:****此模块只帮助配置yum仓库,但如果仓库⾥没有软件包,安装⼀样会失败。所以可以手动去挂载光驱到/mnt⽬录

mount /dev/cdrom /mnt

删除/etc/yum.repos.d/local.repo配置 文件

root@m0 \~#ansible group02 -m yum_repository -a "name=local state=absent"

user模块

创建账户abc

root@m0 \~# ansible group02 -m user -a 'name=abc state=present'

root@ab \~# id abc

uid=1002(abc) gid=1002(abc) 组=1002(abc)

创建mysql账户

root@m0 \~# ansible group02 -m user -a 'name=mysql state=present system=yes shell="/sbin/nologin"'

root@ab \~# grep mysql /etc/passwd

mysql:x:997:994::/home/mysql:/sbin/nologin

root@m0 \~# ansible group02 -m file -a 'path=/usr/local/mysql/mysql-files owner=mysql group=mysql mode=750 state=directory'

root@ab \~# ll /usr/local/mysql/

drwxr-x---. 2 mysql mysql 6 8月 16 16:09 mysql-files

创建账户并设置uid、密码password

root@m0 \~# ansible group02 -m user -a 'name=tom uid=1009 state=present password=tom

root@ab \~# grep tom /etc/passwd

tom:x:1009:1009::/home/tom:/bin/bash

root@ab \~# grep tom /etc/group

tom:x:1009:

创建⼀个普通⽤户叫hadoop,并产⽣空密码密钥对

root@m0 \~# ansible group02 -m user -a 'name=hadoop generate_ssh_key=yes'

root@ab \~# ls ./.ssh/

authorized_keys known_hosts

root@ab \~# cat ./.ssh/authorized_keys

ssh-rsa

删除账户但家目录还存在,使⽤remove=yes参数让其删除⽤户的同时也删除家⽬录

root@m0 \~# ansible group02 -m user -a 'name=hadoop state=absent'

root@ab \~# grep had /etc/passwd

root@ab \~# tree /home/

/home/

├── abc

├── hadoop

├── juan

├── mysql

├── tom

└── user01

root@ab \~# ll /home/

drwx------. 3 1010 1010 74 8月 16 16:20 hadoop

root@m0 \~# ansible group02 -m user -a 'name=tom state=absent remove=yes'

root@ab \~# ls /home/

abc hadoop juan mysql user01

cron模块

添加计划任务

root@m0 \~# ansible group02 -m cron -a 'name="test cron1" user=root job="/usr/sbin/ntpdate cn.ntp.org.cn" hour=2'

root@ab \~# crontab -l

#Ansible: test cron1

* 2 * * * /usr/sbin/ntpdate cn.ntp.org.cn

删除计划任务

root@ab \~# ansible group1 -m cron -a 'name="test cron1" state=absent'

yum模块

批量安装ntpdate

root@m0 \~# ansible group02 -m yum -a 'name=ntpdate state=present'

root@ab \~# yum list installed|grep ntpdate

ntpdate.x86_64 4.2.6p5-29.el7.centos.2 @base

root@ab \~# ntpdate cn.ntp.org.cn

16 Aug 16:36:38 ntpdate4952: adjust time server 203.107.6.88 offset 0.004739 sec

批量安装rsync

root@m0 \~# ansible group02 -m yum -a 'name=rsync state=present'

root@ab \~# yum list installed|grep rsync

rsync.x86_64 3.1.2-12.el7_9 @updates

service模块

关闭防火墙

root@m0 \~# ansible group02 -m service -a 'name=firewalld state=stopped enabled=false'

root@ab \~# systemctl status firewalld

● firewalld.service - firewalld - dynamic firewall daemon

相关推荐
悠然南风19 小时前
Ansible常见模块总结及LDAP Role 编写与调试
ansible
荣--1 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森1 天前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜2 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
SelectDB3 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode4 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220705 天前
如何搭建本地yum源(上)
运维
大树888 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠8 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质8 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务