Ansible自动化运维

Ansible自动化运维

介绍

ansible是新出现的自动化运维工具,由python开发,集合了众多自动化运维工具的优点,实现了批量
系统部署、批量程序部署,批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能
力,真正具有批量部署能力的是ansible运行的模块,ansible只是提供一个框架。

核心组件

在这里插入图片描述

ansbile:核心程序

HostInventory :记录由Ansible管理的主机信息,包括端口、密码、ip等。

modules:包括ansible自带的核心模块以及自定义模块

plugins:完成模块功能的补充,包括连接插件,邮箱插件

palybooks:剧本,定义ansbile多任务配置文件,由ansible自动执行

inventory:定义ansbile管理的主机清单
connection plugins:负责和被监控端实现通信

特 点

  • 不需要在被监控端上安装任何服务程序

  • 无服务器端,使用时直接运行命令即可

  • 基于模块工作,可以使用任意语言开发

  • 使用yaml语言编写playbook

  • 基于ssh工作

  • 可实现多级指挥

  • 具有幂等性,一种操作重复多次执行结果相同

  • 执行过程:

    加载自己的配置文件,默认为/etc/ansible/ansible.cfg

    加载自己对应的模块文件

    通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远 程服务器

    对应执行用户的家目录的.ansible/tmp/xx.py文件

    给文件+x执行

    执行并将返回结果,删除临时py文件,sleep 0 退出

安装部署ansible

  • 安装 ansible方式

    yum安装

    [root@localhost ~]# yum install epel-release.noarch -y
    [root@localhost ~]# yum install -y ansible
    

    使用pip安装(python的包管理模块)

    首先,我们需要安装一个python-pip 包,安装完成以后,则直接使用pip 命令来安装我们的包

    yum install python-pip
    pip install ansible
    
  • 免密登陆

    [root@ansible ~]# ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/root/.ssh/id_rsa):
    Created directory '/root/.ssh'.
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /root/.ssh/id_rsa.
    Your public key has been saved in /root/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:IVCukQxzkroHAUvVovvB4ga3JrY4OlkwMnV9rZhVEFE root@ansible
    The key's randomart image is:
    +---[RSA 2048]----+
    |o.=o+o. +BE      |
    |o.oB.=. o .      |
    |.+..= o=..       |
    |B. oo...         |
    |.*o . S          |
    |oo+o             |
    |o=o..            |
    |*+o.             |
    |**.              |
    +----[SHA256]-----+
    
  • 发送主机公钥到受控制结点

[root@ansible ~]# cd .ssh/ 
[root@ansible .ssh]# ll

总用量  8

-rw------- 1 root root 1679 911 09:54 id_rsa

-rw-r--r-- 1 root root  394 911 09:54 id_rsa.pub
[root@ansible .ssh]# ssh-copy-id -i id_rsa.pub  root@192.168.174.20

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "id_rsa.pub"

The authenticity of host '192.168.174.20 (192.168.174.20)' can't be established. ECDSA key 
fingerprint is SHA256:l5y8+0D0KcBmCK2edW3ZSY7RyIDgBdlLOE10JAlVtKk.

  • ansible文件

    • /etc/ansible/ansible.cfg: 主机配置文件
    • /etc/ansible/hosts: 主机清单文件
    • /etc/ansible/roles: 角色目录
    [defaults]
    # some basic default values...
    #inventory = /etc/ansible/hosts
    # 定义主机清单文件
    #library = /usr/share/my_modules/ # 库
    文件的存放位置
    #module_utils = /usr/share/my_module_utils/
    #remote_tmp = ~/.ansible/tmp
    # 生成的临时py文件在远程主机的目录
    #local_tmp = ~/.ansible/tmp
    # 生成的临时py文件在本地主机的目录
    #plugin_filters_cfg = /etc/ansible/plugin_filters.yml #
    #forks = 5 # 默认的并发数
    #poll_interval = 15 # 默认的线程池
    #sudo_user = root # 默认的sudo用户
    #ask_sudo_pass = True
    #ask_pass = True
    #transport = smart
    #remote_port = 22
    #module_lang = C
    #module_set_locale = False
    
  • 常用命令

    • ansible:常用于执行临时命令
    • ansible-playbook
    • ansible-doc块的查询

ansible主机清单

  • 定义主机hosts文件

    [root@ansible ~]# tail /etc/hosts
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.174.10 ansible
    192.168.174.20 node1 
    192.168.174.30 node2
    
  • 在/etc/ansible/hosts/文件中添加ansible主机清单

    [root@ansible ~]# grep -Ev '#|^$' /etc/ansible/hosts
    [all-servers]
    192.168.146.165
    192.168.146.166
    192.168.146.167
    [server1]
    192.168.146.165
    [server2]
    192.168.146.166
    [server3]
    192.168.146.167
    

ansible常用参数

-a MODULE_ARGS:指定模块的参数
-m MODULE_NAME:指定模块
-C:坚持执行结果
-e EXTRA_VARS:指明变量名
-f FORKS:指定并发进程数
-i INVENTORY:指定主机清单文件
--syntax-check:检查执行命令是否存在语法错误

ansible-doc命令

ansible-doc 命令常用于获取模块信息及其使用帮助,一般用法如下:

ansible-doc -l               #获取全部模块的信息 
ansible-doc -s MOD_NAME     #获取指定模块的使用帮助
  • ansbile执行状态

绿色:执行成功并且不需要做改变的操作黄色:执行成功并且对目标主机做变更 红色:执行失败

粉色:警告信息

蓝色:显示ansible命令执行的过程

常用模块

ping模块:主机连通性测试

[root@ansible ~]# ansible -m ping nodes

user模块

[root@ansible ~]# ansible-doc -s user
comment # 用户的描述信息
createhom # 是否创建家目录
force # 在使用`state=absent'是, 行为与`userdel --force'一致.
group # 指定基本组
groups # 指定附加组,如果指定为('groups=')表示删除所有组
home # 指定用户家目录
name # 指定用户名
password # 指定用户密码
remove # 在使用 `state=absent'时, 行为是与 `userdel --remove'一致.
shell # 指定默认shell
state #设置帐号状态,不指定为创建,指定值为absent表示删除
system # 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
uid #指定用户的uid
update_password # 更新用户密码
expires #指明密码的过期时间
1.添加系统用户,指定uid、家目录、主组及注释
ansible -m user -a "system=yes name=zhangsan home=/home/zhangsan uid=111
group=zhangsan comment='hello zhangsan'" nodes
2.删除用户及家目录
ansible -m user -a "name=zhangsan state=absent remove=yes"

group模块

[root@ansible ~]# ansible-doc -s group
- name: 添加或删除组
action: group
gid # 设置组的GID号
name= # 管理组的名称
state # 指定组状态,默认为创建,设置值为absent为删除
system # 设置值为yes,表示为创建系统组
ansible -m group -a "name=eagles gid=111 system=yes" nodes
ansible -m group -a "name=eagles gid=111 state=absent" nodes

command模块

1.默认使用的模块
2.不支持管道,变量及重定向等

ansible-doc -s command - name: Executes a command on a
remote node

案例:

[root@ansible ~]# ansible -m command -a "ls ~/playbook" server1
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details
192.168.146.165 | CHANGED | rc=0 >>
conf
hosts.j2
hosts.yaml
nginx-virtualhost.yaml
test.j2
users.yaml

shell模块

1.调用bash执行命令
2.但是某些复杂的操作即使使用shell也可能会失败
解决方法:将操作写到脚本中,通过script模块

3.执行时给脚本x权限

[root@ansible ~]# ansible node1 -m shell -a "cat /etc/passwd | grep 'root'"
node1 | CHANGED | rc=0 >>
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

scrip模块

free_form参数 :必须参数,指定需要远程执行的命令,需要说明一点,free_form参数与其他参数并不相同,在之前的模块示例中,如果想要使用一个参数,那么则需要为这个参数赋值,举个例子,之前的示例模块中,大多都有path参数,当我们需要指定要操作的文件时,通常需要对path参数赋值,比如,path=/testdir/test,表示我们想要操作/testdir/test文件,但是free_form参数则不同,”free_form”并不是一个”实际存在”的参数名,比如,当我们想要在远程主机上执行ls命令时,我们并不需要写成”free_form=ls” ,这样写反而是错误的,因为并没有任何参数的名字是free_form,当我们想要在远程主机中执行ls命令时,直接写成ls即可,这就是free_form参数的含义,因为command模块的作用是执行命令,所以,任何一个可以在远程主机上执行的命令都可以被称为free_form,如果你还是不明白,看下面的小示例就行了。

chdir参数: 此参数的作用就是指定一个远程主机中的目录,在执行对应的脚本之前,会先进入到
chdir 参数指定的目录中。
creates参数: 使用此参数指定一个远程主机中的文件,当指定的文件存在时,就不执行对应脚本,可参
考 command 模块中的解释。
removes参数: 使用此参数指定一个远程主机中的文件,当指定的文件不存在时,就不执行对应脚本,可
参考 command 模块中的解释。
[root@ansible ~]# ansible -m script -a '/root/test.sh chdir=/tmp
creates=test2' server2


192.168.146.165 | SKIPPED


copy

[root@ansible ~]# ansible-doc -s copy
backup:在覆盖之前,将源文件备份,备份文件包含时间信息。
content:用于替代“src”,可以直接设定指定文件的值
dest:必选项。要将源文件复制到的远程主机的绝对路径
directory_mode:递归设定目录的权限,默认为系统默认权限
force:强制覆盖目的文件内容,默认为yes
others:所有的file模块里的选项都可以在这里使用
src:被复制到远程主机的本地文件,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归
复制
ansible -m copy -a "src=/本地文件 dest=/远程文件" nodes
  • 在创建文件时修改文件的属主和属组信息
[root@ansible ~]# ansible -m copy -a "src=/root/test1 dest=/root/test owner=root group=root" node1
  • 在传输文件时修改权限信息,并且备远程主机文件
[root@ansible ~]# ansible -m copy -a "src=/root/test1 dest=/root/test bakup=yes
mode=1777" node1
  • 创建一个文件并直接编辑文件
[root@ansible ~]# ansible -m copy -a "content='hello eagles\n' dest=/root/test1" server2

file模块

[root@ansible ~]# ansible-doc -s file
- name: Sets attributes of files
force:需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一
种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
group:定义文件/目录的属组
mode:定义文件/目录的权限
owner:定义文件/目录的属主
path:必选项,定义文件/目录的路径
recurse:递归设置文件的属性,只对目录有效
src:被链接的源文件路径,只应用于state=link/hard的情况
dest:被链接到的路径,只应用于state=link/hard的情况
state:
absent: 删除文件
directory:如果目录不存在,就创建目录
file:验证文件是否存在,即使文件不存在,也不会被创建
link:创建软链接
hard:创建硬链接
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其后修改时间
1.创建目录
[root@ansible ~]# ansible -m file -a "name=test1 owner=root group=root mode=1644 state=directory " server2
2.创建文件
[root@ansible ~]# ansible -m file -a "path=/root/test2 owner=root group=root mode=1644 state=touch" server2
3.删除文件
[root@ansible ~]# ansible -m file -a "path=/root/test2 owner=root group=root mode=1644 state=absent" server2
7.创建软链文件
[root@ansible ~]# ansible -m file -a "src=/root/test1 dest=/root/test2 state=link" server2
8.创建硬链接文件
[root@ansible ~]# ansible -m file -a "src=/root/test.txt dest=/root/test2 state=hard" server2


yum模块

[root@ansible ~]# ansible-doc -s yum
conf_file #设定远程yum安装时所依赖的配置文件。如配置文件没有在默认的位置。
disable_gpg_check #是否禁止GPG checking,只用于`present' or `latest'。
disablerepo #临时禁止使用yum库。 只用于安装或更新时。
enablerepo #临时使用的yum库。只用于安装或更新时。
name= #所安装的包的名称
state #present安装, latest安装新的, absent 卸载软件。
update_cache #强制更新yum的缓存

示列:

ansible -m yum -a "name=httpd 1 state=latest" nodes

service

[root@ansible ~]# ansible-doc service
> SERVICE (/usr/lib/python2.7/site-packages/ansible/modules/system/service.py)
Controls services on remote hosts. Supported init systems include BSD init,
OpenRC, SysV, Solaris
SMF, systemd, upstart. For Windows targets, use the [win_service] module
instead.
* note: This module has a corresponding action plugin.
arguments #命令行提供额外的参数
enabled #设置开机启动,可以设置为yes或者no。
name= #服务名称
runlevel #开机启动的级别,一般不用指定。
sleep #在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。
state #started启动服务, stopped停止服务, restarted重启服务, reloaded重载配置

示例:
设置开机自启动服务

ansible -m service -a "name=httpd state=started" server1

selinux模块

[root@ansible ~]# ansible-doc -s selinux
# selinux模块针对selinux的修改操作是针对配置文件进行修改的
- name: Change policy and state of SELinux
selinux:
configfile: # path to the SELinux configuration file, if non-standard
policy: # name of the SELinux policy to use
state: # (required) The SELinux mode
  • setup
ansible -m setup nodes #获取远程主机的详细信息

playbook

简介
playbook是由一个或者多个play组成的列表,可以让这些列表按事先编排的机制执行;所谓task是调用
ansible的具体模块,在模块参数中可以使用变量。模块执行是幂等性的,意味着多次执行结果相同。使 用
yaml语言编写playbook,后缀名一般为.yml
特点
yaml的可读性好
yaml和脚本语言的交互性好
yaml使用实现语言的数据类型
yaml有一个一致性的信息模型
yaml易于实现
yaml可以基于流来处理

核心组件

  • hosts:执行的远程主机列表
    tasks:任务,由模块定义操作列表
    variables:内置变量或者自定义变量
    templates:模板,定义模板文件,模板文件一般是由jinja2语言编写的
    handlers:和notity结合使用,为条件触发操作,满足条件则执行
    roles:角色
    Playbook语

Playbook语法

  • playbook 使用yaml 语法格式,后缀可以是yaml ,也可以是yml 。
    在单一一个playbook 文件中,可以连续三个连子号( — )区分多个play 。还有选择性的连续三个点好( … )用来表示play 的结尾,也可省略。
  • 次行开始正常写playbook 的内容,一般都会写上描述该playbook 的功能。
  • 使用#号注释代码。
  • 缩进必须统一,不能空格和tab 混用。

特点*

yaml语言的参考博客http://www.ruanyifeng.com/blog/2016/07/yaml.html

  • yaml的可读性好
  • yaml和脚本的交互性好
  • yaml使用实现语言的数据类型
  • yaml有一个一致性的信息模型
  • yaml易于实现
  • yaml可以给予流来处理

官方示例
官方文档: http://www.ansible.com.cn/docs/playbooks_intro.html
在线检测工具:http://www.yamllint.com/

---
- hosts: webservers
  vars:
    http_port: 80
    max_clients: 200
  remote_user: root
  tasks:
  - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest
 - name: write the apache config file
   template: src=/srv/httpd.j2 dest=/etc/httpd.conf
   notify:
   - restart apache
 - name: ensure apache is running
   service: name=httpd state=started
 handlers:
   - name: restart apache
     service: name=httpd state=restarted
常见变量
主机名: "{{ ansible_hostname }}"
操作系统版本: "{{ ansible_distribution }}" "{{ ansible_distribution_version
}}"
内核版本: "{{ ansible_kernel }}"
系统位数: "{{ ansible_userspace_bits }}"
网卡:"{{ ansible_eth0["device"] }}"
IP地址: "{{ ansible_eth0["ipv4"]["address"] }}"
子网掩码: "{{ ansible_eth0["ipv4"]["netmask"] }}"
总内存: "{{ ansible_memory_mb["real"]["total"] }}"
内存空闲: "{{ ansible_memfree_mb }}"

自定义剧本


安装httpd

[root@ansible ansible]# cat httpd_install.yml
- name: Configure Apache HTTP Server
  hosts: node1
  remote_user: root
  tasks:
    - name: Install httpd
      yum:
        name: httpd
        state: latest
    - name: Start httpd
      service:
        name: httpd
        state: started

  • 检查脚本格式
[root@ansible ansible]# ansible-playbook --syntax-check httpd_install.yml
playbook: httpd_install.yml

执行脚本

[root@ansible ansible]# ansible-playbook httpd_install.yml
PLAY [Configure Apache HTTP Server]
*******************************************************
TASK [Gathering Facts]
********************************************************************
ok: [node1]
TASK [Install httpd]
**********************************************************************
ok: [node1]
TASK [Start httpd]
************************************************************************
changed: [node1]
PLAY RECAP
********************************************************************************
node1 : ok=3 changed=1 unreachable=0 failed=0
skipped=0 rescued=0 ignored=0

定义网站内容

[root@ansible ansible]# cat template/index.j2
<h1>hello siri~</h1>
这是我的博客地址,欢迎大家学习ansible!
This web server is {{ ansible_hostname }}
[root@ansible ansible]# cat index.yml
- name: Configure Apache index file
  hosts: nodes
  remote_user: root
  tasks:
  - name: Copy index.j2 to nodes servers
    template:
      src: /ansible/template/index.j2
      dest: /var/www/html/index.html
  • 执行教本
[root@ansible ansible]# ansible-playbook --syntax-check httpd_install.yml
  • 验证
[root@ansible ansible]# curl node1
<h1>hello siri~</h1>
这是我的博客地址,欢迎大家学习ansible!
This web server is node1
[root@ansible ansible]# curl node2
<h1>hello siri~</h1>
这是我的博客地址,欢迎大家学习ansible!
This web server is node2

条件判断

  • 选择性关闭node1的apache服务
[root@ansible ansible]# cat httpd_stop.yml
- name: Stop httpd
  hosts: nodes
  remote_user: root
  
  tasks:
  - name: stop httpd
    service:
      name: httpd
      state: stopped
    when: ansible_hostname == "node1"
[root@ansible playbook]# ansible-playbook  httpd_stop.yml --syntax-check
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details

playbook: httpd_stop.yml

[root@ansible playbook]# ansible-playbook  httpd_stop.yml
[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details

PLAY [Stop httpd] ******************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************
ok: [192.168.146.165]

TASK [stop httpd] ******************************************************************************************************************************
skipping: [192.168.146.165]

PLAY RECAP *************************************************************************************************************************************
192.168.146.165            : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0 

循环迭代

  • 创建用户
[root@ansible ansible]# cat user_create.yml
- name: Create User
  hosts: node1
  remote_user: root
  tasks:
  - name: Create server users
    user:
      name: "{{ item.name }}"
      group: "{{ item.group }}"
      state: "present"
    with_items:
      - { name: 'zhangsan', group: 'wheel'}
      - { name: 'lisi', group: 'root'}
  • 案例二
[root@ansible playbook]# cat users.yaml 
- name: make user
  hosts: server2
  remote_user: root


  tasks:
  - name: cteate groups
    group:
      name: "{{ item.name }}"
    with_items:
      - { name: 'xsb' }
      - { name: 'jsb' }
      - { name: 'cwb' }
  - name: create users
    user:
      name: "{{ item.name }}"
      group: "{{ item.group }}"
      home: "{{ item.home }}"
      shell: "{{ item.shell }}"
      comment: "{{ item.comment }}"
      state: present
    with_items:
      - { name: 'zhangsan',group: 'xsb',home: '/home/xsb/zhangsan',shell: '/bin/bash',comment: '销售' }
      - { name: 'lisi',group: 'xsb',home: '/home/xsb/lisi',shell: '/bin/bash',comment: '销售' }
      - { name: 'wangwu',group: 'jsb',home: '/home/jsb/wangwu',shell: '/bin/sh',comment: 'linux工程师' }
      - { name: 'maliu',group: 'jsb',home: '/home/jsb/maliu',shell: '/bin/sh',comment: 'Java工程师' }
      - { name: 'zhaoqi',group: 'cwb',home: '/home/xsb/zhaoqi',shell: '/bin/sh',comment: '会计' }

安装nginx并且修改配置文件

[root@ansible playbook]# cat nginx-virtualhost.yaml 
- name: Update web server
  hosts: all-servers
  remote_user: root

  tasks:
  - name: install  epel-release.noarch 
    yum:
      name: epel-release.noarch 
      state: latest

  - name: updata nginx
    yum:
      name: nginx
      state: latest
  - name: copy nginx config file
    copy:
      src: /root/playbook/conf/site.conf
      dest: /etc/nginx/conf.d/site.conf
  - name: make web_dir
    shell: mkdir -p /usr/share/nginx/html/{bbs,blog,www}
  - name: create index.html
    shell: echo "bbs" > /usr/share/nginx/html/bbs/index.html && echo "blog" > /usr/share/nginx/html/blog/index.html && echo "www" > /usr/share/nginx/html/www/index.html
  - name: start nginx
    service:
      name: nginx
      state: restarted

  • 定义配置文件
[root@ansible conf]#  cat /esite1.conf
server {
listen *:8080;
server_name bbs.eagle.com;
location / {
root /usr/share/nginx/html/bbs;
index index.html;
}
}
server {
listen *:8080;
server_name blog.eagle.com;
location / {
root /usr/share/nginx/html/blog;
index index.html;
}
}
server {
listen *:8080;
server_name www.eagle.com;
location / {
root /usr/share/nginx/html/www;
index index.html;
}
}
[root@ansible conf]# pwd
/root/playbook/conf

  • 记得定义/etc/host/文件

roles介绍

角色(roles)是ansible自1.2版本开始引入的新特性,用于层次性,结构化地组织playbook。roles能够根据层
次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。
简单的说,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中、并可以便捷地
include他们的一种机制。角色一般用于基于主机构建服务的场景中、但也可以是用于构建守护进程等场景

*目录结构*
[root@ansible roles]# tree /etc/ansible/roles/
	/etc/ansible/roles/
├── http
│ ├── defaults
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── template
│ └── vars
├── mysql
├── redis
└── site.yaml

- tasks:此目录中至少有一个名为main.yaml文件,用于定义各种task,其他文件需要由
main.yaml文件进行调用
- handlers:此目录中至少有一个名为main.yaml文件,用于定义各种handler,其他文件需要被
main.yaml进行调用
- vars:此目录中至少有一个名为main.yaml文件,用于定义各种变量,其他文件需要被main.yaml
进行调用
- templates:存储template模块调用的模板文件
- meta:此目录中至少有一个名为main.yaml文件,定义当前角色的设定及其依赖关系,其他的文件
需要被main.yaml文件进行调用
- default:此目录中至少有一个main.yaml文件,用于设定默认的值
- files:此目录存放copy或者script等模块调用的文件

案例介绍,使用角色安装httpd:

第一步,准备相关目录,init初始化

[root@server1 roles]# ansible-galaxy init httpd
- Role httpd was created successfully
[root@server1 tasks]# tree -a /etc/ansible/roles/
/etc/ansible/roles/
├── http
│ ├── defaults
│ │ └── main.yaml
│ ├── files
│ ├── handlers
│ │ └── main.yaml
│ ├── meta
│ │ └── main.yaml
│ ├── tasks
│ │ └── main.yaml
│ ├── template
│ └── vars
├── mysql
├── redis
└── site.yaml

第二步书写site.yaml文件

[root@eagle tasks]# cat /etc/ansible/roles/site.yaml
- hosts: node2
  remote_user: root
  roles:
  	- http

第三步,书写tasks里的main.yaml文件

[root@server1 tasks]# cat main.yaml
- name: Install httpd
  yum:
	name: httpd
	state: present
- name: Start httpd
  service:
	name: httpd
	state: restarted
- name: Write conf file
  shell: echo "httpd2" > /var/www/html/index.html
- name: Curl web
  shell: curl 192.168.80.20

验证语法

[root@server1 roles]# ansible-playbook site.yaml --syntax-check
[root@eagle tasks]# ansible-playbook /etc/ansible/roles/site.yaml
#验证结果
[root@eagle tasks]# curl 192.168.80.20
httpd2

角色参考案例,安装halo博客:https://www.wumingx.com/linux/ansible-roles.html

使用role的方式来安装halo,相对来说,结构会比较清晰明了。还是使用ansible去自动部署halo博客系
统。功能很简单,就是在一台机器上面自动部署java+halo+nginx服务

  • 准备角色
[root@server1 roles]# ansible-galaxy init halo
- Role halo was created successfully
[root@server1 roles]# ansible-galaxy init java
- Role java was created successfully
[root@server1 roles]# ansible-galaxy init nginx
- Role nginx was created successfully
  • 编写site.yaml,pre_tasks为运行play之前执行的任务,post_tasks为运行play之后执行的任务

    [root@server1 roles]# cat /etc/ansible/roles/site.yaml 
    ---
      - hosts: www.guoheng.cn
        remote_user: root
        strategy: free
        pre_tasks:
          - name: config nginx repo for centos 7
            yum_repository:
              name: nginx
              description: nginx
              baseurl: http://nginx.org/packages/centos/$releasever/$basearch/
              gpgcheck: no
            when: ansible_distribution_major_version == "7"
          - name: Disable SELinux
            selinux: state=disabled
    
        roles:
          - nginx
    
        post_tasks:
          - shell: echo 'Deplay halo finished.'
            register: ret
          - debug: var=ret.stdout
    
    
  • 编写nginx角色

    [root@server1 roles]# cat nginx/tasks/main.yml
    ---
    # tasks file for nginx
      - name: make sure nginx state is installed
        yum: name=nginx state=installed
      - name: copy halo to nginx config file
        template: src=halo.conf dest="/etc/nginx/conf.d/halo.conf"
      - name: make sure nginx service is running
        service: name=nginx state=started
      - name: make sure port is open
        wait_for: port="{{ nginx_port }}"
    # meta/main.yml为role的依赖关系,要先运行这里面的内容才会运行自己的nginx这个role。
    [root@server1 roles]# cat nginx/meta/main.yml | grep -Ev  "#|^$"
    galaxy_info:
      author: your name
      description: your role description
      company: your company (optional)
      license: license (GPL-2.0-or-later, MIT, etc)
      min_ansible_version: 2.9
      galaxy_tags: []
    dependencies:
      - role: java
      - role: halo
    
    
    [root@server1 roles]# cat nginx/templates/halo.conf
    server {
        listen 80;
    
        server_name {{ halo_domain }};
    
        client_max_body_size 1024m;
    
        location / {
            proxy_set_header HOST $host;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
            proxy_pass http://127.0.0.1:{{halo_port}}/;
        }
    }
    
    
  • 编写java角色

    [root@server1 roles]# cat java/tasks/main.yml
    ---
    # tasks file for java
      - name: install java
        yum: name=java-11-openjdk state=installed
    
    
  • 编写halo角色

    [root@server1 roles]# cat halo/tasks/main.yml
    ---
    # tasks file for halo
      - name: get halo
        get_url: url=https://dl.halo.run/release/halo-1.4.12.jar dest={{ halopath }}
    
      - name: add halo service file
        template: src=halo.service dest=/etc/systemd/system/halo.service
    
      - name: touch ~/.halo directory
        file: path=~/.halo state=directory
    
      - name: copy halo config file
        template: src=application.yaml dest="~/.halo/application.yaml"
    
      - name: restart halo
        systemd:
          daemon_reload: yes
          name: halo
          state: started
          enabled: yes
    
      - name: wait to start halo
        wait_for: port={{ halo_port }}
    
    
    [root@server1 roles]# cat halo/vars/main.yml
    ---
    # vars file for halo
      memory: 512m
      halo_port: 8090
      halopath: /root/halo.jar
      halo_domain: 139.196.11.216
      nginx_port: 80
    # 下载service文件并编辑
    [root@server1 roles]# wget https://dl.halo.run/config/halo.service -O
    halo/templates/halo.service
    
    [root@server1 roles]# cat halo/templates/halo.service
    [Unit]
    Description=Halo Service
    Documentation=https://docs.halo.run
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=simple
    User=root
    ExecStart=/usr/bin/java -server -Xms256m -Xmx256m -jar /root/halo.jar
    ExecStop=/bin/kill -s QUIT $MAINPID
    Restart=always
    StandOutput=syslog
    
    StandError=inherit
    
    [Install]
    WantedBy=multi-user.target
    
    [root@server1 roles]# wget https://dl.halo.run/config/applicationtemplate.
    yaml -O halo/templates/application.yaml
    
  • 运行site.taml

    [root@server1 roles]# ansible-playbook site.yaml
    

port={{ halo_port }}


```shell
[root@server1 roles]# cat halo/vars/main.yml
---
# vars file for halo
  memory: 512m
  halo_port: 8090
  halopath: /root/halo.jar
  halo_domain: 139.196.11.216
  nginx_port: 80
# 下载service文件并编辑
[root@server1 roles]# wget https://dl.halo.run/config/halo.service -O
halo/templates/halo.service
[root@server1 roles]# cat halo/templates/halo.service
[Unit]
Description=Halo Service
Documentation=https://docs.halo.run
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
ExecStart=/usr/bin/java -server -Xms256m -Xmx256m -jar /root/halo.jar
ExecStop=/bin/kill -s QUIT $MAINPID
Restart=always
StandOutput=syslog

StandError=inherit

[Install]
WantedBy=multi-user.target

[root@server1 roles]# wget https://dl.halo.run/config/applicationtemplate.
yaml -O halo/templates/application.yaml
  • 运行site.taml

    [root@server1 roles]# ansible-playbook site.yaml
    
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值