设为首页 收藏本站
查看: 1153|回复: 0

[经验分享] CLOUD 1: ansible

[复制链接]
YunVN网友  发表于 2018-7-29 06:40:40 |阅读模式
  1.系统一致性
  2.软件版本一致性
  3.安装路径一致性
  选择ansible
  1.活跃度
  2.学习成本
  3.使用成本
  4.编码语言
  5.性能
  6.使用是否广泛
  安装ansible
  · ansible 可以基于源码运行
  · 源码安装
  – pip,需要配置扩展软件包源 extras
  – git
  yum install epel-release
  yum install git python2-pip
  – pip安装依赖模块
  pip install paramiko PyYAML Jinja2 httplib2 six
  · ansible 源码下载
  – git clone git://github.com/ansible/ansible.git
  – yum install python-setuptools python-devel
  – python setup.py build
  – python setup.py install
  · pip 方式安装
  – pip install ansible
  · yum 扩展源安装简单,自劢解决依赖关系(推荐)
  – http://mirror.centos.org/.../.../extras/
  – yum install ansible
  · 安装完成以后验证
  – ansible -version
  一.ad-hoc
  1.主机管理
  · 安装好了 Ansible 之后就可以开始一些简单的任务了
  · Ansible配置文件查找顺序
  – 首先检测 ANSIBLE_CONFIG 变量定义的配置文件
  – 其次检查当前目彔下的 ./ansible.cfg 文件
  – 再次检查当前用户家目彔下 ~/ansible.cfg 文件
  – 最后检查 /etc/ansible/ansible.cfg 文件
  · /etc/ansible/ansible.cfg 默认配置文件路径
  · ansible.cfg 配置文件
  – inventory 是定义托管主机地址配置文件
  – 首先编辑 /etc/ansible/hosts 文件,写入一些进程主
  机的地址。
  · 格式
  – # 表示注释
  [组名称]
  主机名称或ip地址,登彔用户名,密码、端口等信息
  · 测试
  – ansible [组名称] --list-hosts
  · inventory 参数说明
  – ansible_ssh_host
  – 将要连接的进程主机名.不你想要设定的主机的别名不
  同的话,可通过此变量设置.
  – ansible_ssh_port
  – ssh端口号.如果不是默认的端口号,通过此变量设置.
  – ansible_ssh_user
  – 默认的 ssh 用户名
  – ansible_ssh_pass
  – ssh 密码(这种方式并不安全,我们强烈建议使用 --ask-
  pass 或 SSH 密钥)
  – ansible_sudo_pass
  – sudo 密码(建议使用 --ask-sudo-pass)
  – ansible_sudo_exe (new in version 1.8)
  – sudo 命令路径(适用于1.8及以上版本)
  – ansible_connection
  – 不主机的连接类型.比如:local, ssh 或者 paramiko.
  Ansible 1.2 以前默认使用 paramiko.1.2 以后默认使
  用 'smart','smart' 方式会根据是否支持
  ControlPersist, 来判断'ssh' 方式是否可行.
  – ansible_ssh_private_key_file
  – ssh 使用的私钥文件.适用有有多个密钥,而你不想使用
  SSH 代理的情况.
  – ansible_shell_type
  – 目标系统的shell类型.默认情况下,命令的执行使用 'sh'
  语法,可设置为 'csh' 或 'fish'.
  – ansible_python_interpreter
  – 目标主机的 python 路径.适用于的情况: 系统中有多个
  Python, 或者命令路径不是"/usr/bin/python”
  vim /etc/ansible/hosts
  [web]
  web11
  192.168.4.12  ansible_ssh_user="root" ansible_ssh_pass="123456" #或者192.168.4.[11:12]
  [db]
  db[1:2]  #连续可以用此方法
  [cache]
  192.168.4.15
  [wd:children]  #集合2个组
  web
  db
  [db:vars]
  ansible_ssh_user="root"
  ansible_ssh_pass="123456"
  ansible_ssh_port="22"
  :wq
  ansible web --list-host #查看定义的组
  ansible wd -m ping #测试连通
  vim /etc/ansibleansible.cfg
  61 host_key_checking = False #开启ssh不验证yes
  自定义配置文件
  mkdir /root/myansible  #随便一个文件夹
  cd /root/myansible
  vim ansible.cfg
  [defaults]
  inventory = myhost #定义分组文件
  :wq
  vim myhost  #编辑分组文件
  [aa]
  web1
  web2
  [bb]
  db1
  db2
  :wq
  ansible aa --list-hosts #在当前文件夹下执行查看分组
  动态主机
  无限可能
  – Ansible Inventory实际上是包含静态Inventory和动
  态Inventory两部分,静态Inventory指的是在文件
  /etc/ansible/hosts中指定的主机和组,Dynamic
  Inventory指通过外部脚本获取主机列表,并按照
  ansible 所要求的格式返回给ansilbe命令的。
  · json
  – JSON的全称是”JavaScript Object Notation”,意
  思是JavaScript对象表示法,它是一种基于文本,独立
  于语言的轻量级数据交换格式。
  · 注意事项:
  – 1、主机部分必须是列表格式的;
  – 2、hostdata行,其中的"hosts" 部分可以省略,但如
  果使用时,必须是"hosts"
  · 脚本输出主机列表
  #!/usr/bin/python
  import json
  hostlist = {}
  hostlist["bb"] = ["192.168.1.15", "192.168.1.16"]
  hostlist["192.168.1.13"] = {
  "ansible_ssh_user":"root","ansible_ssh_pass":"pwd"
  }
  hostlist["aa"] = {
  "hosts" : ["192.168.1.11", "192.168.1.12"],
  "vars" : {
  "ansible_ssh_user":"root","ansible_ssh_pass":"pwd"
  }
  }
  print( json.dumps(hostlist))
  · 脚本输出样例
  {
  "aa" : {
  "hosts" : ["192.168.1.11", "192.168.1.12"],
  "vars" : {
  "ansible_ssh_user" : "root",
  "ansible_ssh_pass" : "pwd"
  }
  },
  "bb" : ["192.168.1.15", "192.168.1.16"],
  "192.168.1.13": { "ansible_ssh_user" : "root",
  "ansible_ssh_pass" : "pwd"}
  }
  vim ansible.cfg
  [defaults]
  inventory = myhost.py  #指定脚本返回JSON格式
  ansible命令基础
  · ansible <host-pattern> [options]
  – host-pattern 主机或定义的分组
  – -M 指定模块路径
  – -m 使用模块,默认 command 模块
  – -a or --args 模块参数
  – -i inventory 文件路径,或可执行脚本
  – -k 使用交互式登彔密码
  – -e 定义变量
  – -v 详细信息,-vvvv 开启 debug 模式
  · 列出要执行的主机,不执行任何操作
  – ansible all --list-hosts
  · 批量检测主机
  – ansible all -m ping
  · 批量执行命令
  – ansible all -m command -a 'id' -k
  2.批量执行
  ansible命令基础
  ansible <host-patter> [options]
  -host-pattern
  ansible all -m command -a &quot;id&quot; -k #所有机器使用用command模块,执行id命令,-K 交互输入密码
  ansible all -m copy -a &quot;src=./2.txt dest=/tmp/&quot; -k #批量复制
  批量部署证书文件
  批量部署证书文件
  · 每次交互输入密码比较麻烦
  · 密码写入配置文件安全性很差
  · 不同主机不同密码,配置文件要上天
  · 使用 key 方式认证,是一个不错的选择
  · 给所有主机部署公钥
  – ansible all -m authorized_key -a &quot;user=root
  exclusive=true manage_dir=true key='$(<
  /root/.ssh/authorized_keys)'&quot; -k -v
  · 报错
  – &quot;msg&quot;: &quot;Using a SSH password instead of a key is
  not possible because Host Key checking is
  enabled and sshpass does not support this.
  Please add this host's fingerprint to your
  known_hosts file to manage this host.&quot;
  – 解决方法:
  – 修改 ansible.cfg
  host_key_checking = False
  ansible all -m authorized_key -a &quot;user=root exclusive=true manage_dir=true key='$(< /root/.ssh/authorized_keys)'&quot; -k -v  #或/root/.ssh/id_rsa.pub
  exclusive=true  #覆盖之前的key文件
  模块
  · ansible-doc
  – 模块的手册,相当不 shell 的 man
  – 非常重要,非常重要,非常重要
  – ansible-doc -l 列出所有模块
  – ansible-doc modulename 查看帮助
  · ping 模块
  – 测试网络连通性, ping模块没有参数
  – 注:测试 ssh 的连通性
  – ansible host-pattern -m ping
  · command模块
  – 默认模块,进程执行命令
  – 用法
  – ansible host-pattern -m command -a '[args]'
  – 查看所有机器负载
  ansible all -m command -a 'uptime'
  – 查看日期和时间
  ansible all -m command -a 'date +%F_%T'
  · command模块注意事项:
  – 该模块通过-a跟上要执行的命令可以直接执行,不过
  命令里如果有带有如下字符部分则执行不成功
  – &quot;<&quot;, &quot;>&quot;, &quot;|&quot;, &quot;&&quot;
  – 该模块不启动 shell 直接在 ssh 进程中执行,所有使用
  到 shell 特性的命令执行都会失败
  – 下列命令执行会失败
  ansible all -m command -a 'ps aux|grep ssh'
  ansible all -m command -a 'set'
  · shell | raw 模块
  – shell 模块用法基本和command一样,区别是 shell模
  块是通过/bin/sh进行执行命令,可以执行任意命令
  – raw模块,用法和shell 模块一样 ,可以执行任意命令
  – 区别是 raw 没有chdir、creates、removes参数
  – 执行以下命令查看结果
  ansible t1 -m command -a 'chdir=/tmp touch f1'
  ansible t1 -m shell -a 'chdir=/tmp touch f2'
  ansible t1 -m raw -a 'chdir=/tmp touch f3'
  · script模块
  – 复杂命令怎么办?
  – ansible 要上天
  – 直接在本地写脚本,然后使用 script 模块批量执行
  – ansible t1 -m script -a 'urscript'
  – 友情提示: 该脚本包含但不限于 shell 脚本,只要指
  定 Sha-bang 解释器的脚本都可运行
  #!/bin/bash
  if ! $(id li4 &> /dev/null);then
  useradd zhang3
  echo 123456 |passwd --stdin zhang3
  chage -d 0 zhang3
  fi
  · copy 模块
  – 复制文件到进程主机
  – src:要复制到进程主机的文件在本地的地址,可以是
  绝对路径,也可以是相对路径。如果路径是一个目彔,
  它将递归复制。在这种情况下,如果路径使用&quot;/&quot;来结
  尾,则只复制目彔里的内容,如果没有使用&quot;/&quot;来结尾,
  则包含目彔在内的整个内容全部复制,类似于rsync
  – dest:必选项。进程主机的绝对路径,如果源文件是
  一个目录,那么该路径也必须是个目录
  · copy 模块
  – backup:在覆盖之前将原文件备份,备份文件包含时
  间信息。有两个选项:yes|no
  – force:如果目标主机包含该文件,但内容不同,如果
  设置为yes,则强制覆盖,如果为no,则只有当目标主
  机的目标位置不存在该文件时,才复制。默认为yes
  – 复制文件
  ansible t1 -m copy -a 'src=/root/alog dest=/root/a.log'
  – 复制目彔
  ansible t1 -m copy -a 'src=urdir dest=/root/'
  · lineinfile | replace 模块
  – 类似 sed 的一种行编辑替换模块
  – path 目的文件,修改哪个文件
  – regexp 正则表达式,修改哪个地方
  – line 替换后的结果,修改成啥样
  ansible t1 -m lineinfile -a 'path=&quot;/etc/selinux/config&quot;
  regexp=&quot;^SELINUX=&quot; line=&quot;SELINUX=disabled&quot;'
  ansible all -m lineinfile -a 'path=&quot;/etc/sysconfig/network-scripts/ifcfg-eth0&quot; regexp=&quot;^BOOTPROTO=&quot; line=&quot;BOOTPROTO=none&quot;'
  – 替换指定字符
  ansible t1 -m replace -a 'path=&quot;/etc/selinux/config&quot;
  regexp=&quot;^(SELINUX=).*&quot; replace=&quot;\1disabled&quot;'
  ansible all -m replace -a 'path=&quot;/etc/sysconfig/network-scripts/ifcfg-eth0&quot; regexp=&quot;^(BOOTPROTO=).*&quot; replace=&quot;\1static&quot;'
  · yum模块
  – 使用yum包管理器来管理软件包
  – config_file:yum的配置文件
  – disable_gpg_check:关闭gpg_check
  – disablerepo:不启用某个源
  – enablerepo:启用某个源
  – name:要进行操作的软件包的名字,也可以传递一个
  url或者一个本地的rpm包的路径
  – state:状态(present,absent,latest)
  安装 ,删除,更新
  · yum模块
  – 删除软件包
  ansible t1 -m yum -a 'name=&quot;lrzsz&quot; state=absent'
  – 删除多个软件包
  ansible t1 -m yum -a 'name=&quot;lrzsz,lftp&quot; state=absent'
  – 安装软件包
  ansible t1 -m yum -a 'name=&quot;lrzsz&quot;'
  – 安装多个软件包
  ansible t1 -m yum -a 'name=&quot;lrzsz,lftp&quot;'
  · service模块
  – name:必选项,服务名称
  – enabled:是否开机启动 yes|no
  – sleep:如果执行了restarted,在则stop和start之间
  沉睡几秒钟
  – state:对当前服务执行启动,停止、重启、重新加载
  等操作(started,stopped,restarted,reloaded)
  ansible t1 -m service -a 'name=&quot;sshd&quot; enabled=&quot;yes&quot;
  state=&quot;started&quot;'
  在web1 web2上安装apache并且设置开机启动,启动服务,端口给为8080,主页是hello world
  

ansible web -m yum -a 'name="httpd"'  
ansible web -m service -a 'name="httpd" enabled="yes" state="started"'
  
ansible web -m lineinfile -a 'path="/etc/httpd/conf/httpd.conf" regexp="^Listen" line="Listen 8080"'
  
ansible web -m shell -a 'echo hello world > /var/www/html/index.html'
  
ansible web -m service -a 'name="httpd" enabled="yes" state="restarted"'
  
ansible web -m shell -a 'curl http://127.0.0.1:8080'
  
ansible web -m replace -a 'path="/etc/httpd/conf/httpd.conf" regexp="(^Listen).*" replace="\1 8080"'
  

  · setup模块
  – 主要用于获取主机信息,在playbooks里经常会用到的
  一个参数gather_facts就不该模块相关。setup模块下
  经常使用的一个参数是filter参数
  – filter 可以过滤到我们需要的信息
  ansible t1 -m setup -a 'filter=ansible_distribution'
  ansible七种武器
  · 第一种武器
  – ansible 命令,用于执行临时性的工作,也是我们之前
  主要学习的功能,必须掌握
  · 第二种武器
  – ansible-doc 是 Ansible模块文档说明,针对每个模块
  都有详细的用法说明及应用案例介绍,功能和Linux系
  统man命令类似,必须掌握
  第三种武器
  – ansible-console 是 Ansible 为用户提供的一款交互
  式工具,用户可以在 ansible-console 虚拟出来的终
  端上像 Shell 一样使用 Ansible 内置的各种命令,
  这为习惯于使用 Shell 交互方式的用户提供了良好的
  使用体验。
  · 第四种武器
  – ansible-galaxy 从 github 上下载管理 Roles 的一款
  工具,不 python 的 pip 类似。
  第五种武器
  – ansible-playbook 是日常应用中使用频率最高的命令,
  其工作机制是:通过读取预先编写好的 playbook 文
  件实现批量管理。要实现的功能不命令 ansible 一样,
  可以理解为按一定条件组成的 ansible 任务集,必须
  掌握
  · 第六种武器
  – ansible-vault 主要用于配置文件加密,如编写的
  Playbook 配置文件中包含敏感信息,不希望其他人随
  意查看, ansible-vault 可加密/解密这个配置文件
  第七种武器
  – ansible-pull
  – Ansible 有两种工作模式 pull/push ,默认使用 push
  模式工作,pull 模式和通常使用的 push 模式工作机
  理刚好相反
  – 适用场景:有数量巨大的机器需要配置,即使使用高
  并发线程依旧要花费很多时间;
  – 通常在配置大批量机器的场景下会使用,灵活性稍有
  欠缺,但效率几乎可以无限提升,对运维人员的技术
  水平和前瞻性规划有较高要求。
  json简介
  · json 是什么?
  – json 是 JavaScript 对象表示法,它是一种基于文本,
  独立于语言的轻量级数据交换格式。
  – JSON中的分隔符限于单引号 ' 、小括号 ()、中括号
  [ ]、大括号 { } 、冒号 : 和逗号 ,
  · json 特性
  – JSON 是纯文本
  – JSON 具有&quot;自我描述性&quot;(人类可读)
  – JSON 具有层级结构(值中存在值)
  – JSON 可通过 JavaScript 进行解析
  json 语法规则
  – 数据在名称/值对中
  – 数据由逗号分隔
  – 大括号保存对象
  – 中括号保存数组
  · json 数据的书写格式是:名称/值对。
  – 名称/值对包括字段名称(在双引号中),后面写一个
  冒号,然后是值,
  yaml简介
  · yaml 是什么
  – 是一个可读性高,用来表达数据序列的格式。
  – YAML:YAML Ain't Markup Language
  – YAML参考了其他多种语言,包括:C语言、Python、
  Perl,并从XML、电子邮件的数据格式(RFC 2822)
  中获得灵感。Clark Evans在2001年首次发表了这种语
  言[1],另外Ingy döt Net不Oren Ben-Kiki也是这语
  言的共同设计者[2]。目前已经有数种编程语言或脚本
  语言支持(或者说解析)这种语言。
  yaml 基础语法
  – YAML的结构通过空格来展示
  – 数组使用&quot;- &quot;来表示
  – 键值对使用&quot;: &quot;来表示
  – YAML使用一个固定的缩进风格表示数据层级结构关系
  – 一般每个缩进级别由两个以上空格组成
  – # 表示注释
  · 注意:
  – 不要使用tab,缩进是初学者容易出错的地方之一
  – 同一层级缩进必须对齐
  YAML的键值表示方法
  – 采用冒号分隔
  – : 后面必须有一个空格
  – YAML键值对例子
  &quot;人名&quot;: &quot;称号&quot;
  – 或
  &quot;人名&quot;:
  &quot;称号&quot;
  – 复杂YAML的键值对嵌套
  &quot;讲师&quot;:
  &quot;人名&quot;: &quot;aa&quot;
  – 或
  &quot;讲师&quot;:
  &quot;aa&quot;:
  &quot;bb&quot;
  – 数组
  [&quot;aa&quot;, &quot;丁丁&quot;, &quot;bb&quot;, &quot;cc&quot;]
  YAML 数组表示方法
  – 使用一个短横杠加一个空格
  – YAML 数组例子


  • &quot;aa&quot;
  • &quot;vv&quot;
  • &quot;cc&quot;
  • &quot;dd&quot;  – 哈希数组复吅表达式
      &quot;讲师&quot;:

  • &quot;dd&quot;
  • &quot;vv&quot;
  • &quot;dd&quot;
  • &quot;zz&quot;
– 高级复吅表达式
  &quot;讲师&quot;:

&quot;aa&quot;: &quot;小逗比&quot;
  &quot;阶段&quot;: 1

&quot;bb&quot;: &quot;老逗比&quot;
  &quot;阶段&quot;: 2

&quot;cc&quot;: &quot;漂亮姐&quot;
  &quot;阶段&quot;: 3

  &quot;dd&quot;: &quot;老司机&quot;
  &quot;阶段&quot;: 4
  yaml高级语法
  – | 不 > 表示对应的值为多行字符, > 不 | 的区别是会
  把 \n 转换为空格
  – ! 可以设置类型,!! 可以强制类型转换
  – 为了维持文件的简洁,并避免数据输入的错误,YAML
  提供了结点参考(*)和散合并(<<)参考到其他
  结点标签的锚点标记(&)。参考会将树状结构加入锚
  点标记的内容,并可以在所有数据结构中运作,合并
  叧有散列表可以使用,可以将键值自锚点标记复制到
  指定的散列表中
  jinja2模版简介
  · jinja2 是什么
  – Jinja2是基于python的模板引擎,包含 变量 和 表达
  式两部分,这两者在模板求值的时候会被替换为值。
  模板中还有标签,控制模板的逻辑。
  · 为什么要学习 jinja2 模版
  – 要使用 ansible 就要深入学习 playbook 配置及模板。
  playbook 的模板使用 python 的 jinja2 模块来处理的
  jinja2 模版基本语法
  – 模板的表达式都是包含在分隔符 &quot;{{}}&quot; 内的;
  – 控制语句都是包含在分隔符 &quot;{% %}&quot; 内的;
  – 另外,模板也支持注释,都是包含在分隔符 &quot;{# #}&quot;
  内,支持块注释。
  – 调用变量
  {{varname}}
  – 计算
  {{2+3}}
  – 判断
  {{1 in [1,2,3]}}
  jinja2 模版控制语句
  {% if name == 'aa' %}
  讲故事
  {% elif name == 'bb' %}
  嘿嘿
  {% elif name == 'cc' %}
  哈哈
  {% else %}
  沉迷学习,无法自拔
  {% endif %}
  jinja2 模版控制语句
  {% if name == ... ... %}
  ... ...
  {% elif name == '曹操' %}
  {% for method in [约会, 逛街, 吃饭, 看电影] %}
  {{do method}}
  {% endfor %}
  ... ...
  {% endif %}
  jinja2 过滤器
  – 变量可以通过 过滤器 修改。过滤器不变量用管道符号
  ( | )分割,并且也 可以用圆括号传递可选参数。多
  个过滤器可以链式调用,前一个过滤器的输出会被作
  为 后一个过滤器的输入。
  – 例如:
  – 把一个列表用逗号连接起来: {{ list|join(', ') }}
  – 过滤器这里不一一列丼,需要的可以查询在线文档
  http://docs.jinkan.org/docs/jinja2/templates.html
  #builtin-filters
  playbook是什么
  · playbook 是什么?
  – playbook 是 ansible 用于配置,部署,和管理托管主
  机剧本。通过 playbook 的详绅描述,执行其中的一系
  列 tasks,可以让进端主机达到预期的状态。
  – 也可以这么理解,playbook 字面意思,即剧本,现实
  中由演员按照剧本表演,在 Ansible 中由计算机进行表
  演,由计算机安装,部署应用,提供对外服务,以及组
  细计算机处理各种各样的事情
  为什么要使用playbook
  – 执行一些简单的任务,使用ad-hoc命令可以方便的解决
  问题,但是有时一个设施过于复杂,需要大量的操作时
  候,执行的 ad-hoc 命令是不适吅的,这时最好使用
  playbook,就像执行 shell 命令不写 shell 脚本一样,
  也可以理解为批处理任务
  – 使用 playbook 你可以方便的重用编写的代码,可以移
  植到不同的机器上面,像函数一样,最大化的利用代码
  在使用 Ansible 的过程中,你也会发现,你所处理的大
  部分操作都是编写 playbook
  playbook 语法格式
  – playbook由 YAML 语言编写,遵循 YAML 标准
  – 在同一行中,#之后的内容表示注释
  – 同一个列表中的元素应该保持相同的缩进
  – playbook 由一个或多个 play 组成
  – play 中 hosts,variables,roles,tasks 等对象的表示
  方法都是键值中间以 &quot;: &quot; 分隔表示
  – YAML 还有一个小的怪癖. 所有的 YAML 文件开始行都
  应该是 ---. 这是 YAML 格式的一部分, 表明一个文件的
  开始
  playbook 构成
  – Target: 定义将要执行 playbook 的进程主机组
  – Variable: 定义 playbook 运行时需要使用的变量
  – Tasks: 定义将要在进程主机上执行的任务列表
  – Handler: 定义 task 执行完成以后需要调用的任务
  Playbook执行结果
  · 使用 ansible-playbook 运行playbook文件,得到输
  出内容为 JSON 格式。并且由不同颜色组成,便于识
  别。一般而言
  · 绿色代表执行成功
  · ***代表系统代表系统状态发生改变
  · 红色代表执行失败

第一个playbook


  • hosts: all  remote_user: root
      tasks:

  • ping:
    第一行,表示开始
      ansible-playbook myping.yml -f 5
      – -f 并发进程数量,默认是 5
      – hosts 行的内容是一个或多个组或主机的 patterns,以
      逗号为分隔符
      – remote_user 就是账户名

第一个playbook


  • hosts: all  remote_user: root
      tasks:

  • ping:
    第一行,表示开始
      ansible-playbook myping.yml -f 5
      – -f 并发进程数量,默认是 5
      – hosts 行的内容是一个或多个组或主机的 patterns,以
      逗号为分隔符
      – remote_user 就是账户名

  续... ...
  – tasks
  – 每一个 play 包含了一个 task 列表(任务列表).
  – 一个 task 在其所对应的所有主机上(通过 host
  pattern 匹配的所有主机)执行完毕之后,下一个 task
  才会执行.
  – 有一点需要明白的是(很重要),在一个 play 之中,
  所有 hosts 会获取相同的任务指令,这是 play 的一个
  目的所在,也就是将一组选出的 hosts 映射到 task,执
  行相同的操作

playbook 执行命令
  – 给所有主机添加用户 plj,设置默认密码 123456
  – 要求第一次登录修改密码


  • hosts: all  remote_user: root
      tasks:

  • name: create user plj  user: group=wheel uid=1000 name=plj

  • shell: echo 123456 | passwd --stdin plj
  • shell: chage -d 0 plj  变量
      · 添加用户
      – 给所有主机添加用户 plj,设置默认密码 123456

– 要求第一次登录修改密码(使用变量)


  • hosts: 192.168.1.16  remote_user: root
      vars:
      username: plj
      tasks:

  • name: create user &quot;{{username}}&quot;  user: group=wheel uid=1000 name={{username}}

  • shell: echo 123456 | passwd --stdin plj
  • shell: chage -d 0 {{username}}
  续... ...
  – 解决密码明文问题
  – user 模块的 password 为什么不能设置密码呢?
  – 经过测试发现,password 是把字符串直接写入
  shadow,并没有改变,而 Linux 的 shadow 密码是
  经过加密的,所以不能使用
  – 解决方案:
  – 变量过滤器 password_hash
  – {{ 'urpassword' | password_hash('sha512')}}
  变量过滤器
  – 给所有主机添加用户 plj,设置默认密码 123456

– 要求第一次登录修改密码(使用变量)


  • hosts: 192.168.1.16  remote_user: root
      vars:
      username: plj
      tasks:

  • name: create user &quot;{{username}}&quot;  user: group=wheel uid=1000 password={{'123456' | password_hash('sha512')}} name={{username}}  #分为多行写时,值要用“”引起 如 group: &quot;whell&quot;

  • shell: chage -d 0 {{username}}
error
  · ansible-playbook 对错误的处理
  – 默认情况判断 $?,如果 值 不为 0 就停止执行
  – 但某些情况我们需要忽略错误继续执行


  • hosts: 192.168.1.16  remote_user: root
      vars:
      username: plj
      tasks:

  • name: create user &quot;{{username}}&quot;  user: group=wheel uid=1000
      password={{'123456'|password_hash('sha512')}}
      name={{username}}

  • shell: setenforce 0
  • shell: chage -d 0 {{username}}
  error
  · 续... ...
  – 我们要关闭 selinux,如果 selinux 已经是关闭的,返
  回 1 ,但我们的目的就是关闭,已经关闭算错误,
  这个情况我们就需要忽略错误继续运行,忽略错误有
  两种方法
  – 第一种方式:
  shell: /usr/bin/somecommand || /bin/true
  – 第二种方式:


  • name: run some command  shell: /usr/bin/somecommand
      ignore_errors: True

完整 playbook


  • hosts: 192.168.1.16  remote_user: root
      vars:
      username: plj
      tasks:

  • name: create user &quot;{{username}}&quot;  user: group=wheel uid=1000
      password={{'123456'|password_hash('sha512')}}
      name={{username}}

  • shell: setenforce 0  ignore_errors: true

  • shell: chage -d 0 {{username}}
  handlers
  · 用于当关注的资源发生变化时采取一定的操作。
  · &quot;notify&quot; 这个action可用于在每个play的最后被触发
  这样可以避免多次有改变发生时每次都执行指定的操
  作取而代之仅在所有的变化发生完成后一次性地执行
  指定操作。
  · 在 notify 中列出的操作称为 handler 也即 notify 中
  调用 handler 中定义的操作
  前面我们安装了 apache,很多情况是要修改 httpd
  的配置文件的,修改配置文件以后要重新载入配置文
  件让服务生效
  · 这时候,我们可以使用 handlers 来实现
  handlers:


  • name: restart apache  service: name=apache state=restarted

结和之前试验,完整 playbook


  • hosts: 192.168.1.16  remote_user: root
      tasks:

  • name: config httpd.conf  copy: src=/root/playbook/httpd.conf
      dest=/etc/httpd/conf/httpd.conf
      notify:

  • restart httpd  handlers:

  • name: restart httpd  service: name=httpd state=restarted

  注意事项:
  – notify 调用的是 handler 段 name 定义的串,必须一
  致,否则达不到触发的效果
  – 多个 task 触发同一个 notify 的时候,同一个服务叧会
  触发一次
  – notify 可以触发多个条件,在生产环境中往往涉及到
  某一个配置文件的改变要重启若干服务的场景,
  handler 用到这里非常适吅.
  – 结吅 vars 可以写出非常普适的服务管理脚本
  when
  · 某些时候我们可能需要在满足特定的条件后在触发某
  一项操作,或在特定的条件下织止某个行为,这个时
  候我们就需要进行条件判断,when 正是解决这个问
  题的最佳选择,进程中的系统变量 facts 变量作为
  when 的条件,这些 facts 我们可以通过 setup 模块
  查看
  – when 的样例:
  tashs:


  • name: somecommand  command: somecommand
      when: expr

一个使用 when 的例子


  • name: Install VIM  hosts: all
      tasks:

  • name: Install VIM via yum  yum: name=vim-enhanced state=installed
      when: ansible_os_family == &quot;RedHat&quot;

  • name: Install VIM via apt  apt: name=vim state=installed
      when: ansible_os_family == &quot;Debian&quot;

  register
  · register
  – 有时候我们可能还需要更复杂的例子,比如判断前一
  个命令的执行结果,根据结果处理后面的操作,这时
  候我们就需要 register 模块来保存前一个命令的返回
  状态,在后面进行调用


  • command: test command  register: result

  • command: run command  when: result

  register
  · 变量注册
  – 例如我们需要判断 plj 这个用户是否存在
  – 如果存在我就修改密码,如果不存在就跳过
  tasks:


  • shell:>register: result
  • name: change &quot;{{username}}&quot; password  user: password={{'12345678'|password_hash('sha512')}}
      name={{username}}
      when: result

  变量注册进阶
  – 我们还可以针对运行命令结果的返回值做判定

– 当系统负载超过一定值的时候做特殊处理


  • hosts: 192.168.1.16  remote_user: root
      tasks:

  • shell: uptime |awk '{printf(&quot;%f\n&quot;,$(NF-2))}'  register: result

  • shell: touch /tmp/isreboot  when: result.stdout|float > 0.5  #标准输出转化为浮点数

  with_items

· with_items 是 playbook 标准循环,最常用到的就
  是它,with_items 可以用于迭代一个列表或字典,
  通过{{ item }}获取每次迭代的值
  – 例如创建多个用户


  • hosts: 192.168.1.16  remote_user: root
      tasks:

  • name: add users  user: group=wheel password={{'123456' |
      password_hash('sha512')}} name={{item}}
      with_items: [&quot;nb&quot;, &quot;dd&quot;, &quot;plj&quot;, &quot;lx&quot;]

  with_items
  · with_items进阶
  – 为不同用户定义不同组


  • hosts: 192.168.1.16  remote_user: root
      tasks:

  • name: add users  user: group={{item.group}} password={{'123456' |
      password_hash('sha512')}} name={{item.name}}
      with_items:

  • {name: 'nb', group: 'root'}
  • {name: 'dd', group: 'root'}
  • {name: 'plj', group: 'wheel'}
  • {name: 'lx', group: 'wheel'}
  with_nested
  · 嵌套循环:


  • hosts: 192.168.1.16  remote_user: root
      vars:
      un: [a, b, c]
      id: [1, 2, 3]
      tasks:

  • name: add users  shell: echo {{item}}
      with_nested:

  • &quot;{{un}}&quot;
  • &quot;{{id}}&quot;
  tags
  · tags:给指定的任务定义一个调用标识;
  · 使用格式:
  – name: NAME
  – module: arguments
  – tags: TAG_ID
  · playbook 调用方式
  – -t TAGS, --tags=TAGS
  – --skip-tags=SKIP_TAGS
  – --start-at-task=START_AT
  tags
  · tags样例:
  vars:
  soft: httpd
  tasks:


  • name: install {{soft}}  yum: name={{soft}}

  • name: config httpd.conf  copy: src=/root/playbook/httpd.conf
      dest=/etc/httpd/conf/httpd.conf

  • name: config services  service: enabled=yes state=restarted name={{soft}}
      tags: restartweb
      · 调用方式
      ansible-playbook i.yml --tags=restartweb

  include and roles
  · 我们在编写 playbook 的时候随着项目越来越大,
  playbook 也越来越复杂,修改起来也越来越麻烦。
  这时候可以把一些 play、task 或 handler 放到其他
  文件中,然后通过include指令包含进来是一个不错
  的选择
  tasks:


  • include: tasks/setup.yml
  • include: tasks/users.yml user=plj #users.yml 中可以通过  {{ user }}不使用这些变量
      handlers:

  • include: handlers/handlers.yml
  include and roles
  · roles 像是加强版的 include,他可以引入一个项目
  的文件和目录
  · 一般所需的目录层级有
  – vars 变量层
  – tasks 任务层
  – handlers 触发条件
  – files
  文件
  – template 模板
  – default
  默认,优先级最低

include and roles
  · 假如有一个play包含了一个叨 &quot;x&quot; 的role,则


  • hosts: host_group  roles:
      -x
      – x/tasks/main.yml
      – x/vars/main.yml
      – x/handler/main.yml
      – x/... .../main.yml
      – 都会自劢添加进这个 play

  debug
  · 对于 python 语法不熟悉的同学,playbook 书写起
  来容易出错,且排错困难,这里介终几种简单的排错
  调试方法
  – 检测语法
  ansible-playbook --syntax-check playbook.yaml
  – 测试运行
  ansible-playbook -C playbook.yaml
  – 显示收到影响到主机 --list-hosts
  – 显示工作的 task --list-tasks
  – 显示将要运行的 tag --list-tags

debug
  · debug 模块可以在运行时输出更为详绅的信息,来
  帮助我们排错,debug 使用样例:


  • hosts: 192.168.1.16  remote_user: root
      tasks:

  • shell: uptime |awk '{printf(&quot;%f\n&quot;,$(NF-2))}'  register: result

  • shell: touch /tmp/isreboot  when: result.stdout|float > 0.5

  • name: Show debug info  debug: var=result


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-542715-1-1.html 上篇帖子: Linux自学笔记——Ansible 下篇帖子: ansible常用基础命令整合
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表