标签:判断 机器 开机自启 zone agent dev news 现在 ota
Ansible是一个IT自动化的配置管理工具,自动化主要体现在Ansible集成了丰富模块、丰富的功能组件,可以通过一个命令完成一系列的操作。进而减少我们重复性的工作和维护成本,以提高工作效率!
$ wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
$ yum install ansible -y
$ ansible --version
ansible 2.9.10
config file = /etc/ansible/ansible.cfg
configured module search path = [u‘/root/.ansible/plugins/modules‘, u‘/usr/share/ansible/plugins/modules‘]
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Nov 20 2015, 02:00:19) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]
$ ansible <host-pattern> [option]
--version: # ansible版本信息
-v:显示详细信息
-i:主机清单文件路径,默认是/etc/ansibel/hosts
-m:使用的模块的名称,默认使用command模块
-a:使用的模块参数,模块的具体工作
-k:提示输入ssh密码,而不使用基于ssh的秘钥认证
-C:模拟执行测试,但不会真的执行
-T:指定命令的超时时间
ansible配置文件优先级顺序:
Inventory
文件中填写需要被管理主机与主机组信息(逻辑上定义)。默认Inventory
文件在/etc/ansible/hosts
。当然也可以自定义,然后使用-i
指定Inventory
文件位置:示例:
$ cat /etc/ansible/hosts
# 方法一
[webservers]
192.168.100.225 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=‘123456‘
192.168.100.226 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=‘123456‘
# 方法二
[webservers]
web[1:2].lzj.com ansible_ssh_pass=‘123456‘
# 方法三
[webservers]
web[1:2].lzj.com
[webservers:vars]
ansible_ssh_pass=‘123456‘
$ ssh-keygen
$ ssh-copy-id 192.168.100.225
$ ssh-copy-id 192.168.100.226
$ mkdir project1/ && cd project1/
$ vim hosts
[web]
192.168.100.225
192.168.100.226
$ ansible web -m ping -i hosts
[lbservers]
192.168.100.221
192.168.100.222
[webservers]
192.168.100.223
192.168.100.224
[servers:children] # 定义servers组包含两个子组(lbservers、webservers)
lbservers
webservers
$ ansible all -i hosts --list-hosts
hosts (2):
192.168.100.225
192.168.100.226
$ ansible web -i hosts --list-hosts
hosts (2):
192.168.100.225
192.168.100.226
ad-hoc
就是临时命令,执行完成后就结束,并不会保存!
比如在多台机器上查看某个进程是否启动,或拷贝指定文件到本地,等等!
command # 指定shell命令(不支持管道等特殊字符)
shell # 执行shell命令
scripts # 执行shell脚本
yum_repository # 配置yum仓库
yum # 安装软件
copy # 变更配置文件
file # 建立目录或文件
service # 启动、停止服务
mount # 挂载设备
cron # 定时任务
firewalld # 防火墙
get_url # 下载软件
$ ansible-doc -l # 查看所有模块说明
$ ansible-doc copy # 表示指定模块方法
$ ansible-doc -s copy # 表示指定模块参数
# 示例一: 安装当前最新的Apache软件,如果存在则更新
$ ansible web -m yum -a "name=httpd state=latest" -i hosts
# 示例二: 安装当前最新的Apache软件,通过epel安装
$ ansible web -m yum -a "name=httpd state=present enablerepo=epel" -i hosts
# 示例三: 通过公网URL安装rpm软件
$ ansible web -m yum -a "name=https://mirrors4.tuna.tsinghua.edu.cn/zabbix/zabbix/4.0/rhel/7/x86_64/zabbix-agent-4.0.0-2.el7.x86_64.rpm state=present" -i hosts
# 示例四:更新所有的软件包,但排除和kernel相关的
$ ansible web -m yum -a "name="*" state=present exclude="kernel*" -i hosts
# 示例五: 删除Apache软件
$ ansible web -m yum -a "name=httpd state=absent" -i hosts
# 示例一: 将本地的httpd.conf文件Listen 端口修改为9999,然后推送到远程主机
$ sed -i ‘s/Listen 80/Listen 9999/g‘ httpd.conf
$ ansible web -m copy -a "src=httpd.conf dest=/etc/httpd/conf/httpd.conf owner=root group=root mode-644" -i hosts
# 示例二: 将本地的httpd.conf文件Listen端口修改为9988,然后推送到远端,检查远端是否存在上次备份的文件
$ sed -i ‘s/Listen 9999/Listen 9988/g‘ httpd.conf
$ ansible web -m copy -a "src=httpd.conf dest=/etc/httpd/conf/httpd.conf owner=root group=root mode=644 backup=yes" -i hosts
# 示例三: 往远程的主机文件写入内容
$ ansible web -m copy -a "content=123456........ dest=/var/www/html/index.html" -i hosts
# 示例一: 创建文件,并设置属主、属组、权限
$ ansible web -m file -a "path=/var/www/html/t1.html state=touch owner=apache group=apache mode=644" -i hosts
# 示例二: 创建目录,并设置属主、属组、权限
$ ansible web -m file -a "path=/var/www/html/dd state=directory owner=apache group=apache mode=755" -i hosts
# 示例三:递归授权目录的方式
$ ansible web -m file -a "path=/var/www/html state=directory owner=apache group=apache recurse=yes" -i hosts
# 示例一: 下载互联网的软件到本地
$ ansible web -m get_url -a "url=http://192.168.99.181:12138/document/Ansible.docx dest=/root/" -i hosts
# 示例二: 下载互联网文件并进行mds校验
$ md5sum Ansible.docx # 获取文件md5值
7b1a6fe7af7252005987e16ce64e1e1a Ansible.docx
$ ansible web -m get_url -a "url=http://192.168.99.181:12138/document/Ansible.docx dest=/root/ checksum=md5:7b1a6fe7af7252005987e16ce64e1e1a" -i hosts
# 示例一: 启动httpd服务
$ ansible web -m service -a "name=httpd state=started" -i hosts
# 示例二: 重载httpd服务
$ ansible web -m service -a "name=httpd state=reloaded" -i hosts
# 示例三: 重启httpd服务
$ ansible web -m service -a "name=httpd state=restarted" -i hosts
# 示例四: 停止httpd服务
$ ansible web -m service -a "name=httpd state=stopped" -i hosts
# 示例五: 启动httpd服务,并加入开机自启
$ ansible web -m service -a "name=httpd state=started enabled=yes" -i hosts
# 示例一: 创建news基本组,指定gid为9999
$ ansible web -m group -a "name=news gid=9999 state=present"
-i hosts
# 示例二: 创建http系统组,指定gid为8888
$ ansible web -m group -a "name=http gid=8888 state=present
system=yes" -i hosts
# 示例三: 删除test基本组
$ ansible web -m group -a "name=test state=absent" -i hosts
# 示例一: 创建job用户,uid是1040,主要组是adm
$ ansible web -m user -a "name=job uid=1040 group=adm" -i hosts
# 示例二: 创建joh用户,登录shell是/sbin/nologin,追加bin、sys两个组
$ ansible web -m user -a "name=joh groups=bin,sys shell=/sbin/nologin" -i hosts
# 示例三: 创建jsm用户,为其添加123作为登录密码,并创建家目录
$ ansible localhost -m debug -a "msg={{ ‘123‘ | password_hash(‘sha512‘,‘salt‘) }}"
# 获取123加密后的字符串
$6$salt$jkHSO0tOjmLW0S1NFlw5veSIDRAVsiQQMTrkOKy4xdCCLPNIsHhZkIRlzfzIvKyXeGdOfCBoW1wJZPLyQ9Qx/1
$ ansible web -m user -a ‘name=jsm password=$6$salt$jkHSO0tOjmLW0S1NFlw5veSIDRAVsiQQMTrkOKy4xdCCLPNIsHhZkIRlzfzIvKyXeGdOfCBoW1wJZPLyQ9Qx/1 create_home=yes‘ -i hosts
# 示例四: 移除job用户
$ ansible web -m user -a "name=job state=absent remove=yes" -i hosts
# remove=yes删除普通用户家目录
# 示例五: 创建http用户,并为该用户创建2048字节的私钥,存放在~/http/.ssh/id_rsa
$ ansible web -m user -a "name=http generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa" -i hosts
# 示例一: 添加定时任务,每分钟执行一次ls
$ ansible web -m cron -a "name=job1 job=‘ls > /dev/null‘" -i hosts
# 示例二: 添加定时任务,每天的凌晨2点和凌晨5点执行一次ls
$ ansible web -m cron -a "name=job2 job=‘ls > /dev/null‘ minute=0 hour=2,5" -i hosts
# 示例三: 关闭定时任务,使定时任务失败
$ ansible web -m cron -a "name=job2 job=‘ls > /dev/null‘ minute=0 hour=2,5 disabled=yes" -i hosts
# 环境准备:
$ ansible localhost -m yum -a "name=nfs-utils state=present"
$ ansible localhost -m file -a "path=/ops state=directory"
$ ansible localhost -m copy -a ‘content="/ops 192.168.100.1/24(rw,sync)" dest=/etc/exports‘
$ ansible localhost -m service -a "name=nfs state=restarted"
# 示例一: 挂载nfs存储到本地的/opt目录,并实现开机自动挂载
$ ansible web -m mount -a "src=192.168.99.181:/ops path=/opt fstype=nfs opts=defaults state=mounted" -i hosts
# 示例二: 临时卸载nfs的挂载,但不会清理/etc/fstab
$ ansible web -m mount -a "src=192.168.99.181:/ops path=/opt fstype=nfs opts=defaults state=unmounted" -i hosts
# 示例三: 永久卸载ns的挂载,清理/etc/fstab
$ ansible web -m mount -a "src=192.168.99.181:/ops path=/opt fstype=nfs opts=defaults state=absent" -i hosts
# 示例一: 永久放行https的流量,只有重启才生效
$ ansible web -m firewalld -a "zone=public service=https permanent=yes state=enabled" -i hosts
# 示例二: 永久放行8081端口的流量,只有重启才生效
$ ansible web -m firewalld -a "zone=public port=8081/tcp permanent=yes state=enabled" -i hosts
# 示例三: 放行8080-8090的所有的tcp端口流量,临时和永久都生效
$ ansible web -m firewalld -a "zone=public port=8080-8090/tcp immediate=yes permanent=yes state=enabled" -i hosts
总结:playbook是由一个多个多个play组成,一个play可以包含多个task任务。可以理解为:使用不同的模块来共同完成一件事情!
playbook是由yaml语法书写,结构清晰、可读性强。所以必须掌握yaml基础语法!
语法 | 概述 |
---|---|
缩进 | YAML使用固定的缩进风格表示层级结构,每个缩进由两个空格组成,不能使用ta键 |
冒号 | 以冒号结尾的除外,其他所有冒号后面所有必须有空格 |
短横线 | 表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为统一列表 |
变量提供了便捷的方式来管理ansible项目中的动态值,比如:nginx-1.12,可能后期会反复的使用这个版本的值,那么如果将此值设置为变量,后续使用和修改都将变得非常方便。这样可以简化项目的创建和维护。
那么在ansible中定义变量分为以下三种方式:
如果定义的变量出现重复,且造成冲突,怎么办?谁说了算?
1、在playbook的文件开头通过vars关键字进行变量定义
- hosts: web
vars:
- web_packages: httpd
- ftp_packages: vsftpd
tasks:
- name: Install Rpm Packages "{{ web_packages }}" "{{ ftp_packages }}"
yum:
name:
- "{{ web_packages }}"
- "{{ ftp_packages }}"
state: present
2、可以在playbook中使用vars_files
指定文件作为变量文件,好处就是其他的playbook也可以调用
# 1)准备一个变量的文件,建议使用yml格式
$ cat vars.yml
web_packages: httpd
ftp_packages: vsftpd
# 2)准备playbook进行调用
$ cat test.yml
- hosts: web
vars_files:
- vars.yml
tasks:
- name: Install Rpm Packages "{{ web_packages }}" "{{ ftp_packages }}"
yum:
name:
- "{{ web_packages }}"
- "{{ ftp_packages }}"
state: present
3、在Inventory主机清单中定义变量,但是注意:主机变量优先级高于主机组变量
# 1)在Inventory主机清单中对主机组进行定义变量
$ cat hosts
[web]
192.168.100.225
192.168.100.226
[web:vars]
filename=group_vars
# 2)playbook中直接调用变量
$ cat test.yml
- hosts: web
tasks:
- name: Create File
file:
name: /tmp/{{ filename}}
state: touch
4、官方建议是在ansible项目目录中创建两个额外的变量目录,分别是host_vars
和group_vars
group_vars
定义变量方式$ cat hosts
[web]
192.168.100.225
192.168.100.226
# 1)在当前的项目目录中创建两个变量的目录
$ mkdir {group,host}_vars
# 2)在group_vars目录中创建一个文件,文件名与Inventory清单中的主机组名称要保持一致
$ cat group_vars/web
web_packages: wget
ftp_packages: tree
# 3)编写playbook,只需在playbook中使用变量即可
$ cat test.yml
- hosts: web
tasks:
- name: Install Rpm Packages "{{ web_packages }}" "{{ ftp_packages }}"
yum:
name:
- "{{ web_packages }}"
- "{{ ftp_packages }}"
state: present
测试test组能否使用web组定义的变量,无法使用!但是系统提供了特殊的all组,也就是说group_vars
目录下创建一个all文件,定义变量对所有的主机都生效!
host_vars
定义变量方式# 1)在host_vars目录创建一个文件,文件名与Inventory清单中的主机名称要保持一致,如果是IP地址,则创建相同的IP
$ cat hosts
[web]
192.168.100.225
192.168.100.226
# 2)在host_vars目录中创建文件,给192.168.100.225主机定义变量
$ cat host_vars/192.168.100.225
web_packages: zlib-static
ftp_packages: zmap
# 3)转别一个playbook文件调用host主机变量
$ cat test.yml
- hosts: 192.168.100.225
tasks:
- name: Install Rpm Packages "{{ web_packages }}" "{{ ftp_packages }}"
yum:
name:
- "{{ web_packages }}"
- "{{ ftp_packages }}"
state: present
5、通过命令行-extra-vars
或-e
外置穿餐设定变量
# 1)准备playbook文件
$ cat test.yml
- hosts: "{{ host }}"
tasks:
- name: Install Rpm Packages "{{ web_packages }}" "{{ ftp_packages }}"
yum:
name:
- "{{ web_packages }}"
- "{{ ftp_packages }}"
state: present
# 2)执行playbook时进行变量的传递
$ ansible-playbook -i hosts test.yml -e "host=web"
6、变量的优先级顺序:
命令行变量——>paly中的vars_files——>paly中的vars——>host_vars——>group_vars/all
register
关键字可以将某个task任务结果存储至变量中,最后使用debug输出变量内容,可以用于后续排查故障!
- hosts: all
tasks:
- name: system status
shell: netstat -lntp
register: System_Status
- name: System Status
debug: msg="{{ System_Status.stdout_lines }}"
Ansible facts是在被管理主机上通过ansible自动采集发现的变量。facts包含每台特定的主机信息。比如:被控端主机的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态等等。
默认情况的facts变量名都已经预先定义好了,只需要采集被控端的信息,然后传递至facts变量即可!
$ ansible web -m setup -i hosts > facts.txt
# 获取所有的facts变量
facts变量使用场景:
通过facts变量检查被控端主机硬件CPU信息,从而生成不同的Nginx配置文件;
通过facts变量检查被控端主机名称信息,从而生成不同的zabbix配置文件;
通过facts变量检查被控端主机内存状态信息,从而生成不同的memcached配置文件;
………………
1、facts基本用法:比如获取被控端的主机名和IP地址,然后通过debug输出
- hosts: all
tasks:
- name: OutPut variables ansible facts
debug:
msg: this default IPv4 address "{{ ansible_fqdn }}" is "{{ ansible_default_ipv4.address }}"
2、facts开启后会影响Ansible主机的性能,如果没有采集被控端主机需求可选择关闭
- hosts: web
gather_facts: no # 关闭信息采集
判断在Ansible任务中的使用频率非常高,比如yum模块可以检测软件包是否已经被安装,而在这个过程中我们不用做太多的人工干预。但是也有部分任务需要进行判断。
- hosts: web
tasks:
- name: Centos Install Httpd
yum:
name: httpd
state: present
when: ( ansible_distribution == "CentOS" )
- hosts: all
tasks:
- name: Create YUM Repo
yum_repository:
name: ansible_nginx
description: ansible_test
baseurl: http://nginx.org/packages/centos/$releasever/$basearch/
enabled: yes
gpgcheck: no
when: ( ansible_fqdn is match("web*") )
# 当然when也可以使用and与or方式
# when: ( ansible_fqdn is match("web*") ) or
# ( ansible_fqdn is match("lb*") )
通过register将命令执行结果保存至变量,然后通过when语句进行判断
- hosts: all
tasks:
- name: Check Httpd Server
command: systemctl is-active httpd
ignore_errors: yes # 忽略错误
register: check_httpd
- name: Httpd Restart # 如果check_httpd执行命令结果等于0,则重启httpd,否则跳过
service:
name: httpd
state: restarted
when: check_httpd.rc == 0
有时候我们写playbook的时候会发现了很多task都要重复引用某个模块,比如一次启动10个服务,或者一个拷贝10个文件。如果安装传统的写法最少要写10次,这样会显得playbook很臃肿。如果使用循环的方式来编写playbokk,这样可以减少重复使用某个模块!
- hosts: all
tasks:
- name: Service Start
service:
name: "{{ item }}"
state: started
with_items:
- httpd
- sshd
- hosts: all
tasks:
- name: Add Users
user:
name: "{{ item.name }}"
group: "{{item.group }}"
state: present
with_items:
- { name: ‘test01‘,group: ‘bin‘ }
- { name: ‘test02‘,group: ‘root‘ }
- hosts: all
tasks:
- name: Copy File
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
with_items:
- { src: ‘rsync.conf‘ , dest: ‘/tmp/rsync.conf‘ , mode: 644 }
- { src: ‘rsync.pass‘ , dest: ‘/tmp/rsync.pass‘ , mode: 600 }
高级写法(变量套变量):
- hosts: all
vars:
- Path: /tmp
tasks:
- name: Copy File
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
with_items:
- { src: ‘rsync.conf‘ , dest: ‘{{ Path }}/rsync.conf‘ , mode: 644 }
- { src: ‘rsync.pass‘ , dest: ‘{{ Path }}/rsync.pass‘ , mode: 600 }
handlers是一个触发器,也是一个tasks,只不过是一个特殊的tasks,它是需要被tasks触发才会执行。只要配置文件发生变更,则会触发handlers执行重启服务操作,如果配置文件不发生任何变化,则不会重启!
notify监控——>通知——>handlers触发
- hosts: web
tasks:
- name: Instll Nginx
yum:
name: nginx
state: present
- name: Copy Nignx.conf
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nignx Service
handlers:
- name: Restart Nignx Service
service:
name: nginx
state: restarted
handlers注意事项:
默认情况下,Ansible在执行一个playbook时,会执行playbook中的定义的所有任务。Ansible的标签(Tags)功能可以给单独任务甚至整个playbook打上tag标签,然后利用tag标签指定要运行的个别任务,或跳过个别的任务!
- hosts: web
tasks:
- name: Instll Nginx
yum:
name: nginx
state: present
tags: install nginx # 添加tag标签
- name: Copy Nignx.conf
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nignx Service
- name: Start Nginx
service:
name: nginx
state: started
tags: start nginx # 添加tag标签
handlers:
- name: Restart Nignx Service
service:
name: nginx
state: restarted
$ ansible-playbook -i hosts test.yml -t ‘install nginx‘
# 仅仅执行playbook中的某个tag标签
$ $ ansible-playbook -i hosts test.yml --skip-tags ‘install nginx‘
# 跳过playbook中的特定的tag标签
$ ansible-playbook -i hosts test.yml -t ‘install nginx‘ -t ‘start nginx‘
# 指定多个tag标签
$ ansible-playbook -i hosts test.yml --skip-tags ‘install nginx‘ --skip-tags ‘start nginx‘
# 跳过多个tag标签
有时发现大量的playbook内容要重复编写,与tasks之间贡呢需相互调用才能完成各自贡呢。playbook庞大到维护困难,这是就需要使用include!
$ cat restart_httpd.yml
- name: Restart Httpd Service
service:
name: httpd
state: restarted
A Project的yaml文件:
- hosts: web
tasks:
- name: A Project command
command: echo "A"
- name: Restart Httpd
include: restart_httpd.yml
A Project的yaml文件:
- hosts: web
tasks:
- name: B Project command
command: echo "B"
- name: Restart Httpd
include: restart_httpd.yml
高级用法:
一次执行的多个playbook文件!
$ cat tasks_total.yml
- import_playbook: test.yml
- import_playbook: test01.yml
$ ansible-playbook -i hosts tasks_total.yml
- hosts: web
tasks:
- name: Command
command: /bin/false
ignore_errors: yes
- name: Create File
file:
path: /tmp/file
state: touch
通常情况下,当task失败后,play将会终止,任何在前面已经被tasks notify的handlers都不会被执行。如果在play中设置force_handlers
,被通知的handlers就会被强制执行。
- hosts: web
force_handlers: yes # 强制调用handlers
tasks:
- name: Touch File
file:
path: /tmp/test
state: touch
notify: Restart Httpd Service
- name: Install Packages
yum:
name: sb
state: present
handlers:
- name: Restart Httpd Service
service:
name: httpd
state: restarted
- hosts: web
tasks:
- name: Install Httpd Server
yum:
name: httpd
state: present
- name: Service Httpd Started
service:
name: httpd
state: started
- name: Check Httpd Server
shell: ps aux | grep httpd
register: check_httpd
changed_when: false
- name: OutPut Variables
debug:
msg: "{{ check_httpd.stdout_lines }}"
- hosts: web
tasks:
- name: Configure Nginx Server
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nginx Server
- name: Check Httpd
shell: /usr/sbin/nginx -t
register: nginx_check
changed_when:
- (nginx_check.stdout.find(‘successful‘))
- false
- name: Start Httpd Server
service:
name: nginx
state: started
enabled: yes
- handlers: Restart Httpd Server
service:
name: nginx
state: restarted
标签:判断 机器 开机自启 zone agent dev news 现在 ota
原文地址:https://www.cnblogs.com/lvzhenjiang/p/14199445.html