ansible自动化运维以及云服务基础知识
ansible相对来说比较简单,playbook(剧本)用来实现相对于比较复杂的任务,Roles用来实现更加复杂的任务。
ansible使用模块性开发,相当于各种命令参数的集合。
https://baike.baidu.com/item/%E4%BA%91%E6%9C%8D%E5%8A%A1/7843499?fr=aladdin 云服务详情见上述链接
云计算(Cloud Computing)是分布式计算(Distributed Computing)、并行计算(Parallel Computing)、效用计算(Utility Computing)、网络存储(Network Storage Technologies)、虚拟化(Virtualization)、负载均衡(Load Balance)内容分发网络(Content Delivery Network)等传统计算机和网络技术发展融合的产物。
简单来说,云服务可以将企业所需的软硬件、资料都放到网络上,在任何时间、地点,使用不同的IT设备互相连接,实现数据存取、运算等目的。当前,常见的云服务有公共云(Public Cloud)与私有云(Private Cloud)两种 [2] 。
公共云成本较低
公共云是最基础的服务,多个客户可共享一个服务提供商的系统资源,他们毋须架设任何设备及配备管理人员,便可享有专业的IT服务,这对于一般创业者、中小企来说,无疑是一个降低成本的好方法。公共云还可细分为3个类别,包括Software-as-a-Service, SaaS(软件即服务)、Platform-as-a-Service, PaaS(平台即服务)及Infrastructure-as-a-Service, IaaS(基础设施即服务)。
我们平日常用的Gmail、Hotmail、网上相册都属于SaaS的一种,主要以单一网络软件为主导;至于PaaS则以服务形式提供应用开发、部署平台,加快用户自行编写CRM(客户关系管理)、ERP(企业资源规划)等系统的功能,用户必须具备丰富的IT知识。
iaaS(Infrastructure as a Service):基础架构即服务(只给你硬件)
PaaS(Paltform as a Service):平台即服务(连操作系统一块给你)
SaaS(Software as a Service):软件即服务(你要啥软件给你啥软件)
灰度发布:一100台生产服务器,先发布其中10台服务器,这10台就是灰度服务器。(基于服务器,用户,地区都可以)一般使用软连接形式,将一个软连接从原来的版本指向新的版本。
常见的自动化运维工具:
- Ansible:Python,不需要部署代理,中小型应用环境
- Saltstack:python,一般需部署agent(代理),执行效率高
- Puppet(怕配特):功能强大,配置复杂,适合大型环境
- Fabric:python
- Cfengine:
- func:
ansible的架构:
一个主机控制多台主机
主控端(中控、master、堡垒机):Host Inventory:主机清单,ansible怎么知道哪些主机需要管理呢?那么在这个文件中记录的哪些主机需要控制。
/etc/ansible/hosts:存放主机清单的文件,存放进去之后才能被ansible控制
如果一些日常的小任务,可以使用一些模块来实现,但是一些例行性的任务,就要使用Playbook来实现了。
也支持一些额外的插件,比如日志、邮件等,中间要想和这些远程主机进行关联或者控制、需要有连接插件,这个插件目前来讲就是基于SSH协议来实现的。
被控端:有代理(QQ远程控制)、无代理(SSH服务),有代理比没有代理性能更好。
ansible的特性:
- 幂等性:一个任务执行一遍和执行n遍效果相同,不会因为重复执行带来意外情况(假如你第一次使用ansible创建了一个用户,你第二次在使用ansible创建的时候,它最多是不执行而已,不会产生报错)
- 可使用任何编程语言写模块
- 安全,基于SSH协议
- 支持自定义模块
- 主控端不能是windows
ansible的工作原理:
通过ansible管理远程的主机,可以用户敲命令,可以使用批量执行Playbook,也可以通过公有云/私有云,也可以使用CMDB(配置管理数据库)
ansible命令执行来源:
User:普通用户,敲命令
CMDB:API调用
PUBLIC/PRIVATE CLOUD:API调用
Ansible PlayBook:
ansible实现管理的方式:
AdHoc:即Ansible命令,适用于临时命令使用场景
Ansible PlayBook:主要用于长期规划好的,大型项目的场景
ansible的安装:
ansible相关文件:
第一次加入一个新主机,不可能使用ssh每次都链接,所以可以给配置文件中添加一行:
host_key_checking = False
建议启用日志功能:
log_path
ansible-doc:显示模块帮助,相当于man命令
ansible-doc -l:显示可用模块
ansible的命令使用:
ansible webservers -m command -a 'ls /root' -u lxw -k -b -K
-k:使用key进行验证
-b:sudo到配置文件的用户
-K:sudo用户的密码
sudo用户的方法:visudo,打开选项%wheel,然后修改用户的附加组为wheel,但是如果不想输入sudo密码的话就修改visudo文件,打开%wheel选项下的NOPASSWD选项。(echo export EDITOR=vim >> /etc/profile.d/env.sh然后重新加载一下环境变量)
基于key验证:
ssh-******生成**对,然后使用ssh-copy-id传送到每个主机上
ssh-copy-id 192.168.15.138
*:通配所有
: :或的关系,两个组包含的所有主机(123)(126)(1236)
‘ :& ’ :与的关系,两个组都有的主机(123)(126)(12)
‘ :! ’ :非的关系,在前边组但是不再后边组
支持正则表达式:
“~(web|db). * \ .baidu \ . com”
ansible的执行过程:
1、加载自己的配置文件,默认为/etc/ansible/ansible.cfg
2、加载自己对应的模块文件,如command
3、通过ansible将模块或命令生成对应的临时 .py文件,并将文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-随机数字/XXX.py文件
4、给文件+x执行
5、执行并返回结果
6、删除临时py文件,sleep 0退出
ansible是否执行成功的颜色在ansible配置文件中有定义
ansible的常见模块:
查看帮助文档:ansible-doc
command模块:默认使用,可以省略。
chdir:先切换目录并且执行命令,不管存在不存在都执行命令
creates:如果文件存在,则不执行命令
removes:如果文件不存在,则不执行命令
ansible all -a 'chdir=/etc/fs cat /etc/fstab'
ansible all -a 'chdir=/boot ls'相当于查看boot文件夹
ansible all -a 'creates=/etc/fs cat /etc/fstab'
ansible all -a 'removes=/etc/fs cat /etc/fstab'
shell模块:不是默认模块,要使用-m shell,支持一些特殊符号,比如管道和$。
修改用户密码:
ansible web -m shell -a 'echo 123456|passwd --stdin lxw'
script模块:不需要复制脚本去其他主机,只需要在ansible主机上编好脚本,然后就可以在指定的主机上执行。
file模块:专门管理文件的模块
copy模块:把本机文件复制到远程
mode:权限
owner:所有者
ansible all -m copy -a 'src=/root/ansible/selinux dest=/etc/selinux/config backup=yes'
ansible all -m copy -a 'content="hello\nworld\n" dest=/data/f2'直接给文件写入内容
fetch:从客户端拉取文件至服务器,与copy相反,但是只能拉取单个文件,要是目录的话,必须先进行打包。
ansible all -m fetch -a 'src=/var/logs/messages dest=/data'
archive:打包模块 unarchive:解包模块
file模块:ansible-doc file
ansible all -m file -a 'name/path/dest=/data/test state=touch'---创建新文件
ansible all -m file -a 'name/path/dest=/data/test state=absent'---删除文件/目录
ansible all -m file -a 'name/path/dest=/data/dir1 state=directory'---创建目录
ansible all -m file -a 'src=/etc/fstab dest/path/name=/data/fstab.link state=link'---创建软连接
Cron:计划任务模块
ansible all -m cron -a 'minute=* weekday=1,3,4 job="/usr/bin/wall FBI warning" name=warningcron'---创建计划任务
ansible all -m cron -a 'disabled=true/yes job="/usr/bin/wall FBI warning" name=warningcron'---注销计划任务,必须加name,不加那么就会创建一个新的定时任务默认注释,只不过name为null
disabled=false/no---重新启用定时任务
absible all -m cron -a 'job="/usr/bin/wall FBI warning" name=warningcron state=absent'
yum:yum模块
ansible all -m yum -a 'name=vsftpd,memcached state=present/installd/lastest'----安装
state=absent/removed----卸载
先批量cp过去,然后再使用rpm的方式安装。
也可以使用disable_gpg_check=yes来跳过检查。
update_cache=yes用来更新缓存,但是安装包,EX:'name=httpd update_cache=yes'
service:服务模块
ansible all -m service -a 'name=vsftpd state=started/restarted/reloaded/stopped ensbled=yes/true'
setup:显示被控制主机的信息
ansible all -m setup -a 'filter=ansible_*'—————filter表示过滤
user:管理用户模块
ansible all -m user -a 'name=nginx shell=/sbin/nologin system=yes home=/home/nginx groups=root uid=8080 comment(描述)=nginx service'
group是指定基本组的,groups是指定附加组的
ansible all -m user -a 'name=nginx state=absent remove=yes(是否删除家目录)'
group:管理组模块
ansible all -m user -a 'name=nginx system=yes gid=8080 state=absent/present'
ansible命令:
ansile-galaxy:可以自动连接galaxy.ansible.com网站下载你要的roles,首先找到并复制你想要的roles,然后在虚拟机上使用ansible-galaxy install/remove rolesname下载
ansible-vault:加入playbook文件有敏感信息,可以对playbook文件进行加密操作
ansible-vault encrypt hello.yml————加密后则不能查看playbook文件内容,并且加密后不能运行,要想运行,必须要先解密
ansible-vault decrypt hello.yml----解密playbook文件
ansible-vault view hello.yml----查看加密的文件内容
ansible-vault edit hello.tml----修改加密文件
ansible-vault rekey hello.yml----修改密码
ansible-vault create hello2.yml---创建新的加密文件
ansible-console:交互式控制
可以使用cd,执行命令时,前边是模块名,后边是对应的命令(ansible用法)
ansible-playbook:(相当于脚本)
play的主要功能是在于将实现归并为一组的主机装扮成事先通过ansible中的task定义好的角色,从根本上来讲,task就是调用ansible的一个模块,将多个play组织在一个playbook中,让他们联合起来按照事先编排的机制执行
语法:
--- //习惯而已,不写也行,表示里边要写playbook了
- hosts: webserver //接下来的要对那些主机执行操作
remote_user: root //接下来要执行的操作以谁的身份来执行
tasks:
- name: hello //只是一个说明而已,说明要执行什么
command: hostname //模块名:用法
ansible-playbook hello.yaml
工作流程:
YAML格式:
- 它是一种语言,并不是ansible特有的
- 在单一档案中,可用连续的三个 - 区分多个档案,另外,用三个 . 来表示该档案结尾
- 次行开始写内容,一般建议写上该playbook的功能。
- 使用#注释代码
- 缩进必须统一,不能和tab混用
- 区分大小写,K/V值均需大小写敏感
- k/v可以同行写,也可以换行写,同行使用:分开,v也可以是一个列表
- 一个完整的代码块最少需要一个name和一个task,并且一个name只能包括一个task
YAML语法:
列表:所有的元素均使用"-"打头
Directory:字典
name:lxw
job:student
hobby:play
{name:lxw,job:student,hobby:play}
playbook核心元素:
- hosts:执行的远程主机列表
- tasks:任务集
- Varniables:内置变量或自定义变量在playbook中调用
- templates:模板,可替换模板文件中的变量并实现一些简单逻辑的文件
- handlers和notity结合使用,由特定条件触发的操作,满足才执行。
- tags:标签,指定某条任务执行,用于选择运行playbook中的部分代码,ansible具有幂等性,因此会跳过没有变化的部分,但是有的代码测试其确实没有ansible-playbook -t tagsname useradd.yml
---
- host: all
remote_user: root
tasks:
- name: create new file
file: name=/data/test state=touch
- name: create new user
user: name=ymy system=yes shell=/sbin/nologin
- name: install package
yum: name=httpd
- name: copy html
copy: src=/var/www/html/index.html dest=/var/www/html
- name: start service
service: name=httpd state=started enabled=yes
sudo: yes
sudo_user: lxw---需要授权
ansible-playbook -C file.yml----检查有没有错误
让出错之后继续执行下去方法:
- name: error
shell: /usr/bin/somecommand || /bin/true
或者ignore_errors: True
--limit 192.168.15.101——————只在特定的主机上执行
一个模块对应一个内容,相同的内容都不行。
tasks中的src如果写成相对路径的话,就是相对于当前用户的家目录而言的
Handlers和notify的使用:
tasks:按照次序执行,如果服务已经启动,然么再将修改过的配置文件拷贝过去后,服务不会重启,所以配置文件就不会生效,所以就要用handlers。
---
#httpd的基本配置文件
- hosts: all
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=yes
notify: restart service——————必须和handlers中的name保持一致
- name: start service
service: name=httpd state=started enabled=yes
handlers:
- name: restart service
service: name=httpd state=restarted
________________________________________________
notify:
- restart service
- check nginx process
handlers:
- name: restart service
service: name=httpd state=restarted enabled=yes
- name: check nginx process
shell: killall -0 nginx > /tmp/nginx.log
tags:标签,作用就是将来可以调用标签中的内容
---
#httpd的基本配置文件
- hosts: all
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd
tags: installhttpd
- name: copy conf file
copy: src=files/httpd.conf dest=/etc/httpd/conf backup=yes
notify: restart service——————必须和handlers中的name保持一致
- name: start service
service: name=httpd state=started enabled=yes
tags: restartedhttpd
handlers:
- name: restart service
service: name=httpd state=restarted
ansible-playbook httpd.yml -t installhttpd,restartedhttpd httpd.yml——————挑某个标签来执行
--skip_tags two————跳该标记
多个动作可以使用同一个标签,将标签名字起相同就行了。
Playbook中的变量:
可以针对不同的主机执行不同的操作。
变量名:仅能由字母、数字、下划线组成,且只能由字母开头
变量来源:
-
ansible setup facts远程主机的所有变量都可以调用
-
在/etc/ansible/hosts中定义(就是对组中的某个主机有效,也可以对组中所有主机有效)
- 普通变量:主机组中单独定义,优先级高于公共变量
- 公共(组)变量:针对主机组中所有主机定义同一变量
-
通过命令行指定变量,优先级最高
-
在playbook中定义
- vars:
- vars1: value1
- vars2: value2
- vars:
-
在role中定义
-
在变量文件中定义(后缀为 .yml)
#直接在命令行中定义变量
---
- hosts: all
remote_user: root
tasks:
- name: install package
yum: name={{ pkname }}
- name: start service
service: name={{ pkname }} state=started enable=yes
ansible-playbook -e 'pkname=vsftpd' app.yml----两个变量赋值可以使用逗号分开
#可以在playbook中直接定义变量:
---
- hosts: all
remote_user: root
vars:
- pkname1: httpd
- pkname2: vsftpd
tasks:
- name: install package
yum: name={{ pkname1 }}
- name: start service
service: name={{ pkname2 }} state=started enable=yes
#在/etc/ansible/hosts中定义
[web01]
192.168.15.100 http_port=81
192.168.15.101 http_port=82
[web01:vars]
name1=www.
name2=.com
---
- host: web01
remote_user: root
tasks:
- name: set hostname
hostname: name={{ name1 }}{{ http_port }}{{ name2 }}
#在变量文件中定义
var1: httpd
var2: vsftpd
---
- host: all
remote_user: root
vars_files:
- vars.yml
tasks:
- name: install package
yum: name={{ var1 }}
template模板:只能在playbook命令行使用,不能再ansible(adhoc)中使用,使用Jinja2语法
应用场景:配置服务时,机器硬件的不同可能会导致服务的配置文件的不同,copy模块不能实现这一功能,只能使用template模板。
templates文件必须存在在templates目录下,且文件名后缀为 .j2,templates目录和 . yml后缀的文件平级
---
- host: all
remote_user: root
tasks:
- name: install package
yum: name=nginx
- name: copy template
template: src=nginx.conf.j2 dest=/etc/nginx.conf backup=yes
notify: restart service
- name: start service
service: name=nginx state=started enabled=yes
handlers:
- name: restart service
service: name=nginx state=restarted
tasks:
- name: "shutdown RedHat"
command: /sbin/shutdown -h now
when: ansible_os_family=="RedHat"
变量可以使用set up 模块中的变量
迭代(循环):
---
- host: all
remote_user: root
tasks:
- name: create some files
file: name=/data/{{ item }} state=touch
when: ansible_distribution_major_version == "7"
with_items:
- file1
- file2
- file3
- name: install some packages
yum: name={{ item }}
with_items:
- htop
- sl
- hping3
#固定结构
#用户属于各自的组
- name: install some packages
yum: name={{ item.name }} group={{ item.group }}
with_items:
- { name: 'user1', group: 'g1' }
- { name: 'user2', group: 'g2' }
- { name: 'user3', group: 'g3' }
for循环:
---
- name: all
remote_user: root
vars:
prots:
- 81
- 82
- 83
tasks:
- name:copy conf
template: src=for1.conf.j2 dest=/data/for1.conf
-----------------------
cat for1.conf.j2-->
{% for port in ports %}
server{
listen {{ port }}
}
{% endfor %}
#另一种方式
---
- name: all
remote_user: root
vars:
prots:
- web1:
port: 81
name: www.baidu1.com
rootdir: /data/web1
- web2:
port: 82
name: www.baidu2.com
rootdir: /data/web2
- web3:
port: 83
name: www.baidu3.com
rootdir: /data/web3
tasks:
- name:copy conf
template: src=for1.conf.j2 dest=/data/for1.conf
-----------------------
cat for1.conf.j2-->
{% for pin ports %}
server{
listen {{ p.port }}
servername {{ p.name }}
documentroot {{ p.rootdir }}
}
{% endfor %}
迭代和判断结合使用:
{% for pin ports %}
server{
listen {{ p.port }}
{% if p.name is defined %}
servername {{ p.name }}
{% endif %}
documentroot {{ p.rootdir }}
}
{% endfor %}
roles:
适合大型任务,结构更清晰。将原来在playbook中的东西全部拆开,变量在一个文件中,模板在一个文件中,需要复制的文件放在一个文件中,任务都拆开了,放在一个文件中夹。思想就是模块化,代码重用性高。