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

[经验分享] Ansible详解(三)

[复制链接]

尚未签到

发表于 2018-7-29 07:50:24 | 显示全部楼层 |阅读模式
  一、template模板
  二、playbook中的条件判断
  三、PlayBook中的循环
  四、角色(roles)
  一、template模板
  template使用了Jinjia2格式作为文件模版,进行文档内变量的替换的模块。它的每次使用都会被ansible标记为”changed”状态。基于模板方式生成一个文件复制到远程主机
  常用参数:
参数名     是否必须     默认值     选项     说明  
backup     no         no     yes/no     建立个包括timestamp在内的文件备份,以备不时之需.
  
dest     yes             远程节点上的绝对路径,用于放置template文件。//必须是绝对路径
  
group     no             设置远程节点上的的template文件的所属用户组
  
mode     no             设置远程节点上的template文件权限。类似Linux中chmod的用法 //group,owner
  
owner     no             设置远程节点上的template文件所属用户
  
src     yes             本地Jinjia2模版的template文件位置。 //绝对或者相对路径
  一般编程语言都有把自己嵌入到文本的模板语言
  php:直接嵌入
  python:Jinja2 //ansible就是python写的
  Jinja2 中常用的编程元素
  字面量:字符串,单引号或者双引号引用即可
  数字:整数和浮点数
  列表:[item1,item2,...]
  元祖:(item1,itme2,...) //不可变
  字典:{key1:value1,key2:value2,...}
  布尔型:true/false
  算数运算:
  +,-,*,/,%, //,**     //:表示只要熵
  比较运算:
  ==,!=,>=,<=,<,
  逻辑运算符:
  and,or,not
  ansible-doc -s template
  利用模板:实现对不同主机的nginx配置成不同的启动processor
  vim nginx.conf.j2
  worker_processes {{ ansible_processor_vcpus }}; //使用模板变量
  listen {{ http_port }};  //自定义变量
  注:这个参数是在setup模板中
  worker_processes {{ ansible_processor_vcpus-1 }}; //可以直接增加或减去
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf mode=0644
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf owner=bin group=wheel mode=&quot;u=rw,g=r,o=r&quot;
  vim ansible/hosts
  [websrvs]
  192.168.4.100 http_port=888
  192.168.4.116 http_port=808  //使用主机变量
  [root@localhost ~]# cat nginx.yaml
- hosts: websrvs  
  remote_user: root
  
  tasks:
  
  - name: install nginx
  
    yum: name=nginx state=present
  
  - name: install conf
  
    template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf mode=0644
  
    notify: restart nginx
  
    tags: instconf
  
  - name: start nginx service
  
    service: name=nginx state=started
  
  handlers:
  
  - name: restart nginx
  
    service: name=nginx state=restarted
  ansible-playbook --check nginx.yaml
  ansible-playbook  nginx.yaml
  注意:6和7的配置nginx配置文件不一样
  执行结果
  RUNNING HANDLER [restart nginx]
  ************************************************
  changed: [192.168.4.110]  //发生改变的话,就会执行 restart nginx
  changed: [192.168.4.106]
  handlers:用于当关注的资源发生变化时触发一定的操作。
  “notify”这个action可用于在每个play的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作
  取而代之,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作。
  二、playbook中的条件判断
  多个条件:and/when/or
  1.条件测试:tasks上使用when语句,在tasks上使用,Jinja2的语法格式。根据不同的OS分配不同的机制
  字符串要加引号{单双都可},数值一定不加引号
  ansible all -m setup | grep &quot;ansible_distribution&quot; //版本信息
  &quot;ansible_distribution&quot;: &quot;CentOS&quot;,
  &quot;ansible_distribution_major_version&quot;: &quot;6&quot;,
  &quot;ansible_distribution_release&quot;: &quot;Final&quot;,
  &quot;ansible_distribution_version&quot;: &quot;6.6&quot;,
  tasks:
  - name: install conf file
  template: src=nginx.conf.7
  when: ansible_distribution_major_version == '7'        4tasks:
  - name: install conf file
  template: src=nginx.conf.6
  when: ansible_distribution_major_version == '6'
  条件测试1: when
- hosts: websrvs  
  remote_user: root
  
  tasks:
  
  - name: copy file 6
  
    template: src=/tmp/6.txt dest=/tmp
  
    when: ansible_distribution_major_version == '6'
  
    notify: restart nginx
  
  - name: copy file 7
  
    template: src=/tmp/7.txt dest=/tmp
  
    when: ansible_distribution_major_version == '7'
  
    notify: restart nginx
  
handlers:
  
- name: restart nginx
  
  service: name=nginx state=restarted
  2.register
  示例,判断sda6是否存在。存在就执行一些相应的脚本,则可以为该判断注册一个register变量,并用它来判断是否存在,存在返回 succeeded, 失败就是 failed.
- name: Create a register to represent the status if the /dev/sda6 exsited  
  shell: df -h | grep sda6
  
  register: dev_sda6_result
  
  ignore_errors: True
  
  tags: docker
  

  
- name: Copy docker-thinpool.sh to all hosts
  
  copy: src=docker-thinpool.sh dest=/usr/bin/docker-thinpool mode=0755
  
  when: dev_sda6_result | succeeded
  
  tags: docker
  假如我们想忽略某一错误,通过执行成功与否来做决定,我们可以像这样:
  tasks:
  - command: /bin/false
  register: result
  ignore_errors: True
  - command: /bin/something
  when: result|failed
  - command: /bin/something_else
  when: result|success
  - command: /bin/still/something_else
  when: result|skipped
  三、PlayBook中的循环   
  循环:迭代,需要重复执行的任务;
  例如需要同时安装,nginx,httpd,php-fpm,php-mysql,mariabd等
  对迭代项的引用,固定变量名为&quot;item&quot;
  而后,要在task中使用with_items给定要迭代的元素列表
  列表方法:
  字符串:
  字典:
  1.标准循环:        
- name: install some packages  
  yum: name={{ item }} state=present
  
  with_items:
  
  - nginx
  
  - memcached
  
  - php-fpm
  
    //将可以安装多个软件同时安装
  
循环测试脚本:item
  
[root@localhost ~]# cat e.yaml
  
- hosts: websrvs
  
  remote_user: root
  
  tasks:
  
  - name: install pkgs
  
    yum: name={{ item }} state=present
  
    with_items:
  
    - telnet
  
    - vim
  
    - tree
  循环测试脚本3.
  创建三个用户分别属于不同组
  [root@localhost ~]# cat f.yaml
- hosts: websrvs  
  remote_user: root
  
  tasks:
  
  - name: group add
  
    group: name={{ item }} state=present     //注意:引用的时候使用的是{{ }}没有s,列举参数的时候使用的是复数,items
  
    with_items:
  
    - group11
  
    - group12
  
    - group13
  
  - name: add users
  
    user: name={{ item.name }}  group={{ item.group }} state=present
  
    with_items:
  
    - { name: 'user11', group: 'group11' }
  
    - { name: 'user12', group: 'group12' }
  
    - { name: 'user13', group: 'group13' }
  ==============================
  [root@localhost ~]# cat c.yaml
- hosts: testweb  
  remote_user: root
  
  tasks:
  
  - name: install user
  
    user: name={{ item.name }} state=present groups={{ item.groups }}
  
    with_items:
  
      - { name: 'testuser1', groups: 'wheel' }
  
      - { name: 'testuser2', groups: 'root' }
  //创建testuser1{wheel},testuser2{root}
  注意:
  1.hosts 不是host
  2.严格对齐,列表和内容分开
  3.name: 'user11' //中间必须有空格,字符必须用引号,
  4.目标主机存在user11或其中一个用户的话,也会返回错误
  5.whih_itmes后的内容为下一个key-value (先加空格)
  2.嵌套循环:
-name:give users access to multiple databases  
mysql_user:name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
  
with_nested:
  
  -['alice','bob']        //表示item[0],nested:嵌套
  
  -['clientdb','employeedb','providerdb']
  

  
- name: here, 'users' contains the above list of employees
  
  mysql_user: name={{ item[0] }} priv={{ item[1] }}.*:ALL append_privs=yes password=foo
  
  with_nested:
  
    - &quot;{{users}}&quot;
  
    - [ 'clientdb', 'employeedb', 'providerdb' ]
  [root@localhost ~]# cat c.yaml
- hosts: testweb  
  remote_user: root
  
  tasks:
  
  - name: install user
  
    user: name={{ item.name }} state=present groups={{ item.groups }}
  
    with_items:
  
      - { name: 'testuser1', groups: 'wheel' }
  
      - { name: 'testuser2', groups: 'root' }
  
  - name: give users access to multiple databases
  
    command: &quot;echo name={{ item[0] }} priv={{ item[1] }} test={{ item[2] }}&quot;
  
    with_nested:
  
      - [ 'alice', 'bob' ]
  
      - [ 'clientdb', 'employeedb', 'providerdb' ]
  
      - [ '1', '2', ]
  
    tags: netsted
  输出:
skipping: [192.168.2.122] => (item=[u'alice', u'clientdb', u'1'])  
skipping: [192.168.2.122] => (item=[u'alice', u'clientdb', u'2'])
  
skipping: [192.168.2.122] => (item=[u'alice', u'employeedb', u'1'])
  
skipping: [192.168.2.122] => (item=[u'alice', u'employeedb', u'2'])
  
skipping: [192.168.2.122] => (item=[u'alice', u'providerdb', u'1'])
  
skipping: [192.168.2.122] => (item=[u'alice', u'providerdb', u'2'])
  
skipping: [192.168.2.122] => (item=[u'bob', u'clientdb', u'1'])
  
skipping: [192.168.2.122] => (item=[u'bob', u'clientdb', u'2'])
  
skipping: [192.168.2.122] => (item=[u'bob', u'employeedb', u'1'])
  
skipping: [192.168.2.122] => (item=[u'bob', u'employeedb', u'2'])
  
skipping: [192.168.2.122] => (item=[u'bob', u'providerdb', u'1'])
  
skipping: [192.168.2.122] => (item=[u'bob', u'providerdb', u'2'])
  3.字典循环
  假如你有以下变量:
  users:
  alice:
  name: Alice Appleworth
  telephone: 123-456-7890
  bob:
  name: Bob Bananarama
  telephone: 987-654-3210
  你想打印出每个用户的名称和电话号码.你可以使用 with_dict 来循环哈希表中的元素:
  tasks:
  - name: Print phone records
  debug: msg=&quot;User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})&quot;
  with_dict: &quot;{{users}}&quot;
  4.遍历文件whith_file,whith_fileglob
  with_file 是将每个文件的文件内容作为item的值
- hosts: all  
  tasks:
  
    # first ensure our target directory exists
  
    - file: dest=/etc/fooapp state=directory
  
    # copy each file over that matches the given pattern  //注意copy必须要用 “-”
  
    - copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600
  
      with_fileglob:
  
        - /playbooks/files/fooapp/*
  with_fileglob 是将每个文件的全路径作为item的值, 在文件目录下是非递归的, 如果是在role里面应用改循环, 默认路径是roles/role_name/files_directory
  5.并行数据循环
  已知变量:
  alpha: [ 'a', 'b', 'c', 'd' ]
  numbers:  [ 1, 2, 3, 4 ]
  如果你想得到’(a, 1)’和’(b, 2)’之类的集合.可以使用’with_together’:
  tasks:
  - debug: msg=&quot;{{ item.0 }} and {{ item.1 }}&quot;
  with_together:
  - &quot;{{alpha}}&quot;
  - &quot;{{numbers}}&quot;
  还有更多的循环介绍方法请参考本文尾部链接地址...
  四、角色:(roles)
  一个主机可以担任多种角色:
  定义为多个身份,用的时候直接调用该身份即可
  角色名就是目录名,任何角色都不能引用自己所属目录之外的其他目录文件
  roles/
  mysql/
  httpd/
  nginx/
  memcached/
  每个角色,以特定的层级目录结构进行组织: 注意:大多数都是复数&quot;s&quot;,除了meta
  mysql/
  files/        存放由copy或script模块等调用的文件
  templates/  template模块查找所需要的模板文件目录;
  handlers/   至少应该包含一个名为main.yml文件
  vars/        至少一个main.yml
  tasks/        基本元素:至少一个名为main.yml的文件,其他的文件需要在此文件中通过include进行包含
  meta/        main.yml,定义当前角色的特殊设定,及其依赖关系
  default/      设定默认变量时使用此目录中的main.yml文件
  调用角色:
  - hosts: websrvs
  remote_user: root
  roles:
  - mysql        //会自动到mysql目录中跑一遍
  - memcached
  - nginx
  mkdir /etc/ansible/roles/nginx/{files,tasks,templates,handlers,vars,default,meta} -pv
  cd /etc/ansible/roles/nginx/
  1.tasks   
  [root@localhost nginx]# cat tasks/main.yml
- name: install nginx pkg  
  yum: name=nginx state=present
  
- name: install conf file
  
  template: src=nginx.conf dest=/etc/nginx/nginx.conf.test   ///nginx.conf不在同级目录,但是role可以直接识别为template中的文件
  
- name: start nginx
  
  service: name=nginx state=started enabled=true
  templates 目录中有存放的nginx.conf
  2.在其他地方创建nginx.yaml //这个可以放在其他地方
- hosts: websrvs  
  remote_user: root
  
  roles:
  
  - nginx
  执行:
  ansible-playbook --check nginx.yaml
/etc/ansible/roles/nginx/  
├── default
  
├── files
  
├── handlers
  
├── meta
  
├── tasks
  
│   └── main.yml
  
├── templates
  
│   └── nginx.conf
  
└── vars
  3.添加handler
  修改handlers/main.yml
  - name: restart nginx        //注意,前面的 - 不可少,代表是handler的一个清单
  service: name=nginx state=restarted
  创建tasks/main.yml
- name: install nginx pkg  
  yum: name=nginx state=present
  
- name: install conf file
  
  template: src=nginx.conf dest=/etc/nginx/nginx.conf.test
  
  notify: restart nginx
  
  tags: instconf
  
- name: start nginx
  
  service: name=nginx state=started enabled=true
  修改一下nginx.conf //否则不会触发handler
  ansible-playbook -t instconf --check g.yaml
  4.变量
  [root@localhost yaml]# cat h.yaml
- hosts: websrvs  
  remote_user: root
  
  vars:
  
  - username: testuser1
  
  - groupname: testgroup1
  
  tasks:
  
  - name: create group
  
    group: name={{ groupname }} state=present
  
  - name: create user
  
    user: name={{ username }} group={{ groupname }} state=present
  在playbook中定义变量的方法
  vars:
  - var1: value1
  - var2: value2
  ansible-playbook -e &quot;groupname=mygrp1&quot; -e &quot;username=myuser&quot;  --check h.yaml
  //可以覆盖变量,在命令行中定义的变量,会覆盖
  5.变量使用,roles中
  vim nginx/vars/main.yml
  username: nginx
  vim templates/nginx.conf
  user {{ username }} //让nginx以该用户的身份运行
  其他不修改
  ansible
  问题:
  [root@localhost yaml]# ansible-playbook --check g.yaml
  ERROR! The vars/main.yml file for role 'nginx' must contain a dictio
  nary of variables
  原因:vars/main.yml 前面不需要 - ,和其他的main.yml不一样
  ansible-playbook -e &quot;username=adm&quot; --check nginx.yml //假如想改变运行nginx的用户,直接修改即可
  6.在playbook中调用角色方法2
  vim nginx.yaml
  - hosts: websrvs
  remote_user: root
  roles:
  - {role: nginx, username: nginx} //向该角色传递变量
  键role用于指定角色名称,后续的k/v用于传递变量给角色
  还可以基于条件测试,实现角色调用;
  例如:
  roles:
  - {role: nginx,when: &quot;ansible_distribution_major_version == '7' }
  //条件满足时,应用该角色
  [root@localhost yaml]# cat i.yaml
  - hosts: websrvs
  remote_user: root
  roles:
  - { role: nginx, username: nginx, when: &quot;ansible_distribution_major_version == '7'&quot; }
  //只有在OS为7才会执行
  7.安装memcached,占用内从空间为当前可用空间的1/3
  mkdir -pv memcached/{tasks,vars,templates,hanlers}
vim tasks/main.yml  
- name: install pack
  
  yum: name=memcached state=present
  
- name: install conf
  
  template: src=memcached.j2 dest=/etc/sysconfig/memcached
  
  notify: restart memcached
  
  tags: memconf
  
- name: start memcached
  
  service: name=memcached state=started enabled=true
  

  
vim templates/memcached
  
PORT=&quot;11211&quot;
  
USER=&quot;memcached&quot;
  
MAXCONN=&quot;1024&quot;
  
CACHESIZE=&quot;{{ ansible_memtotal_mb//4  }}&quot;  //除以4,可能是小数,因此// 取出整数
  
OPTIONS=&quot;&quot;
  

  
vim handlers/main.yml
  
- name: restart memcached
  
  service: name=memcached state=restarted
  
vim lnm.yaml  //同时调用两个role
  
- hosts: websrvs
  
  remote_user: root
  
  - roles:
  
  - { role: nginx, when: ansible_distribution_version == '7' }
  
  - { role: memcached, when: ansible_hostname == 'memcached' }
  ansible-playbook -t memconf lnm.yaml
  出错原因:
  1.main.yml中,template是没有s的,但是目录名是有s的
  2.notify不是nofify
  =======================================================
  yaml和yml格式的区别:
  1.yml不需要hosts,remote_user //这些在yaml中定义
  - name: install pkgs
  yum: name=memcached state=present
  2.yaml一定要-hosts,-remote_user
  - hosts: all
  remote_user: root
  roles:
  - { role: nginx,when:ansible_distribution_version == '7' }
  ansible all -m setup  //查看所有内置变量
  www.ansible.com.cn //站点,
  推荐:参考ansible官方role的写法,自行创建role进行练习
  http://blog.csdn.net/kellyseeme/article/details/50619562
  http://www.ansible.com.cn/docs/playbooks_loops.html
  https://www.cnblogs.com/v394435982/p/5593274.html

运维网声明 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-542775-1-1.html 上篇帖子: Ansible详解(二) 下篇帖子: 免密码交互方式+ansible批量管理服务介绍
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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