Ansible自动化运维工具 —— Playbook 剧本

news2024/11/27 13:41:42

playbooks 本身由以下各部分组成
(1)Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行
(2)Variables:变量
(3)Templates:模板
(4)Handlers:处理器,当changed状态条件满足时,(notify)触发执行的操作
(5)Roles:角色

playbook 剧本 总结

vim  XXX.yaml

- name:                      #指定play名称
  hosts:                     #指定主机组
  remote_user:               #执行用户 
  gather_facts: true|false   #是否收集远程主机facts信息
  vars:                      #定义变量
  tasks:                     #定义task任务列表
  - name:                 #定义task任务名称
    模块:                 #定义任务使用的模块和参数
    with_items:           #定义循环列表
    when:                 #定义判断条件(== != >= > <= <),true则执行任务,否则不执行任务
    ignore_errors: true   #忽略任务失败
    notify:               #定义task任务changed状态时触发的任务名
    tags:                 #指定标签,ansible-playbook --tags 仅执行拥有指定 tags 标签的任务(always标签总会执行)
  handlers:                  #定义notify触发的任务列表

task任务 模块语法格式

模块名: 参数选项1=值  参数选项2={{变量名}}  ...

模块名:
  参数选项1: 值
  参数选项2: "{{变量名}}"
  ...

with_items 和 变量 的语法格式

with_items: ["值1", "值2", "值3"]

with_items:
- 值1
- 值2
- 值3

值为对象(键值对字段)时:

with_items:
- {key1: value1, key2: value2, ...}
- {key1: value3, key2: value4, ...}


with_items:
- key1: value1
  key2: value2
- key1: value3
  key2: value4

template模板模块
1)先要准备一个 xxx.j2 模板文件,在文件中使用 {{变量名}} 引用主机变量 或者 vars 自定义的变量 及 facts 字段的值
2)在 playbook 中的 tasks 中定义 template 模板配置  template: src=xxx.j2  dest=xxx
 

实验

架构

192.168.80.101 ansible

192.168.80.102 被控服务器

192.168.80.103 被控服务器

/etc/ansible/hosts配置如下

cat /etc/ansible/hosts

示例1 安装httpd服务

mkdir -p /etc/ansible/playbook/
cp /etc/httpd/conf/httpd.conf /etc/ansible/playbook/httpd.conf
#本机的httpd配置复制到ansible目录。可以自定义位置,在下面yaml更改对应位置即可。
vim /etc/ansible/playbook/test1.yaml

---     #yaml文件以---开头,以表明这是一个yaml文件,可省略。
        #若文件中存在多个--- 则代表有多个yaml配置文件存在于同一个文件中
- name: the first play for install apache     #定义一个play的名称,可省略
  gather_facts: false    #设置不进行facts信息收集,这可以加快执行速度,可省略
  hosts: webservers    #指定要执行任务的被管理主机组,如多个主机组用冒号分隔
  remote_user: root    #指定被管理主机上执行任务的用户
  tasks:     #定义任务列表,任务列表中的各任务按次序逐个在hosts中指定的主机上执行
   - name: test connection    #自定义任务名称
     ping:     #使用 module: [options] 格式来定义一个任务
   - name: disable selinux
     command: '/sbin/setenforce 0'    #command模块和shell模块无需使用key=value格式
     ignore_errors: True     #如执行命令的返回值不为0,就会报错,tasks停止,可使用ignore_errors忽略失败的任务。
			     #这里需要忽略是因为如果selinux已经关闭再次关闭会返回1
   - name: disable selinux forever
     replace: path=/etc/selinux/config  regexp="enforcing"  replace="disabled"
   - name: disable firewalld
     service: name=firewalld state=stopped enabled=no    #使用 module: options 格式来定义任务,option使用key=value格式
#======================================================================================================================
# 若想要挂载光盘使用本地yum源安装(需要在控制服务器存在/etc/yum.repos.d/repo.bak/local.repo配置文件)可以省略
   - name: mount cdrom
     mount: src=/dev/sr0 path=/mnt fstype=iso9660 state=mounted
   - name: copy local yum configuration file
     copy: src=/etc/yum.repos.d/repo.bak/local.repo  dest=/etc/yum.repos.d/local.repo
#======================================================================================================================
   - name: install httpd
     yum: name=httpd state=latest
   - name: prepare httpd configuration file
     copy: src=/etc/ansible/playbook/httpd.conf dest=/etc/httpd/conf/httpd.conf #这里需要一个事先准备好的/opt/httpd.conf文件
     notify: "restart httpd" ##如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作
   - name: start apache httpd
     service: name=httpd state=started enabled=yes
  handlers:     #handlers中定义由notify触发的任务
   - name: restart httpd    #notify和handlers中任务的名称必须一致。注意reload不能让httpd重新加载配置文件中端口等配置,只能restart
     service: name=httpd state=restarted

##Ansible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler
##这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启。


//运行playbook

ansible-playbook test1.yaml

//补充参数:
-k(–ask-pass):用来交互输入ssh密码
-K(-ask-become-pass):用来交互输入sudo密码
-u:指定用户

ansible-playbook test1.yaml --syntax-check    #检查yaml文件的语法是否正确
ansible-playbook test1.yaml --list-task       #检查tasks任务
ansible-playbook test1.yaml --list-hosts      #检查生效的主机
ansible-playbook test1.yaml --start-at-task='install httpd'     #指定从某个task开始运行

 

定义、引用变量

vim /etc/ansible/playbook/test2.yaml

- name: second play
  hosts: dbservers
  remote_user: root
  #remote_user: zhangsan
  #become: yes #这三行代表 远程控制时 使用的普通用户zhangsan提升权限使用root用户
  #become_user: root #需要先修改sudo配置/etc/sudoers使zhangsan用户可以使用sudo提权
  vars:                 #定义变量
   - groupname: mysql   #格式为 key: value
   - username: nginx
   - filename: /opt/123.txt
  gather_facts: true #可以不写 默认开启
  tasks:
   - name: create group
     group: name={{groupname}} system=yes gid=2800    #使用 {{key}} 引用变量的值 system为默认项可以省略不写不影>响
   - name: create user
     user: name={{username}} uid={{uid}} group={{groupname}} #uid并未写在var中,由外部命令执行时传参
   - name: copy file
     #copy: content="{{ansible_default_ipv4}}" dest={{filename}}     #在setup模块中可以获取facts变量信息 这里获>取ipv4块所有信息
     copy: content="{{ansible_default_ipv4.address}}" dest={{filename}}     #在setup模块中可以获取facts变量信息 这里获取ipv4块中address一项信息
   - name: modify username and groupname of file
     file: path={{filename}} owner={{username}}  group={{groupname}}
ansible-playbook test2.yaml -e "username=nginx2" -e "uid=1234"
#在命令行里定义变量 命令行内指定的参数优先级更高可以覆盖playbook var内写的变量

可看到命令行的传参username覆盖了playbook中定义的变量,并且uid也传参进去,其余参数都从playbook中已经定义的var变量中取 



指定远程主机sudo切换用户

在上面的脚本做修改

额外注意在 /etc/ansible/hosts 组变量中是否已经指定了 用户等参数!优先级:命令行传参>host组定义>playbook中定义变量

若host组中已经规定了用户,playbook中的用户设置,become提权等可能被覆盖不会生效!

---
- hosts: dbservers
  remote_user: zhangsan            
  become: yes                    #2.6版本以后的参数,之前是sudo,意思为切换用户运行
  become_user: root              #指定sudo用户为root

运行前需要先在被控制的远程主机上创建zhangsan用户,并修改sudo配置使zhangsan用户可以使用sudo提权,才能在playbook中使用become 使用root用户

adduser zhangsan
passwd zhangsan

vim /etc/sudoers
    zhangsan ALL=ALL

执行playbook,原先命令上附加上 -k -K参数

ansible-playbook test2.yaml  -e "username=nginx3" -e "uid=1357" -k -K
 -k -K
-k(–ask-pass):用来交互输入ssh密码
-K(-ask-become-pass):用来交互输入sudo密码 都输入zhangsan密码即可
-u:指定用户

 

when条件判断

在Ansible中,提供的唯一一个通用的条件判断是when指令,当when指令的值为true时,则该任务执行,否则不执行该任务。

when一个比较常见的应用场景是实现跳过某个主机不执行任务或者只有满足条件的主机执行任务

vim /etc/ansible/playbook/test3.yaml

---
- name: third play
  hosts: all
  remote_user: root
  tasks:
   - name: touch file
     file: path=/opt/1.txt state=touch #创建文件
     #command: /sbin/shutdown/ -r now  #重启指令
     when: inventory_hostname == "192.168.80.102"
       #写法1 inventory_hostname为主机清单 /etc/ansible/hosts的主机名
     #when: ansible_default_ipv4.address != "192.168.80.103" 
       #写法2 ansible_default_ipv4.address为gather_facts获取的主机信息    != 含义为除了103主机
     #when指令中的变量名不需要手动加上 {{}} 
ansible-playbook test3.yaml

迭代(循环) with_items

Ansible提供了很多种循环结构,一般都命名为with_items,作用等同于 loop 循环。

with_items普通取值  写法演示

vim /etc/ansible/playbook/test4.yaml

#😊with_items普通取值
---
- name: fouth play
  hosts: dbservers
  remote_user: root
##############################################################################
  vars:
    myfile:
    - /opt/a
    - /opt/b
    - /opt/c
    - /opt/d
  tasks:
  - name: touch directory #✨方法1 预先编写var变量,随后赋值给with_items
    with_items: "{{myfile}}"
    file: path={{item}} state=directory #🧯模组 横向写法
##############################################################################
  - name: touch file 1    #✨方法2 直接在with_items中定义
    file:                               #🧯模组 纵向写法
      path: "{{item}}"
      state: touch
    with_items:                                        #🔥with_items纵向写法
    - /root/a
    - /root/b
    - /root/c
    - /root/d

  - name: touch file 2
    file:                               #🧯模组 纵向写法
      path: "{{item}}"
      state: touch
    with_items: [ /opt/aa, /opt/bb, /opt/cc, /opt/dd ] #🔥with_items横向写法

with_items——值为对象(键值对字段) 写法演示

vim /etc/ansible/playbook/test5.yaml

#😊with_items——值为对象(键值对字段)
---
- name: fifth play
  hosts: dbservers
  remote_user: root
  tasks:
  - name: touch file
    with_items: #✨with_items(键值对字段对象)横向写法
    - {filename: /opt/afile, username: xue, groupname: xue}
    - {filename: /opt/bfile, username: zhangsan, groupname: zhangsan}
        #当值为对象(键值对字段)引用值需要像item.filename指定对象中的某个字段
    file: path={{item.filename}}  owner={{item.username}} group={{item.groupname}} state=touch #模块 横向写法

  - name: create dir
    with_items: #✨with_items(键值对字段对象)纵向写法
    - filename: /opt/cfile
      username: xue
      groupname: xue
    - filename: /opt/dfile
      username: zhangsan
      groupname: zhangsan
    file: #模块 纵向写法
      path: "{{item.filename}}"
      owner: "{{item.username}}"
      group: "{{item.groupname}}"
      state: directory

  


执行playbook test4

ansible-playbook test4.yaml


 执行playbook test5

由于playbook中指定了用户与组,需要在被控制的远程主机创建
adduser xue
adduser zhangsan

 查看用户 与 组 信息(playbook中指定的{filename: /opt/afile, username: xue, groupname: xue}一定要与系统中的用户—组对应关系相匹配!不然报错)

 

在ansible服务器运行
ansible-playbook test5.yaml

Templates 模块

Jinja是基于Python的模板引擎。Template类是Jinja的一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递Python的变量给模板去替换模板中的标记。

1)先要准备一个 xxx.j2 模板文件,在文件中使用 {{变量名}} 引用主机变量 或者 vars 自定义的变量 及 facts 字段的值
2)在 playbook 中的 tasks 中定义 template 模板配置  template: src=xxx.j2  dest=xxx

1.先准备一个以 .j2 为后缀的 template 模板文件,设置引用的变量

cp /etc/httpd/conf/httpd.conf /etc/ansible/playbook/httpd.conf.j2
vim /etc/ansible/playbook/httpd.conf.j2

Listen {{http_port}}                 #42行
ServerName {{server_name}}           #95行
DocumentRoot "{{root_dir}}"          #119行

2.修改主机清单文件,定义变量,用于传参给模版

vim /etc/ansible/hosts

[webservers]
192.168.80.102 http_port=192.168.80.102:80 server_name=www.ws1.com:80 root_dir=/var/www/html/webserver1
192.168.80.103 http_port=192.168.80.103:80 server_name=www.ws2.com:80 root_dir=/var/www/html/webserver2

3.编写 playbook,在其中引用第一步定义的template模版。运行时host文件变量会传给playbook yaml配置文件再传参给模版。

根据不同host ip为不同的服务器生成指定的配置文件。

vim /etc/ansible/playbook/test6.yaml

- name: sixth play
  hosts: webservers
  remote_user: root
  vars:
  - pkgname: httpd

  tasks:
  - name: install apache
    yum: name=httpd state=latest

    #创建webserver1 webserver2文件夹(此处直接在每个主机上都创建这两个文件夹,可以指定when不同ip做更细分优化)
  - name: create root dir
    file: state=directory path={{item}}
    with_items:
    - /var/www/html/webserver1
    - /var/www/html/webserver2

    #根据不同ip生成不同页面
  - name: create index.html in www.ws1.com
    copy: content="<h1>this is web1</h1>" dest=/var/www/html/webserver1/index.html
    when: ansible_default_ipv4.address == "192.168.80.102"
  - name: create index.html in www.ws2.com
    copy: content="<h1>this is web2</h1>" dest=/var/www/html/webserver2/index.html
    when: inventory_hostname == "192.168.80.103"

    #引用template模板,生成配置后触发restart 
  - name: prepare configuration file
    template: src=/etc/ansible/playbook/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
    notify: "restart apache" 
    #本处可以为reload也可以为restart。虽然触发项最后才执行,会在start后reload。
    #但是实测可能是由于start需要时间,reload第一次运行会报错,第二次运行httpd完全启动后才正常。
    #所以直接使用restart,即使未启动restart也会直接执行start不报错。
         #后续补充:restart 似乎也需要执行两次,应该也与触发项或是启动时间有关

  - name: start apache
    service: name={{pkgname}} state=started enabled=yes

  handlers:
  - name: reload apache
    service: name={{pkgname}} state=reloaded
ansible-playbook test6.yaml

 

tags 模块

可以在一个playbook中为某个或某些任务定义“标签”,在执行此playbook时通过ansible-playbook命令使用--tags选项能实现仅运行指定的tasks。
playbook还提供了一个特殊的tags为always。作用就是当使用always作为tags的task时,无论执行哪一个tags时,定义有always的tags都会执行。

vim /etc/ansible/playbook/test7.yaml

- name: seventh play
  hosts: dbservers
  remote_user: root
  tasks:
  - name: create together-do.txt
    file: path=/opt/together-do.txt state=touch
    tags:
    - xiaoming_do_it
    - xiaohong_do_it

  - name: create always-do.txt
    file: path=/opt/always—do.txt state=touch
    tags:
    - always

  - name: create xiaohong-do.txt
    copy: content="0721" dest=/opt/xiaohong—do.txt
    tags:
    - xiaohong_do_it
ansible-playbook test7.yaml --tags="xiaoming_do_it"
#执行 tag:xiaoming与always

 

ansible-playbook test7.yaml --tags="xiaohong_do_it"
#执行 tag:xiaohong与always

Roles 模块

roles用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令引入即可。
简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷的include它们的一种机制。roles一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。主要使用场景代码复用度较高的情况下。

roles 角色 的作用?

把playbook剧本里的各个play看作为角色,将各个角色的tasks任务、vars变量、templates模板、files文件等内容放置到角色的目录中统一管理,需要的时候可在playbook中直接使用roles调用,所以roles可以实现playbook代码的复用。

roles 的目录结构

cd /etc/ansible/
tree roles/

roles/
├── httpd/                 #相当于 playbook 中的 每一个 play 主题,目录名即为角色名
│   ├── files/                  #存放copy 模块或 script 模块调用的文件
│   ├── templates/              #存放template 模块调用的jinjia2 模板文件
│   ├── tasks/main.yml          #定义此角色的任务列表
│   ├── handlers/main.yml       #定义此角色通过notity触发条件时执行的任务列表
│   ├── vars/main.yml           #定义此角色用到的自定义变量
│   ├── defaults/main.yml       #定义此角色用到的设定默认变量(一般不用)
│   └── meta/main.yml           #定义此角色的元数据信息
└── mysql/
    ├── files/
    ├── templates/
    ├── tasks/
    ├── handlers/
    ├── vars/
    ├── defaults/
    └── meta/

●files
用来存放由 copy 模块或 script 模块调用的文件。

●templates
用来存放 jinjia2 模板,template 模块会自动在此目录中寻找 jinjia2 模板文件。

●tasks
此目录应当包含一个 main.yml 文件,用于定义此角色的任务列表,此文件可以使用 include 包含其它的位于此目录的 task 文件。

●handlers
此目录应当包含一个 main.yml 文件,用于定义此角色中触发条件时执行的动作。

●vars
此目录应当包含一个 main.yml 文件,用于定义此角色用到的变量。

●defaults
此目录应当包含一个 main.yml 文件,用于为当前角色设定默认变量。 这些变量具有所有可用变量中最低的优先级,并且可以很容易地被任何其他变量覆盖。所以生产中我们一般不在这里定义变量

●meta
此目录应当包含一个 main.yml 文件,用于定义此角色的元数据信息及其依赖关系。

在一个 playbook 中使用 roles的步骤

(1)创建以 roles 命名的目录

mkdir /etc/ansible/roles/ -p
#yum装完默认就有

(2)创建全局变量目录(可选)

mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all
#文件名自己定义,引用的时候注意

(3)在 roles 目录中分别创建以各角色名称命名的目录,如 httpd、mysql

mkdir /etc/ansible/roles/httpd
mkdir /etc/ansible/roles/mysql

(4)在每个角色命名的目录中分别创建files、handlers、tasks、templates、meta、defaults和vars目录,用不到的目录可以创建为空目录,也可以不创建

mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta}

(5)在每个角色的 handlers、tasks、meta、defaults、vars 目录下创建 main.yml 文件,千万不能自定义文件名

touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml

(6)修改 site.yml 文件,针对不同主机去调用不同的角色

vim /etc/ansible/site.yml
---
- hosts: webservers
  remote_user: root
  roles:
     - httpd
- hosts: dbservers
  remote_user: root
  roles:
     - mysql

(7)运行 ansible-playbook

cd /etc/ansible
ansible-playbook site.yml

示例:安装分布式LNMP架构web服务器

创建工作目录
mkdir /etc/ansible/roles/nginx/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta} -p

touch /etc/ansible/roles/nginx/{defaults,vars,tasks,meta,handlers}/main.yaml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yaml
touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yaml
编辑主机列表
vim /etc/ansible/hosts

[webservers]
192.168.80.101

[mysqlservers]
192.168.80.102

[phpservers]
192.168.80.103
创建playbook,包含roles
vim /etc/ansible/playbook/lnmp.yaml

- name: nginx play
  hosts: webservers
  remote_user: root
  roles:
    - nginx

- name: php play
  hosts: phpservers
  remote_user: root
  roles:
    - php

- name: mysql play
  hosts: mysqlservers
  remote_user: root
  roles:
    - mysql

 

role:nginx

vars (变量)

vim /etc/ansible/roles/nginx/vars/main.yaml

http_port: 192.168.80.101:80
http_hostname: www.xue.com
root_dir: /usr/share/nginx/html
php_remote: 192.168.80.103:9000
pkg: nginx
service: nginx

tasks (任务)

vim /etc/ansible/roles/nginx/tasks/init.yaml

- name: disable firewalld
  service: name=firewalld  state=stopped  enabled=no

- name: disable selinux
  shell: "/usr/sbin/setenforce 0"
  ignore_errors: true
vim /etc/ansible/roles/nginx/tasks/main.yaml

- include: "init.yaml"

- name: copy nginx yum repo file
  copy: src=nginx.repo  dest=/etc/yum.repos.d/

- name: install nginx
  yum: name={{pkg}}  state=latest

- name: copy index.php
  unarchive: src=/etc/ansible/roles/nginx/files/wordpress-4.9.4-zh_CN.tar.gz dest={{root_dir}} copy=yes

- name: copy nginx template configuration file
  template: src=default.conf.j2  dest=/etc/nginx/conf.d/default.conf
  notify: reload nginx

- name: start nginx
  service: name={{service}} state=started enabled=yes

handles (task中触发器)

vim /etc/ansible/roles/nginx/handlers/main.yaml

- name: reload nginx
  service: name={{service}}  state=reloaded

files (文件)

vim /etc/ansible/roles/nginx/files/nginx.repo

nginx.repo 用于yum下载nginx。
也可以不使用这个方法用不着准备这个文件,直接yum install epel 更新epel源

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
准备 WordPress论坛安装包 
(不一定要藏这么深的文件夹,只要脚本中对应上路径即可。为了显示file文件夹的作用,就放在这里)

/etc/ansible/roles/nginx/files/wordpress-4.9.4-zh_CN.tar.gz

templates(模版 用于给nginx服务器生成配置)

vim /etc/ansible/roles/nginx/templates/default.conf.j2

server {
    listen       {{http_port}};
    server_name  {{http_hostname}};

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   {{root_dir}};
        index  index.php index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        root           {{root_dir}};
        fastcgi_pass   {{php_remote}};
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  {{root_dir}}$fastcgi_script_name;
        include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}
role:mysql

 vars (变量)

vim /etc/ansible/roles/mysql/vars/main.yaml

http_port: 192.168.80.101:80
http_hostname: www.xue.com
root_dir: /usr/share/nginx/html
php_remote: 192.168.80.103:9000
pkg: nginx
service: nginx

tasks (任务)

vim /etc/ansible/roles/mysql/tasks/init.yaml

- name: disable firewalld
  service: name=firewalld  state=stopped  enabled=no

- name: disable selinux
  shell: "/usr/sbin/setenforce 0"
  ignore_errors: true
vim /etc/ansible/roles/mysql/tasks/main.yaml

- name: yum uninstall mariadb*
  yum: name=mariadb* state=absent

- name: wget mysql
  shell: wget -i -c http://repo.mysql.com/mysql57-community-release-el7-11.noarch.rpm -P /etc/yum.repos.d

- name: rpm mysql57-community-release
  shell: rpm -ivh /etc/yum.repos.d/mysql57-community-release-el7-11.noarch.rpm
  ignore_errors: True

- name: turn off yum gpgcheck
  replace: path=/etc/yum.repos.d/mysql-community.repo regexp='gpgcheck=1' replace='gpgcheck=0'

- name: yum install mysql
  yum: name=mysql-server

- name: start and enable mysql
  service: enabled=true name=mysqld.service state=started

- name: get passwd from log
  shell: grep "password" /var/log/mysqld.log | awk 'NR==1{print $NF}'
  register: mysql_password   #将获取的密码导入到mysql_password的变量中
- name: echo passwd
  debug:    
   msg: "{{ mysql_password }}"           #输出变量mysql_password的值
#grep "password" /var/log/mysqld.log     #在日志文件中找出root用户的初始密码
#2021-07-31T07:55:00.366359Z 1 [Note] A temporary password is generated for root@localhost: ga7%<d<0*jD&
#grep "password" /var/log/mysqld.log | awk '{print $NF}'

#临时密码修改
- name: grant location
  shell:  mysql --connect-expired-password -uroot -p"{{ mysql_password['stdout'] }}" -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'Admin@123';"
  ignore_errors: True
#授予root用户所有权限 
- name: grant option
  shell: mysql --connect-expired-password -uroot -pAdmin@123 -e "grant all privileges on *.* to 'root'@'%' identified by 'Admin@123456' with grant option;"
  ignore_errors: True
#创建wordpress数据库
- name: create database
  shell: mysql --connect-expired-password -uroot -pAdmin@123 -e "create database wordpress;"
  ignore_errors: True
#赋予mywordpress用户访问wordpress的权限(本地权限与远程权限)
- name: grant
  shell: mysql --connect-expired-password -uroot -pAdmin@123 -e "grant all on wordpress.* to 'admin'@'%' identified by 'mywordpress@123456';"
  ignore_errors: True
- name: grant
  shell: mysql --connect-expired-password -uroot -pAdmin@123 -e "grant all on wordpress.* to 'admin'@'localhost' identified by 'mywordpress@123456';"
  ignore_errors: True
#刷新权限
- name: flush privileges
  shell: mysql --connect-expired-password -uroot -pAdmin@123 -e 'flush privileges;'
  ignore_errors: True

- name: yum uninstall mariadb*
  yum: name=mysql57-community-release-el7-11.noarch.rpm state=absent
  #为了防止每次yum操作都会自动更新,卸载这个软件

role:php

vars (变量)

vim /etc/ansible/roles/php/vars/main.yaml

timezone: Asia/Shanghai
user_name: php
http_port: 192.168.80.103:9000
nginx_addr: 192.168.80.101
root_dir: /usr/share/nginx/html
service: php-fpm

tasks (任务)

vim /etc/ansible/roles/php/tasks/init.yaml

- name: disable firewalld
  service: name=firewalld  state=stopped  enabled=no

- name: disable selinux
  shell: "/usr/sbin/setenforce 0"
  ignore_errors: true
vim /etc/ansible/roles/php/tasks/main.yaml

- include: "init.yaml"

- name: install yum repo
  shell: "rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm && rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm"
  ignore_errors: True

- name: install php
  with_items:
  - php72w
  - php72w-cli
  - php72w-common
  - php72w-devel
  - php72w-embedded
  - php72w-gd
  - php72w-mbstring
  - php72w-pdo
  - php72w-xml
  - php72w-fpm
  - php72w-mysqlnd
  - php72w-opcache
  yum: name={{item}}

- name: create php user
  user: name={{user_name}}

- name: crate web root dir
  file: name={{root_dir}} state=directory

- name: copy index.php
  unarchive: src=/etc/ansible/roles/nginx/files/wordpress-4.9.4-zh_CN.tar.gz dest={{root_dir}} copy=yes

- name: modify php configuration file
  replace: path=/etc/php.ini  regexp=";date.timezone ="  replace="date.timezone = Asia/Shanghai"
  notify: reload php

- name: modify username and groupname in www.conf
  replace: path=/etc/php-fpm.d/www.conf  regexp="apache"  replace="{{user_name}}"
  notify: reload php

- name: modify listen addr in www.conf
  replace: path=/etc/php-fpm.d/www.conf  regexp="127.0.0.1:9000"  replace="{{http_port}}"
  notify: reload php

- name: modify allowed client in www.conf
  replace: path=/etc/php-fpm.d/www.conf  regexp="127.0.0.1"  replace="{{nginx_addr}}"
  notify: reload php

- name: start php
  service: name={{service}} state=started enabled=yes

handles (task中触发器)

vim /etc/ansible/roles/php/handlers/main.yaml

- name: reload php
  service: name={{service}} state=reloaded

配置密钥对验证 免交互登录

ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa

yum install -y sshpass
sshpass -p '密码' ssh-copy-id -o StrictHostKeyChecking=no root@192.168.80.102
sshpass -p '密码' ssh-copy-id -o StrictHostKeyChecking=no root@192.168.80.102
sshpass -p '密码' ssh-copy-id -o StrictHostKeyChecking=no root@192.168.80.103

执行 

ansible-playbook /etc/ansible/playbook/lnmp.yaml

 访问http://192.168.80.101/wordpress/index.php

故障处理

出现这种情况,由于是分布式部署lnmp,与单机不同,分布式部署必须在php服务器和nginx服务器上都存在相同的html目录以及其中的内容。

本次只在NGINX的html存放了WordPress论坛文件,而没有创建php服务器的文件夹,导致出错


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/818789.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu16.04忘记密码了怎么办,亲测有效

由于装载Ubuntu系统的电脑&#xff08;非虚拟机&#xff09;好久没有用&#xff0c;忘记了密码&#xff0c;只能进行密码重置&#xff0c;亲测有效&#xff1a; 1.首先ubuntu系统开机&#xff0c;期间按着shift键不放&#xff0c;选择高级选项。 2.enter键进入如下界面&#x…

python-occ入门指北

0、系统环境: Win10 在Windows环境中玩PythonOCC比较简单的方式是使用anaconda的cmd prompt或者powershell的prompt&#xff0c;这里我用的是cmd。PowerShell也有很多粉丝&#xff0c;但是个人真的觉得这个东西挺鸡肋的。 另外在Win10或Win11上另一个玩法是使用WSL2&#xff…

【漏洞挖掘】Xray+rad自动化批量漏洞挖掘

文章目录 前言一、挖掘方法二、使用步骤工具安装使用方法开始挖掘 总结 前言 自动化漏洞挖掘是指利用计算机程序和工具来扫描、分析和检测应用程序、网络和系统中的安全漏洞的过程。这种方法可以帮助安全专家和研究人员更高效地发现和修复潜在的安全威胁&#xff0c;从而提高整…

企业级开发中协同开发与持续集成持续部署

文章目录 1 创建代码仓库2 使用git协同开发2.1 独立团队开发2.2 多团队开发git工作流 2 持续集成和持续部署2.1 创建docker镜像2.2 使用coding构建 1 创建代码仓库 每个项目有唯一的代码仓库&#xff0c;所以不是每个开发者都需要创建一个代码仓库&#xff0c;一般都是项目负责…

Node版本自由切换之nvm安装教程

1.nvm安装包下载&#xff0c;这里推荐1.1.7版本 https://github.com/coreybutler/nvm-windows/releases/download/1.1.7/nvm-setup.zip 2.解压后运行exe文件&#xff0c;一路默认就可以了&#xff0c;自定义的话&#xff0c;文件路径不要有中文&#xff1b; 3.安装之后使用命…

CloudCompare软件手册01

1. 介绍 1.1 历史 CloudCompare是一个3D点云(和三角形网格)编辑和处理软件。 最初&#xff0c;它被设计用于在密集的3D点云之间进行直接比较。它依赖于一种特定的八叉树结构&#xff0c;在执行这类任务时&#xff0c;这种结构能够提供出色的性能。此外&#xff0c;由于大多数…

基于python+Xception算法模型实现一个图像分类识别系统

一、目录 Xception介绍数据集处理模型训练模型评估项目扩展 二、Xception介绍 在计算机视觉领域&#xff0c;图像识别是一个非常重要的任务&#xff0c;其应用涵盖了人脸识别、物体检测、场景理解等众多领域。随着深度学习技术的发展&#xff0c;深度卷积神经网络&#xff0…

C++继承——多继承问题

目录 单继承&#xff1a; 多继承&#xff1a; 菱形继承&#xff1a;菱形继承是多继承的一种特殊情况。 三.菱形继承的两种解决方式区别&#xff1a; 3.1采用作用域解决的菱形继承&#xff1a; 检测器运行图&#xff1a; 反汇编运行图&#xff1a; 3.1菱形虚继承&…

webstorm配置less转译

Program中路径如果识别不到 项目文件\node_modules.bin\lessc

如何优雅的显示404页面

源码&#xff1a;mumangguo/404-notfound - 码云 - 开源中国https://gitee.com/mumangguo/404-notfound 1.孤独型404页面 2.酷炫效果404页面 3.太空404页面 4.404寻亲页面&#xff08;公益&#xff09; 每一次刷新都是一个公益捐赠活动&#xff01; 以上就是笔者要分享的4个4…

【H5移动端】常用的移动端方案合集-键盘呼起、全面屏适配、图片大小显示、300ms点击延迟、首屏优化(不定期补充~)

文章目录 前言键盘呼起问题靠近底部的输入项被键盘遮挡底部按钮被顶上去 全面屏适配图片大小显示问题解决300ms延迟首屏优化 前言 这篇文章总结了我在工作中做H5遇到的一些问题&#xff0c;包括我是怎么解决的。可能不是当下的最优解&#xff0c;但是能保证解决问题。 单位适…

【hive】Install hive using mysql as hive metadata service

文章目录 一. Requirements二. Installing Hive from a Stable Release三. Running Hive四. Running Hive CLI五.Running HiveServer2 and Beeline1. 下载安装mysql2. 下载mysql驱动3. 配置hive-site.xml4. 初始化元数据库5. 通过beeline进行连接 一. Requirements Users are s…

简易博客系统自动化测试

&#x1f349;作者 Autumn60 &#x1f3c4;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f472;微语 &#xff1a;只有镜子和钱包&#xff0c;可以告诉你生活中&#xff0c;大部分的为什么和凭什么 文章目录 目录 文章目录 概述: 测试方法&am…

自动化测试和手动测试相比,哪个更具优势?

在软件测试行业中&#xff0c;争议最大的话题是“更好的是手动测试还是自动化测试”。尽管自动化测试最常谈论流行语&#xff0c;并且正在慢慢主导测试领域&#xff0c;手动测试的必要性不可忽视。 在本文中&#xff0c;将探讨手动测试和自动化测试之间的更深差异。 什么是手动…

javascript实现几何粒子星空连线背景效果

javascript实现几何粒子星空连线背景效果 <html><head><meta charset"UTF-8"><title>几何星空连线背景</title><script src"./ParticleBackground.js"></script> </head><body><canvas id"…

【计算机视觉】BLIP:统一理解和生成的自举多模态模型

文章目录 一、导读二、背景和动机三、方法3.1 模型架构3.2 预训练目标3.3 BLIP 高效率利用噪声网络数据的方法&#xff1a;CapFilt 四、实验4.1 实验结果4.2 各个下游任务 BLIP 与其他 VLP 模型的对比 一、导读 BLIP 是一种多模态 Transformer 模型&#xff0c;主要针对以往的…

如何选择微信客户管理系统?

为何要给客户打上标签&#xff1f; 主要为企业搭建一个完善的客户体系&#xff0c;将客户资源整合&#xff0c;分层管理并进行针对性营销推广&#xff0c;以实现精准获客转化&#xff0c;简单来说就是更好的分类管理。 客户标签不应该只是作为的客户登记资料&#xff0c;后续每…

一起来探索用ai绘画二次元描述词绘制出来图画吧

在二次元的世界中&#xff0c;画笔是创作的灵魂&#xff0c;绘画作品是艺术家灵魂的抒发。而如今&#xff0c;随着科技的不断进步&#xff0c;我们迎来了一款令人兴奋的技术——ai绘画。这项软件可以帮助我们创造出色彩斑斓、令人惊叹的二次元作品。让你无需具备专业绘画技巧&a…

为什么说国内数字孪生平台gis架构采用Cesium是不错的选择?

Gis作为数字孪生平台开发中重要的一环对数字孪生平台是否好用是一个重要的判定方式&#xff0c;国内数字孪生软件在融合GIS系统方面采取了多种方式&#xff0c;例如Unity或Unreal Engine等游戏引擎&#xff0c;以增强数字孪生的空间感知和空间分析能力&#xff0c;提供更全面、…

银河麒麟V10系统忘记密码解决

1、正常开机等待系统进入GRUB界面&#xff0c;按下e键&#xff0c;如下图&#xff1a; 2、进入编辑文件&#xff1a; 3、 修改ro为rw 然后再行尾添加空格输入&#xff1a;consoletty init/bin/bash (或 single init/bin/bash) 输入完成按&#xff1a;ctrlx或F10进入修改密码阶段…