ansible是什么?

ansible是一个开源的自动化运维工具,实现了批量系统配置、批量程序部署、批量运行命令等功能。

ansible安装

  1. 免密登录
  2. 安装epel-release
  3. 安装ansible
    1. yum install -y epel-release
    2. yum install -y ansible

    命令

    ```shell ansible all -m command -a “chdir=/bin pwd”

mkdir /backup ansible all -m command -a “chdir=/backup pwd”

ansible Server -m copy -a “src=/etc/hosts dest=/tmp/oldboly123.txt”

ansible Server -m copy -a “content=’Hello Ansible’ dest=/tmp/oldboly123.txt” cat /tmp/oldboly123.txt Hello Ansible ansible Server -m copy -a “src=/tmp/oldboy123.txt dest=/tmp/remote_src.test” ansible Server -m copy -a “src=/etc/hosts dest=/tmp/remote_src.test backup=yes”

级联创建(目录后不加文件) ansible Server -m copy -a “src=/etc/hosts dest=/tmp/1/2/3/ backup=yes”

ansible Server -m yum -a ‘name=httpd state=installed’ ansible Server -m yum -a ‘name=httpd state=latest’ 最新版本 ansible Server -m yum -a ‘name=httpd state=removed’

ansible Server -m setup -a “filter=ansible_default_ipv4” ansible Server -m setup -a “filter=ansible_memory_mb”

  1. <a name="vzkH9"></a>
  2. ### ansible的常用模块有哪些?
  3. 1. ping(测试连通性)
  4. 1. command(在远程主机上执行命令)
  5. 1. shell(支持bash的特性如管道)
  6. 1. script(在远程主机上执行控制端的脚本文件)
  7. 1. copy(从管理端到被管理端)
  8. 1. fetch(从被管理端到管理端)
  9. 1. file(用于配置文件属性)
  10. 1. user(配置用户)
  11. 1. group(配置用户组)
  12. 1. yum(用于安装软件包)
  13. 1. cron(配置计划任务)
  14. 1. service(用于管理服务)
  15. 1. setup(查看远程主机的基本信息)
  16. 1. synchronize(使用rsync同步文件)
  17. 1. package(使用os包管理器安装、升级和删除包)
  18. 1. systemd
  19. 1. get_url(该模块主要用于从http、ftp、https服务器上下载文件,类似于wget)
  20. <a name="LE7eY"></a>
  21. ### 命令行参数
  22. - -i : 指定主机清单文件
  23. - -k : 使用密码远程
  24. - -f : 启动的并发线程数(默认5)
  25. - -m : 要使用的模块
  26. - -a : 模块特有的参数
  27. 运维自动化场景
  28. 1. 操作系统的预备自动化(镜像)
  29. - PXE
  30. - kickstart
  31. - cobber
  32. 2. 配置自动化
  33. 2. 监控自动化
  34. - 系统及应用监控
  35. - 日志监控
  36. 4. 代码的持续集成和发布自动化
  37. git github jenkins docker
  38. <a name="snaIO"></a>
  39. ## 一、配置自动化场景
  40. 配置自动化可以帮助企业在大量服务器存在的情况下,快速实现应用部署,软件配置等一大利器。通过配置自动化可以在如下方面有优异表现:
  41. - 提高配置效率
  42. - 提高配置的准确性
  43. - 降低人工参与度
  44. <a name="bY2OJ"></a>
  45. ## 二、配置自动化产品
  46. | 序号 | 工具 | 描述 |
  47. | --- | --- | --- |
  48. | 1 | ansible | 开箱即用,使用ssh协议 |
  49. | 2 | saltstack | 需要anget端配合,配置部署速度快 |
  50. | 3 | puppet | 老牌配置自动化工具,需要agent端配合 |
  51. <a name="CxUCc"></a>
  52. ## 三、ansible介绍
  53. 无主无从 开箱即用 用完即走
  54. <a name="XiNmM"></a>
  55. ### 1. 工作原理图
  56. ![截屏2021-12-01 00.18.59.png](https://cdn.nlark.com/yuque/0/2021/png/352740/1638289154618-819d3712-71d7-4244-94ae-684e013e9d8d.png#clientId=u23fd0b0a-5e32-4&crop=0&crop=0&crop=1&crop=1&from=ui&height=294&id=u0fda8e5b&margin=%5Bobject%20Object%5D&name=%E6%88%AA%E5%B1%8F2021-12-01%2000.18.59.png&originHeight=588&originWidth=920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=354639&status=done&style=stroke&taskId=u1363eeca-38dd-4ee0-a749-d0082949f2e&title=&width=460)
  57. - 可以对大量主机进行操作(主机)
  58. - 本身包含大量的模块 hostname copy 用户自定义模块(ansible)
  59. - 主机清单(ansible必须认识你,不会胡乱更改。ansible)
  60. - 借助ssh,不用部署客户端(ansible)
  61. - playbook(剧本)可以完成复杂的批量部署工作(ansible)
  62. <a name="U5PwX"></a>
  63. ## 2. 安装ansible
  64. 1. 安装epel源(epel源安装的ansible会更新)
  65. 1. 安装ansible
  66. ```shell
  67. rpm -qa|grep ansible #验证

3. ansible主机清单

存储位置在:/etc/ansible/hosts
主机清单的作用

  • 读取主机列表
  • 实现主机分组

两种方法定义主机清单

  • 直接写入ip地址或主机名
  • 在主机清单中添加分组,再到主机清单中添加ip或主机名(要熟练使用第二种) ```shell [webgroup] 11.22.33.44

[webgroup2] web1 web2

  1. ansible的工作原理<br />ansible主机清单定义
  2. <a name="adyeo"></a>
  3. ### 4. ping模块
  4. 如何使用ansible来实现主机间联通性测试?
  5. - 多主机间免密登陆
  6. ```shell
  7. ssh-keygen -t rsa -f ~/root/.ssh/id_rsa -N ''
  8. ssh-copy-id xx.xx.xx.xx
  • 定义主机清单
  • 使用ping模块测试联通性
    1. ansible xx.xx.xx.xx -m ping
    问题:
  1. 这里的ping是真ping还是假ping?

ansible是通过ssh协议来通信的,这里ansible的ping是假象的ping。

4. cron模块实现配置多主机时间同步

  1. 时钟源服务器
  • 国内选择阿里时钟源 time1.aliyun.com
  • 国际选择微软时钟源 time.windows.com
    1. ntpdate time1.aliyun.com
  1. cron模块应用配置

    1. ansible xx.xx.xx.xx -m cron -a 'name="test cron" job="ntpdate time1.aliyun.com" minute=0 hour=*/1'
    2. ansible xx.xx.xx.xx -m cron -a 'name="global cron" job="ntpdate time.windows.com" minute=*/3'
  2. 验证远程主机结果

    1. crontab -l

    5. copy模块

  3. 准备本地解析文件:/etc/hosts

    1. 192.168.1.10 ansiblecontroller
    2. 192.168.1.20 web1
    3. 192.168.1.30 web2
    4. 192.168.1.40 web3
  4. copy模块应用

    1. ansible xx.xx.xx.xx -m copy -a "src=/etc/hosts dest=/etc/hosts"
  5. 远程主机验证

    1. cat /etc/hosts

    达内ansible

    ansible也是cobbler的作者,Michael DeHaan
    批量修改密码、批量安装软件、批量执行
    基于SSH架构
    可以管理Linux和Windows

主机列表

截屏2021-12-01 01.25.41.png

配置文件

  • 主配置文件:/etc/ansible/ansible.cfg(习惯性命名)

ansible配置文件检查顺序:

  • 环境变量ANSIBLE_CONFIG变量定义的配置文件
  • 当前目录下的./ansible.cfg
  • 用户家目录下的~/ansible.cfg
  • 最后检查/etc/ansible/ansible.cfg

ansible.cfg内容

  1. mkdir ~/ansible
  2. vim ~/ansible/ansible.cfg
  3. [defaults]
  4. inventory = ~/ansible/inventory
  5. #fork = 5 # ssh并发数
  6. #ask_pass = True # 使用密钥还是密码
  7. #host_key_ckecking = False # 是否校验密钥
  8. 这些都是默认参数

主机清单文件:参考/etc/ansible/hosts

  1. vim ~/ansible/hosts
  2. [test]
  3. node1
  4. [proxy]
  5. node2
  6. [webserver]
  7. node[3:4]
  8. [database]
  9. node5
  10. [cluster:children] # 嵌套组,children为关键词
  11. webserver
  12. database

测试ansible配置和环境是否正常

  1. cd ~/ansible
  2. ansible all --list-hosts
  3. ansible node1 -m ping
  4. ansible node1,node2 -m ping
  5. ansible webserver -m ping

Ansible ad-hoc命令

ansible ad-hoc是一种通过命令行批量管理的方式

格式:
ansible 主机 -m 模块名 -a “参数”

  • 其他参数
  • -k 使用密码远程
  • -i 指定其他主机列表文件

什么是模块?
模块就是写好的py脚本,拷贝到被管理端主机,然后执行!
默认模块是command

  1. ansible node1 -m command -a 'uptime'
  2. ansible node1 -a 'ip a s' # 默认使用command模块
  3. ansible test -a 'date'
  4. ansible all -a 'date' # all是一个特殊的组

获取帮助

  1. ansible-doc -l # 获取所有已安装的模块
  2. ansible-doc -l|grep yum
  3. ansible-doc yum # 查看yum模块的帮助

总结:

  • 掌握ansible ad-hoc命令行方式
  • 掌握获取帮助文档

    shell模块

  • command模块不启动shell,直接通过ssh执行命令

  • command模块不支持bash特性,如管道和重定向等功能
  • 所有需要调用shell的功能都无法使用

    1. ansible test -m command -a "ps -ef|wc -l"
    2. ansible test -m command -a "ps > a.txt"
    3. ansible test -m command -a "ps &"
    4. # 以上都需要开启bash解释器,所以都会报错

    使用shell模块注意事项

    1. ansible test -m shell -a "cd /tmp"
    2. ansible test -m shell -a "touch my.txt"
    3. # 前后是两个shell,这可能不是我们想要的结果

    空格分割,传递多个参数(chdir)

    1. ansible test -m shell -a "chdir=/tmp touch my.txt"
    2. ansible test -m shell -a "chdir=/tmp touch touch a.txt b.txt c.txt"
    3. ansible-doc shell

    shell模块还支持判断(creates、removes)

  • creates 文件名:文件存在、不执行shell命令

  • removes 文件名:文件不存在、不执行shell命令
    1. ansible test -m shell -a "ssh-keygen -f ~/.ssh/id_rsa -N '' creates=~/.ssh/id_rsa"
    2. ansible node1,node2 -m shell -a "unzip xxx.zip removes=/bin/unzip"

    script模块

    如果命令很复杂,script允许在本地写脚本,拷贝到被管理端并执行。脚本可以是python、shell、perl等 ```shell cat test.sh yum install httpd systemctl start httpd

ansible node1,node2 -m script -a “./test.sh”

  1. <a name="v62J9"></a>
  2. ### file模块(幂等性)
  3. 为什么要存在这么多单独的模块?<br />幂等性<br />创建文件、目录、链接;修改全新和属性
  4. ```shell
  5. ansible test -m file -a "path=/tmp/file.txt state=touch"
  6. ansible test -m file -a "path=/tmp/mydir state=directory"
  7. # 删除
  8. ansible test -m file -a "path=/tmp/file.txt state-absent"
  9. ansible test -m file -a "path=/tmp/mydir state-absent"
  10. # 软链接
  11. ansible test -m file -a "src=/etc/hosts path=/tmp/hosts state=link"

copy模块

backup=yes 如果目标主机有同名文件,则先备份

  1. ansible test -m copy -a "src=~/a3.txt dest=/root/a3.txt"
  2. # 没有源文件直接定义内容
  3. ansible test -m copy -a "content='hello world\ntest' dest=/root/test.txt"

fetch模块(收集远程主机上的文件)

  1. ansible node1,node2 -m fetch -a "src=/etc/hostname dest=~"
  2. # 自动创建了node1和node2的目录 拷贝的文件放在对应的目录下

lineinfile模块|replace模块

  1. ansible test -m lineinfile -a "path=/etc/issue line='hello world'"
  2. # 在文件末尾添加一行
  3. ansible test -m lineinfile -a "path=/etc/issue line='insert' insertafter='Kernel'"
  4. 将内容插入到Kernel行的后面

替换

  1. ansible test -m lineinfile -a "path=/etc/issue regexp='hello' line='ni hao'"
  2. # 如果在/etc/issue文件中匹配到包含hello的行,把整行内容替换为ni hao
  3. # 如果无法匹配到hello,则在文件最后添加一行nihao
  4. # 如果有多行内容包含hello, 仅替换最后一行

lineinfile替换的是一整行,replace可以替换一个词

  1. ansible test -m replace -a "path=/etc/issue.net regexp=Kernel replace=Ocean"

user模块

user模块可以管理Linux系统账户

  1. ansible test -m user -a "name=user1"
  2. ansible test -m user -a "name=user2 uid=1010 group=adm groups=daemon,root home=/home/user2"
  3. ansible test -m test -a "name=user3 password={{'abc'|password_hash('sha512')}}"
  4. # 不管什么密码都需要hash,这是Linux的标准算法,不可改变
  5. ansible test -m test -a "name=user1 groups=daemon,root"
  6. # 修改user1的附加组
  7. ansible test -m test -m user -a "name=user2 state=absent remove=true"
  8. # 删除用户的时候同时删除加目录、邮箱

yum_repository模块

创建或修改yum配置文件

  1. ansible test -m yum_repository -a "name=myyum description=hello baseurl=ftp://192.168.4.254/centos gpgcheck=no"
  2. ansible test -m yum_repository -a "name=myyum state=absent"

yum模块

  1. ansible node2 -m yum -a "name=unzip state=persent" # 安装
  2. ansible node2 -m yum -a "name=unzip state=latest" # 升级
  3. ansible node2 -m yum -a "name=unzip state=absent" # 卸载

service模块

管理服务,是否开机自启动等

  1. ansible test -m service -a "name=httpd state=started"
  2. ansible test -m service -a "name=httpd state=stopped"
  3. ansible test -m service -a "name=httpd state=started enabled=yes" # 启动服务并开机自启动

逻辑卷相关模块

lvg模块 创建、删除卷组(VG),修改卷组大小

  1. ansible test -m yum -a "name=lvm2"
  2. ansible test -m lvg -a "vg=myvg pvs=/dev/sdb1"
  3. ansible test -m lvg -a "vg=myvg pvs=dev/sdb1,/dev/sdb2"

lvol模块 创建、删除逻辑卷(LV),修改逻辑卷的大小

  1. ansible test -m lvol -a "lv=mylv vg=myvg size=2G"
  2. ansible test -m lvol -a "lv-mylv vg-myvg size=4G" # 修改逻辑卷的大小
  3. ansible test -m lvol -a "lv-mylv vg-myvg state=ansent force=yes"
  4. ansible test -m lvg -a "vg=myvg state=absent"

Ansible进阶

sudo提权

  • 管理员先授权(/etc/sudoers)
  • 普通用户以sudo的方式执行命令 ```shell jerry ALL=(root) /usr/bin/systemctl # 任何主机上以root的身份 jerry ALL=(ALL) /usr/bin/systemctl # 任何主机上以任何人的身份 jerry ALL=(ALL) NOPASSWD:/usr/bin/systemctl # 不需要输入密码

sudo systemctl restart httpd

ansible test -m lineinfile -a “path=/etc/sudoers line=’alice ALL=(ALL) NOPASSWD:ALL’”

  1. <a name="CP0Aa"></a>
  2. ### Ansible配置进阶
  3. /etc/ansible/ansible.cfg<br />[default]<br />remote_user = alice # 以什么用户管理远程主机<br />![截屏2021-12-01 16.03.09.png](https://cdn.nlark.com/yuque/0/2021/png/352740/1638345807219-669256f7-498f-49b2-98fd-26b2f920d63b.png#clientId=u9f4dc086-80e6-4&crop=0&crop=0&crop=1&crop=1&from=ui&height=282&id=ua6a3e75a&margin=%5Bobject%20Object%5D&name=%E6%88%AA%E5%B1%8F2021-12-01%2016.03.09.png&originHeight=564&originWidth=1662&originalType=binary&ratio=1&rotation=0&showTitle=false&size=706424&status=done&style=stroke&taskId=u93c004f3-b9c1-46ba-a504-348ba6c475a&title=&width=831)
  4. ```shell
  5. ansible all -m shell -a "who"
  6. ansible all -m shell -a "ls /root"

主机清单单独变量

截屏2021-12-01 16.11.49.png
多个变量之间用空格隔开

Ansible playbook

命令行:需要反复编写
剧本:重复执行的,复杂的命令写到一个文件中

YAML

一种可读性高,用来表达数据序列的语言格式
YAML以数据为中心,重点描述数据的关系和结构

YAML格式

截屏2021-12-01 16.18.09.png
跨行文本
截屏2021-12-01 16.23.32.png
Playbook语法格式

  • playbook采用YAML格式编写
  • playbook文件中由一个或多个play组成
  • 每个play中包含:
    • hosts(主机)、tasks(任务)
    • variables(变量)、roles(角色)、handers等元素
  • 使用ansible-playbook命令运行playbook剧本

测试第一个playbook

  1. ---
  2. - hosts: all
  3. tasks:
  4. - name: This is my first playbook
  5. ping:
  1. ansible-playbook ~/ansible/test.yml

多个组或多个任务的playbook

  1. ---
  2. - hosts: test, webserver # 多个组用逗号分隔
  3. tasks:
  4. - name: This is my first playbook
  5. ping:
  6. - name: Run a shell command
  7. shell: touch ~/shell.txt
  1. ansible-playbook ~/ansible/test.yml -f 5 # 并发连接数

截屏2021-12-01 16.46.31.png

创建用户

  1. ---
  2. - hosts: webserver
  3. tasks:
  4. - name: Add the user john
  5. user:
  6. name: john
  7. uid: 1040
  8. group: daemon
  9. password: "{{'123' | password_hash('sha512')}}"
  1. ---
  2. - hosts: webserver
  3. tasks:
  4. - name: Add the user john
  5. user:
  6. name: john
  7. shell: /bin/bash
  8. groups: bin, adm
  9. password: "{{'123' | password_hash('sha512')}}"
  1. ---
  2. - hosts: webserver
  3. tasks:
  4. - name: Add the user john
  5. user:
  6. name: john
  7. state: absent

使用playbook分区的例子

  1. ---
  2. - hosts: test
  3. tasks:
  4. - name: Create a new primary partition with a size of 1GiB
  5. parted:
  6. device: /dev/sdb
  7. number: 1
  8. state: present
  9. part_end: 1GB
  10. - name: Create a new primary partition with a size of 2GiB
  11. parted:
  12. device: /dev/sdb
  13. number: 2
  14. state: present
  15. part_start: 1GB
  16. part_end: 3GB
  17. - name: Create a volume group on top of /dev/sdb1
  18. lvg:
  19. vg: my_vg
  20. pvs: /dev/sdb1
  21. - name: Create a logic volume of 512m
  22. lvol:
  23. vg: my_vg
  24. lv: my_lv
  25. size: 512m

安装软件

  1. ---
  2. - hosts: webserver
  3. tasks:
  4. - name: Install a list of packages
  5. yum:
  6. name:
  7. - httpd
  8. - mariadb
  9. - mariadb-server
  10. - name: Install the 'Development tools' package group
  11. yum:
  12. name: "@Development tools" # @表示主包
  13. - name: update software
  14. yum:
  15. name: '*'
  16. state: latest

setup模块

  • ansible_facts用于采集被管理设备的系统信息
    1. ansible test -m setup # 查看收集的信息,保存在变量中
    2. ansible test -m setup -a "filter=ansible_mem*"
    在剧本中是可以直接调用变量的,使用debug模块去显示 ```yaml

  • hosts: test tasks:
    • debug: var: ansible_all_ipv4.addresses
    • debug: msg: “主机名称是:{{ansible_hostname}}”
    • debug: var: ansible_devices.sda.partitions.sda1.size
    • debug: msg: “总内存大小:{{ ansible_memtotal_mb }}” ``` 利用setup模块获取主机信息
      通过debug模块显示变量信息

Ansible定义变量

根据优先级排序

  • Inventory变量
  • Host Facts变量(可以直接调用ansible收集的系统信息)
  • Register变量
  • Playbook变量
  • Playbook提示变量
  • 变量文件
  • 命令行变量

定义主机清单的变量文件

  1. cat ~/ansible/hosts
  2. [test]
  3. node1 myvar1="hello the world" myvar2="content"
  4. [webserver:vars]
  5. yourname="jacob"
  1. cat ~/ansible/inventory_var.yml
  2. ---
  3. - hosts: test
  4. tasks:
  5. - name: create a file with var.
  6. shell: echo {{myvar1}} > /tmp/{{myvar2}}
  7. - hosts: webserver
  8. tasks:
  9. - name: create a user with var.
  10. user:
  11. name: "{{yourname}}"

Host Facts变量

  1. cat ~/ansible/facts_var.yml
  2. ---
  3. - hosts: test
  4. tasks:
  5. - name: Use facts info.
  6. copy:
  7. content: "{{ansible_hostname}}:{{ansible_bios_version}}"
  8. dest: /tmp/facts.txt

register定义变量

  1. cat ~/ansible/register.yml
  2. ---
  3. - hosts: test
  4. tasks:
  5. - name: save shell result to a variable
  6. shell: hostname
  7. register: myvar
  8. - name: print the variable
  9. debug:
  10. msg: "{{ myvar }}"
  11. msg: "{{ myvar.stdout }}" # 仅显示一部分信息

playbook变量(vars定义变量)

  1. cat ~/ansible/playbook_var.yml
  2. ---
  3. - hosts: test
  4. vars:
  5. iname: heal
  6. ipass: '123456'
  7. tasks:
  8. - name: Use variables create user.
  9. user:
  10. name: "{{iname}}"
  11. password: "{{ipass | password_hash('sha512')}}"

playbook变量(vars_prompt变量)

  1. cat ~/ansible/prompt_var.yml
  2. ---
  3. - hosts: test
  4. vars_prompt:
  5. - name: iname
  6. prompt: "请输入用户名"
  7. private: no
  8. - name: ipass
  9. prompt: "请输入密码"
  10. private: yes
  11. tasks:
  12. - name: Use variables create user.
  13. user:
  14. name: "{{iname}}"
  15. password: "{{ipass | password_hash('sha512')}}"

vars_files变量

-e参数定义

  1. cat ~/ansible/prompt_var.yml
  2. ---
  3. - hosts: test
  4. tasks:
  5. - name: create user
  6. user:
  7. name: "{{iname}}"
  8. password: "{{ipass | password_hash('sha512')}}"

执行的时候:

  1. ansible-playbook command_var.yml -e iname=tiechui -e ipass=123456

Ansible模块应用

  • firewalld
  • template(拷贝文件模版,文件内容支持变量)

    使用firewalld模块设置防火墙规则

    ```yaml cat ~/ansible/firewall.yml

  • hosts: test tasks:

    • name: install firewalld yum: name: firewalld state: present
    • name: run firewalld service: name: firewalld state: started enabled: yes
    • name: set firewalld rule firewalld: port: 80/tcp permanent: yes # 永久生效的 state: enable # 打开 ``` firewall-cmd —list-all permanent
      80/tcp
      firewall-cmd —list-ports permanent

      Ansible高级语法

  • 错误处理机制: 第一个任务出错,后面的任务中断;ignore_errors: true 也可以全局忽略错误

  • 熟悉handers任务
  • 熟悉when条件判断
  • 熟悉block任务块
  • 熟悉loop循环的使用方法

    Ansible Vault

    数据的加密和解密