博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ansible自动化运维配置与应用(结合实例)
阅读量:6497 次
发布时间:2019-06-24

本文共 16364 字,大约阅读时间需要 54 分钟。

hot3.png

1.1 ansible安装与配置认证

ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。

ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。 主要包括:
(1)、连接插件connection plugins:负责和被监控端实现通信;
(2)、host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
(3)、各种模块核心模块、command模块、自定义模块;
(4)、借助于插件完成记录日志邮件等功能;
(5)、playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。

特点:

  • 不需要安装客户端
  • 基于模块工作,模块可以以任何语言开发
  • 不仅支持命令行使用模块,也可以支持yaml(python)格式的playbook
  • 支持sudo
  • 有提供UI(浏览器图形化)

安装

只需在服务端安装(IP:192.168.0.106)。

[root@adailinux ~]# yum install -y epel-release[root@adailinux ~]# yum install -y ansible

配置密钥

创建密钥:[root@adailinux ~]# 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:9f:e7:73:61:9e:af:ea:14:f8:af:82:de:c9:50:06:b0 root@adailinuxThe key's randomart image is:+--[ RSA 2048]----+|      .          ||       o         ||      E .        ||         . .     ||        S + .    ||         + o .o  ||        ..o +o o ||        .+.=..+  ||       .. +o==oo.|+-----------------+

将公钥拷贝到客户机:

[root@adailinux ~]# cat /root/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAuoWwgauteoSamitR+tMXz90nKQJMHJmknTVctIzkJ5YNTdAdHrKBeNiKP3HoODJVkO0Fj3MnWOFHRZtFfzaJ690y846JzKllGmnDcVeaZC6/1Mg3jNVZ7wmtNhMplj+ObJicAOSIoi5bauYPfTQ3F3caCWa/wLBu46pQLu8hCdlKb4TR6t3t+DJqTA5aZz0zrx08YqCZFlv92B+THWhIp0bOd+uJW+ivd38u/FdNaY54z7Qr+S6cQ9Dir5HrG5oWcrd1HbNcHiBrIXXH8t5aQCWJAy0zrG8hfh5d3PJQjo4q7COtj090CAdWIEtT8euz25asnmNmeDdU8CoZkyoiIw== root@adailinux客户机:[root@client ~]# vim .ssh/authorized_keys#ansiblessh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAuoWwgauteoSamitR+tMXz90nKQJMHJmknTVctIzkJ5YNTdAdHrKBeNiKP3HoODJVkO0Fj3MnWOFHRZtFfzaJ690y846JzKllGmnDcVeaZC6/1Mg3jNVZ7wmtNhMplj+ObJicAOSIoi5bauYPfTQ3F3caCWa/wLBu46pQLu8hCdlKb4TR6t3t+DJqTA5aZz0zrx08YqCZFlv92B+THWhIp0bOd+uJW+ivd38u/FdNaY54z7Qr+S6cQ9Dir5HrG5oWcrd1HbNcHiBrIXXH8t5aQCWJAy0zrG8hfh5d3PJQjo4q7COtj090CAdWIEtT8euz25asnmNmeDdU8CoZkyoiIw== root@adailinux服务端:[root@adailinux ~]# ssh 192.168.0.109Address 192.168.0.109 maps to bogon, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT!Last login: Thu Sep 28 00:49:07 2017 from 192.168.0.106[root@client ~]# 即,106可以登录109机器

ansible远程执行命令

定义主机群组

更改配置文件:[root@adailinux ~]# vim /etc/ansible/hosts# Ex 2: A collection of hosts belonging to the 'webservers' group[testhosts]127.0.0.1192.168.0.109##创建主机组注意,如果要使用127.0.0.1连接本地主机(106)需要将密钥写入本机密钥配置文件:[root@adailinux ~]# vim .ssh/authorized_keys#本地公钥ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAuoWwgauteoSamitR+tMXz90nKQJMHJmknTVctIzkJ5YNTdAdHrKBeNiKP3HoODJVkO0Fj3MnWOFHRZtFfzaJ690y846JzKllGmnDcVeaZC6/1Mg3jNVZ7wmtNhMplj+ObJicAOSIoi5bauYPfTQ3F3caCWa/wLBu46pQLu8hCdlKb4TR6t3t+DJqTA5aZz0zrx08YqCZFlv92B+THWhIp0bOd+uJW+ivd38u/FdNaY54z7Qr+S6cQ9Dir5HrG5oWcrd1HbNcHiBrIXXH8t5aQCWJAy0zrG8hfh5d3PJQjo4q7COtj090CAdWIEtT8euz25asnmNmeDdU8CoZkyoiIw== root@adailinux

执行远程命令(ansible模块——command)

执行结果如下:

单个机器:[root@adailinux ~]# ansible 192.168.0.109 -m command -a 'hostname'192.168.0.109 | SUCCESS | rc=0 >>client机器组:[root@adailinux ~]# ansible testhosts -m command -a 'hostname'192.168.0.109 | SUCCESS | rc=0 >>client127.0.0.1 | SUCCESS | rc=0 >>adailinux

说明: -m:指定ansible要调用的模块;-a:指定具体命令。

报错:

"msg" Aborting target uses selinux but python bindings (libselinux-python) aren't installed.

解决办法:

[root@adailinux ~]# yum install -y libselinux-python

ansible模块——shell

[root@adailinux ~]# ansible 192.168.0.109 -m shell -a 'hostname'192.168.0.109 | SUCCESS | rc=0 >>client[root@adailinux ~]# ansible 192.168.0.109 -m shell -a 'cat /etc/passwd|grep root'192.168.0.109 | SUCCESS | rc=0 >>root:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologin

注: command模块和shell模块的区别是:shell模块支持“管道符”及脚本。

ansible拷贝文件或目录

使用copy模块。

[root@adailinux ~]# ansible 192.168.0.109 -m copy -a "src=/tmp/test.txt dest=/tmp/testdir/ owner=root group=root mode=0644"192.168.0.109 | SUCCESS => {    "changed": true,     "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",     "dest": "/tmp/testdir/test.txt",     "gid": 0,     "group": "root",     "md5sum": "d41d8cd98f00b204e9800998ecf8427e",     "mode": "0644",     "owner": "root",     "size": 0,     "src": "/root/.ansible/tmp/ansible-tmp-1506533297.89-81185506773616/source",     "state": "file",     "uid": 0}#此处IP可以换成机器组:testhosts“客户机:[root@client ~]# ls /tmp/testdir

注意: 源文件或目录会放到目标目录下面。src表示源地址,dest表示目标地址

远程执行脚本

服务端:192.168.8.141

客户端:192.168.8.142

[root@adailinux ~]# vim /etc/ansible/hosts[testhosts]127.0.0.1192.168.8.142
创建脚本:[root@adailinux ~]# vim /tmp/test.sh#!/bin/bashd=`date`echo $d > /tmp/an_test.txt分发脚本;[root@adailinux ~]# ansible testhosts -m copy  -a "src=/tmp/test.sh dest=/tmp/test.sh  mode=0755"远程执行脚本:[root@adailinux ~]# ansible testhosts -m shell -a "/bin/sh /tmp/test.sh"192.168.8.142 | SUCCESS | rc=0 >>127.0.0.1 | SUCCESS | rc=0 >>在客户机查看:[root@client ~]# ls /tmp/an_test.txt  test.sh[root@client ~]# cat /tmp/an_test.txt2017年 09月 28日 星期四 05:30:25 CST

ansible实现任务计划

创建计划任务:

[root@adailinux ~]# ansible 192.168.8.142 -m cron -a "name='test cron' job='/bin/touch /tmp/110.txt' weekday=6"192.168.8.142 | SUCCESS => {    "changed": true,     "envs": [],     "jobs": [        "test cron"    ]}查看客户机:[root@client ~]# crontab -l#Ansible: test cron* * * * 6 /bin/touch /tmp/110.txt时间:分钟minute 小时hour  日day 月份month

删除计划任务:

只需加上参数——“state=absent”

[root@adailinux ~]# ansible 192.168.8.142 -m cron -a "name='test cron' job='/bin/touch /tmp/110.txt' weekday=6 state=absent"192.168.8.142 | SUCCESS => {    "changed": true,     "envs": [],     "jobs": []}客户机:[root@client ~]# crontab -l

ansible安装rpm包&&管理服务

安装rpm包

[root@adailinux ~]# ansible 192.168.8.142 -m yum -a "name=zabbix-agent.i686"

注意: name后面需要跟一个准确的包名。

管理服务

[root@adailinux ~]# ansible 192.168.8.142 -m service -a "name=httpd state=started enable=no"
列出所有模块:[root@adailinux ~]# ansible-doc -l查看指定模块的参数:[root@adailinux ~]# ansible-doc cron

ansible playbook

相当于把模块写入到配置文件里面,然后单独执行配置文件实现自动化操作。

创建文件

[root@jumpserver ~]# vim /etc/ansible/test.yml---- hosts: 192.168.8.130  remote_user: root  tasks:    - name: test_playbook      shell: touch /tmp/test.txt

说明: hosts参数指定了对哪些主机进行操作;user参数指定了使用什么用户登录远程主机操作;tasks指定了一个任务,其下面的name参数同样是对任务的描述,在执行过程中会打印出来。

定义完成后只需要执行命令:

[root@jumpserver ~]# ansible-playbook test.ymlPLAY [192.168.8.130] ************************************************************************TASK [Gathering Facts] **********************************************************************ok: [192.168.8.130]TASK [test_playbook] ************************************************************************ [WARNING]: Consider using file module with state=touch rather than running touchchanged: [192.168.8.130]PLAY RECAP **********************************************************************************192.168.8.130              : ok=2    changed=1    unreachable=0    failed=0  查看客户机:[root@localhost ~]# ls /tmp/test.txt

即可完成所有配置。

创建用户

[root@jumpserver ansible]# vim create_user.yml---- name: create_user  hosts: 192.168.8.130  user: root  gather_facts: false  vars:    - user: "test"  tasks:    - name: create user      user: name="{
{ user }}"

说明: name参数对该playbook实现的功能做一个概述,后面执行过程中,会打印 name变量的值 ,可以省略;gather_facts参数指定了在以下任务部分执行前,是否先执行setup模块获取主机相关信息,这在后面的task会使用到setup获取的信息时用到;vars参数,指定了变量,这里指字一个user变量,其值为test ,需要注意的是,变量值一定要用引号引住;user提定了调用user模块,name是user模块里的一个参数,而增加的用户名字调用了上面user变量的值。

循环with_items:

---- hosts: testhost  user: root  tasks:    - name: change mod for file      file: path=/tmp/{
{ item }} mode=600 owner=root group=root with_items: - 1.txt - 2.txt

说明: with_items 就是循环的关键

条件when:

---- hosts: testhost  remote_user: root  gather_facts: True  tasks:    - name: use when      shell: touch /tmp/when.txt      when: facter_ipaddress == "172.7.15.106"

模块handlers:

执行task之后,服务器发生变化之后要执行的一些操作,比如我们修改了配置文件后,需要重启一下服务,具体示例:

---- hosts: testhost  remote_user: root  tasks:    - name: test copy    copy: src=/tmp/1.txt dest=/tmp/2.txt    notify: test handlers  handlers:    - name: test handlers      shell: echo "121212" >> /tmp/2.txt

说明,只有copy模块真正执行后,才会去调用下面的handlers相关的操作。也就是说如果1.txt和2.txt内容是一样的,并不会去执行handlers里面的shell相关命令。这种比较适合配置文件发生更改后,重启服务的操作。

实例:安装ansible

因为换了机器,所以重新安装ansible并进行配置。

机器 IP
server(centos7) 192.168.8.139
client(centos7) 192.168.8.130

server机器上编译安装好nginx。

使用ansible源码安装nginx

思路:

先在一台机器上安装好nginx,然后打包,再利用ansible分发下去;或者直接把/usr/local/nginx目录同步到其他机器。
需要注意的是编译安装的nginx会需要一些库文件,所以再同步之后还要在client机器上yum安装这些包。

准备工作

[root@jumpserver conf]# cd /usr/local/打包:[root@jumpserver local]# tar czf nginx.tar.gz nginx[root@jumpserver local]# lsbin  etc  games  include  lib  lib64  libexec  nginx  nginx.tar.gz  sbin  share  src创建一系列目录:[root@jumpserver local]#  cd /etc/ansible/[root@jumpserver ansible]# lsansible.cfg  hosts  roles[root@jumpserver ansible]# mkdir nginx_install[root@jumpserver ansible]# cd nginx_install/[root@jumpserver nginx_install]# mkdir roles[root@jumpserver nginx_install]# cd roles/[root@jumpserver roles]# mkdir common install#common:用于做前期准备工作(准备一些依赖的包)

定义common内的目录及文件:

[root@jumpserver roles]# cd common/[root@jumpserver common]# mkdir tasks[root@jumpserver common]# cd tasks/[root@jumpserver tasks]# vim main.yml- name: Install initializtion require software  yum: name={
{ item }} state=installed with_items: - zlib-devel - pcre-devel - openssl-devel

定义install内的目录及文件:

[root@jumpserver install]# pwd/etc/ansible/nginx_install/roles/install[root@jumpserver install]# mkdir tasks vars files templates[root@jumpserver install]# cp /usr/local/nginx.tar.gz files/说明: 我们需要把源码包放到 files目录里面[root@jumpserver install]# cp /usr/local/nginx/conf/nginx.conf templates/[root@jumpserver install]# cp /etc/init.d/nginx templates/[root@jumpserver install]# vim vars/main.ymlnginx_user: wwwnginx_basedir: /usr/local/nginx#指定解压后文件存放目录

说明: 需要再templates下面准备好 默认页、安装nginx的shell脚本、nginx启动脚本、nginx配置文件以及虚拟主机配置文件

[root@jumpserver install]# cd tasks/[root@jumpserver tasks]# vim copy.yml- name: Copy Nginx Software  copy: src=nginx.tar.gz dest=/tmp/nginx.tar.gz owner=root group=root- name: Uncompression Nginx Software  shell: tar zxf /tmp/nginx.tar.gz -C /usr/local/- name: Copy Nginx Start Script  template: src=nginx dest=/etc/init.d/nginx owner=root group=root mode=0755- name: Copy Nginx Config  template: src=nginx.conf dest={
{ nginx_basedir }}/conf/ owner=root group=root mode=0644

说明: 首先把压缩包拷贝到/tmp/目录下,然后解压到/usr/local/下,再拷贝启动脚本到/etc/init.d/下,再拷贝nginx.conf以及vhost.conf

[root@jumpserver tasks]# vim install.yml- name: Create Nginx User  user: name={
{ nginx_user }} state=present createhome=no shell=/sbin/nologin- name: Start Nginx Service service: name=nginx state=stopped- name: Add Boot Start Nginx Service shell: chkconfig --level 345 nginx on- name: Delete Nginx compression files shell: rm -rf /tmp/nginx.tar.gz[root@jumpserver tasks]# vim main.yml- include: copy.yml- include: install.yml

说明: roles目录下有三个角色,common为一些准备操作,install为安装nginx的操作;每个角色下面又有几个目录,handlers下面是当发生改变时要执行的操作,通常用在配置文件发生改变,重启服务。files为安装时用到的一些文件,meta为说明信息,说明角色依赖等信息,tasks里面是核心的配置文件,templates通常存一些配置文件,启动脚本等模板文件,vars下为定义的变量。

至此,两个roles:common和install定义完成,接下来定义一个文件入口。

定义入口文件

[root@jumpserver tasks]# cd /etc/ansible/nginx_install/[root@jumpserver nginx_install]# vim install.yml---- hosts: 192.168.8.130  remote_user: root  gather_facts: True  roles:    - common    - install

执行

[root@jumpserver nginx_install]# pwd/etc/ansible/nginx_install[root@jumpserver nginx_install]# ansible-playbook install.ymlPLAY [192.168.8.130] ************************************************************************TASK [Gathering Facts] **********************************************************************ok: [192.168.8.130]TASK [common : Install initializtion require software] **************************************ok: [192.168.8.130] => (item=[u'zlib-devel', u'pcre-devel', u'openssl-devel'])TASK [install : Copy Nginx Software] ********************************************************changed: [192.168.8.130]TASK [install : Uncompression Nginx Software] *********************************************** [WARNING]: Consider using unarchive module rather than running tarchanged: [192.168.8.130]TASK [install : Copy Nginx Start Script] ****************************************************ok: [192.168.8.130]TASK [install : Copy Nginx Config] **********************************************************ok: [192.168.8.130]TASK [install : Create Nginx User] **********************************************************ok: [192.168.8.130]TASK [install : Start Nginx Service] ********************************************************ok: [192.168.8.130]TASK [install : Add Boot Start Nginx Service] ***********************************************changed: [192.168.8.130]TASK [install : Delete Nginx compression files] ********************************************* [WARNING]: Consider using file module with state=absent rather than running rmchanged: [192.168.8.130]PLAY RECAP **********************************************************************************192.168.8.130              : ok=10   changed=4    unreachable=0    failed=0 查看客户机:[root@localhost ~]# ps aux |grep nginxroot     10791  0.0  0.1  20488   628 ?        Ss   19:41   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.confnobody   10794  0.0  0.6  22932  3212 ?        S    19:41   0:00 nginx: worker processnobody   10795  0.0  0.6  22932  3212 ?        S    19:41   0:00 nginx: worker processroot     13242  0.0  0.1 112668   968 pts/0    R+   19:46   0:00 grep --color=auto nginx

配置成功!!!

参考

官方文档

安装配置
常见错误 样例库:

ansible常用命令及参数

参数:  -a 'Arguments', --args='Arguments' 命令行参数  -m NAME, --module-name=NAME 执行模块的名字,默认使用 command 模块,所以如果是只执行单一命令可以不用 -m参数  -i PATH, --inventory=PATH 指定库存主机文件的路径,默认为/etc/ansible/hosts.  -u Username, --user=Username 执行用户,使用这个远程用户名而不是当前用户  -U --sud-user=SUDO_User  sudo到哪个用户,默认为 root  -k --ask-pass  登录密码,提示输入SSH密码而不是假设基于密钥的验证  -K --ask-sudo-pass 提示密码使用sudo  -s --sudo sudo运行  -S --su 用 su 命令  -l  --list 显示所支持的所有模块  -s --snippet 指定模块显示剧本片段  -f  --forks=NUM 并行任务数。NUM被指定为一个整数,默认是5。 #ansible testhosts -a "/sbin/reboot" -f 10 重启testhosts组的所有机器,每次重启10台  --private-key=PRIVATE_KEY_FILE 私钥路径,使用这个文件来验证连接  -v --verbose 详细信息  all  针对hosts 定义的所有主机执行  -M MODULE_PATH, --module-path=MODULE_PATH 要执行的模块的路径,默认为/usr/share/ansible/  --list-hosts 只打印有哪些主机会执行这个 playbook 文件,不是实际执行该 playbook 文件  -o --one-line 压缩输出,摘要输出.尝试一切都在一行上输出。  -t Directory, --tree=Directory 将内容保存在该输出目录,结果保存在一个文件中在每台主机上。  -B 后台运行超时时间  -P 调查后台程序时间  -T Seconds, --timeout=Seconds 时间,单位秒s  -P NUM, --poll=NUM 调查背景工作每隔数秒。需要- b  -c Connection, --connection=Connection  连接类型使用。可能的选项是paramiko(SSH),SSH和地方。当地主要是用于crontab或启动。  --tags=TAGS 只执行指定标签的任务    例子:ansible-playbook test.yml --tags=copy  只执行标签为copy的那个任务  --list-hosts 只打印有哪些主机会执行这个 playbook 文件,不是实际执行该 playbook 文件  --list-tasks 列出所有将被执行的任务  -C, --check 只是测试一下会改变什么内容,不会真正去执行;相反,试图预测一些可能发生的变化  --syntax-check 执行语法检查的剧本,但不执行它  -l SUBSET, --limit=SUBSET 进一步限制所选主机/组模式  --limit=192.168.0.15 只对这个ip执行  --skip-tags=SKIP_TAGS 只运行戏剧和任务不匹配这些值的标签  --skip-tags=copy_start  -e EXTRA_VARS, --extra-vars=EXTRA_VARS  额外的变量设置为键=值或YAML / JSON        #cat update.yml        ---        - hosts: {
{ hosts }} remote_user: {
{ user }} .............. #ansible-playbook update.yml --extra-vars "hosts=vipers user=admin" 传递{
{hosts}}、{
{user}}变量,hosts可以是 ip或组名 -l,--limit 对指定的 主机/组 执行任务 --limit=192.168.0.10,192.168.0.11 或 -l 192.168.0.10,192.168.0.11 只对这个2个ip执行任务

配置sudo用户

---- hosts: all  vars:    user: test    password: "$6$rounds=100000$O2BHfT2XIF6oDb9w$8Hhv4vOrLN6JF/nRVYDd8zZdnn9TNkQutyYYywIcPF2kRiHgkwAjqHIN7sDUkd1DcjLRABWT9ULHZPBOF2bZS/"  remote_user: root  tasks:  - name: Add user {
{ user }} user: name={
{user}} comment="ceph user" password={
{ password }} - name: Config /etc/sudoers lineinfile: dest=/etc/sudoers state=present line='{
{item}}' validate='visudo -cf %s' with_items: - "{
{ user}} ALL=(ALL) NOPASSWD: ALL" - "Defaults: {
{user}} !requiretty"

此playbook将添加一个具有sudo权限的 test 用户 密码为password

更改用户只用更改vars:中的user 即可

生成密码:

$ pip install passlibpython -c "from passlib.hash import sha512_crypt; import getpass; print sha512_crypt.encrypt(getpass.getpass())"

输入密码后确认

会生成一长串字符替换playbook中的即可

转载于:https://my.oschina.net/adailinux/blog/1545016

你可能感兴趣的文章
Android Touch事件传递机制 二:单纯的(伪生命周期) 这个清楚一点
查看>>
Django web框架
查看>>
9.8.6恢复系统数据库
查看>>
权限组件(10):三级菜单的展示和增删改查
查看>>
Android--Retrofit的简单使用(一)
查看>>
LoadRunner监控Linux
查看>>
搭建Jupyter学习环境
查看>>
Fling!
查看>>
中国大学MOOC-C程序设计(浙大翁恺)—— 时间换算
查看>>
最好的品质
查看>>
各种排序方法
查看>>
【转】对random_state参数的理解
查看>>
[LeetCode]16. 3Sum Closest最接近的三数之和
查看>>
蓝桥杯 扑克序列(全排列)
查看>>
C#综合揭秘——Entity Framework 并发处理详解
查看>>
RecycleView的notifyItemRemoved使用注意
查看>>
mui 微信支付 与springMVC服务器交互
查看>>
传参防SQL注入函数
查看>>
Java Web整合开发读书笔记
查看>>
linux 安装安装rz/sz 和 ssh
查看>>