ansible学习

ansible

与salt对比javascript

  • 相同
    • 都是为了同时在多台机器上执行相同的命令
    • 都是python开发
  • 不一样
    • agent(saltstack须要安装、ansible不须要)
    • 配置(salt配置麻烦,ansible基本不用配置)
    • 学习路线(salt比较陡峭,ansible比较平缓)
    • 第三方工具(salt比较少)
    • 开源社区的对接(salt比较少)
    • 现有用户(salt仍是ansible少一些)
    • 二次开发扩展的能力(ansible比较差,尤为是2.0之后)
    • 大规模并发(200之内同样,200以上salt会好一些,固然咱们也能够对ansible作一些配置使其在200以上追上salt)
    • Windows的支持(salt会好不少)

安装

yum install -y ansible

查看ansible生成的命令,用到的命令css

ansible            
ansible-doc        
ansible-galaxy(下载第三方插件)        
 ansible-playbook

查看ansible 安装生成的html

rpm -ql ansible |more /etc/ansible /etc/ansible/ansible.cfg #配置文件 /etc/ansible/hosts #主要文件

hosts文件详解java

cat /etc/ansible/hosts
# This is the default ansible 'hosts' file. # # It should live in /etc/ansible/hosts # # - Comments begin with the '#' character #注释为# # - Blank lines are ignored #空白行被忽略 # - Groups of hosts are delimited by [header] elements #主机组名被写在[]里面 # - You can enter hostnames or ip addresses #你能够写ip地址也能够写hostnames # - A hostname/ip can be a member of multiple groups #一个主机能够被多个主机组包含

能够在hosts文件中填写的内容node

ansible_ssh_host
  ansible经过ssh链接的IP或者FQDN
ansible_ssh_port
  SSH链接端口
ansible_ssh_user
  默认SSH链接用户
ansible_ssh_pass
  SSH链接的密码(这是不安全的,ansible极力推荐使用--ask-pass选项或使用SSH keys)
ansible_sudo_pass
  sudo用户的密码
ansible_connection
  SSH链接的类型:local,ssh,paramiko,在ansible 1.2以前默认是paramiko,后来智能选择,优先使用基于ControlPersist的ssh(支持的前提)
ansible_ssh_private_key_file
  SSH链接的公钥文件

查看ansible的命令帮助

ansible <host-pattern> [options]

-a MODULE_ARGS 模块参数
-m MODULE_NAME 模块名称python

-f forks 指定一次执行的机器linux

-C 测试nginx

--list-hosts 查看运行的机器web

-v 输出详细信息sql

第一个ansible程序

ansible test -m ping

获取文档

ansible-doc --help
-s 指定模块名称 -l 列出全部的模块 

操做日志

/var/log/message

命令相关

shell command script command模块 [执行远程命令] ansible all -a 'echo "hello world"' ansible all -a 'pwd' ansible all -a 'echo "oldboy"|passwd --stdin user1' #直接输出结果 script模块 [在远程主机执行主控端的shell/python脚本 ] (使用相对路径) ansible all -m script -a 'a.sh' #执行本地脚本 ansible all -a 'ls /' #查看文件目录 shell模块 [执行远程主机的shell/python脚本,支持管道] ansible all -m shell -a 'echo oldboy|passwd --stdin user1' #设置密码 ansible all -m shell -a 'cat /etc/shadow|grep user1' #查看用户 ansible all -m shell -a 'python a.py' #执行远程脚本

文件相关

copy
  dest 目标地址
  src 本地地址  
  mode 权限 wrx/755
  owner  属主
  group  属组
  backup content 直接写内容,能够用转移符号 ansible all -m copy -a 'dest=/data src=/data/a.txt' #复制单个文件 ansible all -m copy -a 'src=/etc/init.d dest=/data/' ansible all -m copy -a 'src=/etc/init.d/ dest=/data' #若是带/则复制里面的内容,不带/则复制目录,若是是目录的话,则会递归复制 ansible all -m copy -a 'content="hello world" dest=/data/test.txt' 直接输入内容 file path src state file file表明拷贝后是文件 link link表明最终是个软连接 directory directory表明文件夹 hard hard表明硬连接 touch touch表明生成一个空文件 absent absent表明删除 ansible all -m file -a 'dest=/data/html state=directory' #建立目录 ansible all -m file -a 'dest=/data/html2 state=link src=/etc' #建立软连接 ansible all -m file -a 'dest=/data/a.txt state=touch' ansible all -m file -a 'dest=/data/a.txt state=absent' 删除 fetch #远程主机复制到本地,不能指定多个 dest src ansible 10.211.55.14 -m fetch -a 'src=/data/test.txt dest=/data'

软件相关

pip
ansible all -m pip -a 'name=django==1.11' yum name state absent #卸载 installed #安装 latest #安装最新的版本 present #安装 removed #卸载 ansible all -m yum -a 'name=python-pip state=latest' ansible all -m yum -a 'name=nginx state=latest' ansible all -m yum -a 'name=nginx state=absent'

service

name
state
 ansible all -m service -a 'name=nginx state=started'
 ansible all -m service -a 'name=nginx state=stopped'

cron

name
weekday 周
hour 时
day 天
minute 分钟
month 月
job
state
  absent  #删除
  present  #建立
ansible all -m cron -a 'name=testjob  minute=1 job=ntpdate'
ansible all -m cron -a 'name=testjob  state=absent'

user

name
password
shell
state
uid
group
groups
update_password 
home
ansible all -m user -a 'name=usertest' ansible all -m user -a 'name=usertest state=absent'

group

gid
name
state  #present 建立  absent 删除
system #是不是系统组
ansible all -m group -a 'name=usertest '
ansible all -m group -a 'name=usertest state=absent'

playbook 剧本(注意空格)先收集主机

Playbooks 与 ad-hoc 相比,是一种彻底不一样的运用 ansible 的方式,是很是之强大的.

简单来讲,playbooks 是一种简单的配置管理系统与多机器部署系统的基础.与现有的其余系统有不一样之处,且很是适合于复杂应用的部署.

Playbooks 可用于声明配置,更强大的地方在于,在 playbooks 中能够编排有序的执行过程,甚至于作到在多组机器间,来回有序的执行特别指定的步骤.而且能够同步或异步的发起任务.

---
- hosts: webservers
  remote_user: root

  tasks:
  - name: ensure apache is at the latest version
    yum:
      name: httpd
      state: latest - name: write the apache config file template: src: /srv/httpd.j2 dest: /etc/httpd.conf - hosts: databases remote_user: root tasks: - name: ensure postgresql is at the latest version yum: name: postgresql state: latest - name: ensure that postgresql is started service: name: postgresql state: started

主机与用户

你能够为 playbook 中的每个 play,个别地选择操做的目标机器是哪些,以哪一个用户身份去完成要执行的步骤(called tasks)

--- - hosts: webservers remote_user: root

task list

每个 play 包含了一个 task 列表(任务列表).一个 task 在其所对应的全部主机上(经过 host pattern 匹配的全部主机)执行完毕以后,下一个 task 才会执行.有一点须要明白的是(很重要),在一个 play 之中,全部 hosts 会获取相同的任务指令,这是 play 的一个目的所在,也就是将一组选出的 hosts 映射到 task.
在运行 playbook 时(从上到下执行),若是一个 host 执行 task 失败,这个 host 将会从整个 playbook 的 rotation 中移除. 若是发生执行失败的状况,请修正 playbook 中的错误,而后从新执行便可.
每一个 task 的目标在于执行一个 moudle, 一般是带有特定的参数来执行.在参数中可使用变量(variables).
modules 具备”幂等”性,意思是若是你再一次地执行 moudle(译者注:好比遇到远端系统被意外改动,须要恢复原状),moudle 只会执行必要的改动,只会改变须要改变的地方.因此重复屡次执行 playbook 也很安全.
每个 task 必须有一个名称 name,这样在运行 playbook 时,从其输出的任务执行信息中能够很好的辨别出是属于哪个 task 的. 若是没有定义 name,‘action’ 的值将会用做输出信息中标记特定的 task.

tasks:
  - name: make sure apache is running service: name=httpd state=running

比较特别的两个 modudle 是 command 和 shell ,它们不使用 key=value 格式的参数,而是这样:

tasks:
  - name: disable selinux command: /sbin/setenforce 0

使用 command module 和 shell module 时,咱们须要关心返回码信息,若是有一条命令,它的成功执行的返回码不是0, 你或许但愿这样作:

tasks:
  - name: run this command and ignore the result shell: /usr/bin/somecommand || /bin/true
tasks:
  - name: run this command and ignore the result shell: /usr/bin/somecommand ignore_errors: True

若是 action 行看起来太长,你可使用 space(空格) 或者 indent(缩进) 隔开连续的一行:

tasks: - name: Copy ansible inventory file to client copy: src=/etc/ansible/hosts dest=/etc/ansible/hosts owner=root group=root mode=0644 

在 action 行中可使用变量.假设在 ‘vars’ 那里定义了一个变量 ‘vhost’ ,能够这样使用它:

tasks:
  - name: create a virtual host file for {{ vhost }} template: src=somefile.j2 dest=/etc/httpd/conf.d/{{ vhost }}

检查语法错误

--syntax-check

tags

tags:install

在anible-playbook -t 指定tag

Handlers: 在发生改变时执行的操做

上面咱们曾提到过,module 具备”幂等”性,因此当远端系统被人改动时,能够重放 playbooks 达到恢复的目的. playbooks 自己能够识别这种改动,而且有一个基本的 event system(事件系统),能够响应这种改动.

(当发生改动时)’notify’ actions 会在 playbook 的每个 task 结束时被触发,并且即便有多个不一样的 task 通知改动的发生, ‘notify’ actions 只会被触发一次.

举例来讲,好比多个 resources 指出由于一个配置文件被改动,因此 apache 须要从新启动,可是从新启动的操做只会被执行一次.

- name: template configuration file template: src=template.j2 dest=/etc/foo.conf notify: - restart memcached - restart apache

‘notify’ 下列出的便是 handlers.
Handlers 也是一些 task 的列表,经过名字来引用,它们和通常的 task 并无什么区别.Handlers 是由通知者进行 notify, 若是没有被 notify,handlers 不会执行.无论有多少个通知者进行了 notify,等到 play 中的全部 task 执行完成以后,handlers 也只会被执行一次.

handlers:
    - name: restart memcached
      service:  name=memcached state=restarted - name: restart apache service: name=apache state=restarted

ansible2.2之后能够写listen,咱们来监听一个时间,

handlers:
    - name: restart memcached
      service:
        name: memcached
        state: restarted listen: "restart web services" - name: restart apache service: name: apache state:restarted listen: "restart web services" tasks: - name: restart everything command: echo "this task will restart the web services" notify: "restart web services"

执行一个playbook

ansible-playbook playbook.yml -f 10

Include

Include 指令看起来像下面这样,在一个 playbook 中,Include 指令能够跟普通的 task 混合在一块儿使用:

tasks: - include: tasks/foo.yml

变量

变量命名规则

变量名能够为字母,数字以及下划线.变量始终应该以字母开头

还有其它地方能够获取变量,这些变量是自动发现的,而不是用户本身设置的.

Facts经过访问远程系统获取相应的信息. 一个例子就是远程主机的IP地址或者操做系统是什么. 使用如下命令能够查看哪些信息是可用的:

ansible hostname -m setup 
{{ ansible_nodename }}

注册变量

变量的另外一个主要用途是在运行命令时,把命令结果存储到一个变量中.不一样模块的执行结果是不一样的.运行playbook时使用-v选项能够看到可能的结果值.

    • hosts: web_servers tasks:
    • shell: /usr/bin/foo
      register: foo_result
      ignore_errors: True
    • shell: /usr/bin/bar
      when: foo_result.rc == 5
       

命令行中传递变量

除了vars_promptvars_files也能够经过Ansible命令行发送变量.若是你想编写一个通用的发布playbook时则特别有用,你能够传递应用的版本以便部署:

ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo" 

其它场景中也颇有用,好比为playbook设置主机群组或用户.

---

- hosts: '{{ hosts }}' remote_user: '{{ user }}' tasks: - ... ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"

变量的来源

  • 经过setup获取

  • 用户自定义

    • 经过命令行传递 -e

    • playbook传递

    • vars:
    • name:name-value
      name2:name2-value
       

    hosts配置文件中定义

    ​ 直接在主机后面定义

    [hostgourpname:vars] name:name-value

访问复杂变量数据

有些提供的facts,好比网络信息等,是一个嵌套的数据结构.访问它们使用简单的 {{ foo }} 语法并不够用,当仍然很容易.以下所示:

{{ ansible_eth0["ipv4"]["address"] }} {{ ansible_eth0.ipv4.address }}

条件判断

when: 条件==“条件”

循环

一般你想在一个任务中干不少事,好比建立一群用户,安装不少包,或者重复一个轮询步骤直到收到某个特定结果.

标准循环

为了保持简洁,重复的任务能够用如下简写的方式:

- name: add several users user: name={{ item }} state=present groups=wheel with_items: - testuser1 - testuser2

嵌套循环

- hosts: all
  remote_user: root
  tasks:
  - name: add user user: name={{ item[0] }} groups={{ item[1] }} with_nested: - ["old1","old2"] - ["nginx,docker"]

Ansible Galaxy

Ansible Galaxy 是一个自由网站,网站提供全部类型的由社区开发的 roles,这对于实现你的自动化项目是一个很好的参考。网站提供这些 roles 的排名、查找以及下载。

应用实例

你如今已经学过 tasks 和 handlers,那怎样组织 playbook 才是最好的方式呢?简单的回答就是:使用 roles ! Roles 基于一个已知的文件结构,去自动的加载某些 vars_files,tasks 以及 handlers。基于 roles 对内容进行分组,使得咱们能够容易地与其余用户分享 roles 。
若是 roles/x/tasks/main.yml 存在, 其中列出的 tasks 将被添加到 play 中
若是 roles/x/handlers/main.yml 存在, 其中列出的 handlers 将被添加到 play 中
若是 roles/x/vars/main.yml 存在, 其中列出的 variables 将被添加到 play 中
若是 roles/x/meta/main.yml 存在, 其中列出的 “角色依赖” 将被添加到 roles 列表中 (1.3 and later)
全部 copy tasks 能够引用 roles/x/files/ 中的文件,不须要指明文件的路径。
全部 script tasks 能够引用 roles/x/files/ 中的脚本,不须要指明文件的路径。
全部 template tasks 能够引用 roles/x/templates/ 中的文件,不须要指明文件的路径。
全部 include tasks 能够引用 roles/x/tasks/ 中的文件,不须要指明文件的路径。

production # inventory file for production servers 关于生产环境服务器的清单文件 stage # inventory file for stage environment 关于 stage 环境的清单文件 group_vars/ group1 # here we assign variables to particular groups 这里咱们给特定的组赋值 group2 # "" host_vars/ hostname1 # if systems need specific variables, put them here 若是系统须要特定的变量,把它们放置在这里. hostname2 # "" library/ # if any custom modules, put them here (optional) 若是有自定义的模块,放在这里(可选) filter_plugins/ # if any custom filter plugins, put them here (optional) 若是有自定义的过滤插件,放在这里(可选) site.yml # master playbook 主 playbook webservers.yml # playbook for webserver tier Web 服务器的 playbook dbservers.yml # playbook for dbserver tier 数据库服务器的 playbook roles/ common/ # this hierarchy represents a "role" 这里的结构表明了一个 "role" tasks/ # main.yml # <-- tasks file can include smaller files if warranted handlers/ # main.yml # <-- handlers file templates/ # <-- files for use with the template resource ntp.conf.j2 # <------- templates end in .j2 files/ # bar.txt # <-- files for use with the copy resource foo.sh # <-- script files for use with the script resource vars/ # main.yml # <-- variables associated with this role defaults/ # main.yml # <-- default lower priority variables for this role meta/ # main.yml # <-- role dependencies webtier/ # same kind of structure as "common" was above, done for the webtier role monitoring/ # "" fooapp/ # ""

site.yml

在 site.yml 中,咱们包含了一个定义了整个基础设施的 playbook.注意这个 playbook 是很是短的, 由于它仅仅包含了其余 playbooks.记住, playbook 不过就是一系列的 plays:

---
# file: site.yml
- include: webservers.yml
- include: dbservers.yml

在诸如 like webservers.yml 的文件中(一样也在顶层结构),咱们仅仅将 Web 服务器组与对应的 role 行为作映射.一样值得注意的是这也很是的短小精悍.例如:

---
# file: webservers.yml
- hosts: webservers
  roles:
    - common
    - webtier

理念是咱们可以经过 “运行”(running) site.yml 来选择整个基础设施的配置.或者咱们可以经过运行其子集 webservers.yml 来配置. 这与 Ansible 的 “–limit” 相似,并且相对的更为显式:

ansible-playbook site.yml --limit webservers
ansible-playbook webservers.yml

接下来的示例任务文件展现了一个 role 是如何工做的.咱们这里的普通 role 仅仅用来配置 NTP,可是若是咱们想的话,它能够作更多:

---
# file: roles/common/tasks/main.yml

- name: be sure ntp is installed
  yum: pkg=ntp state=installed
  tags: ntp

- name: be sure ntp is configured
  template: src=ntp.conf.j2 dest=/etc/ntp.conf
  notify:
    - restart ntpd
  tags: ntp

- name: be sure ntpd is running and enabled
  service: name=ntpd state=running enabled=yes
  tags: ntp

这是个处理文件样例.做为一种审核,它只有当特定的任务报告发生变化时会被触发,并在每一个 play 结束时运行:

---
# file: roles/common/handlers/main.yml
- name: restart ntpd
  service: name=ntpd state=restarted
相关文章
相关标签/搜索