自动化运维专题(三):Ansible的roles标准化与Jenkins持续集成

Mr.chen运维执教笔记(QQ:215379068)

--私人课件,不公开,不出版,禁止传播

想做好运维工作,人先要学会勤快; 
居安而思危,勤记而补拙,方可不断提高; 
别人资料不论你用着再如何爽那也是别人的; 
自己总结东西是你自身特有的一种思想与理念的展现; 
精髓不是看出来的,精髓是记出来的; 
请同学们在学习的过程中养成好的学习习惯; 
勤于实践,抛弃教案,勤于动手,整理文档。

 

十二,使用roles标准化Playbook

roles功能可以用来规范playbook的编写

 

12.1 创建所需要的roles原型目录结构

 
  1. #创建roles基本原型的目录结构
  2. [root@ansible myroles]# tree /myroles/
  3. /myroles/
  4. ├── nginx.yaml #入口触发配置文件
  5. └── roles #playbook的原型配置目录
  6. └── nginx #nginx相关模组配置目录
  7. ├── files #copy模块和script模块的参数src默认会从这个文件夹查找
  8. ├── handlers #用来存放notify的
  9. ├── tasks #用来存放ansible模块任务的
  10. ├── templates #用来存放j2的
  11. └── vars #用来存放变量的
  12. 7 directories, 1 file
  13. #入口触发配置文件
  14. [root@ansible myroles]# cat /myroles/nginx.yaml
  15. ---
  16. - hosts: all #执行的主机范围
  17. gather_facts: True #开启系统内置变量
  18. roles: #启用roles原型配置
  19. - nginx #执行nginx原型模组
 

12.2 roles中tasks任务编排模组的使用

 
  1. #在nginx模组添加tasks任务配置文件
  2. [root@ansible myroles]# cat roles/nginx/tasks/main.yaml
  3. ---
  4. - name: check alived #任务1的名字
  5. ping: #执行ping模块
  6. - name: #任务2的名字
  7. shell: ls / #执行shell模块
  8. register: ls_result #将执行结果保存给变量
  9. - debug: var=ls_result #变量的值赋值给debug进行输出
  10. #完成后的目录结构如下所示
  11. [root@ansible myroles]# tree /myroles/
  12. /myroles/
  13. ├── nginx.yaml #nginx模组入口配置文件
  14. └── roles
  15. └── nginx #nginx原型模组目录
  16. ├── files
  17. ├── handlers
  18. ├── tasks
  19.    └── main.yaml #nginx模组的tasks任务配置文件
  20. ├── templates
  21. └── vars
  22. 7 directories, 2 files
 

12.3 执行简单的roles任务模型

 
  1. #执行nginx入口配置文件
  2. [root@ansible myroles]# ansible-playbook nginx.yaml
  3. PLAY [all] ****************************************************************************************************
  4. TASK [Gathering Facts] ****************************************************************************************
  5. ok: [webA]
  6. ok: [webB]
  7. TASK [nginx : check alived] ***********************************************************************************
  8. ok: [webA]
  9. ok: [webB]
  10. TASK [nginx : shell] ******************************************************************************************
  11. changed: [webA]
  12. changed: [webB]
  13. TASK [nginx : debug] ******************************************************************************************
  14. ok: [webA] => {
  15. "ls_result": {
  16. "changed": true,
  17. "cmd": "ls /",
  18. "delta": "0:00:00.002805",
  19. "end": "2018-06-21 11:52:29.343592",
  20. "failed": false,
  21. "rc": 0,
  22. "start": "2018-06-21 11:52:29.340787",
  23. "stderr": "",
  24. "stderr_lines": [],
  25. "stdout": "bin\nboot\ndev\netc\nhome\nlib\nlib64\nmedia\nmnt\nopt\nproc\nroo\nroot\nrun\nsbin\nservice\nsrv\nsys\ntmp\nusr\nvar",
  26. "stdout_lines": [
  27. "bin",
  28. "boot",
  29. "dev",
  30. "etc",
  31. "home",
  32. "lib",
  33. "lib64",
  34. "media",
  35. "mnt",
  36. "opt",
  37. "proc",
  38. "roo",
  39. "root",
  40. "run",
  41. "sbin",
  42. "service",
  43. "srv",
  44. "sys",
  45. "tmp",
  46. "usr",
  47. "var"
  48. ]
  49. }
  50. }
  51. ok: [webB] => {
  52. "ls_result": {
  53. "changed": true,
  54. "cmd": "ls /",
  55. "delta": "0:00:00.002708",
  56. "end": "2018-06-21 11:52:29.359754",
  57. "failed": false,
  58. "rc": 0,
  59. "start": "2018-06-21 11:52:29.357046",
  60. "stderr": "",
  61. "stderr_lines": [],
  62. "stdout": "bin\nboot\ndev\netc\nhome\nlib\nlib64\nmedia\nmnt\nopt\nproc\nroo\nroot\nrun\nsbin\nservice\nsrv\nsys\ntmp\nusr\nvar",
  63. "stdout_lines": [
  64. "bin",
  65. "boot",
  66. "dev",
  67. "etc",
  68. "home",
  69. "lib",
  70. "lib64",
  71. "media",
  72. "mnt",
  73. "opt",
  74. "proc",
  75. "roo",
  76. "root",
  77. "run",
  78. "sbin",
  79. "service",
  80. "srv",
  81. "sys",
  82. "tmp",
  83. "usr",
  84. "var"
  85. ]
  86. }
  87. }
  88. PLAY RECAP ****************************************************************************************************
  89. webA : ok=4 changed=1 unreachable=0 failed=0
  90. webB : ok=4 changed=1 unreachable=0 failed=0
  • ansible-playbook执行入口配置文件nginx.yaml后,它会自动在roles目录下查找nginx目录并进入后查找tasks任务目录并执行main.yaml的任务配置文件。
  • 其实,这个roles的操作等效于以下配置
 
  1. #本配置和之前的roles配置等效
  2. [root@ansible myroles]# cat /service/scripts/test.yaml
  3. ---
  4. - hosts: all
  5. gather_facts: True
  6. tasks: #其实roles的本质就是将tasks任务单独写了。
  7. - name: check alived #并在入口文件里追加了roles去查找tasks配置文件路径
  8. ping:
  9. - name:
  10. shell: ls /
  11. register: ls_result
  12. - debug: var=ls_result
 

12.4 roles中vars自定义变量模组的使用

 
  1. #创建自定义变量vars模组的配置文件
  2. [root@ansible myroles]# cat roles/nginx/vars/main.yaml
  3. ---
  4. my_name: yunjisuan
  5. phone: 1800000000
  6. [root@ansible myroles]# cat roles/nginx/tasks/main.yaml
  7. ---
  8. - name: check alived
  9. ping:
  10. - name:
  11. shell: ls /
  12. register: ls_result
  13. - debug: var=ls_result
  14. - name: #添加对变量引用的任务编排
  15. shell: echo my phone is {{ phone }}
  16. register: echo_result
  17. - debug: var=echo_result
  18. [root@ansible myroles]# ansible-playbook nginx.yaml #执行入口配置文件
 

12.5 使用copy,script模块的标准化

roles模型里使用copy,script模块,默认从roles/nginx/files这里面找

 
  1. [root@ansible myroles]# cat roles/nginx/files/test
  2. welcome to yunjisuan
  3. [root@ansible myroles]# cat roles/nginx/files/test.sh
  4. echo "aaa" >> /tmp/test
  5. [root@ansible myroles]# chmod +x roles/nginx/files/test.sh
  6. [root@ansible myroles]# cat roles/nginx/tasks/main.yaml
  7. ---
  8. - name: check alived
  9. ping:
  10. - name:
  11. shell: ls /
  12. register: ls_result
  13. - debug: var=ls_result
  14. - name:
  15. shell: echo my phone is {{ phone }}
  16. register: echo_result
  17. - debug: var=echo_result
  18. - name: #添加copy模块
  19. copy: src=test dest=/root/
  20. - name: #添加script模块(自动在目标IP机器上执行脚本)
  21. script: test.sh
  22. [root@ansible myroles]# ansible-playbook nginx.yaml
 

12.6 roles中template模块的使用

roles模型里使用template模块,默认从roles/nginx/template里面找

 
  1. [root@ansible myroles]# cat roles/nginx/templates/test.j2
  2. myname is {{ my_name }},my phone is {{ phone }} #引用自定义变量
  3. my ipaddress is {{ansible_all_ipv4_addresses[0]}} #引用内置变量
  4. [root@ansible myroles]# cat roles/nginx/tasks/main.yaml
  5. ---
  6. - name: check alived
  7. ping:
  8. - name:
  9. shell: ls /
  10. register: ls_result
  11. - debug: var=ls_result
  12. - name:
  13. shell: echo my phone is {{ phone }}
  14. register: echo_result
  15. - debug: var=echo_result
  16. - name:
  17. copy: src=test dest=/root/
  18. - name:
  19. script: test.sh
  20. - name:
  21. template: src=test.j2 dest=/root/test2 #下发可变配置文件
  22. [root@ansible myroles]# ansible-playbook nginx.yaml
 

12.7 roles中notify模块的使用

roles使用notify模块,默认从roles/nginx/handles里面找

 
  1. [root@ansible myroles]# cat roles/nginx/handlers/main.yaml
  2. ---
  3. - name: start_nginx #定义handlers的动作类型
  4. shell: /usr/local/nginx/sbin/nginx
  5. - name: stop_nginx #定义handlers的动作类型
  6. shell: /usr/local/nginx/sbin/nginx -s stop
  7. - name: reload_nginx #定义handlers的动作类型
  8. shell: /usr/local/nginx/sbin/nginx -s reload
  9. [root@ansible myroles]# cat roles/nginx/tasks/main.yaml
  10. ---
  11. - name: check alived
  12. ping:
  13. - name:
  14. shell: ls /
  15. register: ls_result
  16. - debug: var=ls_result
  17. - name:
  18. shell: echo my phone is {{ phone }}
  19. register: echo_result
  20. - debug: var=echo_result
  21. - name:
  22. copy: src=test dest=/root/
  23. - name:
  24. script: test.sh
  25. - name:
  26. template: src=test.j2 dest=/root/test2
  27. notify: start_nginx #执行template任务后下发通知给handlers执行start_nginx
  28. [root@ansible myroles]# ansible-playbook nginx.yaml

特别提示: 
notify下发通知只有当之前的任务造成了变化那么才会被执行,如果没有发生任何改变,则notify不会被执行。例如:

 
  1. #tasks任务造成改变,触发notify
  2. [root@ansible myroles]# cat /tmp/test.yaml
  3. ---
  4. - hosts: webA
  5. gather_facts: True
  6. tasks:
  7. - name:
  8. copy: src=/tmp/test dest=/root/ #这步造成目标改变才能出发notify
  9. notify: start_nginx
  10. handlers:
  11. - name: start_nginx
  12. shell: /usr/local/nginx/sbin/nginx
  13. [root@ansible myroles]# ansible-playbook /tmp/test.yaml
  14. PLAY [webA] ***************************************************************************************************
  15. TASK [Gathering Facts] ****************************************************************************************
  16. ok: [webA]
  17. TASK [copy] ***************************************************************************************************
  18. changed: [webA] #发生了改变
  19. RUNNING HANDLER [start_nginx] #触发notify *********************************************************************************
  20. changed: [webA]
  21. PLAY RECAP ****************************************************************************************************
  22. webA : ok=3 changed=2 unreachable=0 failed=0
  23. #我们再次执行/tmp/test.yaml
  24. [root@ansible myroles]# ansible-playbook /tmp/test.yaml
  25. PLAY [webA] ***************************************************************************************************
  26. TASK [Gathering Facts] ****************************************************************************************
  27. ok: [webA]
  28. TASK [copy] ***************************************************************************************************
  29. ok: [webA] #没有造成任务改变,未触发notify通知
  30. PLAY RECAP ****************************************************************************************************
  31. webA : ok=2 changed=0 unreachable=0 failed=0
 

十三,Jenkins环境搭建

由于Jenkins是依赖于java的,所以先介绍java环境的搭建

(1)使用官方的二进制包解压安装,官方二进制包的下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

(2)安装java(解压,移动即可)

 
  1. [root@localhost ~]# tar xf jdk-8u171-linux-x64.tar.gz -C /usr/local/
  2. [root@localhost ~]# cd /usr/local/
  3. [root@localhost local]# mv jdk1.8.0_171 jdk
  4. #全路径验证java是否安装成功
  5. [root@localhost local]# /usr/local/jdk/bin/java -version
  6. java version "1.8.0_171"
  7. Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
  8. Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)

(3)配置java环境变量/etc/profile

 
  1. [root@localhost local]# sed -i.org '$a export JAVA_HOME=/usr/local/jdk/' /etc/profile
  2. [root@localhost local]# sed -i.org '$a export PATH=$PATH:$JAVA_HOME/bin' /etc/profile
  3. [root@localhost local]# sed -i.org '$a export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar' /etc/profile
  4. [root@localhost local]# tail -3 /etc/profile
  5. export JAVA_HOME=/usr/local/jdk/
  6. export PATH=$PATH:$JAVA_HOME/bin
  7. export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
  8. [root@localhost local]# source /etc/profile
  9. [root@localhost local]# java -version
  10. java version "1.8.0_171"
  11. Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
  12. Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)

(4)Jenkins的下载和运行

 
  1. #下载jinkins
  2. [root@localhost ~]# wget http://ftp-chi.osuosl.org/pub/jenkins/war-stable/2.107.2/jenkins.war
  3. #启动jenkins并后台运行
  4. [root@localhost ~]# nohup java -jar jenkins.war &> /tmp/jenkins.out &
  5. [root@localhost ~]# netstat -antup | grep java | grep -v grep
  6. tcp6 0 0 :::8080 :::* LISTEN 15662/java
  7. udp6 0 0 :::5353 :::* 15662/java
  8. udp6 0 0 :::33848 :::* 15662/java

然后我们在浏览器上进行访问:http://IP:8080 出现如下界面

QQ截图20180622111511.png-47.9kB

 

十四,Jenkins介绍和初始化配置

  • Jenkins的作用?

    • 可视化管理服务器
    • 持续构建,可以直接去svn或者git上拉取代码并下发到服务器上
    • 可视化ansible
  • Jenkins监听端口8080

    • nohup java -jar jenkins.war &> /tmp/jenkins.out & #启动Jenkins方式
    • netstat -antup | grep java #查看监听端口
    • http://IP:8080 #访问方式
  • Jenkins默认密码路径,需要到Jenkins所在的服务器进行查看

    • /root/.jenkins/secrets/initialAdminPassword

Jenkins初始化配置:

将服务器上的密码复制过来到浏览器上提交后,静心等待,出现如下界面

QQ截图20180622112929.png-49.8kB

(1)安装必要的插件

1.png-50.5kB

2.png-70.3kB

3.png-65.3kB

(2)新添加一个用户yunjisuan

QQ截图20180622115907.png-25.3kB

(3)查看Jenkins的权限(登录用户可以做任何事情)

系统管理--->全局安全配置

QQ截图20180622121255.png-59.6kB

 

十五,Jenkins实现命令结果的可视化

(1)添加ssh方式的被管理服务器

系统管理--->系统设置--->找到Publish over SSH可以添加对应的操作服务器

1.png-39.5kB

2.png-68.3kB

3.png-23.4kB

4.png-24.3kB

5.png-31kB

6.png-28.9kB

这就添加好一台被管理的主机了。要继续添加被管理的主机只需要重复之前的过程

QQ截图20180622225504.png-19.2kB

(2)创建新任务*

11.png-34.1kB

12.png-67kB

13.png-16.2kB

14.png-43.8kB

(3)立刻构建任务并执行

31.png-39.1kB

32.png-44.7kB

33.png-42.5kB

34.png-45.6kB

35.png-38.3kB

36.png-92.6kB

 

十六,Jenkins+svn实现持续化集成

需求,开发改完代码上传到svn上,然后运维打包最新版本代码部署到业务服务器上。 
svn的部署与应用请参考专题(一)

 

16.1 设置svn的连接密码,并进行代码的部署测试

411.png-48.4kB

412.png-42.8kB

413.png-37kB

414.png-31kB

415.png-27.4kB

416.png-36.5kB

417.png-45kB

420.png-41.4kB

419.png-45.1kB

设置完毕后,应用保存。 
在windows上对svn的yunjisuan项目进行版本提交后 
选择立刻构建项目

QQ截图20180626002020.png-20.5kB

 
  1. [root@webB tmp]# hostname -I
  2. 192.168.200.138
  3. [root@webB tmp]# ls /tmp/test/
  4. mycode
  5. [root@webB tmp]# ls /tmp/test/mycode/
  6. python.py 云计算最终架构示例模板(一).png 云计算最终架构示例模板(二).png 云计算期中架构模版(一).png
 

16.2 模拟真实环境web服务器的代码部署和备份

 
  1. [root@localhost tmp]# mkdir -p /www/{html,backup}
  2. [root@localhost tmp]# tree /www/
  3. /www/
  4. ├── backup #html网页目录的备份放置目录
  5. └── html #网页目录

在jenkins上设置webA,webB两台服务器作为项目的构建目标

911.png-42.6kB

912.png-37.4kB

将以下shell脚本代码复制到构建目标的Exec command里

 
  1. #备份web服务器旧网页目录代码,并将部署到服务器上的新代码覆盖到网页目录里
  2. cd /www
  3. /usr/bin/tar zcf html_$(date +%F-%H-%S).tar.gz html
  4. rm -rf html/*
  5. mv html_*.tar.gz backup/
  6. mv /tmp/test/* /www/html/

913.png-51.5kB

选择立刻构建进行测试

 
  1. #检查webA和webB,代码构建情况
  2. [root@webA tmp]# tree /www/
  3. /www/
  4. ├── backup
  5.    └── html_2018-06-25-12-58.tar.gz #旧网页目录备份
  6. └── html
  7. └── mycode
  8. ├── python.py
  9. ├── \344\272\221\350\256\241\347\256\227\346\234\200\347\273\210\346\236\266\346\236\204\347\244\272\344\276\213\346\250\241\346\235\277\357\274\210\344\270\200\357\274\211.png
  10. ├── \344\272\221\350\256\241\347\256\227\346\234\200\347\273\210\346\236\266\346\236\204\347\244\272\344\276\213\346\250\241\346\235\277\357\274\210\344\272\214\357\274\211.png
  11. └── \344\272\221\350\256\241\347\256\227\346\234\237\344\270\255\346\236\266\346\236\204\346\250\241\347\211\210\357\274\210\344\270\200\357\274\211.png
  12. 3 directories, 5 files
  13. [root@webB tmp]# tree /www/
  14. /www/
  15. ├── backup
  16.    └── html_2018-06-25-12-58.tar.gz #旧网页目录备份
  17. └── html
  18. └── mycode
  19. ├── python.py
  20. ├── \344\272\221\350\256\241\347\256\227\346\234\200\347\273\210\346\236\266\346\236\204\347\244\272\344\276\213\346\250\241\346\235\277\357\274\210\344\270\200\357\274\211.png
  21. ├── \344\272\221\350\256\241\347\256\227\346\234\200\347\273\210\346\236\266\346\236\204\347\244\272\344\276\213\346\250\241\346\235\277\357\274\210\344\272\214\357\274\211.png
  22. └── \344\272\221\350\256\241\347\256\227\346\234\237\344\270\255\346\236\266\346\236\204\346\250\241\347\211\210\357\274\210\344\270\200\357\274\211.png
  23. 3 directories, 5 files
 

16.3 模拟真实环境,开发进行代码回滚

QQ截图20180626011200.png-5kB

(1)右键点击共享目录选择TortoiseSVN--->Show log

QQ截图20180626011434.png-28.9kB

右键点击想要回滚的版本选择Revert to this revision

QQ截图20180626011605.png-14.7kB

QQ截图20180626011617.png-30kB

此时你发现你的共享目录里的东西已经被回滚到了指定的版本。 
最后我们千万别忘记了右键点击共享目录,将结果进行提交(SVN commit)

QQ截图20180626011751.png-32.8kB

(2)重新进行jenkins项目构建,并检查部署情况

 
  1. [root@webA tmp]# tree /www/
  2. /www/
  3. ├── backup
  4. ├── html_2018-06-25-12-58.tar.gz
  5. └── html_2018-06-25-13-15.tar.gz
  6. └── html
  7. └── mycode
  8. ├── python.py
  9. └── \346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.txt
  10. 3 directories, 4 files
  11. [root@webB tmp]# tree /www/
  12. /www/
  13. ├── backup
  14.    ├── html_2018-06-25-12-58.tar.gz
  15.    └── html_2018-06-25-13-15.tar.gz
  16. └── html
  17. └── mycode
  18. ├── python.py
  19. └── \346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.txt
  20. 3 directories, 4 files

QQ截图20180626011930.png-19.7kB

至此,测试成功!

 

十七,Jenkins实现ansible可视化

(1)安装jenkins ansible插件,启动ansible插件

1.png-44.8kB

2.png-68.3kB

3.png-51kB

4.png-17.6kB

最后进入安装界面最下方勾选,安装完成时重启Jenkins

5.png-36.3kB

(2)系统管理--->全局工具配置---->配置ansible

11.png-24.5kB

12.png-52.5kB

13.png-17.1kB

14.png-33.5kB

15.png-9.6kB

(3)新建一个项目任务,使用ansible进行构建,跑个shell和copy模块

新建一个叫做ansible_test的新项目任务,过程略

16.png-87.3kB

进入项目的配置里。构建一个基于ansible的任务

17.png-51.7kB

18.png-53.4kB

然后点击立刻构建功能,并查看输出结果

19.png-35.5kB

(4)新建一个项目任务,使用ansible-playbook进行构建

 
  1. #准备一个playbook的配置文件
  2. [root@ansible scripts]# cat /service/scripts/test.yaml
  3. ---
  4. - hosts: all
  5. tasks:
  6. - name: test jenkins ansible-playbook
  7. shell: echo "welcome to yunjisuan" >> /tmp/yunjisuan.txt

然后新建一个新的项目任务,进行配置

21.png-31.3kB

22.png-32.6kB

23.png-41.3kB

55.png-49kB

56.png-41.3kB

最后查看构建的可视化输出结果

99.png-42.4kB

posted on 2018-07-26 19:01  热巴热吧  阅读(237)  评论(0编辑  收藏  举报