利用ansible来做tomcat应用的持续交付

在做持续交付这件事,想必大家都是用jenkins这款程序来做基石。当然,我们这次也是用jenkins作为承载工具,jenkins强大的插件是有目共睹的,有些ansible做起来不容易的事情交给jenkins反而简单有效。下面我会详细说明怎么持续交付tomcat应用。

希望本实验可以引导大家在持续交付的过程中使用ansible工具,也希望本实验能帮助到有需要的人,更希望给到大家一个简单的持续交付思想和启发。如想继续交流的,还请加入QQ群:425931784。

应用架构


本次使用的应用架构是常见的负载均衡实例。

image.png

软件版本


os: centos 6.7 X64
ansible: 2.3.1.0
python: 2.6.6
ant: 10.1
java: 1.8.0_13
tomcat: 8.5.14
jenkins: 2.73

Ansible roles


服务器角色


主机 角色
node1 nginx,jenkins
node130 tomcat
node131 tomcat

集群搭建


本次使用anisble playbook

---

- hosts: node130 node131
  vars:
   - java_version: "1.8"
   - tomcat_version: "8.5.14"
   - iptables_allowed_tcp_ports: ["8080"]
  roles:
  - java
  - { role: tomcat, java_home: "/usr/java/jdk1.8.0_131" }
  - iptables

- hosts: node1
  vars:
   - java_version: "1.8"
   - nginx_version: "1.12.1"
   - nginx_upstreams:
     - name: upstremtest
       servers:
       - 192.168.77.130:8080 max_fails=2 fail_timeout=2
       - 192.168.77.131:8080 max_fails=2 fail_timeout=2
   - nginx_vhosts:
     - listen: 80
       locations:
       - name: /
         proxy_pass: http://upstremtest
   - jenkins_version: "2.73"
   - jenkins_plugins_extra:
     - ansible
     - ansicolor
   - iptables_allowed_tcp_ports: ["80","8080"]
  roles:
  - ant
  - java
  - nginx
  - jenkins
  - iptables
  tasks:
  - name: install ansible
    package: name=ansible

怎么使用ansible roles,请移步到 Ansible Role【怎么用?】

确保正常访问以下服务:

node1服务器操作


在服务器上配置ansible playbook

# cd /etc/ansible/
# cat tomcat-deploy.yml
---

- hosts: all
  serial: 1
  roles:
   - deploy-tomcat

# cat hosts
[node130]
192.168.77.130

[node131]
192.168.77.131

[testservers:children]
node130
node131

[testservers:vars]
ansible_ssh_user=root
ansible_ssh_pass=123456

# git clone https://github.com/kuailemy123/Ansible-roles.git /etc/ansible/roles/
# chown jenkins.jenkins /etc/ansible/

jenkins 操作


登录jenkins之后,设置工具
点击“系统管理”==》“Global Tool Configuration”

image.png
image.png
image.png

创建发布项目

image.png

配置参数化构建


image.png

配置源码仓库地址


image.png

repo: https://github.com/kuailemy123/AntSpringMVC.git

配置构建环境


image.png

配置编译

image.png

配置ansible

image.png

配置ansible变量


image.png

这里就不配置邮件通知了。

创建回滚项目

image.png

配置参数化构建


image.png

配置构建环境


image.png

配置ansible

image.png

配置anisble变量
image.png

测试


执行tomcat_deploy任务

选择发布的节点,默认all

任务执行的日志

Started by user admin
Building in workspace /var/lib/jenkins/workspace/tomcat_deploy
Cloning the remote Git repository
Cloning repository https://github.com/kuailemy123/AntSpringMVC.git
 > git init /var/lib/jenkins/workspace/tomcat_deploy # timeout=10
Fetching upstream changes from https://github.com/kuailemy123/AntSpringMVC.git
 > git --version # timeout=10
 > git fetch --tags --progress https://github.com/kuailemy123/AntSpringMVC.git +refs/heads/*:refs/remotes/origin/*
 > git config remote.origin.url https://github.com/kuailemy123/AntSpringMVC.git # timeout=10
 > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
 > git config remote.origin.url https://github.com/kuailemy123/AntSpringMVC.git # timeout=10
Fetching upstream changes from https://github.com/kuailemy123/AntSpringMVC.git
 > git fetch --tags --progress https://github.com/kuailemy123/AntSpringMVC.git +refs/heads/*:refs/remotes/origin/*
 > git rev-parse refs/remotes/origin/master^{commit} # timeout=10
 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision 989ea3a6549e16e3dd4cd329ab969b47658c9d67 (refs/remotes/origin/master)
Commit message: "Create README.md"
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 989ea3a6549e16e3dd4cd329ab969b47658c9d67
First time build. Skipping changelog.
[tomcat_deploy] $ ant -file build.xml -Ddeploy_node=all
Buildfile: /var/lib/jenkins/workspace/tomcat_deploy/build.xml

clean:
   [delete] Deleting directory /var/lib/jenkins/workspace/tomcat_deploy/war/WEB-INF/classes

init:
    [mkdir] Created dir: /var/lib/jenkins/workspace/tomcat_deploy/target
    [mkdir] Created dir: /var/lib/jenkins/workspace/tomcat_deploy/war/WEB-INF/classes

resolve:
     [echo] Getting dependencies...
[ivy:retrieve] :: Apache Ivy 2.4.0 - 20141213170938 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: url = jar:file:/usr/local/ant/lib/ivy-2.4.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: org.apache#WebProject;working@node1
[ivy:retrieve]  confs: [compile, runtime, test]
[ivy:retrieve]  found org.slf4j#slf4j-api;1.7.6 in public
[ivy:retrieve]  found jstl#jstl;1.2 in public
[ivy:retrieve]  found ch.qos.logback#logback-classic;1.1.2 in public
[ivy:retrieve]  found ch.qos.logback#logback-core;1.1.2 in public
[ivy:retrieve]  found org.springframework#spring-core;4.1.3.RELEASE in public
[ivy:retrieve]  found commons-logging#commons-logging;1.2 in public
[ivy:retrieve]  found org.springframework#spring-beans;4.1.3.RELEASE in public
[ivy:retrieve]  found org.springframework#spring-context;4.1.3.RELEASE in public
[ivy:retrieve]  found org.springframework#spring-aop;4.1.3.RELEASE in public
[ivy:retrieve]  found aopalliance#aopalliance;1.0 in public
[ivy:retrieve]  found org.springframework#spring-expression;4.1.3.RELEASE in public
[ivy:retrieve]  found org.springframework#spring-web;4.1.3.RELEASE in public
[ivy:retrieve]  found org.springframework#spring-webmvc;4.1.3.RELEASE in public
[ivy:retrieve] downloading https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.6/slf4j-api-1.7.6.jar ...
[ivy:retrieve] ............ (28kB)
[ivy:retrieve] .. (0kB)
..... 省略下载的信息
[ivy:retrieve] :: resolution report :: resolve 74135ms :: artifacts dl 120701ms
    ---------------------------------------------------------------------
    |                  |            modules            ||   artifacts   |
    |       conf       | number| search|dwnlded|evicted|| number|dwnlded|
    ---------------------------------------------------------------------
    |      compile     |   13  |   13  |   13  |   0   ||   13  |   13  |
    |      runtime     |   13  |   13  |   13  |   0   ||   13  |   13  |
    |       test       |   13  |   13  |   13  |   0   ||   13  |   13  |
    ---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: org.apache#WebProject
[ivy:retrieve]  confs: [compile, runtime, test]
[ivy:retrieve]  13 artifacts copied, 0 already retrieved (5920kB/79ms)

compile:
    [javac] Compiling 1 source file to /var/lib/jenkins/workspace/tomcat_deploy/war/WEB-INF/classes
copy-resources:
     [copy] Copying 1 file to /var/lib/jenkins/workspace/tomcat_deploy/war/WEB-INF/classes
package:
[ivy:retrieve] :: retrieving :: org.apache#WebProject
[ivy:retrieve]  confs: [runtime]
[ivy:retrieve]  0 artifacts copied, 13 already retrieved (0kB/5ms)
      [war] Building war: /var/lib/jenkins/workspace/tomcat_deploy/target/helloproject-20170819172002.war

main:

BUILD SUCCESSFUL
Total time: 3 minutes 19 seconds
[tomcat_deploy] $ /usr/bin/ansible-playbook /etc/ansible/tomcat-deploy.yml -i /etc/ansible/hosts -l all -f 5 -e deploy_port=8080 -e deploy_file=/var/lib/jenkins/workspace/tomcat_deploy/target/helloproject-*.war

PLAY [all] *********************************************************************

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

TASK [deploy-tomcat : check | 发布文件是否存在] ****************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : check | 目标应用服务的家目录是否存在] **********************************
ok: [192.168.77.130]

TASK [deploy-tomcat : check | 工作目录如果不存在则创建] ************************************
changed: [192.168.77.130] => (item=/tmp/tomcat-ansible-snap/new)
changed: [192.168.77.130] => (item=/tmp/tomcat-ansible-snap/pre)
changed: [192.168.77.130] => (item=/tmp/tomcat-ansible-snap/old)

TASK [deploy-tomcat : deloy | 解压代码至目标服务器] **************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : deloy | 关闭服务] ********************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : deloy | 等待端口关闭] ******************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : deloy | 移动线上代码] ******************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : deloy | 部署最新代码] ******************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : deloy | 启动服务] ********************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : deloy | 等待端口开启] ******************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : backup | 创建存储备份的文件夹] *************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : backup | 备份上线的代码] ****************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : rollback | 检查/tmp/tomcat-ansible-snap/old是否存在代码] *********
skipping: [192.168.77.130]

TASK [deploy-tomcat : rollback | 关闭服务] *****************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : rollback | 等待端口关闭] ***************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : rollback | 部署上一版代码] **************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : rollback | 启动服务] *****************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : rollback | 等待端口开启] ***************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
skipping: [192.168.77.130]

PLAY [all] *********************************************************************

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

TASK [deploy-tomcat : check | 发布文件是否存在] ****************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : check | 目标应用服务的家目录是否存在] **********************************
ok: [192.168.77.131]

TASK [deploy-tomcat : check | 工作目录如果不存在则创建] ************************************
ok: [192.168.77.131] => (item=/tmp/tomcat-ansible-snap/new)
ok: [192.168.77.131] => (item=/tmp/tomcat-ansible-snap/pre)
ok: [192.168.77.131] => (item=/tmp/tomcat-ansible-snap/old)

TASK [deploy-tomcat : deloy | 解压代码至目标服务器] **************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : deloy | 关闭服务] ********************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : deloy | 等待端口关闭] ******************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : deloy | 移动线上代码] ******************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : deloy | 部署最新代码] ******************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : deloy | 启动服务] ********************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : deloy | 等待端口开启] ******************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : backup | 创建存储备份的文件夹] *************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : backup | 备份上线的代码] ****************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : rollback | 检查/tmp/tomcat-ansible-snap/old是否存在代码] *********
skipping: [192.168.77.131]

TASK [deploy-tomcat : rollback | 关闭服务] *****************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : rollback | 等待端口关闭] ***************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : rollback | 部署上一版代码] **************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : rollback | 启动服务] *****************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : rollback | 等待端口开启] ***************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
skipping: [192.168.77.131]

PLAY RECAP *********************************************************************
192.168.77.130             : ok=14   changed=8    unreachable=0    failed=0   
192.168.77.131             : ok=14   changed=7    unreachable=0    failed=0   

Finished: SUCCESS

执行tomcat_rollback任务

image.png

选择回滚的节点,默认all

执行的日志

Started by user admin
Building in workspace /var/lib/jenkins/workspace/tomcat_rollback
[tomcat_rollback] $ /usr/bin/ansible-playbook /etc/ansible/tomcat-deploy.yml -i /etc/ansible/hosts -l all -f 5 -e deploy_rollback=true

PLAY [all] *********************************************************************

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

TASK [deploy-tomcat : check | 发布文件是否存在] ****************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : check | 目标应用服务的家目录是否存在] **********************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : check | 工作目录如果不存在则创建] ************************************
skipping: [192.168.77.130] => (item=/tmp/tomcat-ansible-snap/new) 
skipping: [192.168.77.130] => (item=/tmp/tomcat-ansible-snap/pre) 
skipping: [192.168.77.130] => (item=/tmp/tomcat-ansible-snap/old) 

TASK [deploy-tomcat : deloy | 解压代码至目标服务器] **************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : deloy | 关闭服务] ********************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : deloy | 等待端口关闭] ******************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : deloy | 移动线上代码] ******************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : deloy | 部署最新代码] ******************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : deloy | 启动服务] ********************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : deloy | 等待端口开启] ******************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : backup | 创建存储备份的文件夹] *************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : backup | 备份上线的代码] ****************************************
skipping: [192.168.77.130]

TASK [deploy-tomcat : rollback | 检查/tmp/tomcat-ansible-snap/old是否存在代码] *********
changed: [192.168.77.130]

TASK [deploy-tomcat : rollback | 关闭服务] *****************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : rollback | 等待端口关闭] ***************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : rollback | 部署上一版代码] **************************************
changed: [192.168.77.130]

TASK [deploy-tomcat : rollback | 启动服务] *****************************************
fatal: [192.168.77.130]: FAILED! => {"changed": true, "cmd": "/etc/init.d/tomcat start", "delta": "0:00:20.035003", "end": "2017-08-19 17:24:47.586469", "failed": true, "rc": 1, "start": "2017-08-19 17:24:27.551466", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring

TASK [deploy-tomcat : rollback | 等待端口开启] ***************************************
ok: [192.168.77.130]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
ok: [192.168.77.130]

PLAY [all] *********************************************************************

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

TASK [deploy-tomcat : check | 发布文件是否存在] ****************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : check | 目标应用服务的家目录是否存在] **********************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : check | 工作目录如果不存在则创建] ************************************
skipping: [192.168.77.131] => (item=/tmp/tomcat-ansible-snap/new) 
skipping: [192.168.77.131] => (item=/tmp/tomcat-ansible-snap/pre) 
skipping: [192.168.77.131] => (item=/tmp/tomcat-ansible-snap/old) 

TASK [deploy-tomcat : deloy | 解压代码至目标服务器] **************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : deloy | 关闭服务] ********************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : deloy | 等待端口关闭] ******************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : deloy | 移动线上代码] ******************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : deloy | 部署最新代码] ******************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : deloy | 启动服务] ********************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : deloy | 等待端口开启] ******************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : backup | 创建存储备份的文件夹] *************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : backup | 备份上线的代码] ****************************************
skipping: [192.168.77.131]

TASK [deploy-tomcat : rollback | 检查/tmp/tomcat-ansible-snap/old是否存在代码] *********
changed: [192.168.77.131]

TASK [deploy-tomcat : rollback | 关闭服务] *****************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : rollback | 等待端口关闭] ***************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : rollback | 部署上一版代码] **************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : rollback | 启动服务] *****************************************
changed: [192.168.77.131]

TASK [deploy-tomcat : rollback | 等待端口开启] ***************************************
ok: [192.168.77.131]

TASK [deploy-tomcat : verify | 查看http状态.] **************************************
ok: [192.168.77.131]

PLAY RECAP *********************************************************************
192.168.77.130             : ok=8    changed=4    unreachable=0    failed=0   
192.168.77.131             : ok=8    changed=4    unreachable=0    failed=0   

Finished: SUCCESS

至此,持续交付实验就完成了,但是持续之路还是很漫长了。望大家永远前进。 大家也可在发的过程中,测试发布是否是灰度发布。

for i in `seq 10000`;do curl -s -I http://192.168.77.129 | head -1;sleep 1;done;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,565评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,021评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,003评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,015评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,020评论 5 370
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,856评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,178评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,824评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,264评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,788评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,913评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,535评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,130评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,102评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,334评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,298评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,622评论 2 343

推荐阅读更多精彩内容

  • 1. 什么是Ansible,它有什么用? Ansible它是个集配置管理和应用部署于一体的自动化运维工具。 应用情...
    午觉不眠Orz阅读 1,497评论 0 0
  • ## Topic: playbook 基本语法和常用命令# State:# 1. Ansible pla...
    Michael_林阅读 5,195评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • ansible 系统架构 ansible简介ansible是新出现的自动化运维工具,ansible是一个配置管理和...
    运维阿文阅读 9,554评论 1 52
  • 做吃的应该就只是食品专业、烹饪专业学生的专利了吧。先上图 昨天的肉品工艺实验课上,学姐带我们一块下手做了这道美味的...
    无害小胖子阅读 1,105评论 0 0