运维工作:系统安装(物理机、虚拟机)--> 程序包安装、配置、服务启动 --> 批量操作 --> 程序发布  --> 监控

 

稳定可用     -------      标准化            ---------        自动化

 

系统安装:

1、物理机:PXE、Cobbler

2、虚拟机:Image Templates

 

程序配置Configration:

1、puppet (ruby语言研发)

2、saltstack (python语言研发)

3、chef

4、cfengine

5、ansible

 

批量操作Command and Control:

1、fabric(python语言研发)

2、func

3、ansible

 

程序发布:

1、人工智能(手动发布)

2、脚本

3、发布程序(运维程序)

 

程序发布的标准要求:

1、不能影响用户体验;

2、系统不能停机;

3、不能导致系统故障或造成系统完全不可用;

 

发布路径:

/webapps/tuangou

/webapps/tuangou-1.1

/webapps/tuangou-1.2

 

灰度模型:

主机

用户

 

在调度器上下线一批主机(标记为维护模式)   -----     关闭服务   ------    部署新版本    -------      启动服务    -------   在调度器上启用这一批主机;

 

 

运维工具的分类:

1、agent:puppet,func

2、agentless(ssh):ansible、fabric

 

 

ansible:可以实现系统安装(研发中)、程序配置、批量操作、发布程序(需自定义)

模块化,调用特定的模块,完成特定的任务;

基于Python语言实现,由Paramiko、PyYAML和Jinja2三个关键模块;

部署简单,agentless;

主从模式;

支持自定义模块;

支持Playbook;

幂等性;执行一次跟多次结果一致;

 

安装ansible:epel,ansible

配置文件:/etc/ansible/ansible.cfg

主机清单:/etc/ansible/hosts

 

主程序:

ansible

ansible-playbook

ansible-doc

 

 

ansible的简单使用格式:

ansible    HOST-PATTERN     -f  forks   -m MOD_NAME    -a  MOD_ARGS

 

使用前提:

1、各节点先写入/etc/ansible/hosts里

2、各节点基于ssh密钥认证通信

控制端(即ansible主机)

# ssh-keygen -t rsa -P ''

# ssh-copy-id  -i  ~/.ssh/id_rsa.pub    root@各节点

 

 

常用模块:

获取模块列表:ansible-doc  -l

获取指定模块的帮助:ansible-doc  -s  MOD_NAME

 

1、command模块:在远程主机运行命令;

 

2、shell模块:在远程主机在shell进程下运行命令,支持shell特性,例如管道、重定向等;

 

3、copy模块:复制ansible主机的文件到各远程节点;

用法:

(1)src=  dest=

(2)content=   dest=

owner,group,mode

 

4、cron模块:管理各远程节点的cron任务;

用法:

name=  job=   state=present(创建)|absent(删除)

minute,hour,day,month,weekday,user

 

5、fetch模块:从各远程节点拉取文件到ansible本机;

 

6、file模块:设定远程各节点的文件属性;

用法:

(1)创建链接文件:path=   src=  state=link

(2)修改属性:path= owner=   group= mode=

(3)创建目录:path=   state=directory

 

7、hostname模块:管理远程各节点主机名

 

8、pip模块:安装远程各节点的python所需的库

 

9、yum模块:管理各节点的yum程序;

name=:程序包名,可以带版本号;

state=:安装(present|lastest),卸载(absent);

 

10、service模块:管理远程各节点的服务

name=:

state=:started启动,stopped停止,restarted重启

enabled=0|1:开机是否启动

runlevel=

 

11、ping模块:ping远程各节点;

 

12、user模块:管理远程各节点的用户

name=

system=yes|no

uid=

shell=

state=present|absent

home=:家目录

group=:基本组

groups=:额外组

remove:删除用户,同时删除家目录

 

13、uri模块:访问远程各节点的http|https服务

 

14、setup模块:收集远程各节点的facts信息;

 

15、group模块:添加或删除组

name=

state=present|absent

gid=

system=:是否系统组

 

16、script模块:把一个本地script传递到远程各节点执行

-a “/path/to/script_file”

 

17、template模块:基于模板方式生成一个文件复制到远程主机

src=

dest=

 

 

YAML语法:YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用"-"来代表,Map里的键值对用":"分隔。下面是一个示例。

name: John Smith
age: 41
gender: Male
spouse:
name: Jane Smith
age: 37
gender: Female
children:
- name: Jimmy Smith
age: 17
gender: Male
- name: Jenny Smith
age 13
gender: Female

YAML文件扩展名通常为.yaml,如example.yaml。

 

playbook的核心元素:

hosts:

tasks: 任务

variables: 变量

templates: 模板(包含了模版语法的文本文件)

handlers: 处理器(由特定条件触发的任务)

roles: 角色

 

案例:

heartbeat.yaml

- hosts: hbhosts

 remote_user: root

 tasks:

   - name: ensure heartbeat latest version

     yum: name=heartbeat state=present

   - name: authkeys configure file

     copy: src=/root/hb_conf/authkeys dest=/etc/ha.d/authkeys

   - name: authkeys mode 600

     file: path=/etc/ha.d/authkeys mode=600

     notify:

       - restart heartbeat

   - name: ha.cf configure file

     copy: src=/root/hb_conf/ha.cf dest=/etc/ha.d/ha.cf

     notify:

      - restart heartbeat

 handlers:

 - name: restart heartbeat

   service: name=heartbeat state=restarted

 

playbook的基础组件:

hosts:运行指定任务的目标主机;

remote_user:在远程主机上执行任务的用户;

sudo_user:在需要用到sudo时指定的用户;

tasks:任务列表,自上而下

(1)action:module arguments

(2)module:arguments

注意:shell和command模块后面直接跟命令,而非key=value类的参数列表

handlers:任务,在特定条件下触发,接收到其他任务的通知时被触发;

 

(1)某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers;

(2)任务可以通过“tags”打标签,而后在ansible-playbook命令上使用-t指定进行调用;

 

运行playbook的方式:

(1)测试

ansible-playbook  --check:只检测可能发生的改变,但不真正执行操作;

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

(2)运行

 

 

variables: 变量;调用  {{   variable   }}

1、facts:setup模块提供的;可直接调用

2、ansible-playbook命令的自定义变量:通过双括号进行调用:{{   变量名  }};

3、通过roles传递变量;

4、Host Incentory:

(1)向不同的主机传递不同的变量;在/etc/ansible/hosts文件下,IP/HOSTNAME   variable=value   var2=value2

(b)向组中的主机传递相同的变量;在/etc/ansible/hosts文件下,[groupname:vars]   var=value

 

在playbook中定义变量的方法:

vars:

- var1:  value1

- var2:  value2

 

inventory参数:用于定义ansible远程连接目标主机时使用的参数,而非传递给playbook的变量;

ansible_ssh_host

ansible_ssh_port

ansible_ssh_user

ansible_ssh_pass

ansible_sudo_pass

 

模板:templates;文本文件,嵌套有脚本(使用模板编程语言编写)

jinjar2:

1、字面量:

(1)字符串:使用单引号或双引号;

(2)数值:整数,浮点数;

(3)列表:[item1,item2];

(4)元组:(item1,item2);

(5)字典:{key1:value1,key2:value2,...};

(6)布尔型:true|false

 

2、算术运行:

+,-,*,/,//,%,**

 

3、比较操作:

==,!=,>,>=,<,<=

 

4、逻辑运算:

and,or,not

 

案例:nginx.yaml:在websrvs组安装nginx,并根据模板nginx.j2,启动nginx服务;

# vim nginx.yaml

运维之ansible_第1张图片

其中nginx.j2   传递了2个变量

worker_processes {{ ansible_processor_vcpus-1 }};                  #由setup模块提供的变量;

listen {{ http_port }} default_server;

 

http_port变量是由/etc/ansible/hosts文件传递;如下

运维之ansible_第2张图片

 

 

 

条件测试:

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

在tasks后添加when子句即可使用条件测试;when语句支持jinja2表达式语法。例如:

tasks:
- name: "shutdown Debian flavored systems"
command: /sbin/shutdown -h now
when: ansible_os_family == "Debian"

 

循环:迭代,需要重复执行的任务;

对迭代项的引用,固定变量名为“item”;而后在tasks中,使用with_items给定要迭代的元素列表;a、字符串,2、字典

 

a、例如:

- name: install some package

   yum: name={{  item  }}    state=present

   with_items:

   -    nginx

   -    memcached

   -    php-fpm

 

b、例如

- name:  add some group

   group:   name={{   item   }}   state=present

   with_items:

    -  group1

    -  group2

    -  group3

-  name:  add  some users

    user:name={{   item.name   }}   group={{ item.group   }}     state=present

    with_items:

     -   {  name:  "user1"    group:   "group1"   }

     -   {  name:  "user2"    group:   "group2"   }

     -   {  name:  "user3"    group:   "group3"   }

 

 

 

角色roles:roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。

 

roles模块的路径可以在配置文件/etc/ansible/ansible.cfg里roles_path定义.

1
2
vim   /etc/ansible/ansible .cfg
roles_path  =  /etc/ansible/roles : /usr/share/ansible/roles

role内各目录中可用的文件:

tasks目录:至少应该包含一个名为main.yml的文件,其定义了此角色的任务列表;其他的文件需要在此文件中通过include进行包含;

files目录:存放由copy或script等模块调用的文件;

templates目录:template模块查找所需要模板文件的目录;

handlers目录:至少应该包含一个名为main.yml的文件,用于定义此角色用到的各handler;在handler中使用include包含的其它的handler文件也应该位于此目录中;

vars目录:至少应该包含一个名为main.yml的文件,用于定义此角色用到的变量;

meta目录:至少应该包含一个名为main.yml的文件,用于定义此角色的特殊设定及其依赖关系;ansible 1.3及其以后的版本才支持;

default目录:为当前角色设定默认变量时使用此目录;应当包含一个main.yml文件;

 

 

创建role的步骤

(1) 创建以roles命名的目录;

(2) 在roles目录中分别创建以各角色名称命名的目录,如webservers等;

(3) 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建;

(4) 在playbook文件中,调用各角色;

 

示例:创建nginx角色

#设置任务文件,注意,配置模板文件的src使用相对路径即可,目录的相对路径是:/usr/share/ansible/roles/nginx/templates/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
vim  /usr/share/ansible/roles/nginx/tasks/main .yml 
- name:  install  nginx package
   yum: name=nginx state=latest
- name: copy nginx conf  file
   tempalte: src=web.conf.j2 dest= /etc/nginx/conf .d /web .conf
   notify: reload nginx
   tags: cpfile
- name: create docroot  dir
   file : path={{ ngx_doc_root }} state=directory
   tags: cpfile
- name: start nginx service
   service: name=nginx enabled= true  state=started
#设置变量,在vars目录下定义变量,变量不需要横杆引导
vim  /usr/share/ansible/roles/nginx/vars/main .yml
ngx_port: 8888
ngx_server_name: www.sunny.com
ngx_doc_root:  /webdata
#设置触发后执行的操作
vim  /usr/share/ansible/roles/nginx/handlers/main .yml
- name: reload nginx
   service: name=nginx state=reloaded
#设置模板文件
vim  /usr/share/ansible/roles/nginx/templates/web .conf.j2
server {
     listen {{ ngx_port }}; 
     server_name {{ ngx_server_name }}; 
     location / { 
         root {{ ngx_doc_root }}; 
     }   
}

#调用模块

1
2
3
4
5
vim  /root/ansible/nginxrole .yml
- hosts: dbsrvs
   remote_user: root
   roles:
   - nginx

 测试模块

1
ansible-playbook  -C  /root/ansible/nginxrole .yml

注意,由于测试没有实际安装nginx模块,因此测试时,启动服务会失败

执行模块

1
ansible-playbook   /root/ansible/nginxrole .yml

执行tag cpfile对应的代码,如果文件web.conf.j2 发生变化,包括定义变量的文件发送变化,就会重新服务该文件到对应机器,同时,notify生效,重启nginx服务

1
ansible-playbook -t cpfile  /root/ansible/nginxrole .yml

在执行命令中执行变量,注意,命令里的变量优先级比配置再模块vars下的优先级高

1
ansible-playbook -t cpfile -e  "ngx_port=8899"  /root/ansible/nginxrole .yml

 

在playbook调用角色方法1:

- hosts:  websrvs

   remote_user: root

   roles:

   -  nginx

   -  memcached

 

在playbook调用角色方法2:传递变量给角色

- hosts:  websrvs

   remote_user: root

   roles:

   -  {  role: nginx,  username: nginx }      键role用于指定角色名称,后续的K/V用于传递变量给角色

 

还可以基于条件测试实现角色调用3;

roles:

  -  {   role:  nginx,  when:  ansible_distribution_major_version == '7'  }

 

参考文档:www.ansible.com.cn