Ansible的playbook的基本使用与快速入门
1.使用playbook有什么好处
2.认识playbook(自动部署nginx)(自动部署docker-ce社区版)
3.YAML语法
4.playbook文件结构
5.在变更时执行操作(handlers)
6.任务控制(tags)
7.playbook文件调试
8.案例:自动部署tomcat
9.Playbook变量定义与使用
10.playbok文件复用
11.流程控制
12.jinja模版渲染配置文件
1. 使用playbook有什么好处
Ansible真正的能力在于使用playbook,也就称为剧本当我们在某个目录下执行某个命令的时候,那么我们可以使用ansible的ad hoc的模式快速执行,而无不虚编写文件或者剧本,但是对于配置的管理和应用的部署,通常有很多的操作,单独的去写ad hoc命令麻烦很多,而且ad hoc适用于简单命令的执行,所以我们使用playbook去完成,如果ansible是工作中用到的工具,那么ploybook就是相当于你使用ansible的说明书,而你的主机就是原材料,写playbook就像写说明书一样,它是一个按顺序执行的一个过程,playbook和ad hoc完全不是一种模式,并且功能强大
Playbook的特点易读的编排语言:它是用最主流的yaml格式去编写的来实现应用的编排,非常适合配置和应用部署,也非常适合部署复杂的任务,我们可以通过声明式的内容将复杂的工作通过playbook进行编排。
这个-syntax-check是检查playbook的语法
[root@ansible playbook-test]# ansible-playbook nginx.yaml --syntax-check playbook: nginx.yaml[root@ansible playbook-test]# vim nginx.yaml [root@ansible playbook-test]# cat nginx.yaml --- - hosts: webservers vars: hello: Ansible tasks: - name: Add repo yum_repository: name: nginx description: nginx repo baseurl: http://nginx.org/packages/centos/7/$basearch/ gpgcheck: no enabled: - name: Install nginx yum: name: nginx state: latest - name: Copy nginx configuration file copy: src: ./site.conf dest: /etc/nginx/conf.d/site.conf - name: Start nginx service: name: nginx state: started - name: Create wwwroot directory file: dest: /var/www/html state: directory - name: Create test page index.htmlshell: echo "hello {{hello}}" > /var/www/html/index.html[root@ansible playbook-test]# lsnginx.yaml site.conf[root@ansible playbook-test]# vim site.confserver { listen 80; server_name devops; location / { root /var/www/html;index index.html; }}
执行playbook[root@ansible playbook-test]# ansible-playbook nginx.yaml
查看进程已经启动
[root@ansible playbook-test]# ansible webservers -m shell -a "ps -ef |grep nginx"10.4.7.22 | SUCCESS | rc=0 >>root 10713 1 0 16:46 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.confnginx 10714 10713 0 16:46 ? 00:00:00 nginx: worker processroot 10849 10848 10 16:49 pts/1 00:00:00 /bin/sh -c ps -ef |grep nginxroot 10851 10849 0 16:49 pts/1 00:00:00 grep nginx10.4.7.21 | SUCCESS | rc=0 >>root 10953 1 0 16:46 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.confnginx 10954 10953 0 16:46 ? 00:00:00 nginx: worker processroot 11088 11087 0 16:49 pts/1 00:00:00 /bin/sh -c ps -ef |grep nginxroot 11090 11088 0 16:49 pts/1 00:00:00 grep nginx
批量部署docker-ce社区版
这里运用的模块就shell模块和service,还是很简单的。
---- hosts: webservers gather_facts: no remote_user: root tasks: - name: install packages shell: yum -y install yum-utils device-mapper-persistent-data lvm2 - name: docker packages shell: wget -O /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo - name: install docker-ce shell: yum -y install docker-ce - name: daocloud speed up shell: curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io - name: systemctl start docker service: name=docker state=started
测试查看是否安装成功
[root@ansible ~]# ansible webservers -m shell -a "docker -v"10.4.7.21 | SUCCESS | rc=0 >>Docker version 19.03.5, build 633a0ea10.4.7.22 | SUCCESS | rc=0 >>Docker version 19.03.5, build 633a0ea
YAML语法格式
缩进表示层级关系
不支持制表符"tab" 缩进
通常开头缩进2个空格
字符后缩进1个空格,如冒号,逗号等
"---"表示YAML格式,一个文件的开头
"#"注释
在变更时执行操作(handlers)处理器
主要用于当你出来某个操作变更时,它帮你触发另一个任务
- hosts: webservers
gather_facts: no
这个会收集列表主机的信息,会很耗时间,一般就是禁用掉,这样的话就提高我们playbook的效率
自动部署tomcat
1. 安装jdk
2. 下载tomcat包
3. 解压tomcat
4. 启动
安装tomcat
---- hosts: webservers gather_facts: no vars: tomcat_version: 9.0.29 tomcat_install_dir: /usr/local tasks: - name: Install java-1.8.0-openjdk.x86_64 shell: yum -y install java-1.8.0-openjdk.x86_64 state=present - name: Download tomcat get_url: url=http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.29/bin/apache-tomcat-9.0.29.tar.gz dest=/tmp - name: Unarchive tomcat-{{ tomcat_version }}.tar.gz unarchive: src: /tmp/apache-tomcat-{{ tomcat_version }}.tar.gz dest: "{{ tomcat_install_dir }}" copy: no - name: Start tomcat shell: cd {{ tomcat_install_dir }} && mv apache-tomcat-{{ tomcat_version }} tomcat8 && cd tomcat8/bin && nohup ./startup.sh &[root@ansible tomcat-playbook]# ansible-playbook tomcat.yaml[root@ansible tomcat-playbook]# ansible webservers -m shell -a "ps -ef |grep tomcat"
Playbook变量定义与使用
- 命令行
- 在inventory中定义
- 在playbook中定义
- 在role中定义
- 注册变量(register)
- 系统信息变量(facts)
命令行定义变量
列出主要的变量信息
[root@ansible tomcat-playbook]# ansible-playbook --list-tags tomcat.yaml playbook: tomcat.yaml play #1 (webservers): webservers TAGS: [] TASK TAGS: [][root@ansible tomcat-playbook]# ansible-playbook --list-tasks tomcat.yaml playbook: tomcat.yaml play #1 (webservers): webservers TAGS: [] tasks: Install java-1.8.0-openjdk.x86_64 TAGS: [] Download tomcat TAGS: [] Unarchive tomcat-{{ tomcat_version }}.tar.gz TAGS: [] Start tomcat TAGS: []
debug模块在执行期间打印语句,并且可用于调试变量或表达式,而不必停止playbook。
[root@ansible tomcat-playbook]# vim 1.yaml---- hosts: webservers gather_facts: no remote_user: root tasks: - name: test var debug: msg="{{work_dir}}"[root@ansible tomcat-playbook]# ansible-playbook 1.yaml -e work_dir=/usr/local
定义这个变量也有一定的要求,变量名是要以字母为开头
还有一种在inventory中定义
在/etc/ansible/hosts去定义变量,为一组主机或者多个主机传递不同的变量
也可以单独写到/etc/ansible/group_vars/webservers.yml下,它默认会读取你哪个组里面的变量,以yml的模式更方便
http_port: 8090
server_name: xiabanle
[root@ansible group_vars]# ansible webservers -a "echo {{http_port}}"10.4.7.22 | SUCCESS | rc=0 >>809010.4.7.21 | SUCCESS | rc=0 >>8090[root@ansible group_vars]# ansible webservers -a "echo {{server_name}}"10.4.7.22 | SUCCESS | rc=0 >>xiabanle10.4.7.21 | SUCCESS | rc=0 >>xiabanle
在playbook使用debug模块去定义变量
---- hosts: webservers gather_facts: no remote_user: root vars: - work_dir: /usr/local - nginx_version: 1.16 tasks: - name: Install nginxdebug: msg="{{work_dir}}/nginx/{{nginx_version}}"[root@ansible tomcat-playbook]# ansible-playbook 1.yaml --syntax-checkplaybook: 1.yaml[root@ansible tomcat-playbook]# ansible-playbook 1.yaml
使用file模块创建文件
---- hosts: webservers gather_facts: no remote_user: root vars: - work_dir: /opt - nginx_version: 1.11 tasks: - name: create dir file: "dest={{work_dir}}/nginx/{{nginx_version}} state=directory"
注册变量-register
注册变量就是将你某个任务执行的结果保存到一个变量中,这样的话就是能动态的获取一个变量,例如执行完一个任务,返回有个状态,那么希望根据这个状态异步处理,因为之前的变量由于对应好了,很难知道这次获取的什么变量。
这里有个debug就是专门调试变量用的,这里时创建文件的同时动态定义文件的时间
一般这种就是启动两个服务,这两个服务是有依赖关系的,只有启动第一个服务,第二个才能启动起来,那这种情况下,就可以在启动服务下加一个注册变量,如果第一个服务启动的时候会有pid,或者有其他的输出然后用到定义的注册变量。
---- hosts: webservers gather_facts: no remote_user: root vars: - work_dir: /opt tasks: - name: register var command: date +"%F %T" register: datetime - name: touch file #debug: msg={{datetime}} file: dest=/tmp/r_{{datetime.stdout}} state=touch
系统信息变量(fasts)
以系统变量调用主机名/主机IP并创建文件
这个可以通过set up去调用,来查看我们的ansible的接口api
[root@ansible test]# ansible webservers -m setup---- hosts: webservers gather_facts: yes remote_user: root tasks: - name: touch file file: dest=/tmp/devops_{{ansible_hostname}} state=touch
playbok文件复用
将我们的文件进行复用,可以使用playbook中的incloud_tasks和import_tasks导入进来,这样的好处就是,当我们去写一个比较大的playbook时,可以将它分解成很多小的任务,分解成小的任务之后呢,就能在其他的地方引用,第二个好处就是能组织playbook这些功能模块,如果要写一个大的剧本,可能是上百行,就不太好维护管理了,所以就有了include_tasks和import_tasks的实现来完成这些需求
Include和import的区别
都是导入文件的
Include(动态):在运行时导入
--list-tags, --list-tasks 不会显示到输出
不能使用notify触发来自include内处理程序名称(handlers)
Import*(静态) :在playbook解析时预先导入,就是在playbook之前提前把预先的就导入进来了,
不能与循环一起使用
将变量用于目标文件或角色名称时,不能使用inventory(主机/主机组等)中的变量
复用案例:
安装lnmp/lnmt
只需要将-import调用使用的的那个yaml就可以了
vim lnmp.yaml--- - import_playbook: nginx.yaml - import_playbook: mysql.yaml - import_playbook: php.yamlvim nginx.yaml---- hosts: webservers gather_facts: no remote_user: root tasks: - name: Install nginx debug: msg="install nginx ... " [root@ansible web]# ansible-playbook lnmp.yaml
Import导入的是playbook,而include的是导入的任务文件
[root@ansible web]# ansible-playbook test.yaml---- hosts: webservers gather_facts: no remote_user: root tasks: - name: task1 debug: msg="test1" - name: task2 debug: msg="test2"
但是部署的任务这个tasks,任务比较多时就可以进行分解,可以分成独立的文件,例如有两个任务,我将第一个tasks分解成一个文件,第二个分解成一个文件用include再导入进去
vim test.yaml---- hosts: webservers gather_facts: no remote_user: root tasks: - include_tasks: task1.yaml - include_tasks: task2.yamlvim task1.yaml---- name: tasks1 debug: msg="test1"vim task2.yaml---- name: tasks2 debug: msg="test2"
流程控制
循环
批量创建用户/文件/拷贝文件也可以使用
- name: create file file: path=/tmp/{{item}} state=touch with_items: - "1.txt" - "2.txt" - "3.txt" - "4.txt"执行效果[root@hdss7-200 test-roles]# ansible-playbook -i hosts site.yaml --tags nginxPLAY [roles] ***************************************************************************************************TASK [nginx : create file] *************************************************************************************changed: [10.4.7.22] => (item=1.txt)changed: [10.4.7.22] => (item=2.txt)changed: [10.4.7.22] => (item=3.txt)changed: [10.4.7.22] => (item=4.txt)PLAY RECAP *****************************************************************************************************10.4.7.22 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 常用循环语句:
比如拷贝文件
- name: copy html copy: src=/tmp/{item}} dest=/tmp with_items: - "a.html" - "b.html" - "c.html"
或者通配符,像一些拷贝一些目录的tar.gz的压缩包的时候比如比较多的时候就会用到可以使用fileglob,或者item,进行for循环,进行批量执行,简化操作步骤。
- name: copy html copy: src={{item}} dest=/tmp with_fileglob: - "/tmp/*.html"
模版
比如部署一个应用,nginx,etcd,这些都有自己的配置文件,就比如将nginx,虚拟主机的配置文件,渲染到我们的nginx上,就可以使用template,这个模块就专门支持jr模版
这里定义j2的模版,然后拷贝这个文件过去进行渲染
[root@hdss7-200 test-roles]# cat /tmp/nginx.conf {% set domain_name = domain %}server { listen 80; server_name {{ domain_name }}; location / { root /usr/share/html; }}
定义的变量,进行传递
[root@hdss7-200 test-roles]# cat group_vars/roles.yaml domain: www.xxxxx.com
定义的任务类型
- name: vire hosts template: src=/tmp/nginx.conf dest=/etc/nginx/conf.d/
比如再传递端口的变量,在jinja里使用ansible的变量之间{{ }}去使用
[root@hdss7-200 test-roles]# cat /tmp/nginx.conf {% set domain_name = domain %}server { listen {{ http_port }}; server_name {{ domain_name }}; location / { root /usr/share/html; }}
我在ansible去定义这个变量
[root@hdss7-200 test-roles]# cat group_vars/roles.yaml domain: "www.maidi.com"http_port: "80"
执行成功会将使用j2的模版将我们的配置文件拷贝过来,我们通过j2的模版和ansible定义变量就可以渲染很多我们的功能和需求
[root@hdss7-22 conf.d]# cat nginx.conf server { listen 80; server_name www.maidi.com; location / { root /usr/share/html; }}