我们现在部署应用软件的方式是通过服务串联起来,运行在一系列分布式的计算资源上,并用各种不同的网络协议进行通信,常见的应用包括web服务、应用服务、SQL数据库等。
你可以手动方式来搭建这些服务:安装服务器操作系统,ssh登录每一台,安装软件包,编辑配置文件等等。这些方式耗费大量时间还经常出错,特别是在做了3~4次之后,这些枯燥重复的手工劳动是令人非常痛苦的。
Ansible可以实现以下目标:
ansible集合了众多优秀的运维工具的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。Ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是Ansible所运行的模块,Ansible只是提供一种框架。
Ansible系统由控制主机对被管节点的操作可以分为两大类,即ad-hoc和playbook;
默认Ansible的Inventory是一个静态的INI格式的文件/etc/ansible/hosts,还可以通过-i参数指定自定义的host文件。
demo1:分别针对不通的主机和主机组进行Ansible的ping模块检测,除ping模块之外ansible还内置了大量其他模块,可通过ansible-doc -l命令查看。
Ansible命令都是并发执行的,默认并发数由ansible.cfg中的forks值来控制,也可以通过-f参数指定并发数。
demo2:获取目标主机主机名
demo3:使用copy模块批量下发文件,文件变化是通过MD5值来判断的。
虽然Ad-Hoc命令功能能完成一些基本配置管理工作,但是无法支撑复杂环境的配置管理工作。在实际使用Ansible的工作中,大部分时间都是在编写playbook。
- hosts: docker # 目标主机:all表示所有主机 也可以针对主机组如:docker
tasks: # task集合,如下面定义了3个task
- name: mkdir config dir # task名称
command: mkdir -p /opt/qax/ngsoc/services/{{ SERVER_NAME }}/k8s/etc # 使用command模块针对目标主机创建目录
- name: copy file/directory
copy: # 使用copy模块批量复制文件
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: root
group: root
mode: 755
with_items: # 定义需要循环的集合
- { src: "script/bin", dest: "/opt/qax/ngsoc/services/{{ SERVER_NAME }}" }
- { src: "k8s", dest: "/opt/qax/ngsoc/services/{{ SERVER_NAME }}" }
- { src: "src/main/resources/bootstrap.yml", dest: "/opt/qax/ngsoc/services/{{ SERVER_NAME }}/k8s/etc" }
- { src: "src/main/resources/logback-spring.xml", dest: "/opt/qax/ngsoc/services/{{ SERVER_NAME }}/k8s/etc" }
- name: deploy
shell: /opt/qax/ngsoc/services/{{ SERVER_NAME }}/k8s/deploy.sh {{ SERVER_NAME }} {{ VERSION }} # 使用shell模块执行脚本
编写完剧本,使用–syntax-check参数检测文件语法
ansible-playbook ansible.yml --syntax-check
使用–list-task显示所有task名称
使用–list-hosts参数显示剧本中针对的目标主机
首先把所有变量定义在某个文件内,然后在playbook文件内使用vars_files参数引用这个变量文件。
Ansible plabook内task之间互相传递数据
- hosts: all
gather_facts: False
tasks:
- name: register
shell: hostname
register: info
- name: display variable
debug: msg="The variable is {{ info['stdout'] }}"
- hosts: all
gather_facts: False
tasks:
- name: debug loops
debug: msg="name ----> {{ item }}"
with_items:
- one
- two
- three
对一对多或者多对多的合并
- hosts: all
gather_facts: False
tasks:
- name: debug loops
debug: msg="name ----> {{ item[0] }}---->{{ item[1] }}"
with_netsted:
- ['A']
- ['a','b','c']
散列loops具有更丰富的数据结构,支持yaml格式的数据变量。相当于python中的字典取值方式
- hosts: all
gather_facts: False
vars:
user:
hello111:
name: hello111
shell: bash
hello222:
name: hello222
shell: zsh
tasks:
- name: debug loops
debug: msg="name->{{ item.key }} value->{{ item.value.name }} shell->{{ item.value.shell }}"
with_dict: "{{ user }}"
针对文件进行操作中最常用的一种循环
- hosts: all
gather_facts: False
tasks:
- name: debug loops
debug: msg="filename---->{{ item }}"
with_fileglob:
- /home/mashaokang/*.yaml
hosts: all
gather_facts: False
tasks:
- name: debug loops
debug: msg="filename---->{{ item }}"
with_random_choice:
- "1"
- "2"
- "3"
达到设置的条件则退出Loops
- hosts: all
gather_facts: False
tasks:
- name: register
shell: hostname -i
register: info
until: info.stdout.find("146") != -1 # loops退出条件,如果不成立则继续执行
retries: 5 # 条件不成立执行5次
delay: 5 # 每次执行间隔5秒
with_first_found
- hosts: all
gather_facts: False
tasks:
- name: debug loops
shell: "{{ item }}"
with_items:
- hostname
- hostname -i
register: host
- name: display loops
debug: msg="{% for i in host.results %} {{ i.stdout }} {% endfor %}"
Ansible还支持从外部拉取信息,比如从数据库里面读取信息然后定义成一个变量。
- hosts: all
gather_facts: False
vars:
contents: "{{ lookup('file','/etc/sysconfig/network') }}"
tasks:
- name: debug lookups
debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
- hosts: all
gather_facts: False
vars:
contents: "{{ lookup('password','ansible_book') }}" # 传入需要加密的字符串
tasks:
- name: debug lookups
debug: msg="The contents is {{ contents }}"
相当于python中的if…else 这里用when来判断真假
groups变量是一个全局变量,会打印出Inventory文件中所有主机以及主机组信息,返回一个json字符串可以直接当变量使用,即{{ group }}
还可以引用其中的字符串,如{{ group['docker'] }}
;groups_names变量会打印当前主机所在的groups名称,如果没有定义会返回ungrouped,
返回的也是一个组名称的list列表。