playbooks 是一种简单的配置管理系统与多机器部署系统的基础。与现有的其他系统有不同之处,且非常适合于复杂应用部署
playbook 可以定制配置,可以按指定的步骤有序执行,支持同步以及异步方式。
官网例子:https://github.com/ansible/ansible-examples
playbooks 可以用于声明配置,更强大的地方在于,在playbooks中可以编排有序的执行过程,甚至于做到多组机器间,来回有序的执行特别指定的步骤,并且可以同步或异步发起任务。
ansible-playbook命令参数:
-u REMOTE_USER, --user=REMOTE_USER # ssh 连接的用户名
-k, --ask-pass #ssh登录认证密码 -s, --sudo #sudo 到root用户,相当于Linux系统下的sudo命令
-U SUDO_USER, --sudo-user=SUDO_USER #sudo 到对应的用户
-K, --ask-sudo-pass #用户的密码(—sudo时使用)
-T TIMEOUT, --timeout=TIMEOUT # ssh 连接超时,默认 10 秒
-C, --check # 指定该参数后,执行 playbook 文件不会真正去执行,而是模拟执行一遍,然后输出本次执行会对远程主机造成的修改
-e EXTRA_VARS, --extra-vars=EXTRA_VARS # 设置额外的变量如:key=value 形式 或者 YAML or JSON,以空格分隔变量,或用多个-e
-f FORKS, --forks=FORKS # 进程并发处理,默认 5
-i INVENTORY, --inventory-file=INVENTORY # 指定 hosts 文件路径,默认 default=/etc/ansible/hosts
-l SUBSET, --limit=SUBSET # 指定一个 pattern,对- hosts:匹配到的主机再过滤一次
--list-hosts # 只打印有哪些主机会执行这个 playbook 文件,不是实际执行该 playbook
--list-tasks # 列出该 playbook 中会被执行的 task
--private-key=PRIVATE_KEY_FILE # 私钥路径
--step # 同一时间只执行一个 task,每个 task 执行前都会提示确认一遍
--syntax-check # 只检测 playbook 文件语法是否有问题,不会执行该 playbook
-t TAGS, --tags=TAGS #当 play 和 task 的 tag 为该参数指定的值时才执行,多个 tag 以逗号分隔
--skip-tags=SKIP_TAGS # 当 play 和 task 的 tag 不匹配该参数指定的值时,才执行
-v, --verbose #输出更详细的执行过程信息,-vvv可得到所有执行过程信息。
实例:
[root@localhost ~]# tree /etc/ansible/
/etc/ansible/
├── ansible.cfg
├── group_vars
│ ├── all
│ └── t3
├── hosts
├── roles
│ └── nginx
│ ├── handlers
│ │ └── main.yml
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ ├── default_proxy_params.conf
│ ├── new.conf
│ ├── nginx.conf
│ ├── static_proxy_params.conf
│ ├── upstream.conf
│ ├── vhost.conf
│ ├── vhost_ssl.conf
│ └── websocket_proxy_params.conf
├── site.retry
└── site.yml
[root@localhost ~]# cat /etc/ansible/hosts
[all:vars]
ansible_ssh_private_key_file=/root/.ssh/id_rsa
ansible_ssh_port=22
ansible_ssh_user=root
[t3:vars]
ansible_python_interpreter=/usr/bin/python2
[t3]
192.168.11.162
[root@localhost ~]# cat /etc/ansible/site.yml
- hosts: t3 # 组名
user: root
roles:
- nginx # 角色
[root@localhost ~]# cat /etc/ansible/group_vars/t3 # t3为组名
worker_processes: 4
num_cpus: 4
max_open_file: 65506
worker_connections: 10240
log_format_format: 'json' #日志类型,默认为main
log_format_main: '$remote_addr - $remote_user [$time_local] $request "$status" $body_bytes_sent
"$http_referer" "$request_body" "$http_user_agent" "$http_x_forwarded_for"
cache_status:$upstream_cache_status upstream:$upstream_addr response_time: $request_time
response_time: $request_time host: $host'
log_format_json: '{"client_ip":"$remote_addr","ident":"-","auth":"$remote_user",
"timestamp":"$time_local","request":"$request","response":"$status",
"bytes":"$body_bytes_sent","referer":"$http_referer","request_body":"$request_body",
"user_agent":"$http_user_agent","forwarded":"$http_x_forwarded_for",
"cache_status":"$upstream_cache_status","upstream":"$upstream_addr",
"upstream_status":"$upstream_status","http_host":"$host","ssl_protocol":"$ssl_protocol",
"ssl_cipher":"$ssl_cipher","request_time":"$request_time",
"upstream_response_time":"$upstream_response_time"}'
vhost_domain: ["t1.bet","t2.com","t3.tv"] # 域名列表
upstream_list: [ # upstream 列表
{
"name" : "mobile", # 名称
"server_list": [ # 服务列表
{"ip":"10.0.0.1","port" : 3000,"max_fails":2,"fail_timeout":"30s","weight":5},
{"ip":"10.0.0.2","port" : 3000,"max_fails":2,"fail_timeout":"30s","weight":15},
{"ip":"10.0.0.3","port" : 3000,"max_fails":2,"fail_timeout":"30s","weight":10},
{"ip":"10.0.0.4","port" : 3000,"max_fails":2,"fail_timeout":"30s","weight":5}
]
},
{
"name":"desktop",
"server_list":[
{"ip":"10.0.0.4","port" : 3001,"max_fails":2,"fail_timeout":"30s","weight":1},
{"ip":"10.0.0.3","port" : 3001,"max_fails":2,"fail_timeout":"30s","weight":1},
]
}
]
[root@localhost ~]# cat /etc/ansible/roles/nginx/tasks/main.yml
- name: nginx is at then latest version # 安装nginx
yum: pkg=nginx state=latest
- name: write the nginx.conf config file # nginx.conf 模板文件
template: src=nginx.conf dest=/etc/nginx/nginx.conf
notify:
- restart nginx
- name: write the default_proxy_params.conf config file
template: src=default_proxy_params.conf dest=/etc/nginx/conf.d/default_proxy_params.conf
notify:
- restart nginx
- name: write the default_proxy_params.conf config file
template: src=new.conf dest=/etc/nginx/conf.d/new.conf
notify:
- restart nginx
- name: write the static_proxy_params.conf config file
template: src=static_proxy_params.conf dest=/etc/nginx/conf.d/static_proxy_params.conf
notify:
- restart nginx
- name: write the websocket_proxy_params.conf config file
template: src=websocket_proxy_params.conf dest=/etc/nginx/conf.d/websocket_proxy_params.conf
notify:
- restart nginx
- name: write the upstream.conf config file
template: src=upstream.conf dest=/etc/nginx/conf.d/upstream.conf
notify:
- restart nginx
- name: write the vhost.conf config file
template: src=vhost.conf dest=/etc/nginx/conf.d/vhost.conf
notify:
- restart nginx
- name: write the vhost_ssl.conf config file
template: src=vhost_ssl.conf dest=/etc/nginx/conf.d/vhost_ssl.conf
notify:
- restart nginx
- name: ensure nginx is running
service: name=nginx state=started
[root@localhost ~]# cat /etc/ansible/roles/nginx/handlers/main.yml
- name: restart nginx
service: name=nginx state=started
[root@localhost ~]# cat /etc/ansible/roles/nginx/templates/nginx.conf
worker_processes {{ worker_processes }};
pid /var/run/nginx.pid;
{% if num_cpus == 2 %}
worker_cpu_affinity 01 10;
{% elif num_cpus == 4 %}
worker_cpu_affinity 1000 0100 0010 0001;
{% elif num_cpus >=8 %}
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
{% else %}
worker_cpu_affinity 1000 0100 0010 0001;
{% endif %}
worker_rlimit_nofile {{ max_open_file }}
events {
use epoll;
worker_connections {{ worker_connections }};
multi_accept on;
}
...
# 日志格式配置
{% if log_format_format == 'json' %}
log_format json {{ log_format_json }};
{% else %}
log_format main {{ log_format_main }};
{% endif %}
[root@localhost ~]# cat /etc/ansible/roles/nginx/templates/vhost.conf
{% for domain in vhost_domain %}
server {
listen 80 ;
server_name {{ domain }};
rewrite ^(.*) https://www{{ domain }} permanent;
{% if log_format_format == 'json' %}
access_log logs/{{ domain }}.access.log json;
{% else %}
access_log logs/{{ domain }}.access.log main;
{% endif %}
}
{% endfor %}
[root@localhost ~]# cat /etc/ansible/roles/nginx/templates/vhost_ssl.conf
{% for domain in vhost_domain %}
server {
listen 443;#HTTP Port
server_name www.{{ domain }} {{ domain }};
include /usr/local/nginx/conf.d/new.conf;
index index.jsp index.html index.htm;
{% if log_format_format == 'json' %}
access_log logs/{{ domain }}.access.log json;
{% else %}
access_log logs/{{ domain }}.access.log main;
{% endif %}
if ($http_host = {{ domain }} ) {
rewrite ^(.*)$ https://www.{{ domain }}$1 permanent; }
ssl on;
ssl_certificate /usr/local/nginx/conf.d/ssl/www.{{ domain }}/www.{{ domain }}.crt;
ssl_certificate_key /usr/local/nginx/conf.d/ssl/www.{{ domain }}/www.{{ domain }}.key;
}
{% endfor %}
[root@localhost ~]# cat /etc/ansible/roles/nginx/templates/upstream.conf
{% for upstream_name in upstream_list %}
upstream {{ upstream_name.name }} {
{% for server_name in upstream_name.server_list%}
server {{ server_name.ip }}:{{ server_name.port }} max_fails={{ server_name.max_fails }} fail_timeout={{ server_name.fail_timeout }} weight={{ server_name.weight}};
{% endfor %}
}
{% endfor %}
...
[root@localhost ~]# ansible-playbook /etc/ansible/site.yml
PLAY [t3] ***********************************************************
TASK [Gathering Facts] **********************************************
ok: [192.168.11.162]
TASK [nginx : nginx is at then latest version] **********************
ok: [192.168.11.162]
...