自动化运维工具 ansible (2) playbook的编写

目的:实现自动化的部署
编写语法格式:playbook以yaml语言编写。
文件第一行以 “—”开始,表示文件的开始。
在同一行中井号表示注释。
列表形式以 “-”开头,跟着一个空格。同一个列表中的元素应该保持相同的缩进。
例:

---                        #开头
- hosts: test       #对哪个组进行任务
  tasks:            #任务
    - name: install apache  #下面开始新的列表##任务名
      yum:                  #调用模块
        name: httpd         #服务名
        state: installed    #动作
    - name: start apache
      service:
        name: httpd
        state: started

如果愿意,可以一直往下写。

基本命令

[ansible@server10 ~]$ ansible-playbook playbook.yml --syntax-check ##检测语法使用参数--syntax-check

playbook: playbook.yml
[ansible@server10 ~]$ ansible-playbook playbook.yml --list-hosts  ##检测主机

playbook: playbook.yml

  play #1 (test): test	TAGS: []
    pattern: [u'test']
    hosts (1):        ##现在作用主机就只有一个
      server11
[ansible@server10 ~]$ ansible-playbook playbook.yml --list-tasks    ##查看有几个任务

playbook: playbook.yml

  play #1 (test): test	TAGS: []
    tasks:
      install apache	TAGS: []
      start apache	TAGS: []
[ansible@server10 ~]$ ansible-playbook playbook.yml    ##运行文件中的配置

PLAY [test] ***************************************************************************

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

TASK [install apache] *****************************************************************
ok: [server11]

TASK [start apache] *******************************************************************
changed: [server11]

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

运行完成之后在test组的节点进行查看。

[root@server11 ~]# netstat -antpl  ##80端口已经开启
tcp6       0      0 :::80                   :::*                    LISTEN      2953/httpd    

创建完成之后下一步可以编辑默认发布页面。

  • name: create index.html
    copy: ##拷贝模块
    content: “www.server10.com” ##添加的内容
    dest: /var/www/html/index.html ##复制到的位置

设置完成之后进行运行。

[ansible@server10 ~]$ ansible-playbook playbook.yml 
[ansible@server10 ~]$ curl server11  ##远程访问。
www.server10.com

可以访问之后我们可以在部署之前进行配置。在安装完apache服务之后加入如下。

- name: config apache
  copy:
    src: httpd.conf   ##将本地的httpd配置文件复制到下面的地址
    dest: /etc/httpd/conf/httpd.conf

在本地的配置文件中将端口号进行修改

Listen 8080
[ansible@server10 ~]$ ansible-playbook playbook.yml
TASK [config apache] ******************************************************************
changed: [server11]  ##这里提示已经改变

没有报错后进入远端进行查看。

[root@server11 conf]# netstat -antpl
tcp6       0      0 :::80                   :::*                    LISTEN      2953/httpd     

我们发现这这端口并没有进行改变,因为现在是服务部署完成再进行改变的,如果想让文件生效有两个办法,一个是手动进入远端重启服务,另一个就是继续编写playbook,在文件中将服务重启,或者设置触发机制。
触发器的设置
在playbook文件中最下面设置触发器

  handlers:
    - name: restart apache
      service:
        name: httpd
        state: restarted

设置完成之后,在编辑配置文件的地方放置触发器,只要文件发生变动,就会触发,将服务重启。

- name: config apache
  copy:
    src: httpd.conf
    dest: /etc/httpd/conf/httpd.conf
  notify: restart apache

设置多个play

任务可以有很多,play也可以有很多,下来就设置一个测试用play

- hosts: localhost  ##在本地
  become: no        ##不切换用户
  tasks:            ##任务
    - name : test apache 
      uri:      ##uri模块
        url: http://server11/index.html

编写完成后接着运行

[ansible@server10 ~]$ ansible-playbook playbook.yml
PLAY [localhost] **************************************************************************

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

TASK [test apache] ************************************************************************
ok: [localhost]

PLAY RECAP ********************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
server11                   : ok=7    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

在本地运行的play没有问题。
设置完多个play之后如果我们想跑指定的play呢?目前只能指定从哪个任务开始。–start-at-task参数进行指定

[ansible@server10 ~]$ ansible-playbook playbook.yml --start-at-task "test apache"

PLAY [test] *******************************************************************************

PLAY [localhost] **************************************************************************

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

TASK [test apache] ************************************************************************
ok: [localhost]

PLAY RECAP ********************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

这样就直接从我们的测试任务开始,而不做前面的任务。
或者不加这个参数而是在playbook文件中添加一个标签,这样设置,查看的时候标签也能进行显示。

    uri:
        url: http://server11/index.html
      tags: test
[ansible@server10 ~]$ ansible-playbook playbook.yml --list-tasks
  play #2 (localhost): localhost	TAGS: []
    tasks:
      test apache	TAGS: [test]

使用的时候直接指定标签即可。

[ansible@server10 ~]$ ansible-playbook playbook.yml -t test

上面两个方法的效果是相同的

变量

首先定义模版文件。
可以在hosts文件中直接定义。

[test]
server11  web_package=httpd

定义完成后使用时需要进行调用。调用方法使用"{{ 变量名}}"
比如说我们在安装软件的时候使用变量。

   - name: install apache
      yum:
        name: "{{web_package}}"
        state: installed

然后运行,运行是正常的那就说明变量使用没有问题。
定义变量的位置有很多,也可以直接在playbook文件中进行添加。

---
- hosts: test
  vars:
    web_package: httpd

在开头的地方设置变量,调用的方式都是一样的。但是直接在playbook中进行定义的变量比在别的地方定义的变量优先级要高。因为playbook加载是最后的,playbook中的变量将其他变量覆盖掉了。说白了就是哪个文件最后加载的,最后加载的文件中如果有变量就会覆盖前一个变量。
当然,ansible也有自己的内置变量,使用下面的命令进行查看。

[ansible@server10 ~]$ ansible server11 -m setup

默认是直接启用的,因为在运行playbook文件的时候第一个加载的就是内置变量TASK [Gathering Facts],当然这个选项在你不用他的时候是可以禁掉的。当我们进行调用的时候可以查看完变量再进行设置。例如这样:

  - name: create index.html
      copy:
        content: "{{ansible_hostname}}"
        dest: /var/www/html/index.html

运行之后我们进行查看。

[ansible@server10 ~]$ curl server11
server11

已经添加进去了,这种方法虽然可以设置变量,但是官方建议的方式为:

  • name: create index.html
    copy:
    content: “{{ansible_facts[‘hostname’]}}”
    dest: /var/www/html/index.html

还有更复杂的方式,例如下面,我再起一个play,我们在每一台机器上面都创建一个文件,文件中的内容为本机ip。

- hosts: all
  tasks:
    - name: create hostinfo
      copy:
        content: "{{ ansible_facts['ens3']['ipv4']['address'] }}"  ##这个方法将ip定位ens3网卡上面的ipv4的地址
        dest: /tmp/hostinfo
  tags: info   ##给play设置标签
[ansible@server10 ~]$ ansible-playbook playbook.yml -t info  ##运行从标签info开始
[root@server11 conf]# cat /tmp/hostinfo
192.168.122.11
[root@server12 ~]# cat /tmp/hostinfo 
192.168.122.12

这样每一台主机上的ip地址就都创建完成了。
或者再使用另一种模版jinja2模版。

- hosts: all
  tasks:
    - name: create hostinfo
      template:
        src: hostinfo.j2  ##源文件
        dest: /tmp/hostinfo

在playbook中定义完成后就要去编写jinja2文件来进行运用。

[ansible@server10 ~]$ vim hostinfo.j2
ip:{{ ansible_facts['ens3']['ipv4']['address']}}
hostname:{{ ansible_facts['hostname']}}
hostiface:{{ ansible_facts['interfaces']}}
dns:{{ ansible_facts['dns']['nameservers']}}
{{ ansible_facts['kernel']}}
memoryfree: {{ ansible_facts['memfree_mb']}}

里面全部使用变量形式,playbook运行完之后再推送到远端。

[root@server11 conf]# cat /tmp/hostinfo
ip:192.168.122.11
hostname:server11
hostiface:[u'lo', u'ens3']
dns:[u'114.114.114.114']
3.10.0-1062.el7.x86_64
memoryfree: 686

注册变量

以下面这一段为例

- hosts: localhost
  become: no
  tasks:
    - name : test apache
      uri:
        url: http://server11/index.html

现在这个输出只有ok没有其他的东西,那么我们就要定义一个变量,将变量的值进行输出。

 url: http://server11/index.html
  register: result  ##定义变量
- debug:
    var: result     ##输出

运行之后就有了别的输出值

TASK [debug] ******************************************************************************
ok: [localhost] => {
    "result": {
        "accept_ranges": "bytes", 
        "changed": false, 
        "connection": "close", 
        "content_length": "8", 
        "content_type": "text/html; charset=UTF-8", 
        "cookies": {}, 
        "cookies_string": "", 
        "date": "Sun, 08 Mar 2020 12:42:40 GMT", 
        "elapsed": 0, 
        "etag": "\"8-5a055938dc004\"", 
        "failed": false, 
        "last_modified": "Sun, 08 Mar 2020 10:44:51 GMT", 
        "msg": "OK (8 bytes)", 
        "redirected": false, 
        "server": "Apache/2.4.6 (CentOS)", 
        "status": 200, 
        "url": "http://server11/index.html"
    }
}

但是,如果在进一步,这些东西显示的太多了,我们只想要特定的内容,那么该如何做到。
那么就需要首先知道你需要哪些信息,从上面的信息中进行筛选。
比如说我需要知道时间的信息。

  • debug:
    var: result.date

设置成这样再运行信息就出来了。

TASK [debug] ******************************************************************************
ok: [localhost] => {
    "result.date": "Sun, 08 Mar 2020 13:04:29 GMT"
}

loop循环

重新创建一个play进行用户的创建

- hosts: test
  vars:   ##定义变量
    user: user1
    passwd: aekhg777
  tasks:
    - name: create users
      user:
        name: "{{user}}"
        password: "{{passwd|password_hash('sha512')}}" ##密码加密 不能使用明文密码
  tags: user

创建完成之后可以在server11中进行查看。
如何创建多个用户,使用loop循环,将变量删除,加入循环

  tasks:
    - name: create users
      user:
        name: "{{item.user}}"
        password: "{{item.passwd|password_hash('sha512')}}"
      loop:         ##可以有多组循环
        - {user:user1, passwd:asd }
        - {user:user2, passwd:qwe }

完成之后运行

TASK [create users] ***********************************************************************
changed: [server11] => (item={u'passwd': u'asd', u'user': u'user1'})
changed: [server11] => (item={u'passwd': u'qwe', u'user': u'user2'})

切换到server11上面进行查看

user1:x:1001:1001::/home/user1:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash

已经创建完成。
但是这种方式不安全,密码在文件中全部明文进行展示。
首先创建一个文件

[ansible@server10 ~]$ cat vars/userlist.yml 
---
userlist: ##创建的变量
  - user: user1  ##里面的组
    passwd: asd
  - user: user2
    passwd: qwe

再将这个文件指定进playbook文件

- hosts: test
  vars_files:
    - vars/userlist.yml
  tasks:
    - name: create users
      user:
        name: "{{item.user}}"
        password: "{{item.passwd|password_hash('sha512')}}"
      loop: "{{userlist}}" ##循环变量中的组

创建完成,可以进行查看

魔术变量

自动的循环多台主机,例:自动创建hosts文件
创建一个jinja2的文件

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
{% for host in groups['web']%}  ##for循环开始 提取组为web中的机器
{{ hostvars[host]['ansible_ens3']['ipv4']['address']}} {{ hostvars[host]['ansible_facts']['hostname' ]}} ##提取ip地址  提取用户名
{% endfor%}   ##循化结束

创建完成编写playbook

- hosts: all        ##集群中的所有
  tasks:            
    - name: create hosts
      template:        ##使用模版
        src: test.j2
        dest: /tmp/hosts
  tags: hosts

运行ansible创建。然后进入别的节点进行查看。

[root@server11 conf]# cat /tmp/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.122.11 server11
192.168.122.12 server12

或者在看一个例子,部署haproxy负载均衡
首先配置playbook文件安装haproxy软件。

- hosts: all
  tasks:
    - name: install haproxy
      yum:
        name: haproxy
        state: installed
      when: ansible_hostname == 'server10'##当用户是server10才会安装
  tags: haproxy

安装完成将haproxy的配置文件复制出来改为jinja2形式。并修改配置文件
在配置的时候使用魔术变量

#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  main *:80 
    default_backend             app

#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
    balance     roundrobin
{% for host in groups['web']%} ##开始
     server  {{hostvars[host]['ansible_facts']['hostname']}}  {{ hostvars[host]['ansible_ens3']['ipv4']['address']}}:80 check ##提取用户名 和ip
{% endfor%}  ##结束

这个设置完成再完善playbook,继续添加如下

   - name: config haproxy
      template:
        src: haproxy.cfg.j2
        dest: /etc/haproxy/haproxy.cfg
      notify: restart haproxy
      when: ansible_hostname == 'server10'
    - name: start haproxy
      service:
        name: haproxy
        state: started
      when: ansible_hostname == 'server10'
  handlers:  ##触发器
    - name: restart haproxy
      service:
        name: haproxy
        state: reloaded
  tags: haproxy

在运行访问本机

[ansible@server10 ~]$ curl server10
server11
[ansible@server10 ~]$ curl server10
server12
[ansible@server10 ~]$ curl server10
server11
实现负载均衡

加密文件

ansible自带加密功能使用命令进行加密,我们使用最早实验用的用户名和密码做实验。

[ansible@server10 vars]$ ansible-vault encrypt userlist.yml 
New Vault password: 
Confirm New Vault password: 
Encryption successful
[ansible@server10 vars]$ cat userlist.yml 
$ANSIBLE_VAULT;1.1;AES256
62633139313432323765313233353738326561636166623335313561393034613938333336386661
3262653737643638643934353264363438656161643235340a356136663234396630383732303134
31323833626364316232343565636634623561363262393465316564363435326135626633383137
6431323935653533640a373663663635326332616137626233313762383965626361643737626363
63353966376431653236326365666566373931633038303833333566343034343830666230326139
37393361636236663363303337306335333537386333386139656638643635383631663361643539
66316231386637613535363936313335306232336265663062306539393862343734306138633731
61303365346364343539

这样就被加密了,如何查看,需要输入加密时输入的密码。

[ansible@server10 vars]$ ansible-vault view userlist.yml 
Vault password: 
---
userlist:
  - user: user1
    passwd: asd
  - user: user2
    passwd: qwe

解密

[ansible@server10 vars]$ ansible-vault decrypt userlist.yml 
Vault password: 
Decryption successful
[ansible@server10 vars]$ cat userlist.yml 
---
userlist:
  - user: user1
    passwd: asd
  - user: user2
    passwd: qwe

但是现在用的还时加密文件,这个加密文件应该如何使用?因为如果直接使用加密文件的话会运行playbook会报错,所以使用的时候要给命令行中加一个参数来输入密码--ask-vault-pass

最后附上所有playbook的内容。

---
- hosts: web
  gather_facts: yes
  vars:
    web_package: httpd
    web_service: httpd
  tasks: 
    - name: install apache
      yum:
        name: "{{web_package}}"
        state: installed
      ignore_errors: True
    - name: config apache
      template:
        src: httpd.conf.j2
        dest: /etc/httpd/conf/httpd.conf
      notify: restart apache
    - name: start apache
      service:
        name: "{{web_service}}"
        state: started
        enabled: yes
    - name: create index.html
      copy: 
        content: "{{ansible_facts['hostname']}}"
        dest: /var/www/html/index.html
    - name: start firewall
      service:
        name: firewalld
        state: started
        enabled: yes
    - name: custom firewalld
      firewalld:
        service: http
        permanent: yes
        state: enabled
        immediate: yes
  handlers:
    - name: restart apache
      service:
        name: "{{web_service}}"
        state: restarted
  tags: apache

- hosts: all
  tasks:
    - name: install haproxy
      yum: 
        name: haproxy
        state: installed
      when: ansible_hostname == 'server10'
    - name: config haproxy
      template:
        src: haproxy.cfg.j2
        dest: /etc/haproxy/haproxy.cfg
      notify: restart haproxy
      when: ansible_hostname == 'server10'
    - name: start haproxy
      service:
        name: haproxy
        state: started
      when: ansible_hostname == 'server10'
  handlers:
    - name: restart haproxy
      service:
        name: haproxy
        state: reloaded
  tags: haproxy


- hosts: localhost
  become: no
  tasks:
    - name : test apache
      uri:
        url: http://server11/index.html
      register: result
    - debug: 
        #var: result.date
  tags: test

- hosts: all 
  tasks:
    - name: create hostinfo
      template:
        src: hostinfo.j2
        dest: /tmp/hostinfo
  tags: info

- hosts: all
  tasks:
    - name: create hosts
      template:
        src: test.j2
        dest: /tmp/hosts
  tags: hosts
                              

- hosts: test
  vars_files:
    - vars/userlist.yml
  tasks:
    - name: create users
      user:
        name: "{{item.user}}"
        password: "{{item.passwd|password_hash('sha512')}}"
      loop: "{{userlist}}"
  tags: user

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JavaScript 编写的记忆游戏(附源代码)   项目:JavaScript 记忆游戏(附源代码) 记忆检查游戏是一个使用 HTML5、CSS 和 JavaScript 开发的简单项目。这个游戏是关于测试你的短期 记忆技能。玩这个游戏 时,一系列图像会出现在一个盒子形状的区域中 。玩家必须找到两个相同的图像并单击它们以使它们消失。 如何运行游戏? 记忆游戏项目仅包含 HTML、CSS 和 JavaScript。谈到此游戏的功能,用户必须单击两个相同的图像才能使它们消失。 点击卡片或按下键盘键,通过 2 乘 2 旋转来重建鸟儿对,并发现隐藏在下面的图像! 如果翻开的牌面相同(一对),您就赢了,并且该对牌将从游戏中消失! 否则,卡片会自动翻面朝下,您需要重新尝试! 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,通过单击 memorygame-index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值