Ansible

Ansible自动化运维 随笔 第1张

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

 

Ansible自动化运维 随笔 第2张

安装:yum、编译安装、Git方式、pip安装

配置文件:

/etc/ansible/ansible.cfg 主配置文件,配置ansible特性

/etc/ansible/hosts 主机清单

/etc/ansible/roles/ 存放角色的目录

程序

/usr/bin/ansible 主程序,临时命令执行工具

/usr/bin/ansible-doc 查看配置文档,模块功能查看工具

/usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块官网平台

/usr/bin/ansible-playbook 定制自动化任务,编排剧本工具

/usr/bin/ansible-pull 远程执行命令工具

/usr/bin/ansible-vault 文件加密工具

/usr/bin/ansible-console 给予console界面与用户交互执行工具

 

主机清单

[root@ansible ~]#vim /etc/ansible/hosts 
#可以分组 
[websrvs] 192.168.9.101 192.168.9.102 
[dbsrvs] 192.168.9.101 192.168.9.103 
# 可以指定连续的iP 
[appsrvs] 192.168.9.10[1:3] 
# 可以指定端口,指定的ssh的端口 
[port] 192.168.9.103:2222

 

 

主配置文件

[defaults]

#inventory = /etc/ansible/hosts # 主机列表配置文件

#library = /usr/share/my_modules/ # 开文件存放目录

#remote_tmp = ~/.ansible/tmp # 临时py命令文件存放在远程主机目录

#local_tmp = ~/.ansible/tmp # 本机的临时命令之星目录

#forks = 5 # 默认并发数

#sudo_user = root # 默认并发数

#ask_sudo_pass = True # 每次执行ansible命令是否询问密码

#ask_pass = True

#remote_port = 22

# host_key_checking = False # 检查对应服务器的host_key,建议取消注释

#log_path = /var/log/ansible.log # 日志文件

ansible命令

(ansible 兼容Centos6和Centos5请看:ansible如果兼容Centos5)

-m:指定模块 # ansible 192.168.9.101,192.168.9.102 -m ping -u root -k //ip必须在主机清单

-v 详细过程 -vv -vvv 更详细

--list-hosts:显示主机列表

[root@ansible ~]#ansible all --list-hosts

[root@ansible ~]#ansible websrvs --list-hosts

-k,--ask-pass:输入ssh连接密码,默认key验证

-K,--ask-become-pass 提示输入sudo时的口令

-u:用户名

-T,--timeout=TIMEOUT 执行命令超时时间,默认10s

-u,--user=REMOTE_USER 执行远程知心的用户

-b,--become 代替旧版的sudo切换

 

ansible-doc

-a:列出所有模块文档

-l:列出可用模块

-s 模块名:简单显示模块的使用

模块名:查看模块的帮助文档

 

[root@ansible ~]#ansible dbsrvs -m command -a 'ls /root' -u xuan -k -b -K -m command // 使用的command这个模块 -a 'ls /root' 这个是模块的参数 -u xuan 指定用户 -k 使用密码验证 -b 使用sudo -K 提示输入sudo的密码 
[root@ansible ~]#ansible 'all' -m ping //所有主机 
[root@ansible ~]#ansible '*' -m ping //所有主机 
[root@ansible ~]#ansible 'websrvs:dbsrvs' -m ping //在websrvs组中的和dbsrvs组中的或关系 
[root@ansible ~]#ansible 'websrvs:dbsrvs' --list 
[root@ansible ~]#ansible 'websrvs:&dbsrvs' -m ping //记载websrvs中的又在dbsrvs组中的,与关系 
[root@ansible ~]#ansible 'websrvs:&dbsrvs' --list 
[root@ansible ~]#ansible 'websrvs:!dbsrvs' --list //在websrvs里边,但是不在dbsrvs里边,此处必须为单引号 [root@ansible ~]#ansible "~(web|db)srv" -m ping //正则表达式

 

 

anseble命令执行过程

ansible命令执行过程

①加载子自己的配置文件,默认/etc/ansible/ansiblecfg

②加载自己对应的模块文件,如command

③通过ansible将模块或命令生成对用的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/ansible/tmp/ansible-tmp-数字/XXX.py文件

④ 给文件x权限

⑤执行并返回结果

⑥删除临时py文件,sleep 0 退出

执行状态,在/etc/ansible/ansible.cfg文件中有说明,475行,[colors]模块

绿色:执行成功并且不需要做改变的操作

黄色:执行成功并对目标主机做变更

红色:执行失败

 

 二、常见模块

ansible常见模块

{ping,command,shell,script,fetch,copy,hostname,cron,file,yum,service,user,group}

command

chdir:切换目录

  [root@ansible ~]#ansible all -a 'chdir=/media ls' //查看/media目录

creates:后边的文件存在就不执行

  [root@ansible ~]#ansible all -a 'creates=/media/cdrom mkdir /media/cdrom' //如果存在/media/cdrom,就创建/media/cdrom

removes:如果存在就执行

  [root@ansible ~]#ansible all -a 'removes=/media/cdrom ls -l -d /media/cdrom/' //如果存在/media/cdrom,就查看该文件

 

shell模块:因为command模块不支持重定向、管道、变量等特殊场景,所以需要shell模块

chdir:切换目录

creates:后边的文件存在就不执行

removes:如果存在就执行

[root@ansible ~]#ansible all -m shell -a 'echo $HOSTNAME' //查看每台机器的主机名 
[root@ansible ~]#ansible all -m shell -a 'echo aptech1! | passwd --stdin root' //批量改密码

 

 

Script:可以将本地的脚本在所有主机上执行

chdir:切换目录

creates:后边的文件存在就不执行

removes:如果存在就执行

[root@ansible ansible]#vim script1 #!/bin/bash hostname 
[root@ansible ansible]#ansible all -m script -a '/root/ansible/script1'

 

copy:将本地的文件推送到目标文件

backup:将原有文件备份

content:直接编辑内容

dest:目标文件的位置

mode:权限

owner:所有者

src:源文件

[root@ansible ansible]#ansible all -m copy -a 'src=/root/ansible/selinux dest=/etc/selinux/config backup=yes mode=000 owner=xuan' 

#content 
[root@ansible ansible]#ansible all -m copy -a 'content="hello\n轩\n轩" dest=/tmp/f1'

 

 

Fetch:从客户端提取文件至服务器端,与copy相反

dest:目标文件的位置

src:源文件

[root@ansible ~]#ansible all -m fetch -a 'src=/etc/sysconfig/network dest=/data' 

[root@ansible ~]#tree /data/
/data/
├── 192.168.9.101
│   └── etc
│       └── sysconfig
│           └── network
├── 192.168.9.102
│   └── etc
│       └── sysconfig
│           └── network
└── 192.168.9.103
    └── etc
        └── sysconfig
            └── network

9 directories, 3 files

 

 

file:设置文件属性

[root@ansible ansible]#ansible all -m file -a 'name=/data/f3 state=touch' #在/datax下创建文件f3 
[root@ansible ansible]#ansible all -m file -a 'dest=/data/f3 state=absent' #删除/data/f3 
[root@ansible ansible]#ansible all -m file -a 'path=/data/dir1 state=directory' #在/data下创建dir1文件夹 
[root@ansible ansible]#ansible all -m file -a 'path=/data/dir1 state=absent' #删除/data/dir1文件夹 
[root@ansible ansible]#ansible all -m file -a 'src=/etc/fstab dest=/data/f.link state=link' #将/etc/fstab软连接到/data/f.link文件 
[root@ansible ansible]#ansible all -m file -a 'dest=/data/f.link state=absent' #删除软连接

 

 

hostname:更改主机名,因为每个主机不应该一样,所以后期使用变量批量更改

  [root@ansible ansible]#ansible 192.168.9.101 -m hostname -a 'name=node01'

 

Cron:计划任务

disabled=true、yes、y、fales、no、n.... 禁用或启用

[root@ansible ansible]#ansible all -m cron -a 'minute=* weekday=2,4,6 job="/usr/bin/wall FBI warning" name=xuan'   # 计划任务,在周二、四、六每分钟报警一次 

[root@ansible ansible]#ansible all -m cron -a 'disabled=true job="/usr/bin/wall FBI warning" name=xuan'   # 禁用计划任务,job不加会报错,name不加会新建一个计划任务并注释,原来的并不会被禁用 

[root@ansible ~]#ansible all -m cron -a 'job="/usr/bin/wall" name=xuan state=absent'   # 删除计划任务 

 

 

Yum:管理包

state=latest:安装,默认就是安装

installed:查看已经安装过的

removed:卸载

disable_gpg_check=yes:忽略key验证

update_cache=yes:更新缓存

[root@ansible ~]#ansible all -m yum -a 'name=ftp'   #安装ftp客户端软件,默认为安装,所以默认不需要state=latest 

[root@ansible ~]#ansible websrvs -m yum -a 'list=installed'   #查看已经安装过的软件 

[root@ansible ~]#ansible websrvs -m yum -a 'name=ftp state=removed'   # 卸载ftp客户端软件 # 同时安装多个包 

[root@ansible ~]#ansible websrvs -m yum -a 'name=ftp,vsftpd,httpd' # 同时卸载多个包,absent和removed都可以 
[root@ansible ~]#ansible websrvs -m yum -a 'name=ftp,vsftpd,httpd state=absent' 

#安装rpm单个包,先使用copy,在使用yum   ①copy复制   [root@ansible
~]#ansible all -m copy -a 'src=/media/cdrom/Packages/dstat-0.7.2-12.el7.noarch.rpm dest=/root'   ②yum安装,并且忽略key验证    [root@ansible ~]#ansible all -m yum -a 'name=/root/dstat-0.7.2-12.el7.noarch.rpm disable_gpg_check=yes' [root@ansible ~]#ansible websrvs -m yum -a 'update_cache=yes' # 更新缓存
  

 

 

Service

enabled:开机启动

name:指定服务名

state:started、stopped、restarted、reloaded

[root@ansible ~]#ansible websrvs -m service -a 'state=started enabled=yes name=vsftpd'   # 启动vsftpd,设置为开机启动
 
[root@ansible ~]#ansible websrvs -m service -a 'state=stopped enabled=no name=vsftpd  # 关闭vsftpd,取消开机启动

 

'

 

User:管理用户

comment:注释

create_home:是否创建家目录

expires:过期时间

group:主组

groups:附加组

home:家目录

name:用户名

password:加密口令

remove:删除,而且删除家目录

system:制定系统账号

shell:shell类型

[root@ansible ~]#ansible websrvs -m user -a 'name=nginx shell=/sbin/nologin system=yes create_home=no groups=wheel uid=80 comment="Nginx server"'    # 创建nginx用户,shell为nologin,是一个系统账户,不创建家目录,uid为80,commend描述

[root@ansible ~]#ansible websrvs -m user -a 'name=nginx shell=/sbin/nologin home=/home/nginx system=yes create_home=yes groups=wheel uid=80 comment="Nginx server"'    # home指定家目录 

[root@ansible ~]#ansible websrvs -m user -a 'name=nginx state=absent remove=yes'   # 删除nginx用户,如果有家目录,也将家目录删除 

 

 

Group

system:是否是系统组

gid:

state

name

[root@ansible ~]#ansible websrvs -m group -a 'name=nginx system=y gid=80' # 系统组,gid为80

[root@ansible ~]#ansible websrvs -m group -a 'name=nginx state=absent'  # 删除组

 

 

三、ansible的小命令与Playbook的编写

ansible-galaxy

下载galaxy

  [root@ansible ~]#ansible-galaxy install geerlingguy.nginx

 

查看galaxy

  [root@ansible ~]#ansible-galaxy list //查看所有角色

  [root@ansible ~]#ansible-galaxy list geerlingguy.nginx //查看单个角色

  [root@ansible ~]#cp -ar .ansible/roles/{geerlingguy.nginx,xuan.nginx} //就等于又创建了一个角色

 

删除galaxy

  [root@ansible ~]#ansible-galaxy remove geerlingguy.nginx

 

ansible-pull(push拉,pull推)

速度较快

 

ansible-playbook(后边还有更多介绍)

后缀建议为yml

#第一个plabook
[root@ansible ansible]#vim hello.yml              
---        //第一行的---是一个习惯
- hosts: websrvs      //必须要注意空格,对空格很敏感,hosts代表远程主机,websrvs是之前创建爱你的主机清单组
  remote_user: root   // 在远程使用什么身份执行

  tasks:
    - name: xuan       //playbook的名字
      command: hostname    //command是模块,hostname是命令

 

ansible-vault:用于加密ansible-playbook

[root@ansible ansible]#ansible-vault encrypt hello.yml # 将hello.yml加密

[root@ansible ansible]#ansible-vault view hello.yml # 查看加密后的文件内容,需要输入解密密码

[root@ansible ansible]#ansible-vault edit hello.yml    # 编辑加密后的文件

[root@ansible ansible]#ansible-vault rekey hello.yml  # 修改口令

[root@ansible ansible]#ansible-vault create hello2.yml  # 创建一个新的,加密的文件

[root@ansible ansible]#ansible-vault decrypt hello.yml  # 将hello.yml解密

ansible-console:2.0+新增,可交互式执行命令,支持tab

[root@ansible ansible]#ansible-console
# 远程执行命令的用户@针对的主机 (3个主机) [f:
5]代表并发数 root@all (3)[f:5]$ # 切换针对的主机为websrvs组 root@all (3)[f:5]$ cd websrvs # 修改并发数为10 root@websrvs (2)[f:5]$ forks 10 # 调用command模块 root@websrvs (2)[f:10]$ command hostname

 

 

Playbook:YAML语言编写

 

Ansible自动化运维 随笔 第3张

YAML介绍

 

Ansible自动化运维 随笔 第4张

 

 

YAML语法简介

 Ansible自动化运维 随笔 第5张

Ansible自动化运维 随笔 第6张

 

Ansible自动化运维 随笔 第7张

 

 

YAML语法

 Ansible自动化运维 随笔 第8张

 

 

Playbood核心元素

Hosts 指定的远程主机列表(支持)

Tasks 任务集

tasks中的一个name只能对应一个模块的执行任务,只会执行后边定义的

Varniables 内置变量或自定义变量在playbook中调用

Tempplates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件

Handlers 和 notity集合使用,由特定条件触发的操作,满足条件方执行,否则不执行

[root@ansible ansible]#cat http.yml 
---
- hosts: websrvs
  remote_user: root

  tasks:
    - name: install httpd Package
      yum: name=httpd
    - name: copy conf file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=y
      notify: restart service      //当文件发生改变时,使用notify调用handlers的restart server
    - name: start service
      service: name=httpd state=started enabled=y

  handlers:
    - name: restart service     # 这里的名字用于tasks里边的调用
      service: name=httpd state=restarted

 

tags 标签 指定某条任务执行,用于选择运行playbook 中的部分代码

  多个name公用一个标签,执行的那个标签的时候,都会被执行

[root@ansible ansible]#cat http.yml 
---
- hosts: websrvs
  remote_user: root

  tasks:
    - name: install httpd Package
      yum: name=httpd
      tags: install
    - name: copy conf file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=y
    - name: start service
      service: name=httpd state=started enabled=y
      tags: startservice
# 查看文件中定义了哪些模块
[root@ansible ansible]#ansible-playbook --list-tags http.yml
# 使用-t单独指定执行的tags
[root@ansible ansible]#ansible-playbook -t install http.yml

 

ansible-playbook

-C,--check:不执行,检查与法

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

--list-tags:列出tags

--list-tasks :列出tasks中定义的内容,列出的同时也会有tags信息

--limit:指定运行的主机,前提是主机必须在文件中定义

-t:指定执行的tahs

-v -vv -vvv

 

Playbook执行失败后续怎么继续执行

无论如何返回true方法

tasks:

- name: test1

shell: /aaa || /bin/true

使用playbook自带的忽略错误

tasks:

- name: test2

shell: /aaa

ignore_errors:True

 

 

ShellScripts VS Playbook

 Ansible自动化运维 随笔 第9张

 

 

Playbook示例

# 相对路径
[root@ansible ansible]#cat playbook1.yml 
---
- hosts: websrvs
  remote_user: root

  tasks:
   - name: cppy index
     copy: src=files/index.html dest=/var/www/html/    # 相对路径是相对的当前目录

 

 

 五、变量

变量:字母、数字、下划线组成,字母开头

变量来源

  ①ansible setup facts 远程主机的所有变量可以直接调用

    setup是一个模块,这个模块可以不添加任何参数直接执行,会返回对方主机的很多信息,并且使用变量进行保存

 

 

# 显示所有变量
[root@ansible ~]#ansible websrvs -m setup 

# 也可以使用-a 加参数,过滤其中的某些参数
[root@ansible ~]#ansible websrvs -m setup -a 'filter=ansible_fqdn'     //显示FQDN主机名
[root@ansible ~]#ansible websrvs -m setup -a 'filter=*address*'    //显示地址,会显示包含address关键字的相关信息
[root@ansible ~]#ansible websrvs -m setup -a 'filter=ansible_eth*'   //也可以看某个网卡的参数

  setup在playbook中的示例

 

[root@ansible ansible]#cat var4.yml 
---
- hosts: websrvs
  remote_user: root

  tasks:
  - name: create log file
    file: name=/data/{{ansible_fqdn}}.log state=touch mode=600 owner=xuan  # ansible_fqdn就是一个setup中的变量

  ②在主机清单中定义

    普通变量:主机组中主机单独定义,优先级高于公共变量

    公共(组)变量:针对主机组中所有主机定义统一变量

 

[root@ansible ansible]#cat /etc/ansible/hosts
[websrvs]
192.168.9.101 host_port=81       # 普通变量
192.168.9.102 host_port=82

[websrvs:vars]    # 公共(组)变量
nodename=www
domainname=p-pp.cn

# 在playbook中调用
[root@ansible ansible]#cat var3.yml           
---
- hosts: websrvs
  remote_user: root

  tasks:
    - name: set hostname
      hostname: name={{nodename}}{{host_port}}.{{domainname}}

 

  ③通过命令行指定变量,优先级最高
[root@ansible ~]#cat ansible/var1.yml
---
- hosts: websrvs
  remote_user: root

  tasks:
    - name: install package
      yum: name={{ pkname1 }}
    - name: install package
      yum: name={{ pkname2 }}
# 在执行时定义
[root@ansible ansible]#ansible-playbook -e "pkname1=httpd pkname2=vsftpd" var1.yml -C

 

  ④在playbook中定义
[root@ansible ansible]#cat var2.yml 
---
- hosts: websrvs
  remote_user: root
  vars:
    - pkname1: httpd
    - pkname2: vsftpd

  tasks:
    - name: install package1
      yum: name={{ pkname1 }}
    - name: install package2
      yum: name={{ pkname2 }}

 

  ⑤也可以使用vars_files指定文件

 

[root@ansible ansible]#cat vars.yml 
var1: httpd
var2: vsftpd

[root@ansible ansible]#cat var5.yml  
---
- hosts: websrvs
  remote_user: root
  vars_files:      //调用文件中的变量
    - vars.yml    //vars.yml是文件的名字
  tasks:
  - name: install package
    yum: name={{var1}},{{var2}}
  - name: create file
    file: name=/data/{{var2}}.log state=touch

在rule中定义

 

命令行变量 > playbook > 主机清单

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄