1、特点
- 基于ssh架构
- 模块丰富
- 支持自定义模块
- 支持异构IT架构(支持Linux和Windows、Mac)
- Paramiko(python对ssh的实现),PyYaml和Jinja2三个
- 安全 基于openssh
- 幂等性 一次执行和n次执行效果一致 不会因为重复执行带来意外
- 支持playbook编排任务,yaml格式
2、配置ssh密钥
vim /etc/hosts
ip1 hostname1
ip2 hostname2
ssh-keygen -f /root/.ssh/id_rsa -N ''
for i in master01 master02 worker01 worker02 worker03
do
ssh-copy-id $i
done
输入:y
输入密码
3、ansible配置文件
默认配置文件路径:
/etc/ansible/ansible.cfg
ansible配置文件查找顺序
- 系统变量ANSIBLE_CONFIG定义的配置文件
- 当前目录下的ansible.cfg
- 家目录下的ansible.cfg vim ~/ansible/ansible.cfg
- /etc/ansible/ansible.cfg文件
ansible配置文件
[defaults]
inventory = ~/ansible/hosts # 主机清单文件
forks = 5 # ssh并发数量
ask_pass = True # 使用密钥还是密码远程
host_key_checking = False # 是否校验密钥
4、主机清单inventory
[test1]
node1
[proxy]
node2
node1
[webserver]
node[3:4]
node[a:z]
[test2:children] # 嵌套组
test1
webserver
检查配置是否正常
cd ~/ansible
ansible all --list-hosts
ansible node1 -m ping
ansible node1,node2 -m ping
ansible webserver -m ping
5、ansible ad-hoc命令
ansible 主机集合(主机名) -m 模块名 -a "参数"
- -k:使用密码远程 默认使用密钥远程主机
- -i:指定主机列表文件
模块
模块就是脚本。
默认模块command
ansible node1 -m command -a "uptime"
ansible node1 -m command -a "uname -r"
ansible node1 -a "ip a s eth0"
ansible all -a "date"
ansible --help
ansible-doc -l # 列出所有模块
ansible-doc yum # 查看模块帮助
6、ansible常用模块
6.1、shell和command
command和shell模块区别
- command模块命令不启动shell,直接通过ssh执行命令
- command不支持bash特性,如管道和重定向等
- 所有需要调用shell的功能都无法使用
ansible node1 -a "ps |wc -l" # 失败
ansible node2 -a "ls &" # 失败
使用shell模块会调用shell解释器,但是无法使用vim或者top等。
ansible node1 -m shell -a "ps aux|wc -l"
ansible node1 -m shell -a "who"
ansible node1 -m shell -a "touch /tmp/tmp.txt"
指定命令目录chdir
ansible node1 -m shell -a "chdir=/tmp touch 1.txt"
判断creates、removes
- creates文件名:文件存在,不执行shell
- remove文件名:文件不存在,不执行shell
ansible node1 -m shell -a "ssh-keygen -f ~/.ssh/id_rsa -N '' creates=~/.ssh/id_rsa" # 有~/.ssh/id_rsa,则不创建密钥
ansible node1 -m shell -a "unzip xx.zip removes=/bin/unzip" # 没有/bin/unzip则不执行命令
6.2、script模块
执行复杂命令?
- script允许在本地写脚本,拷贝到被管理端执行脚本
- 脚本不仅仅是shell脚本(python、perl等)
#!/bin/bash
ansible node1 -m script -a "./test.sh"
6.3、file模块
file模块可以创建文件、目录、链接、修改权限和属性等.
幂等性。
state常用值:absent,directory,file,hard,link,touch
# 创建文件
ansible node1 -m file -a "path=/tmp/file.txt state=touch"
# 创建目录
ansible node1 -m file -a "path=/tmp/mydir state=directory"
# 修改权限
ansible node1 -m file -a "path=/tmp/file.txt owner=sshd group=adm mode=0777"
# 删除
ansible node1 -m file -a "path=/tmp/mydir state=absent"
ansible node1 -m file -a "path=/tmp/1.txt state=absent"
# 链接 src源文件 path链接
ansible node1 -m file -a "src=/etc/hosts path=/tmp/host.txt state=link"
6.4、copy模块
文件拷贝到远程主机 backup=yes 目标主机已存在,先备份
ansible node1 -m copy -a "src=~/a3.txt dest=/root/"
ansible node1 -m copy -a "src=~/a3.txt dest=/root/3a.txt"
# content文件内容
ansible node1 -m copy -a "content='hello world\n' dest=/root/new.txt"
6.5、fetch模块
与copy左右相似,但是作用相反:将其他主机文件拷本到本地
ansible node1 -m fetch -a "src=/etc/hostname dest=~/"
6.6、lineinfile和replace模块
修改单个文件单行内容使用lineinfile
# 添加一行内容,默认在最后
ansible node1 -m lineinfile -a "path=/etc/issue line='hello world'"
# 插入到Kernel行后面
ansible node1 -m lineinfile -a "path=/etc/issue line='insert' insertafter='Kernel'"
# 匹配hello行,替换整行。没有匹配到,最后行添加;匹配多行,替换最后一行。
ansible node1 -m lineinfile -a "path=/etc/issue regexp='hello' line='ni hao'"
replace会替换关键字
# 全文替换
ansible node1 -m replace -a "path=/etc/issue.net regexp=Kernel replace=Ocean"
6.7、user模块
实现Linux账户管理。
# 创建用户
ansible node1 -m user -a "name=tuser"
ansible node1 -m user -a "name=tuser2 uid=1010 group=adm groups=daemon,root home=/home/tuser2"
# 修改账户密码
ansible node1 -m user -a "name=tuser2 password={{'abc'|password_hash('sha512')}}"
# 修改附加组
ansible node1 -m user -a "name=tuser2 groups=root,daemon"
# 删除账户
ansible node1 -m user -a "name=tuser2 state=absent"
# 删除账户所有信息
ansible node1 -m user -a "name=tuser2 state=absent remove=true"
6.8、yum_repository模块
使用yum_repository可以创建或修改yum源配置文件
ansible node1 -m yum_repository -a "name=myyum description=hello baseurl=ftp://192.168.1.1/centos gpgcheck=no"
# 新建yum源配置文件 /etc/yum.repos.d/myyum.repo
# yum源文件名为myyum,内容如下
[myyum]
baseurl=ftp://192.168.1.1/centos
gpgcheck=0
name=hello
# 修改yum源文件内容
ansible node1 -m yum_repository -a "name=myyum description=test baseurl=ftp://192.168.1.1/centos gpgcheck=yes"
# 删除yum源文件
ansible node1 -m yum_repository -a "name=myyum state=absent"
6.9、yum模块
可以安装、卸载、升级软件包
state:present(安装)|absent(卸载)|latest(升级)
# 安装Yum包
ansible node1 -m yum -a "name=unzip state=present"
# 升级
ansible node1 -m yum -a "name=unzip state=latest"
6.10、service模块
服务管理模块,启动关闭,重启服务等。
state:started stopped restarted
enable:yes 设置开机启动
ansible node1 -m yum -a "name=httpd"
# 启动服务并设置开启启动
ansible node1 -m service -a "name=httpd state=started enable=yes"
6.11、逻辑卷相关模块
- lvg模块:创建、删除卷组(vg),修改卷组大小
- state:present|absent
- lvol模块
# 安装lvm2软件包
ansible node1 -m yum -a "name=lvm2"
# 创建myvg卷组,卷组由/dev/vdb1组成
ansbile node1 -m lvg -a "vg=myvg pvs=/dev/vdb1 pvs=/dev/vdb1"
6.5、sudo授权
普通用户以管理员身份执行命令
# 修改/etc/sudoers
vim /etc/sudoers 或者visudo
# 格式
# NOPASSWORD 加在命令前面,就不需要sudo时候输入密码
用户或组 主机列表=(提权身份) [NOPASSWD]:命令列表
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
任何主机以root身份
jerry ALL=(root) /usr/bin/systemctl,/usr/bin/xxx
# 查看自己有哪些授权
sudo -l
配置sudo提权
ansible all -m user -a "name=alex password={{'123456'|password_hash('sha512')}}"
ansible all -m lineinfile -a "path=/etc/sudoers line='alice ALL=(ALL) /usr/bin/systemctl'"
7、ansible配置文件进阶
vim ~/ansible/ansible.cfg
[defaults]
inventory=~/ansible/hosts
remote_user=alice
# host_key_checking=False
[privilege_escalation]
become=True # 是否需要切换用户
become_method=sudo # 如何切换用户
become_user=root # 切换成什么用户
become_ask_pass=no # sudo是否需要输入密码
# 普通用户
for i in node1 node2 node3
do
ssh-copy-id alice@$i
done
主机清单文件
多个变量空格隔开
vim ~/ansible/hosts
[test]
node1 ansible_ssh_port=220
[proxy]
node2 ansible_ssh_user=alice ansible_ssh_port=220
[webserver]
node[3:4] ansible_ssh_pass=密码
[database]
node5 ansible_ssh_private_key_file=密钥文件
8、ansible playbook
特点
- 将经常需要执行的任务写入一个文件(剧本)
- 剧本可包含多个任务
- 随时调用剧本
- playbook按照yaml格式编写
- 适合执行周期性经常执行的复杂任务
playbook语法格式
- playBook文件由一个或多个play组成
- 每个playbook包含:host\task\variables\roles\handlers
- ansible-playbook运行playbook
第一个playbook
---
- hosts: all
tasks:
- name: this is first playbook
ping:
运行命令:
ansible-playbook ~/ansible/test.yaml
- hosts由一个或者多个主机组成
- tasks由一个或者多个任务组成,按照顺序执行
---
- hosts: test,webserver
tasks:
- name: this is first playbook
ping:
- name: Run a shell command
shell: touch ~/shell.txt
- 使用-f指定并发量
ansible-playbook ~/ansible/test.yml -f 5
案例:一个playbook多个play
---
- hosts: test
tasks:
- name: this is first play
ping:
- hosts: webserver
tasks:
- name: this is second play
ping:
案例:创建用户
---
- hosts:
tasks:
- name: create system user
user:
name: john
uid: 1040
shell: /bin/bash
#group: daemon
groups: daemon,sys
password: "{{'123'|password_hash('sha512')}}"
案例:删除用户
---
- hosts: webserver
tasks:
- name: delete user john
user:
name: john
state: absent
案例:创建卷组和逻辑卷
---
- hosts: test
tasks:
- name: create a new primary partition with a Size of 1GB
parted:
device: /dev/sdb
number: 1
state: present
part_end: 1GiB
- name: create a new primary partition with a Size of 1GB
parted:
device: /dev/sdb
number: 2 # 分区编号为2
state: present
part_start: 1GiB # 分区从硬盘的第一个G开始分
part_end: 3GiB
- name: create a volume group on top of /dev/sdb11
lvg:
vg: my_vg
pvs: /dev/sdb1
- name: create a logical volume of 512m
lvol:
vg: my_vg
lv: my_lv
size: 512m
案例:软件安装管理
---
- hosts:
tasks:
- name: update list package
yum:
name:
- httpd
- mariadb
- mariadb-server
- name: install dev tool package group
yum:
name: "@Development tools"
- name: update software
yum:
name: '*'
state: latest
9、特殊模块
9.1、setup
- ansible_facts采集被管理端的系统信息
- 收集的信息被保存在变量中
- 每次执行playbook,默认第一个任务就是Gathering Facts
- 使用setup模块可以查询收集到的facts信息
ansible node1 -m setup
过滤filter
支持通配符。
ansible node1 -m setup -a "filter=ip"
9.2、debug模块
可以显示获取facts里的变量。
debug模块可以显示变量的值,辅助排错。
debug模块有2个参数,var和msg。引用变量需要{{}}。
---
- hosts:
tasks:
- debug:
var: ansible_all_ipv4_address
- debug:
msg: "主机名是:{{ansible_hostname}}"
- debug:
var: ansible_ap1.options
10、ansible定义变量
定义变量方法十几种,下面是优先级由低到高。
10.1、inventory变量(主机清单定义)
[test] # 主机定义变量
node1 myvar1="hello world" myvar2="hello jack"
[webserver]
node[3:4]
[webserver:vars] # 组定义变量
yourname="jackjob"
---
- hosts: node1
tasks:
- name: create a file with var.
shell: echo "{{myvar1}}" > /tmp/"{{myvar2}}"
- hosts: webserver
tasks:
- name: create a user with var.
user:
name: "{{youname}}"
10.2、Host facts 变量(可以直接调用ansible收集的信息)
---
- hosts: node1
tasks:
- name: use facts info.
copy:
content: "{{ansible_hostname}}:{{ansible_bios_version}}"
dest: /tmp/facts.txt
10.3、Register变量(可以将某个命令的执行结果保存在变量中)
---
- hosts: node1
tasks:
- name: save the result to a variable.
shell: hostname
register: myvar
- name:
debug:
# msg: "{{myvar}}"
# 通过.可以获取部分
msg: "{{myvar.end}}"
10.4、Playbook变量(vars关键字定义变量)
---
- hosts: node1
vars:
ipname: heal
ipass: "123456"
tasks:
- name: user variable create user
user:
name: "{{ipname}}"
password: "{{ipass|password_hash('sha512')}}"
10.5、Playbook提示变量(根据提示输入变量值)
---
- hosts: test
vars_prompt:
- name: iname
prompt: "请输入用户名"
private: no # 回显用户名
- name: ipasswd
prompt: "请输入密码"
private: yes # 不显示密码
tasks:
- name: create a user.
user:
name: "{{iname}}"
password: "{{ipasswd|password_hash('sha512')}}"
10.6、变量文件 (剧本调用 vars_files)
---
uname: jack
ipass: "123456"
---
- hosts: node1
vars_files: variables.yml
tasks:
- name: create user
user:
name: "{{uname}}"
password: "{{upwd | password_hash('sha512')}}"
10.7、命令行变量
---
- hosts:
tasks:
- name: create user
user:
name: "{{name}}"
password:"{{pwd|password_hash('sha512')}}"
ansible-playbook cmd.yml -e name="zhangsan" -e pwd="123456"
11、自动化运维
11.1、ansible模块应用
1、firewalld模块
---
- hosts: test1
tasks:
- name: install firewalld.
yum:
name: firewalld
state: present
- name: run firewalld.
service:
name: firewalld
state: started
enable: yes
- name: set firewall rule.
firewalld:
port: 80/tcp
permanent: yes
state: enable
2、template模块
- copy可以把文件拷贝给远程主机。
- copy拷贝常量文件,template拷贝变量文件
- 希望每个主机拷贝的变量不一致
- 可以利用jinja2模版读取变量
使用facts自带变量
#index.html
welcome to {{ansible_hostname}} on {{ansible_eth0.ipv4.address}}
---
- hosts: webserver
tasks:
- name: use template copy index.html to webserver.
template:
src: ~/ansible/template/index.html
dest: /var/www/html/index.html
使用自定义变量
# index.j2
{{welcome}} {{iname}}
---
- hosts: webserver
vars:
welcome: "hello",
iname: "jack"
tasks:
- name: use template copy file
template:
src: ~/index.j2
dest: /tmp/
11.2、error处理机制
默认ansible遇到error会立刻停止playbook。
---
- hosts: node1
ignore_errors: true # 针对全局忽略出错
tasks:
- name: start server
service:
name: haha # 没有此应用
state: started
ignore_errors: true # 针对某个服务忽略出错。
11.3、handlers
任务之间存在依赖关系。
- 通过handler定义一组任务
- 某个任务触发handlers时,才执行相应的任务
- 多个notify触发执行handlers任务,也仅执行一次
- 仅当任务状态为changed时,handlers任务才执行
- handlers任务在所有其他任务都执行后才执行。
---
- hosts: node1
tasks:
- name: create direct
file:
path: /tmp/subdir/
state: directory
notify: touch file
handlers:
- name: touch file
file:
path: /tmp/subdir/12.txt
state: touch
11.4、条件判断
-
when可以定义判断条件,条件为真时,才执行某个任务。
-
常见条件操作符
==、!=、>、>=、<、<=
-
多个条件and 或 or分割
-
when表达式调用变量不使用{{}}
-
> 是不保留换行符的,无论多少行都认为是一行
---
- hosts: node1
tasks:
- name: check mem size
service:
name: NetworkManager
state: stopped
when: ansible_memfree_mb < 700
---
- hosts:
tasks:
- name: touch a file
file:
path: /tmp/when.txt
state: touch
when: > # 支持多行输入,不保留换行符
ansible_distribution == "ReadHat"
and
ansible_distribution_major_version == "8"
11.5、block任务块(任务多合一)
将多个任务合并为一个组。
---
- hosts: node1
tasks:
- name: define a gourp of tasks
block:
- name: install httpd
yum:
name: httpd
state: present
- name: start httpd
service:
name: httpd
state: started
when: ansible_distribution == "RedHat"
rescue定义block任务执行失败时要执行的其他任务。
always定义无论block任务是否成功,都要执行的任务。
---
- hosts: node1
tasks:
- block:
- name: touch a file test1.txt
file:
path: /tmp/test1.txt
state: touch
rescue:
- name: touch a file test2.txt
file:
path: /tmp/test2.txt
state: touch
always:
- name: touch a file test3.txt
file:
path: /tmp/test3.txt
state: touch
11.6、loop循环
- item是关键字
# 数组
---
- hosts: webserver
tasks:
- name: mkdir multi dir
file:
path: /tmp/{{item}}
state: directory
loop:
- School
- Legend
- Life
# 对象
---
- hosts: test
tasks:
- name: create multi user.
user:
name: "{{item.iname}}"
password: "{{item.ipass|password_hash('sha512')}}"
loop:
- {iname:'term',ipass:'123456'}
- {iname:'amy', ipass:'654321'}
12、ansible vault
-
Ansible有时需要访问敏感数据,如密码、key等。
-
ansible-vault可以加密和解密数据。
-
- encrypt 加密
- decrypt 解密
- view 查看
- rekey 修改密码
echo 123456 > data.txt
ansible-vault encrypt data.txt
ansible-vault view data.txt
absible-vault rekey data.txt # 修改密码
# 加密解密输入密码麻烦,将密码写入文件。 pass.txt为密码文件
ansible-vault encrypt --vault-id=pass.txt data.txt
ansible-vault decrypt --vault-id=pass.txt data.txt
传送敏感数据到远程主机
# 电脑存放时候先加密,进行传输再解密
ansible-vault encrypt --vault-id=pass.txt data.txt
ansible test -m copy --vault-id=pass.txt -a "src=data.txt dest=/tmp/ mode=0600"
playbook调用敏感数据
iname: cloud
ipass: '123456'
密码文件加密
ansible-vault encrypt variables.yml
---
- hosts: test
vars_files: variables.yml
tasks:
- name: include vault data,create user.
user:
name: "{{iname}}"
password: "{{ipass|password_hash('sha512')}}"
ansible-playbook --ask-vault-pass vault.yml
或者
ansible-playbook --vault-id=pass.txt vault.yml
13、ansible roles
一般情况我们需要实现不同功能,需要编写大量的playbook文件,并且playbook还会调用其他文件(如变量文件)。管理起来很复杂。
ansible 是1.2版本支持Roles。
Roles是管理ansible文件的一种规范(目录结构)。
roles会按照标准规范,自动到特定的目录和文件中读取数据。
目录结构
ansible/roles
└── issue
├── README.md
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
defaults/main.yml | 定义变量的缺省值、默认值,优先级低。 |
---|---|
files目录 | 存储静态文件的目录 |
handlers/main.yml | 定义handlers |
meta/main.yml | 写作者、版本等描述信息 |
tasks/main.yml | 定义任务的地方 |
templates目录 | 存放动态数据文件的地方,模版文件 |
vars/main.yml | 定义变量,优先级高 |
创建Role项目
ansible-galaxy可以创建、管理roles。
mkdir ~/ansible/roles
ansible-galaxy init ~/ansible/roles/issue
tree ~/ansible/roles/issue
This is the system {{ansible_hostname}}
Todays date is : {{ansible_date_time.date}}
Contact to {{admin}}
---
admin: [email protected]
---
- name: delete issue file
template:
src: issue.j2
dest: /etc/issue
调用role
- 1、在role相同目录下创建一个playbook调用
---
- hosts: webserver
roles:
- issue
- role2 # 支持多个role
- 2、在ansible.cfg设置roles_path=路径
在线共享role网站
ansible-galaxy search 'httpd'
# 查看roles基本信息
ansible-galaxy info acandid.httpd
# 下载特定roles
ansible-galaxy install acandid.httpd -p ~/ansible/roles
# 列出本地roles
ansible-galaxy list -p roles
14、综合案例
部署LNMP环境
- 拷贝nginx源码包到roles/files下面
- 编写安装nginx脚本
#!/bin/bash
conf="/usr/local/nginx/conf/nginx.conf"
yum -y install gcc pcre-devel openssl-devel make
cd /tmp/
tar -xf nginx-1.16.1.tar.gz
cd nginx-1.16.1
./configure --with-http_ssl_module
make && make install
sed -i '65,71s/#//' $conf
sed -i '/SCRIPT_FILENAME/d' $conf
sed -i 's/fastcgi_params/fastcgi.conf' $conf
---
- name: copy nginx-1.16.1.tar.gz to webserver
copy:
src: nginx-1.16.1.tar.gz # files下面
dest: /tmp/
- name: install nginx through shell script
script: install_nginx.sh # 也在files下面
creates: /usr/local/nginx/sbin/nginx # 条件判断,文件存在,不执行脚本
- name: copy index.html to webserver
template:
src: index.html
dest: /usr/local/nginx/html/index.html
- name: install php
yum:
name:
- php
- php-fpm
- php-mysqlnd
- mariadb-devel
- name: run all service
block:
- service:
name: php-fpm
state: started
- shell: /usr/local/nginx/sbin/nginx
args:
creates: /usr/local/nginx/logs/nginx.pid
调用剧本
---
- hosts: webserver
roles:
- lnmp
ansible-playbook lnmp.yaml
标签:name,ansible,state,Ansible,hosts,node1,txt From: https://www.cnblogs.com/20190707wdd/p/16831087.html