一.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常用模块
- 获取模块列表
按分类查询
ansible-doc -s shell
ansible-doc -s commandansible的使用
使用ansible -h来获取帮助信息
- 常用选项:
-a:指定命令参数
-m:指定模式名称简单配置演示
ansible的使用格式:ansible HOST-PATTERN -m MOD_NAME -a MOD_ARGS
首先在主机清单中加入要配置的Ip地址
然后使用ansible all -m ping——表示测试所有配置的Ip连通性
注意:当在Hosts清单中加入一个不存在的ip地址,然后去测试就会出现如图的结果,显示主机不可到达查看清单列表
查看所有列表
ansible all --list-hosts
按分类进行查询
ansible websrvs --list-hosts
ansible dbsrvs --list-hosts
常用模块
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的主机上去查看
但是如果已经存在这个目录后还要创建相同目录就会报错
因此引入幂等性只需要在创建的最后加入creates=/tmp/mydir
如上图所示会告诉用户该目录已经存在,但是不会出现报错
删除目录,前提该目录必须存在
ansible 172.18.250.89 -m command -a "rmdir mydir chdir=/tmp removes=mydir"
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"
结果将追加密码的密令识别成字符串,因此使用shell来解决问题
ansible 172.18.250.89 -m shell -a "echo magedu |passwd --stdin user1"
3.user模块:管理用户账号
经常使用的选项
name=
system=
uid=
shell=
group=
groups=
comment=
home=
generate_ssh_key=
local=
示例:
ansible websrvs -m user -a "name=hako groups=ha state=present uid=3000 createhome=yes shell=/bin/tcsh generate_ssh_key=true"
解释:创建一个用户名为hako,组为ha,状态为创建,uid=3000,创建家目录(不写也可以,本身就会默认创建),指定shell类型,并且生成私钥文件,以便今后的ssh验证
创建成功
也可以直接修改,比如修改uid
直接执行
ansible websrvs -m user -a "name=hako groups=ha state=present uid=5000 createhome=yes shell=/bin/tcsh generate_ssh_key=true"
修改成功删除用户
ansible websrvs -m user -a "name=hako groups=ha state=absent"
如果想要将ssh验证取消直接将generate_ssh_key=true改为flase
4. group模块:管理组账号
name=
state=
system=
gid=
示例:
ansible websrvs -m group -a "name=ha system=yes state=present"
5.copy模块: Copies files to remote locations.
用法:
(1) src= dest=
(2) content= dest=
owner, group, mode
示例:
首先在ansible主机上创建一个文件
vim test.txt
然后执行 ansible all -m copy -a " src=test.txt dest=/tmp owner=daemon group=nobody mode=664"
在客户端查询
执行content 是往test.txt中追加内容
查看test.txt
追加内容成功
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"
在客户端查看
添加属性
ansible all -m file -a "path=/tmp/hidir state=directory owner=nobody mode=770"
查看
创建空文件
ansible all -m file -a "path=/tmp/hifile state=touch owner=nobody mode=770"
查看
创建符号链接
ansible all -m file -a "path=/tmp/mytest.txt src=/tmp/text2.txt stste=link"
查看
删除符号链接
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"
8.cron模块
管理任务计划:Manage cron.d and crontab entries.
minute=
day=
month=
weekday=
hour=
job=
name=
state=
present:创建
absent:删除
示例:
ansible-doc -s cron
可以定义一个周期任务实现用ntpdate来到172.18.0.1上同步时间
ansible all -m cron -a "name='timesync' job='/usr/sbin/ntpdate 172.18.0.1 &> /dve/null' minute='*/5' "
到客户端查看
如果想禁止该计划任务可以在后面加上disabled=true
再到客户端去查看
9.git模块
作用:Deploy software (or files) from git checkouts
repo=
dest=
version=
首先要yum git
ansible-doc -s git
示例:
在www.github.com中搜索fastdfs
在服务器上执行
ansible websrvs -m git -a "repo=https://github.com/happyfish100/fastdfs.git dest=/tmp/fastdfs"
在客户端上查看
注意在其他客户端上都要下载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"
来查看
也可以去客户端去查看
10.service模块
*name=
state=
started
stopped
restarted
enabled=
runlevel=
示例:开启nginx服务,并且设为开机自启
ansible websrvs -m service -a "name=nginx enabled=true state=started"
客户端的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来查看
ansible-playbook --list-tasks nginx.yaml来查看任务
ansible-playbook --syntax-check nginx.yaml语法检查
ansible-playbook -C nginx.yaml执行任务属于并行执行
ansible websrvs -m setup 收集客户端的信息变量
注意:当修改某服务的配置文件,会有什么影响
例:将redis.conf配置文件中认证密码改为mageduu后再次执行ansible-playbook -C nginx.yaml
结果所有服务都要重跑一次,而且修改的内容也没有生效
因为服务没有重启,不会因为内容的改变而触发新的变化
首先解决多个任务总是要都重新执行的问题
加标签:
执行ansible-play --list-tasks nginx.yaml
执行:ansible-playbook -t insconf,startredis nginx.yaml
但是新修改的命令也不会生效,如果想要启动重启任务就要加入
再次执行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
(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
在执行过程中也可以执行-e memcached命令
首先要配置一个memcahced.yaml文件
ansible-playbook -e "pkgname=memcached" -C installpkc.yaml
这就说明命令行的优先级是高于playbook的优先级
也可以在ansible的清单文件中进行配置
vim /etc/ansible/hosts
再次执行后观察结果
ansible-playbook -e "pkgname=memcached" -C installpkc.yaml
- 测试用于定义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
以上命令是为了调用内键变量来生成一个.j2格式的模板文件
提取172.18.250.223的内存信息
通过模板文件来实现对内存大小进行计算
vim redis_conf.yml
执行ansible-playbook redis_conf.yaml
在172.18.250.223
vim /etc/reids.conf
内存减少一半
- 一般情况下常用的内键变量
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
到目标主机上查看结果
172.18.25.89
172.18.250.223
循环测试
迭代,需要重复执行的任务;
对迭代项的引用,固定变量名为”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
也可以去目标主机去查看结果
实验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
六.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
如果想修改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 即可
- { roles: ni=ginx,ngx_server_port:8080 }