运维自动化之ansible
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UVnKuPzc-1606212995520)(ansible.assets/image-20201120101256876.png)]
1,安装
-
yum安装
yum install epel-release yum install ansible
-
pip安装
yum install epel-release pip install ansible
检查版本:
ansible --version
2,建立节点和被管理节点SSH信任关系
管理节点创建密钥对
ssh-keygen -t rsa
将本地的公钥传输到被管理节点
ssh-copy-id lcc@192.168.30.39
检测连通性:
ansible all -i 192.168.30.39 -m ping
拷贝文件:
ansible all -i 192.168.30.39, -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf"
- all 在ansible中,将其叫做pattern,即匹配,资产选择器,all是匹配所有指定的所有资产
- -i 指定ansible的资产,就是被管理服务器
- -m 指定要运行的模块
- -a 指定模块参数。
3,ansible资产
/etc/ansible/hosts
192.168.30.39
[webservers]
192.168.30.39
-
检查所有的资产
ansible all -i hosts --list-hosts
-
检查某一个组
ansible wenservers -i hosts --list-hosts
基本语法:
ansible PATTERN -i inventory -m module -a argument
-
选择一台或者几台服务器
ansible 192.168.30.39 --list-hosts ansible 192.168.30.39,192.168.30.40 --list-hosts
-
选择一组服务器
ansible webservers --list-hosts
-
使用*匹配
ansible 192.168.30.* --list-hosts
-
使用逻辑匹配
两个组内的所有主机
ansible 'webservers:dbservers' --list-hosts
两个组内的共有主机
ansible 'webservers:&dbservers' --list-hosts
在webservers中,不在dbservers中
ansible 'webservers:!dbservers' --list-hosts
4,ansible Ad-Hoc命令
ansible提供两种方式去完成任务,一是ad-hoc命令,一是写ansible playbook
前者可以解决一些简单的任务,后者解决较复杂的任务,比如做配置管理或者部署
1,命令格式
absible pattern [-i inventory] -m module -a argument
- pattern:资产选择器
- -i:指定资产清单文件的位置
- -m:指定本次ansible ad-hoc要执行的模块。可以类别成shell中的命令
- -a:模块的参数,可以类比成shell中的命令参数
2,模块类型
- 核心模块
- 附加模块
- 用户自定义模块
3,联机帮助
常用帮助参数
-
列举所有核心模块
ansible-doc -l
-
查询某个模块的使用方法
ansible-doc modulename
-
查询某个模块的使用方法,比较简洁信息
ansible-doc -s modulename
4,常用模块
4.1:command&shell模块
-
command
ansible all -i hosts -a "echo 'hello'"
-
shell
ansible all -i hosts -m shell -a "echo 'hello'"
- shell模块可以执行shell的内置命令和特性(比如管道符)
- command模块无法执行shell的内置命令和特性
4.2:script模块
将管理节点上的借本传递到被管理节点(远程服务器)上进行执行
创建执行脚本:
echo "touch /tmp/testfile" > a.sh
执行script模块:
ansible webservers -i hosts -m script -a "/home/lcc/a.sh"
查看执行情况:
ansible webservers -i hosts -m shell -a "ls -l /tmp/"
4.3:copy模块
copy模块的主要用于管理节点和被管理节点之间的文件拷贝
常用参数:
- src:指定拷贝文件的源地址
- dest:指定拷贝文件的目标地址
- backup:拷贝文件前,若原始文件发生变化,则对目标文件进行备份
- woner:指定新拷贝文件的所有者
- group:指定新拷贝文件的所有组
- mode:指定新拷贝文件的权限
Example:
-
copy管理节点上的’nginx.repo’到被管理节点上
ansible dbservers -i /etc/ansible/hosts -m copy -a "src=/home/lcc/shell/nginx.repo dest=/etc/yum.repos.d/nginx.repo"
查看被管理节点是否有这个文件
ansible dbservers -i /etc/ansible/hosts -a "ls /etc/yum.repos.d/"
-
被管理节点的文件存在,内容不一样时,备份文件
ansible dbservers -i /etc/ansible/hosts -m copy -a "src=/home/lcc/shell/nginx.repo dest=/etc/yum.repos.d/nginx.repo backup=yes"
查看被管理节点是否有这个文件
ansible dbservers -i /etc/ansible/hosts -a "ls /etc/yum.repos.d/"
4.4:添加yum仓库
- name:仓库名称,就是仓库文件中第一行中的括号中名称,必须的参数
- description:仓库描述信息,添加时必须的参数
- baseurl:yum存储库”repodata“目录所在目录的URL,添加时必须的参数
- file:仓库文件保存到本地的文件名,不包含.rep。默认是name的值
- state:preset确认添加仓库文件,absent确认删除仓库文件
- gpgcheck:是否检查GPG yes|no,没有默认值,使用/etc/yum.conf中的配置
4.5:yum模块
等同于linux上的YUM命令,对运城服务器上RPM包进行管理
-
name:要安装的软件包名,第一个软件包以英文逗号隔开
-
state:对当前指定的软件安装、移除操作(present installed latest absent removed)
支持的参数
- present :确认已安装,但不升级
- installed:确认已经安装
- latest:确保安装,且升级为最新
- absent和remove:确认已移除
Example
安装nginx
ansible dbservers -i /etc/ansible/hosts -m yum -a "name=nginx state=present"
ansible dbservers -i /etc/ansible/hosts -m yum -a "name=nginx state=latest"
ansible dbservers -i /etc/ansible/hosts -m yum -a "name=nginx state=installed"
移除一个软件包
ansible dbservers -i /etc/ansible/hosts -m yum -a "name=nginx state=absent"
ansible dbservers -i /etc/ansible/hosts -m yum -a "name=nginx state=removed"
安装软件组
ansible dbservers -m yum -a "name='@Development tools' stat
e=present"
4.6:systemd模块
管理远程节点上的systemd服务,就是由systemd所管理的服务
参数:
- daemon_reload:重新载入systemd,扫描新的或有变动的单元
- enabled:是否开机自启动yes|no
- name:必选项,服务名称,比如httpd,vsftpd
- state:对当前服务执行启动,停止,重启,重新加载等操作(started、stopped、restarted、reloaded)
Example:
重新加载systemd
ansible dbservers -i /etc/ansible/hosts -m systemd -a "daemon_reload=yes'
启动nginx
ansible dbservers -i /etc/ansible/hosts -m systemd -a "name=nginx state=started"
重新启动nginx
ansible dbservers -i /etc/ansible/hosts -m systemd -a "name=nginx state=restarted"
重载nginx
ansible dbservers -i /etc/ansible/hosts -m systemd -a "name=nginx state=reloaded"
停止nginx
ansible dbservers -i /etc/ansible/hosts -m systemd -a "name=nginx state=stopped"
设置开机自启
ansible dbservers -i /etc/ansible/hosts -m systemd -a "name=nginx enabled=yes"
4.7:group模块
在被管理节点上,对组进行管理
参数:
- name:组名称,必须的
- system:是否为系统组,yes|no
- state:删除或者创建,present/absent,默认为present
Example
创建普通组db_admin
ansible dnservers -i /etc/ansible/hosts -m group -a "name=db_admin"
4.8:user模块
用于在被管理节点上对用户进行管理
参数:
- name:必须的参数,指定用户名
- password:设置用户的密码,这里接受的是一个加密的值,因为会直接存在shadow,默认不设置密码
- update_password:假如设置的密码不同于原密码,则会更新密码
- home:指定用户的家目录
- shell:设置用户的shell
- comment:用户的描述信息
- create_home:在创建用户时,是否创建其家目录。默认创建,假如不创建,设置为no
- group:设置用户的主组
- groups:将用户加入到多个其他组中,多个用逗号隔开。默认会把用户从其他已经加入的组中删除。
- append:yes|no和groups配合使用,yes时不会把用户从其他已经加入的组中删除
- system:设置为yes时,将会创建一个系统账号
- expires:设置用户的过期时间,值为时间戳,会转为天数,放在shadow的第8个字段里
- generate_ssh_key:设置为yes将会为用户生成密钥,这不会覆盖原来的密钥
- state:删除或者添加用户,yes为添加,ansent为删除;默认值present
- remove:当与state=absent一起使用,删除一个用户及关联的目录。比如家目录,邮箱目录,可选值为yes/no
Example:
生成加密密码
pass=$(echo "123456" | openssl passwd -1 -stdin)
echo $pass
$1$iK2BR.YQ$SnG5dfDiKFO5qr7T2Ji1X1
执行ansible命令创建用户foo并设置密码
ansible dbservers -i /etc/ansible/hosts -m user -a
"name=foo password=${pass}"
创建用户kunkun,并且为其创建密钥对,并且密钥类型为:ecdsa
ansible dbservers -i /etc/ansible/hosts -m user -a "name=kunkun generate_ssh_key=yes ssh_key_type=ecdsa"
创建用户tom,并且设置其有效时间到2020年11月25日,追加入到组db_admin中
ansible dbserver -i /etc/ansible/hosts -m user -a "name=tom expires=$(date +%s -d 20201125) groups=db_admin append=yes"
date命令说明
// 计算3小时之后是几点几分
data +%T -d '3 hours'
// 任意日期的前N天,后N天的具体日期
date +%F -d "20190910 1 day"
data +%F -d "20190910 -1 day"
// 计算两个日期相差天数,比如计算生日距离现在还有多少天
d1=$(date +%s -d 20180728)
d2=$(date +%s -d 20180726)
echo $(((d1-d2)/86400))
4.9:file模块
file模块主要用于远程主机上的文件操作
参数:
-
group:定义文件/目录的属组
-
mode:定义文件/目录的权限
-
owner:定义文件/目录的属主
-
path:必选项,定义文件/目录的路径
-
recurse:递归的设置文件的属性,只对目录有效
-
src:要被链接的源文件的路径,只应用于state=link的情况
-
dest:被链接到的路径,只应用于state=link的情况
-
state:
-
directory:如果目录不存在,创建目录
-
file:文件不存在,则不会被创建,存在则返回文件的信息,常用于检查文件是否存在
-
link:创建软链接
-
hard:创建硬链接
-
touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
-
absent:删除目录、文件或者取消文件
-
Example
创建一个文件
ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/foo.conf state=touch"
改变文件所有者及权限
ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/foo.conf owner=nobody group=nobody mode=0644"
创建一个软链接
ansible all -i /etc/ansible/hosts -m file -a "src=/tmp/foo.conf dest=/tmp/linl.conf state=link"
创建一个目录
ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/testdir state=directory"
取消一个链接
ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/link.conf state=absent"
删除一个文件
ansible all -i /etc/ansible/hosts -m file -a "path=/tmp/foo.conf state=absent"
4.10:cron模块
关联远程节点的cron服务,等同于linux中的计划任务
[^]: 注意:使用ansible创建的计划任务,是不能使用本地crontab -e去编辑,否则ansible无法再次操作此计划任务
参数:
- name:指定一个cron job的名字,一定要指定,便于日后删除
- minute:指定分钟,可以设置成(0-59,***, **/2等),默认是,也就是每分钟
- hour:指定小时,可以设置成(0-23,***, **/2等),默认是,也就是每小时
- day:指定小时,可以设置成(0-31,***, **/2等),默认是,也就是每天
- month:指定月份,可以设置成(1-12,***, **/2等),默认是,也就是每月
- weekday:指定星期,可以设置成(0-6,**, Sunday-Saturday等),默认是,也就是每星期
- job:指定要执行的内容,通常可以写个脚本,或者一段内容
- state:指定这个job的状态,可以是新增(present)或者是删除(absent),默认为新增(present)
Example
新建一个cron job任务
ansible all -i /etc/ansible/hosts -m cron -a "name='create new job' minute='0' job='ls -alh > /dev/null'"
删除一个cron job任务,删除时,一定要正确指定job的name参数,以免误删除
ansible all -i /etc/ansible/hosts -m cron -a "name='create new job' state=absent"
4.11:debug模块
debug模块主要用于调试时使用,通常的作用是将一个变量的值给打印出来。
参数:
- var:直接打印一个指定的变量值
- msg:打印一段可以格式化的字符串
Example
ansible all -i /etc/ansible/hosts -m debug -a "var=role"
-e "role=web"
ansible all -i /etc/ansible/hosts -m debug -a "msg='role is {{role}}'" -e "role=web"
4.12:template模块
template模块使用jinjia2格式作为文件模板,可以进行文档内变量的替换。文件以.j2结尾
参数:
- src:指定ansible控制端的文件路径
- dest:指定ansible被及控制端文件路径
- owner:指定文件的属主
- group:指定文件的数组
- mode:指定文件的权限
- backup:创建一个包含时间戳信息的备份文件,如果这样以某种方式错误地破坏了原始文件,就可以将其恢复原状。yes/no
Example
建立一个template文件名为hello_world.js
vim hello_world.js
Hello {{var}} !
执行命令,并且设置变量var的值为world
ansible all -i /etc/ansible/hosts -m template -a "src=hello_world.js dest=/tmp/hello_world.world" -e "var=world"
在被控主机上验证
ansible all -i /etc/ansible/hosts -m shell -a "cat /tmp/hello_world.world"
4.13:lineinfile模块
在被管理节点上,用正则匹配的方式对目标文件的一行内容修改删除等操作
如果是在一个文件中把所有匹配到的多行都进行统一处理,请参考replace模块
如果想对一个文件惊醒一次性添加、更新、删除多行内容等操作,参考bloclinfile模块
参数:
-
path:目标文件路径,必须
-
state:可选值absent删除、present替换(默认)
-
regexp:在文件的每一行中查找的正则表达式。
对于state=present,仅找到的最后一行将被替换
-
line:要在文件中插入、替换的行,需要state=present
-
create:文件不存在时,是否要创建文件并添加内容。yes|no
Example
删除被控节点文件里的某一条内容
ansible all -i /etc/ansible/hosts -m lineinfile -a "path=/etc/sudoers regexp='^%wheel' state=absent"
替换某一行
ansible all -i /etc/ansible/hosts -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=disabled' state=present"
匹配的方式对目标文件的一行内容修改删除等操作
如果是在一个文件中把所有匹配到的多行都进行统一处理,请参考replace模块
如果想对一个文件惊醒一次性添加、更新、删除多行内容等操作,参考bloclinfile模块
参数:
-
path:目标文件路径,必须
-
state:可选值absent删除、present替换(默认)
-
regexp:在文件的每一行中查找的正则表达式。
对于state=present,仅找到的最后一行将被替换
-
line:要在文件中插入、替换的行,需要state=present
-
create:文件不存在时,是否要创建文件并添加内容。yes|no
Example
删除被控节点文件里的某一条内容
ansible all -i /etc/ansible/hosts -m lineinfile -a "path=/etc/sudoers regexp='^%wheel' state=absent"
替换某一行
ansible all -i /etc/ansible/hosts -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=disabled' state=present"
5:YAML
5.1:YAML学习
特点:
-
YAML文件以#为注释符
-
YAML文件以.yml或者.yaml结尾
-
YAML文件以—开始,以…结束,但开始和结尾标志都是可选的
5.2:基础语法
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时是用tab键还是使用空格一定达到统一,建议使用空格
- 相同层级的元素必须左侧对其即可
YAML支持的数据结构有三种
- 字符串
- 列表
- 字典
5.2.1:字符串
---
# YAML中的字符串可以不使用引号,即使里面存在空格的时候,淡然使用单引号和双引号也没有错
this is a string
"this is a string"
'this is a string'
# YAML中若一行写不完你要表述的内容的时候,可以进行折行。
long_line: |
Example 1
Example 2
Example 3
long_line: >
Example 1
Example 2
Example 3
...
5.2.2:列表
---
# 以短横线开头+空格+具体的值
- red
- green
- blue
# 以上等同于python的list为:
#["red", "green", "blue"]
...
5.2.3:字典
---
# 以key+冒号(:)+空格+值(value),即key: value
name: Using Ansible
code: D1234
# 以上等同于python的Dict
#{"name": "Using Ansible", "code": "D1234"}
...
5.2.4:混合结构
---
class:
- name: stu1
num: 001
- name: stu2
num: 002
- name: stu3
num: 003
...
5.2.5:验证YAML语法
安装YAML解析库
pip install pyyaml
验证YAML语法
python -c 'import yaml,sys; print(yaml.safe_load(sys.stdin))' < myyaml.yml
6:Playbook的编写
可以认为它是ansible自定义的一门语言
6.1:Play的定义
- 每一个Play都是以短横线开始的
- 每一个Play都是一个YAML字典格式
---
- key1: value1
key2: value2
- key3: value3
key2: value2
- key4: value4
key5: value5
...
6.2:Play属性
常用属性
- name属性,每个play的名字
- hosts属性,每个play涉及的被管理服务器,同ad-hoc中的资产选择器
- tasks属性,每个play中具体要完成的任务,以列表的形式表达
- become属性,如果需要提权,则加上become相关属性
- become_user属性,若提权的话,提权到哪个用户上
- remote_user属性,指定连接用户。若不指定,则默认使用当前执行ansible Playbook的用户
6.3:一个完整剧本
一个Play的Playbook
---
- name: the first play example
hosts: all
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=present
- name: copy nginx.conf to remote server
copy: src=nginx.conf dest=/etc/nginx/nginx.conf
- name: start nginx server
service:
name: nginx
enable: true
state: started
...
具有多个Play的Playbook
---
- name: the first play example
hosts: all
remote_user: root
tasks:
- name: install nginx package
yum: name=nginx state=present
- name: copy nginx.conf to remote server
copy: src=nginx.conf dest=/etc/nginx/nginx.conf
- name: start nginx server
service:
name: nginx
enable: true
state: started
- name: manager db server
hosts: db_servers
tasks:
- name: update datebase cpnfig
copy: src=my.cnf dest=/etc/mycnf
...
6.4:如何队Playbook进行语法校验
ansible-playbook myplaybook.yml --syntax-check
6.5:执行Playbook
ansible-playbook -i /etc/ansible/hosts myplaybook.yml
单步调试模式
ansible-playbook -i /etc/ansible/hosts myplaybook.yml --step
测试Playbook正常运行
ansible-playbook -i /etc/ansible/hosts myplaybook.yml -C