运维自动化之Ansible学习部署(二)

Playbook

  • playbook 剧本是由一个或多个‘play’组成的列表

  • https://yaml.org

1、支持的数据类型

1.1 scalar

	name:wang
	或者
	name:
	  wang

标量是基本的,不可再分割的值。

  • 字符串 布尔值 整数 浮点数 null 时间 日期

1.2 dictionary

字典有多个key:value组成,分号后有空格。
account: { name : wang, age:30}
或者
account:
name: wang
age: 30

#不同行
# an employee record
name: example developer
job: developer
skill: elite#社会精英
{name: "example developer", job: "developer", skill: "elite" }

1.2 list

列表有多个元素组成,类似数组。

course:
  - linux
  - golang
  - python
#也可以这样使用
course: [ linux, golang, python ]

数据里面也可以包含对象

course:
  - linux: 1
  - golang: 2
  - python: 3

示例:

name: john Smith
age: 41
gender: Male
spouse:##配偶
  name: Jae Smith
  age: 37
  gender: Female
children:
  - name: Jimmy Smith
    age: 17
    gender: Male
  - { name: Jenny Smith, age: 13, gender: Female }
  - { name: Hao Smith, age: 20, gender: Male }

1.3 常见数据格式

  • xml
  • json
  • Yaml

格式转换网址:https://www.json2yaml.com;https://www.bejson.com

2、playbook核心组件

  • hosts
  • tasks
  • variables
  • templates
  • handlers
  • tages

2.1 hosts

hosts:playbook中的每一个play的目的都是为了让特定的主机以某个指定的用户身份执行任务,hosts用于指定要执行任务的主机,需要事先定义在主机清单中。

vim hello.yml

---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: hello world
      command: /usr/bin/wall hello world

2.2remote_user

remote_user:可用于host和task中。也可以通过指定其通过sudo的方式在远程主机上之心过任务,其可用于play全局或某任务,甚至可以sudo时使用sudo_user指定sudo时切换用户。

---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: test connection
      ping:
      remote_user: test
      sudo: yes
      sudo_user: wang

ansible-palybook *.yml

2.3 task列表和action组件

play主体部分是task list,task list中有一个或多个task,各个task按顺序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个task任务后,再执行下一个task任务。task的目的使用指定的的参数执行模块,而在模块中可以使用变量,模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。买个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰的描述任务执行步骤,如果未提供那么,则action的结果将用于输出。

task两种格式:

action:  module arguments
module: arguments #建议使用
---
- host: websrvs
  remote_user: root
  gather_facts: no  ##不收集计算机状态信息
  tasks:
    - name: name=httpd state=removed
    - name: install httpd
      yum: name=httpd
    - name: start httpd
      service: name=httpd state=started enabled=yes

语法检查: ansible-playbook -C *.yml or ansible-playbook --syntax-check *.yml

---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: install apache
      yum: name=httpd
    - name: copy file
      copy: src=/tmp/httpd.conf desc=/etc/httpd/conf
    - name: copy file1
      copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
    - name: set enable
      service: name=httpd state=started enabled=yes 

ansible-playbook *.yml --list-hosts ##查看影响的主机
ansible-playbook *.yml --list-tags #列出标签
ansible-playbook *.yml --list-tasks#列出任务
-v -vv -vvv #显示过程
ansible-playbook *.yml --limit 188.188.188.171#只在171服务器上执行

3、利用playbook安装nginx

#!/bin/bash
---
- hosts: websrvs
  remote_user: root
  gather_facts: no

  tasks:
   - name: add group nginx
     group: name=nginx state=present
   - name: add user nginx
     user: name=nginx state=present group=nginx
   - name: install nginx
     yum:  name=nginx state=present
   - name: web page
     copy: src=./index.html dest=/usr/share/nginx/html/index.html
   - name: start nginx
     service: name=nginx state=started enabled=yes

3.1 playbook中使用handlers和notify

  • handlers:触发的动作,必须通过notify触发执行
  • notify: 触发器,取决于文件的变化,文件无变化不出引发notify
#!/bin/bash
---
- hosts: websrvs
  remote_user: root
  gather_facts: no

  tasks:
   - name: add group nginx
     group: name=nginx state=present
   - name: add user nginx
     user: name=nginx state=present group=nginx
   - name: install nginx
     yum:  name=nginx state=present
   - name: web page
     copy: src=./index.html dest=/usr/share/nginx/html/index.html
     notify: restart nginx
   - name: start nginx
     service: name=nginx state=started enabled=yes
  #与tasks平级
  handlers:
   - name: restart nginx
     service: name=nginx state=restarted 

3.2 playbook中使用tags

  • 列出所有标签

      ansible-playbook nginx.yml --list-tags
    
  • 执行tags的task

      ansible-playbook -t conf.service nginx.yml
    
#!/bin/bash
---
- hosts: websrvs
 remote_user: root
 gather_facts: no

 tasks:
  - name: add group nginx
    group: name=nginx state=present
  - name: add user nginx
    user: name=nginx state=present group=nginx
  - name: install nginx
    yum:  name=nginx state=present
  - name: web page
    copy: src=./index.html dest=/usr/share/nginx/html/index.html
    notify: restart nginx
    tags:  conf
  - name: start nginx
    service: name=nginx state=started enabled=yes
    tags:  service
 #与tasks平级
 handlers:
  - name: restart nginx
    service: name=nginx state=restarted 

3.3 playbook中使用变量

3.3.1使用ansible默认变量

变量名:仅能由字母、数字和下划线组成,且只能以字母开始

  • 变量定义

      variable=value
      exp: http_port=80
    
  • 变量调用方式

      通过{{variable_name}}调用变量,且变量名前后建议加空格,有时用"{{variable_name}}"才生效。 
    
---
#var1.yml
- hosts: all
  remote_user: root
  gather_facts: yes
  tasks:
    - name: create dir
      file: name=/app state=directory
    - name: create log file
      file: name=/app/{{ansible_nodename}}.log state=touch owner=qjzhao mode=775

3.3.2使用自定义变量

ansible-playbook -e "pkname=httpd" var2.yml

vim var2.yml

---
- hosts: websrvs
  remote_user: root
  gather_facts: no
  tasks:
    - name: unstall httpd
      yum: name={{pkname}} state=absent 
    - name:  install httpd
      yum: name={{pkname}} state=present
  • 通过文件
ansible-playbook -e  @vars var2.yml
[root@ansibleMaster app]# vim vars 
pkname: memcached
changed: [188.188.188.171]
changed: [188.188.188.172]
changed: [188.188.188.173]
 ____________
< PLAY RECAP >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

188.188.188.171            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
188.188.188.172            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
188.188.188.173            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
  • 在yml文件中定义变量
---
- hosts: websrvs
  remote_user: root
  gather_facts: no
  vars:
    username: user1
    groupname: group1
   tasks:
     - name: create group
       group: name={{groupname}} state=present
     - name: create user
       user: name={{username}} group={{groupname}} state=present
ansible-playbook -e "username=user2 groupname=group2" var3.yml

命令行的(-e "content")优先级高于yml中变量的优先级

  • 使用变量文件(*.yml)
---
- hosts: websrvs
  remote_user: root
  vars_files:
    - vars.yml
   tasks:
     - name: install package
       yum: name={{ package_name }} state=present
       tags: install
     - name: start service
       service: name={{ service_name }} state=started enable=yes

vim vars.yml

package_name: mariadb-server
service_name: mariadb
  • 主机清单里面写变量
    vim /etc/ansible/hosts
[websrvs]
188.188.188.171 name=slave171.qjzhao.com
188.188.188.172 name=slave172.qjzhao.com
188.188.188.173 name=salve173.qjzhao.com

vim var4.yml

---
- hosts: websrvs
  tasks:
    - name: rename hostname
      hostname: name={{name}}
  • 主机清单里面公共变量
[websrvs]

188.188.188.171 name=slave171
188.188.188.172 name=slave172
188.188.188.173 name=salve173
[websrvs:vars]
domain=qjzhao.com.cn

vim var5.yml

---
- hosts: websrvs
  tasks:
    - name: rename hostname
      hostname: name={{name}}.{{domain}}

4、template模板

4.1jinja2语言

  • jinja2 神社 日本人搞的

  • http://jinja.pocoo.org

  • https://jinja.palletsprojects.com/en/2.11.x/

      支持字面量、列表、元组、字典、布尔型、算数运算、比较操作、逻辑运算、流表达式
    
  • 列表:[one1,one2,……]

  • 元组:(one1,one2,……)

  • 字典:{key1:value1,key2:values2,……}

  • 流表达式:for if when

4.2 template

template功能:可以根据和参考模块文件,动态生成类似的配置文件
template文件必须存放于template目录下,切命名为.j2结果
yaml/yml 文件需和template目录评级,目录结果如下:

4.2.1 复制nginx.conf为Nginx.conf.j2

vim temnginx.yml

#准备templates/nginx.conf.j2
---
- hosts:
  remote_user: root
  tasks:
    - name: template config
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
[root@ansibleMaster ansible]# ansible-playbook temnginx.yml

template变更替换

[root@ansibleMaster ansible]#mkdir -p templates
###此处Nginx.conf.j2文件来自nginx.conf
[root@ansibleMaster ansible]#vim templates/nginx.conf.j2
-----
worker_processes {{ ansible_processor_vcpus **3 }};
-----

vim temnginx2.yml

---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: install nginx
      yum: name=nginx
    - name: template
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify: restart nginx
    - name: start service
      service: name=nginx state=started enabled=yes
  handlers:
    - name: restart nginx
      service: name=nginx state=restarted    

ansible-playbook temnginx2.yml

4.3template使用流程控制 for if

运维自动化之Ansible学习部署(二)
运维自动化之Ansible学习部署(二)

5 role角色

5.1 role特性

角色是ansible1.2的新特性。
roles: 多个角色的集合目录
roles
mysql/
nginx/
tocmat/
redis/

roles各目录作用
roles/project/:项目名称,有以下子目录

  • files/:存放由copy或script模块等调用的文件
  • templates/:template模块查找所需要的魔板文件的目录
  • tasks:/ 定义task,role的基本元素,至少应该包含一个名为mail.yml的文件,其他的文件需要在此文件中通过include进行包含
  • handlers/:至少应该包含一个名为main.yml的文件;此目录下的其他需要在此文件中通过include包含
  • vars/:定义变量,至少包含一个名为main.yml的文件,此目录下的其他变量文件需要在此文件中通过includ进行包含
  • meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为mai.yml的文件,其他文件需要在此文件中通过include进行包含
  • default/:设定默认变量时使用此目录中的main.yml文件,比vars的优先级低

5.2创建role

创建role的步骤

	1   创建以roles的命令的目录
	2   在roles目录中分别创建以各角色名称命名的目录,如mysql等
	3   在每个角色命名的目录中分别创建files、handlers、tasks、template和vars等目录;用不到的目录可以创建你为空目录,也可以不创建
	4   在每个角色相关的子目录中创建相应的文件,如 tasks/mail.yml
	5   在playbook文件中,调用需要的角色

运维自动化之Ansible学习部署(二)

5.3 playbook 调用角色

-调用角色方法1

---
- hosts:
  remote_user: root
  roles: 
    - mysql
    - memecached
    - nginx
  • 调用角色方法2
---
- hosts: all
  remote_user: root
  roles: 
    - mysql
    - {role: nginx, username: nginx}
  • 调用角色方法3
    基于条件测试实现角色调用
---
- hosts: all
  remote_user: root
  roles: 
    - mysql
    - {role: nginx, username: nginx, when: ansible_distribution_major_version == '7' }

5.4roles中tags使用

vim nginx-role.yml

---
- hosts: websrvs
  remote_user: root
  roles: 
    - {role: nginx, tags: [ 'nginx','web' ], when: ansible_distribution_major_version == '7' }
    - {role: httpd, tags: [ 'httpd', 'web' ] }
    - {role: mysql, tags: [ 'mysql' ,'db' ] }
    - {role: mariadb, tags: [ 'mariadb', 'db' ] }

ansible-playbook --tags=“nginx,httpd,mysql” nginx-role.yml

5.5 实战案列

5.5.1 实现httpd角色

1)创建目录
mkdir -pv /app/ansible/roles/httpd/{tasks,handlers,files}
2)配置文件
vim  /app/ansible/roles/httpd/tasks/main.yml
- include: group.yml
- include: user.yml
- include: install.yml
- include: config.yml
- include: index.ym
-include: service.yml
  • group.yml
- name: create apache group
  group: name=apache system=yes gid=80
  • user.yml
- name: create user
  user: name=apache system=yes shell=/sbin/nologin home=/var/www/ uid=80 group=apache
  • install.yml
- name: install httpd
  yum: name=httpd
  • config.yml
- name: confile file
  copy: src=httpd.conf dest=/etc/httpd/conf/ backup=yes
  notify: restart
  • index.yml
- name: index.html
  copy: src=index.html dest=/var/www/html/
  • service.yml
- name: start service
  service: name=httpd state=started enabled=yes
  • handlers/main.yml
    被tasks/config.yml引用
- name: restart
  service: name=httpd state=restarted

生成index.html、httpd.conf放置于/app/ansible/roles/httpd/files/

[root@ansibleMaster httpd]# tree 
.
├── files
│   ├── httpd.conf
│   └── index.html
├── handlers
│   └── main.yml
└── tasks
    ├── config.yml
    ├── group.yml
    ├── index.yml
    ├── install.yml
    ├── main.yml
    ├── service.yml
    └── user.yml
3)启动文件

需在/app/ansible/编写一个引用httpd roles的yml文件

vim roles_httpd.yml
---
- hosts: websrvs
  remote_user: root
  roles:
    - httpd
4)卸载

vim roles_unstall_httpd.yml

---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: yum remove httpd
      yum:  name=httpd state=removed
    - name: del user
      shell: userdel -rf apache
    - name: del index.html
      file: path=/var/www/html/index.html state=absent

上一篇:15 分钟学会使用 Git 和远程代码库


下一篇:ansible功能实现