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 9月 11 09:54 id_rsa
-rw-r--r-- 1 root root 394 9月 11 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.174.10 192.168.174.20 192.168.174.30 [server1] 192.168.174.10 [server2] 192.168.174.20 [server3] 192.168.174.30
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.174.10 | 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.174.10 | 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笔记(12):handlers的用法:https://www.zsythink.net/archives/2624/
常见变量
主机名: "{{ 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