2017 11-17 ansible应用

字数 4424阅读 992

一.ansible

(1) ansible:

ansible是一款新出现的自动化运维系统,基于python开发并集合了众多运维工具的优点,实现批量系统配置,具有程序部署,批量运行命令等功能。工作特点是基于模块化工作,但本身不具有部署能力,真正具有部署能力的是ansible所运行的模块,ansible只是提供框架且基于ssh验证实现批量通讯和配置。

(2)特性:

1.模块化:调用特定的模块来完成任务
2.基于python语言实现,由paramiko,pyYAML和jinja2三个关键模块组成
3.部署简单:属于agentless
4.支持自定义模块
5.支持playbook
6.幂等性:执行多次操作,不会造成危险后果并且结果相同

(3)安装

在epel源中下载或去官网下载
配置文件:/etc/ansible/ansible.cfg
主机清单:/etc/ansible/hosts
主程序:ansible,ansible-playbook,ansible-doc

二.ansible常用模块

  • 获取模块列表
    搜狗截图20171118094011.png

    按分类查询
    ansible-doc -s shell
    ansible-doc -s command

  • ansible的使用
    使用ansible -h来获取帮助信息


    搜狗截图20171118094524.png
  • 常用选项:
    -a:指定命令参数
    -m:指定模式名称
  • 简单配置演示
    ansible的使用格式:ansible HOST-PATTERN -m MOD_NAME -a MOD_ARGS
    首先在主机清单中加入要配置的Ip地址


    搜狗截图20171118093220.png

    然后使用ansible all -m ping——表示测试所有配置的Ip连通性


    搜狗截图20171117220036.png

    注意:当在Hosts清单中加入一个不存在的ip地址,然后去测试就会出现如图的结果,显示主机不可到达
  • 查看清单列表
    查看所有列表
    ansible all --list-hosts


    搜狗截图20171117220111.png

    按分类进行查询
    ansible websrvs --list-hosts
    ansible dbsrvs --list-hosts


    搜狗截图20171118095923.png

常用模块

1.command:在远程主机运行命令

chdir=:执行命令前切换工作目录至指定的位置;
creates=/PATH/TO/SOMEFILE_OR_DIR:如果此处给定的文件或目录存在,则不执行命令;
removes=/PATH/TO/SOMEFILE_OR_DIR:如果此处给定的文件或目录不存在,则不执行命令;
意为:令此处给定的文件或目录存在时方执行命令;
示例:
ansible 172.18.250.89 -m command -a "mkdir mydir chdir=/tmp"——针对172.18.250.89创建一个目录并且将目录放在tmp作为子目录
此时会显示创建成功,在172.18.250.89的主机上去查看


搜狗截图20171118100950.png

但是如果已经存在这个目录后还要创建相同目录就会报错


搜狗截图20171117221138.png

因此引入幂等性只需要在创建的最后加入creates=/tmp/mydir
搜狗截图20171117221246.png

如上图所示会告诉用户该目录已经存在,但是不会出现报错
  • 删除目录,前提该目录必须存在
    ansible 172.18.250.89 -m command -a "rmdir mydir chdir=/tmp removes=mydir"


    搜狗截图20171118102115.png

2.shell模块——命令解释器

shell模块:在远程主机在shell进程下运行命令,支持shell特性,如管道等;
chdir:执行命令前切换工作目录至指定的位置;
creates=/PATH/TO/SOMEFILE_OR_DIR:如果此处给定的文件或目录存在,则不执行命令;
removes=/PATH/TO/SOMEFILE_OR_DIR:如果此处给定的文件或目录不存在,则不执行命令;
意为:令此处给定的文件或目录存在时方执行命令;
executable=/PATH/TO/SHELL:指定运行命令使用的shell解释器;
示例:创建用户
ansible 172.18.250.89 -m command -a "useradd use1"
为用户添加密码
如果不设置命令解释器结果如下
ansible 172.18.250.89 -m command -a "echo magedu | passwd --stdin user1"


搜狗截图20171117221838.png

结果将追加密码的密令识别成字符串,因此使用shell来解决问题
ansible 172.18.250.89 -m shell -a "echo magedu |passwd --stdin user1"


搜狗截图20171117221937.png

3.user模块:管理用户账号

  • 经常使用的选项
    name=
    system=
    uid=
    shell=
    group=
    groups=
    comment=
    home=
    generate_ssh_key=
    local=


    搜狗截图20171117222103.png
  • 示例:
    ansible websrvs -m user -a "name=hako groups=ha state=present uid=3000 createhome=yes shell=/bin/tcsh generate_ssh_key=true"


    搜狗截图20171117223235.png

    解释:创建一个用户名为hako,组为ha,状态为创建,uid=3000,创建家目录(不写也可以,本身就会默认创建),指定shell类型,并且生成私钥文件,以便今后的ssh验证


    搜狗截图20171118105255.png

    创建成功
    也可以直接修改,比如修改uid
    直接执行

    ansible websrvs -m user -a "name=hako groups=ha state=present uid=5000 createhome=yes shell=/bin/tcsh generate_ssh_key=true"


    搜狗截图20171117223307.png

    修改成功
  • 删除用户
    ansible websrvs -m user -a "name=hako groups=ha state=absent"


    搜狗截图20171118110053.png

    如果想要将ssh验证取消直接将generate_ssh_key=true改为flase

4. group模块:管理组账号

name=
state=
system=
gid=

  • 示例:
    ansible websrvs -m group -a "name=ha system=yes state=present"


    搜狗截图20171117222406.png

5.copy模块: Copies files to remote locations.

用法:
(1) src= dest=
(2) content= dest=
owner, group, mode


搜狗截图20171118110951.png

示例:
首先在ansible主机上创建一个文件
vim test.txt
然后执行 ansible all -m copy -a " src=test.txt dest=/tmp owner=daemon group=nobody mode=664"


搜狗截图20171117224119.png

在客户端查询
搜狗截图20171117224058.png

执行content 是往test.txt中追加内容
搜狗截图20171117224426.png

查看test.txt
搜狗截图20171118111750.png

追加内容成功

6.file模块Sets attributes of files

用法:
(1) 创建链接文件:*path= src= state=link
(2) 修改属性:path= owner= mode= group=
(3) 创建目录:path= state=directory
注意:state属性的可用值
file,directory,link,hard,touch,absent
示例:
ansible all -m file -a "path=/tmp/hidir state=directory"


搜狗截图20171117224832.png

在客户端查看


搜狗截图20171118112517.png

添加属性
ansible all -m file -a "path=/tmp/hidir state=directory owner=nobody mode=770"
搜狗截图20171117224930.png

查看
搜狗截图20171118112852.png

创建空文件
ansible all -m file -a "path=/tmp/hifile state=touch owner=nobody mode=770"
搜狗截图20171117225130.png

查看
搜狗截图20171118113223.png

创建符号链接
ansible all -m file -a "path=/tmp/mytest.txt src=/tmp/text2.txt stste=link"


搜狗截图20171117225436.png

查看
搜狗截图20171117225555.png

删除符号链接
搜狗截图20171117225640.png

7. get_url模块

Downloads files from HTTP, HTTPS, or FTP to node
常用用法
url=
dest=
sha256sum= 检验校验码
owner, group, mode
示例:登录www.redis.io
复制下载链接
执行 ansible all -m get_url -a "url=/http://download.redis.io/releases/redis-4.0.2.tar.gz dest=/tmp"

搜狗截图20171118114600.png

8.cron模块

管理任务计划:Manage cron.d and crontab entries.
minute=
day=
month=
weekday=
hour=
job=
name=
state=
present:创建
absent:删除
示例:
ansible-doc -s cron


搜狗截图20171118161854.png

可以定义一个周期任务实现用ntpdate来到172.18.0.1上同步时间
ansible all -m cron -a "name='timesync' job='/usr/sbin/ntpdate 172.18.0.1 &> /dve/null' minute='*/5' "
到客户端查看


搜狗截图20171118164054.png

如果想禁止该计划任务可以在后面加上disabled=true
搜狗截图20171118164243.png

再到客户端去查看
搜狗截图20171118164421.png

9.git模块

作用:Deploy software (or files) from git checkouts
repo=
dest=
version=
首先要yum git
ansible-doc -s git

搜狗截图20171118164800.png

示例:
www.github.com中搜索fastdfs
搜狗截图20171118165030.png

在服务器上执行
ansible websrvs -m git -a "repo=https://github.com/happyfish100/fastdfs.git dest=/tmp/fastdfs"
在客户端上查看
搜狗截图20171118165158.png

注意在其他客户端上都要下载git否则无法进行批量复制下载

9.yum模块

name=:程序包名称,可以带版本号;
state=
present, latest, installed
absent, removed
其它的包管理工具:apt(debian), zypper(suse), dnf(fedora), rpm, dpkg, ...
示例:
ansible all -m yum -a "name=nginx state=latest "
可以使用ansible websrvs -a "rpm -q nginx"
来查看


搜狗截图20171118165914.png

也可以去客户端去查看

10.service模块

*name=
state=
started
stopped
restarted
enabled=
runlevel=
示例:开启nginx服务,并且设为开机自启
ansible websrvs -m service -a "name=nginx enabled=true state=started"


搜狗截图20171118170411.png

客户端的Nginx服务被开启

三. Playbook

(1).playbook:YAML格式,任务(task)。
将多个操作命令写到一个文件中,可以同时执行文件中中命令也可以吧playbook叫做"剧本",将编好的内容按剧本进行下去
(2).YAML:YAML(/ˈjæməl/,尾音类似camel骆驼)是一个可读性高,用来表达数据序列的格式。YAML参考了其他多种语言,包括:C语言、Python、Perl,并从XML、电子邮件的数据格式(RFC 2822)中获得灵感。Clark Evans在2001年首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。目前已经有数种编程语言或脚本语言支持(或者说解析)这种语言。
YAML是"YAML Ain't a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言),但为了强调这种语言以数据做为中心,而不是以标记语言为重点,而用反向缩略语重命名。
YAML的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印除错内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。
(3).基本数据结构:
标量、数组、关联数组
(4).Playbook的核心元素:
Hosts:主机
Tasks:任务列表
Variables
Templates:包含了模板语法的文本文件;
Handlers:由特定条件触发的任务;

示例:

在ansible主机上编写脚本
vim nginx.yaml

 1 - hosts: websrvs ——websrvs上安装nginx
  2   remote_user:  root
  3   tasks:
  4   - name: install nginx package——安装nginx安装包
  5     yum: name=nginx state=latest——执行yum命令
  6   - name: start nginx service——开启nginx服务
  7     service: name=nginx enabled=true state=started——设定开机自启
  8 
  9 - hosts: dbsrvs——在dbsrvs上安装redis服务
 10   remote_user: root
 11   tasks:
 12   - name: install redis package
 13     yum: name=redis state=latest
 14   - name: install conf file——安装conf文件
 15     copy: src=/etc/redis.conf dest=/etc/redis.conf owner=redis group=root mode=644——将本地的配置文件复制目标主机上,并设置所有者和所属组,权限为644
 16    # tags: insconf
 17    # notify: restart redis service
 18   - name: start redis service
 19     service: name=redis state=started
 20     #tags: startredis
 21   #handlers:
 22   #- name: restart redis service
 23   #  service: name=redis state=restarted

使用ansible-playbook --list-hosts nginx.yaml来查看


搜狗截图20171118173144.png

ansible-playbook --list-tasks nginx.yaml来查看任务


搜狗截图20171118173221.png

ansible-playbook --syntax-check nginx.yaml语法检查
搜狗截图20171118173426.png

ansible-playbook -C nginx.yaml执行任务属于并行执行


搜狗截图20171118173636.png

ansible websrvs -m setup 收集客户端的信息变量
注意:当修改某服务的配置文件,会有什么影响
例:将redis.conf配置文件中认证密码改为mageduu后再次执行ansible-playbook -C nginx.yaml
结果所有服务都要重跑一次,而且修改的内容也没有生效
因为服务没有重启,不会因为内容的改变而触发新的变化
首先解决多个任务总是要都重新执行的问题
加标签:
搜狗截图20171118175041.png

执行ansible-play --list-tasks nginx.yaml


搜狗截图20171118175443.png

执行:ansible-playbook -t insconf,startredis nginx.yaml
但是新修改的命令也不会生效,如果想要启动重启任务就要加入
搜狗截图20171118175835.png

再次执行ansible-playbook -t insconf,startredis nginx.yaml
发现重启命令生效

四. variables——变量

(1) facts:可直接调用;
注意:可使用setup模块直接获取目标主机的facters;
(2) 用户自定义变量:
(a) ansible-playbook命令的命令行中的
-e VARS, --extra-vars=VARS
(b) 在playbook中定义变量的方法:
vars:
-var1: value1
-var2: value2
变量引用:{{ variable }}
(3) 通过roles传递变量;
(4) Host Inventory
(a) 用户自定义变量
(i) 向不同的主机传递不同的变量;
IP/HOSTNAME varaiable=value var2=value2
(ii) 向组中的主机传递相同的变量;
[groupname:vars]
variable=value

搜狗截图20171118224216.png

(b) invertory参数
用于定义ansible远程连接目标主机时使用的参数,而非传递给playbook的变量;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansbile_sudo_pass

  • 测试
    vim installpkc.yaml
- hosts: websrvs
  remote_user: root
  vars: ——定义变量
  - pkgname: tree——安装tree包
  tasks:
  - name: install package {{ pkgname }}——安装配置格式
    yum: name={{ pkgname }}  state=latest
搜狗截图20171118222100.png

在执行过程中也可以执行-e memcached命令
首先要配置一个memcahced.yaml文件


搜狗截图20171118222408.png

ansible-playbook -e "pkgname=memcached" -C installpkc.yaml


搜狗截图20171118222850.png

这就说明命令行的优先级是高于playbook的优先级
也可以在ansible的清单文件中进行配置
vim /etc/ansible/hosts
搜狗截图20171118223214.png

再次执行后观察结果
ansible-playbook -e "pkgname=memcached" -C installpkc.yaml


搜狗截图20171118223535.png
  • 测试用于定义ansible远程连接目标主机时使用的参数,而非传递给playbook的变量;
    vim /etc/ansible/hosts
    [websrvs]
    172.18.250.89 ansible_ssh_user=root ansible_ssh_pass=mage
    但是通常不建议这么设定,容易暴露密码会带来安全隐患
    所以不经常使用该方法

五.模板文件的应用

基于模板方式生成一个文件复制到远程主机
src=
dest=
owner=
group=
mode=
文本文件,嵌套有脚本(使用模板编程语言编写)
Jinja2:
字面量:
字符串:使用单引号或双引号;
数字:整数,浮点数;
列表:[item1, item2, ...]
元组:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布尔型:true/false
算术运算:
+, -, *, /, //, %, **
比较操作:
==, !=, >, >=, <, <=
逻辑运算:
and, or, not

示例:

cp /etc/redis.conf{,.j2}——复制一个以.j2结尾的配置文件
编辑文件vim /etc/redis.conf.j2


搜狗截图20171118225027.png

以上命令是为了调用内键变量来生成一个.j2格式的模板文件
提取172.18.250.223的内存信息


搜狗截图20171118225132.png

通过模板文件来实现对内存大小进行计算
vim redis_conf.yml
搜狗截图20171118225837.png

执行ansible-playbook redis_conf.yaml


搜狗截图20171118230138.png

在172.18.250.223
vim /etc/reids.conf
搜狗截图20171118230217.png

内存减少一半
  • 一般情况下常用的内键变量
    ansible 172.18.21.200 -m setup |grep vcpu
    ansible 172.18.21.200 -m setup |grep fqdn
    ansible 172.18.21.200 -m setup |grep memtotal
    ansible 172.18.21.200 -m setup |grep version
    ansible 172.18.21.7 -m setup|grep -A 2 "default_ipv4"

条件测试:

when语句:在task中使用,jinja2的语法格式

tasks: 
- name: install conf file to centos7
template: src=files/nginx.conf.c7.j2
when: ansible_distribution_major_version == "7"——根据版本号的不同来进行下载
- name: install conf file to centos6
template: src=files/nginx.conf.c6.j2
when: ansible_distribution_major_version == "6"——同上,版本为6就下载到centos6上                

示例:

在ansible主机上vim diff.txt和diff2.txt,分别写入不同内容
例如在diff.txt中写入'host1',在diif2.txt写入'hosts2'
此时vim copyfiles.yaml

- hosts: websrvs
  remote_user: root
  tasks:
  - name: copy file
    copy: src=/root/diff.txt dest=/tmp/
    when: ansible_default_ipv4['address'] == '172.18.250.89'——判断条件
  - name: copy file 2
    copy: src=/root/diff2.txt dest=/tmp/
    when: ansible_default_ipv4['address'] == '172.18.250.223'——判断条件
以上脚本内容是为了对不同的内容复制到不同的主机上去,实现分别复制的功能  

执行 ansible-playbook -C copyfiles.yaml


搜狗截图20171119144446.png

到目标主机上查看结果
172.18.25.89


搜狗截图20171119144548.png

172.18.250.223
搜狗截图20171119144636.png

循环测试

迭代,需要重复执行的任务;
对迭代项的引用,固定变量名为”item“
而后,要在task中使用with_items给定要迭代的元素列表;
列表方法:
字符串
字典

示例1:

- name: install some packages
yum: name={{ item }} state=present——循环模式的书写格式一定要有{{ item }}
with_items:
- nginx
- memcached
- php-fpm

示例2:

- name: add some groups
group: name={{ item }} state=present——以列组的方式进行安装
with_items:
- group11
- group12
- group13
- name: add some users——添加用户
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- { name: 'user11', group: 'group11' }
- { name: 'user12', group: 'group12' }
- { name: 'user13', group: 'group13' }

为了方便理解做几个示例来加深印象
vim tomcat.yml

1 - hosts: websrvs
2   remote_user: root
3   vars:
4   - jdk_version: 1.8.0
5   tasks:
6   - name: install {{ item }} package
7     yum: name={{ item }} state=latest
8     with_items:
9     - nginx
10   - tomcat
11   - java-{{ jdk_version }}-openjdk
12   - tomcat-webapps
13   - tomcat-docs-webapp
14   - tomcat-admin-webapps

ansible-playbook tomcat.yml


搜狗截图20171119151613.png

也可以去目标主机去查看结果
实验2:对一台主机安装不同软件且指出版本

- hosts: 172.18.250.89
  remote_user: root
  tasks:
  - name: install tomcat package
    yum: name={{ item.name }}-{{ item.version }} state=latest—定义子健为版本号 
    with_items:
    - { name: 'nginx',version: '1.12.2' }
    - { name: 'tomcat',version: '7.0.76'   }

实验3:将同一软件的不同文件复制到远程主机上
以tomcat为例
vim tomcat3.yml

 - hosts: websrvs
   remote_user: root
   vars:
   - jdk_version: 1.8.0
   tasks:
   - name: install {{ item }} package
     yum: name={{ item }} state=latest
     with_items:
     - nginx
     - tomcat
     - java-{{ jdk_version }}-openjdk
     - tomcat-webapps
     - tomcat-docs-webapp
     - tomcat-admin-webapps
  
    - name: install conf file
      copy: src={{ item.f1 }} dest={{ item.f2 }}
      with_items:
      - { f1: '/root/server.xml',f2: '/etc/tomcat/server.xml' }
      - { f1: '/root/tomcat-users.xml',f2: '/etc/tomcat/tomcat-users.xml' }

ansible-playbook tomcat3.yml


搜狗截图20171119155019.png

六.roles

角色集合:
roles/
mysql/
httpd/
nginx/
memcached/
每个角色,以特定的层级目录结构进行组织:
mysql/
files/ :存放由copy或script模块等调用的文件;
templates/:template模块查找所需要模板文件的目录;
tasks/:至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含;
handlers/:至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含;
vars/:至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含;
meta/:至少应该包含一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系;
其它的文件需要在此文件中通过include进行包含;
default/:设定默认变量时使用此目录中的main.yml文件;

在playbook调用角色方法1:

- hosts: websrvs
remote_user: root
roles:
- mysql
- memcached
- nginx
>* 在playbook调用角色方法2:传递变量给角色
>- hosts: 
remote_user:
roles:
>- { role: nginx, username: nginx }
键role用于指定角色名称;后续的k/v用于传递变量给角色;
还可以基于条件测试实现角色调用;
roles:
 -{ role: nginx, when: "ansible_distribution_major_version == '7' " }

示例:
1.cd /etc/ansible/roles/
mkdir nginx/{vars,hanlers,templates,files,tasks}
2.配置playbook vim mywebserves.yml

- hosts: websrvs
  remote_user: root
  roles:——定义角色
  - nginx——调用nginx

3.配置handlers
vim handlers/main.yml

- name: reload nginx——定义触发器,启动重启服务
  service: name=nginx state=reloaded——调用重启服务命令

4.配置tasks/main.yml

- name: install nginx packag
  yum: name=nginx state=latest
- name: install conf file module
  template: src=web.conf.j2  dest=/etc/nginx/conf.d/web.conf——启用模板文件,格式为.j2 复制到目标主机的conf.d下
  notify: reload nginx——定义标志
  tags: instconf——标志名为instconf
- name: install nginx.conf——安装nginx.conf文件
  copy: src=nginx.conf dest=/etc/nginx/nginx.conf——启动复制将文件复制到目标主机上
  notify: reload nginx——定义标志,执行mywebserves.yml时只启动有标志的服务
  tags: instconf——标志名也为instconf
- name: create docroot
  file: path={{ ngx_doc_root }} state=directory——创建目录静态文件
- name: start  nginx service
  service: name=nginx enabled=true state=started

5.配置templates.web.conf.j2——定义模板文件

 1 server{
  2 
  3     listen {{ ngx_server_port }};——监听nginx的端口
  4     server_name {{ ngx_server_name }};——服务名
  5 
  6     location / {
  7             root {{ ngx_doc_root }};——访问地址
  8   }
  9 }

6.配置vars/main.yml——定义变量

ngx_server_port: 80——定义端口
ngx_server_name: www.magedu.com——主机服务器地址
ngx_doc_root: /webdata——定义目录

7.配置flies静态文件
vim files/nginx.conf
scp 172.18.250.89:/etc/nginx/nginx.conf /etc/ansible/roles/nginx/files/

8.配置完成后执行
ansible-playbook mywebserves.yml


搜狗截图20171119181822.png

如果想修改nginx的服务端口并且只让指定的服务运行,可以执行
ansible-playbook -t instconf -e "ngx_server_port=10080" mywebserves.yml 即可
也可以在mywebserves.yml修改

  • hosts: websrvs
    remote_user: root
    roles:
    • { roles: ni=ginx,ngx_server_port:8080 }
      再次执行ansible-playbook -t instconf mywebserves.yml 即可

推荐阅读更多精彩内容