Ansible介绍

ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。无客户端。

Ansible三个核心概念

  • Inventory
    • 对于管理设备的清单与列表,对列表进行分组,列表可以比较复杂,也可以比较简单。
  • Playbook
    • 对于Inventory清单中的分组,对于不同分组,执行不同并且多个Task
  • Module
    • 自带的模块,用于用户和Playbook调用。

Ansible中文文档

Ansible 特点

(1)Ansible不需要安装客户端,通过sshd去通信(无密钥登录)。
(2)Ansible基于模块工作,模块可以由任何语言开发。
(3)Ansible不仅支持命令行使用模块,也支持编写Yaml格式的playbook,易于编写和阅读。
(4)Ansible安装十分简单,CentOS上可直接Yum安装。
(5)Ansible有提供UI(浏览器图形化)www.ansible.com/tower,收费的官方文档 http://docs.ansible.com/ansible/latest/index.html。
Ansible已经被RedHat公司收购,它在Github(https://github.com/ansible/ansible)上是一个非常受欢迎的开源软件。

Ansible 特性

1> 模块化:调用特定的模块,完成特定任务 2> Paramiko(python对ssh的实现),PyYAML,Jinja2(模板语言)三个关键模块 3> 支持自定义模块 4> 基于Python语言实现 5> 部署简单,基于python和SSH(默认已安装),agentless 6> 安全,基于OpenSSH 7> 支持playbook编排任务 8> 幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况 9> 无需代理不依赖PKI(无需ssl) 10> 可使用任何编程语言写模块 11> YAML格式,编排任务,支持丰富的数据结构 12> 较强大的多层解决方案

自动化运维应用场景

文件传输 应用部署 配置管理 任务流编排

Ansible 主要组成部分

ANSIBLE PLAYBOOKS: 任务剧本(任务集),编排定义Ansible任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YML文件 INVENTORY: Ansible管理主机的清单 /etc/anaible/hosts,也可以自定义hosts位置,但需要特殊配置 MODULES: Ansible执行命令的功能模块,多数为内置核心模块,也可自定义 PLUGINS: 模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用 API: 供第三方程序调用的应用程序编程接口 ANSIBLE: 组合INVENTORY、API、MODULES、PLUGINS的绿框,可以理解为是ansible命令工具,其为核心执行工具

基础安装与配置

1.安装

版本 配置 名称
centos7.9 2h2g 50G ans1
centos7.9 2h2g 50G ans2
centos7.9 2h2g 50G ans3

yum安装

  1. #第一台机器
  2. hostnamectl set-hostname ans-con
  3. #第二台机器
  4. hostnamectl set-hostname ans-node1
  5. #第三台机器
  6. hostnamectl set-hostname ans-node2
  7. #三台机器分别添加到hosts
  8. 192.168.218.161 ans1
  9. 192.168.218.162 ans2
  10. 192.168.218.163 ans3
  11. #yum安装ansible
  12. yum install epel* -y
  13. yum install ansible -y

编译安装

  1. yum -y install python-jinja2 PyYAML python-paramiko python-babel
  2. python-crypto
  3. tar xf ansible-1.5.4.tar.gz #建议到官网/github下载最新稳定版
  4. cd ansible-1.5.4
  5. python setup.py build
  6. python setup.py install
  7. mkdir /etc/ansible
  8. cp -r examples/* /etc/ansible

Git安装

  1. git clone git://github.com/ansible/ansible.git --recursive
  2. cd ./ansible
  3. source ./hacking/env-setup

Pip安装

  1. yum install python-pip python-devel
  2. yum install gcc glibc-devel zibl-devel rpm-bulid openssl-devel
  3. pip install --upgrade pip
  4. pip install ansible --upgrade

2.配置文件同步

如果在linux中配置需要使用vim等编辑工具,使用vscode,下载sftp工具,就可以将文件内容同步。(xftp也可以实现该功能)

  • 下载vscode
    • 插件商店,安装Ansible,安装Sftp

image.png

  • 连接Linux
    • 创建一个文件,指定到某文件夹中
    • ctrl+shift+p,SFTP:config,点击后创建sftp.json文件
    • ctrl+shift+p,SFTP:Sync Local -> Remote,连接Linux,输入密码连接成功。并且文件也同步了,此时就不用点什么,Ctrl+s保存就会同步到服务器。

image.png

image.png

image.png
点击SFTP 此时显示的就是/root文件夹的内容。
image.png
Linux中我们并没有创建,此时给我们创建了文件夹.。
image.png

配置文件解释

Inventory 主机清单

1> ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名
2> 默认的inventory file为/etc/ansible/hosts
3> inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成

/etc/ansible/hosts文件格式

inventory文件遵循INI文件风格,中括号中的字符为组名。
可以将同一个主机同时归并到多个不同的组中;
此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明

  1. ntp.magedu.com 不分组,直接加
  2. [webservers] webservers
  3. www1.magedu.com:2222 可以指定端口
  4. www2.magedu.com
  5. [dbservers]
  6. db1.magedu.com
  7. db2.magedu.com
  8. db3.magedu.com

如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机

  1. [websrvs]
  2. www[1:100].example.com ip: 1-100
  3. [dbsrvs]
  4. db-[a:f].example.com dba-dbff

ansible.cfg 配置文件

我们在启动时,我们需要指定host文件,playbook文件,比较麻烦。我们可以通过修改ansible.cfg文件让执行命令更方便。
ansible.cfg常放隐私性的内容,比如ssh秘钥等。

Ansible 配置文件/etc/ansible/ansible.cfg (一般保持默认)

  1. vim /etc/ansible/ansible.cfg
  2. [defaults]
  3. #inventory = /etc/ansible/hosts # 主机列表配置文件
  4. #library = /usr/share/my_modules/ # 库文件存放目录
  5. #remote_tmp = $HOME/.ansible/tmp # 临时py命令文件存放在远程主机目录
  6. #local_tmp = $HOME/.ansible/tmp # 本机的临时命令执行目录
  7. #forks = 5 # 默认并发数,同时可以执行5次
  8. #sudo_user = root # 默认sudo 用户
  9. #ask_sudo_pass = True # 每次执行ansible命令是否询问ssh密码
  10. #ask_pass = True # 每次执行ansible命令是否询问ssh口令
  11. #remote_port = 22 # 远程主机的端口号(默认22)
  12. #建议优化项:
  13. host_key_checking = False # 检查对应服务器的host_key,建议取消注释
  14. log_path=/var/log/ansible.log # 日志文件,建议取消注释
  15. module_name = command # 默认模块


ansible优先级

  1. 当前文件夹下的ansible.cfg
  2. 全局变量配置的ANSIBLE_CONFIG 路径
  3. 每个用户的home文件夹下的 ansible.cfg
  4. /etc/ansible配置文件夹下的ansible.cfg

    相关文件

    | 文件名/文件夹/命令 | 作用 | | —- | —- | | ansible.cfg | 主配置文件,配置ansible工作特性(一般无需修改) | | hosts | 主机清单(将被管理的主机放到此文件) | | roles | 存放角色的目录 | |
    |
    | | ansible | 主程序,临时命令执行工具 | | ansible-doc | 查看配置文档,模块功能查看工具 | | ansible-galaxy | 下载/上传优秀代码或Roles模块的官网平台 | | ansible-playbook | 定制自动化任务,编排剧本工具 | | ansible-pull | 远程执行命令的工具 | | ansible-vault | 文件加密工具 | | ansible-console | 基于Console界面与用户交互的执行工具 |

Ansible基础命令

  • Ansible主要操作对象
    • HOSTS主机
    • NETWORKING网络设备
  • 注意事项:
    • 执行ansible的主机一般称为主控端,中控,master或堡垒机
    • 主控端Python版本需要2.6或以上
    • 被控端Python版本小于2.4需要安装python-simplejson
    • 被控端如开启SELinux需要安装libselinux-python
    • windows不能做为主控端
    • ansible不是服务,不会一直启动,只是需要的时候启动
  1. ansible通过ssh实现配置管理、应用部署、任务执行等功能,
  2. 建议配置ansible端能基于密钥认证的方式联系各被管理节点
  3. ansible <host-pattern> [-m module_name] [-a args]
  4. ansible +被管理的主机(ALL) +模块 +参数
  5. --version 显示版本
  6. -m module 指定模块,默认为command
  7. -v 详细过程 vv -vvv更详细
  8. --list-hosts 显示主机列表,可简写 --list
  9. -k, --ask-pass 提示输入ssh连接密码,默认Key验证
  10. -C, --check 检查,并不执行
  11. -T, --timeout=TIMEOUT 执行命令的超时时间,默认10s
  12. -u, --user=REMOTE_USER 执行远程执行的用户
  13. -b, --become 代替旧版的sudo切换
  14. --become-user=USERNAME 指定sudorunas用户,默认为root
  15. -K, --ask-become-pass 提示输入sudo时的口令
  1. ansible all --list 列出所有主机
  2. ping模块: 探测网络中被管理主机是否能够正常使用 ssh协议
  3. 如果对方主机网络正常,返回pong
  4. ansible-doc -s ping 查看ping模块的语法
  5. 检测所有主机的网络状态
  6. 1> 默认情况下连接被管理的主机是ssh基于key验证,如果没有配置key,权限将会被拒绝
  7. 因此需要指定以谁的身份连接,输入用户密码,必须保证被管理主机用户密码一致
  8. ansible all -m ping -k
  9. 2> 或者实现基于key验证 将公钥ssh-copy-id到被管理的主机上 , 实现免密登录
  10. ansible all -m ping
  1. vim inventory.ini #inventory 主机清单
  2. ans2 ansible_connection=ssh ansible_user=root ansible_ssh_pass=mly118235
  3. ans3 ansible_connection=ssh ansible_user=root ansible_ssh_pass=mly118235
  4. #建议使用字母+数字的密码
  5. ansible all -m ping -i inventory.ini #ansible,ping命令
  6. #出现以下命令就是执行成功
  7. ans3 | SUCCESS => {
  8. "ansible_facts": {
  9. "discovered_interpreter_python": "/usr/bin/python"
  10. },
  11. "changed": false,
  12. "ping": "pong"
  13. }
  14. ans2 | SUCCESS => {
  15. "ansible_facts": {
  16. "discovered_interpreter_python": "/usr/bin/python"
  17. },
  18. "changed": false,
  19. "ping": "pong"
  20. }
  21. ansible ans3 -m ping -i inventory.ini #单独ping ans3

此时ping并不是普通的ping,而是ansible ping代表ansible可以连接到linux。

  • all 对于inventory文件中的所有命令进行ping操作

1.设置分组并且ping

  1. vim inventory.ini
  2. [test1]
  3. ans2 ansible_connection=ssh ansible_user=root ansible_ssh_pass=mly118235
  4. [test2]
  5. ans3 ansible_connection=ssh ansible_user=root ansible_ssh_pass=mly118235
  6. ansible test2 -m ping -i inventory.ini
  7. ans3 | SUCCESS => {
  8. "ansible_facts": {
  9. "discovered_interpreter_python": "/usr/bin/python"
  10. },
  11. "changed": false,
  12. "ping": "pong"
  13. }

2.多机器匹配

  1. vim inventory.ini
  2. [test1]
  3. ans[2:3] ansible_connection=ssh ansible_user=root ansible_ssh_pass=mly118235 #匹配ans2到3
  4. #ans3 ansible_connection=ssh ansible_user=root ansible_ssh_pass=mly118235
  5. ansible test1 -m ping -i inventory.ini
  6. ans3 | SUCCESS => {
  7. "ansible_facts": {
  8. "discovered_interpreter_python": "/usr/bin/python"
  9. },
  10. "changed": false,
  11. "ping": "pong"
  12. }
  13. ans2 | SUCCESS => {
  14. "ansible_facts": {
  15. "discovered_interpreter_python": "/usr/bin/python"
  16. },
  17. "changed": false,
  18. "ping": "pong"
  19. }

3.SSH KEY认证方式的实现

在inventory.ini中,上面我们的ping都是通过密码连接的,如果文件泄露我们的服务器密码也就泄露了,所以我们可以通过SSH KEY来进行安全进入

  1. # ssh-keygen #创建秘钥
  2. Generating public/private rsa key pair.
  3. Enter file in which to save the key (/root/.ssh/id_rsa): /root/.ssh/ansible #设置秘钥的位置与名称
  4. Enter passphrase (empty for no passphrase):
  5. Enter same passphrase again: #不设置密码
  6. Your identification has been saved in /root/.ssh/ansible.
  7. Your public key has been saved in /root/.ssh/ansible.pub.
  8. The key fingerprint is:
  9. SHA256:/2r5xOqF/pqkpMhl2MY1BNyWNH2VbTkkXXzPDfkLOok root@ans-con
  10. The key's randomart image is:
  11. +---[RSA 2048]----+
  12. | ..ooo o+*+|
  13. | ..+.. . =+=|
  14. | .. . ==|
  15. | . . =|
  16. | S . o . .|
  17. | + . E * . |
  18. | . * . +.= |
  19. | . = o +o* |
  20. | o . .oB=+ |
  21. +----[SHA256]-----+
  22. '
  23. [root@ans-con ~]# ssh-copy-id -i .ssh/ansible ans2 #将秘钥添加到ans2服务器中
  24. /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/ansible.pub"
  25. /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
  26. /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
  27. root@ans2's password: '
  28. Number of key(s) added: 1
  29. Now try logging into the machine, with: "ssh 'ans2'"
  30. and check to make sure that only the key(s) you wanted were added.
  31. [root@ans-con ~]# ssh-copy-id -i .ssh/ansible ans3 #将秘钥添加到ans3服务器中
  32. /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/ansible.pub"
  33. /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
  34. /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
  35. root@ans3's password: '
  36. Number of key(s) added: 1
  37. Now try logging into the machine, with: "ssh 'ans3'"
  38. and check to make sure that only the key(s) you wanted were added.
  39. ssh -i .ssh/ansible ans2 #此时输入能直接登录
  40. ssh -i .ssh/ansible ans3
  41. vim inventory.ini
  42. [test1]
  43. ans2 ansible_connection=ssh ansible_user=root
  44. ans3 ansible_connection=ssh ansible_user=root
  45. ansible all -m ping -i inventory/inventory.ini --private-key=/root/.ssh/ansible #

4. ansible 命令执行过程

  1. ansible命令执行过程
  2. 1. 加载自己的配置文件 默认/etc/ansible/ansible.cfg
  3. 2. 加载自己对应的模块文件,如command
  4. 3. 通过ansible将模块或命令生成对应的临时py文件,
  5. 并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
  6. 4. 给文件+x执行
  7. 5. 执行并返回结果
  8. 6. 删除临时py文件,sleep 0退出
  9. 执行状态:
  10. 绿色:执行成功并且不需要做改变的操作
  11. 黄色:执行成功并且对目标主机做变更
  12. 红色:执行失败

PlayBook

playbook是Ansible的配置、部署和编制语言。每个playbook由一个列表中的一个或多个”palys”组成。

  • Ansible-playbook(剧本)执行过程
    • 将已有编排好的任务集写入Ansible-Playbook
    • 通过ansible-playbook命令分拆任务集至逐条ansible命令,按预定规则逐条执行

案例样式

  1. name: "Ansible"
  2. version: 2.4
  3. python_version: 2.7
  4. module:
  5. - "Network"
  6. - "Linux Server"
  7. - "Windows Server"
  8. plugins:
  9. action_plugin: true
  10. cache_plugin: true
  11. shell_plugin: false

ansible 演示 palyload

  1. vim host1.yaml
  2. - hosts: test1 #组名称,或者host名称
  3. name: play-test #设置该host组的名称
  4. gather_facts: no
  5. tasks: #设置任务
  6. - name: check host connection #任务名称
  7. ping: #使用ping模块

debug模块

平时我们在使用ansible编写playbook时,经常会遇到错误,很多时候有不知道问题在哪里 。这个时候可以使用-vvv参数打印出来详细信息,不过很多时候-vvv参数里很多东西并不是我们想要的,这时候就可以使用官方提供的debug模块来查找问题出现在哪里。

debug参数 作用
msg 调试输出的消息
var 将某个任务执行的输出作为变量传递给debug模块,debug会直接将其打印输出
verbosity debug的级别(默认是0级,全部显示,写其他数字则跳过) 加上-vvv 显示详细的debug参数

常见的变量:

  • {{ansible_hostname}} #显示hostname
  • {{ansible_product_uuid}} #显示机器的uuid

  • ```shell vim helloworld.yaml
  • name: Hello world hosts: localhost #只检查本地 gather_facts: no

    tasks:

    • name: Hello world debug: msg: “hello ansible” #msg默认打印hello world verbosity: 0 ansible-playbook playbook/helloworkd.yml -vvv #调用debug模块运行

vim uuids.yaml

  • name: Hello world hosts: localhost

    tasks:

    • name: Hello world debug: msg: “hello ansible” verbosity: 0 ```

image.png

var变量的使用

  1. vim heeloworld.yaml
  2. - name: Hello world
  3. hosts: localhost
  4. gather_facts: no
  5. vars:
  6. grettings: "hello from vars"
  7. tasks:
  8. - name: Hello world
  9. debug:
  10. msg: "{{grettings}}"
  11. verbosity: 0
  12. ansible-playbook playbook/helloworkld.yml

image.png

  1. - name: Hello world
  2. hosts: localhost
  3. vars:
  4. grettings: "hello from vars"
  5. demo:
  6. a:
  7. - a: 1
  8. - b: 2
  9. b: test
  10. tasks:
  11. - name: Hello world
  12. debug:
  13. msg: "{{demo}}"
  14. verbosity: 0
  15. ansible-playbook playbook/helloworkd.yml

image.png

设置变量文件

如果我们将变量在每个文件中创建,文件会变得臃肿,并且占用内存更多,无法重复利用。我们可以将变量创建到某个具体文件中。

  1. mkdir /root/vars
  2. vim deno_vars.yml
  3. grettings: "hello i in vars"
  4. vim helloworld.yml
  5. - name: Hello world
  6. hosts: localhost
  7. vars_files:
  8. - "../vars/demo_vars.yml"
  9. tasks:
  10. - name: Hello world
  11. debug:
  12. msg: "{{grettings}}"
  13. verbosity: 0

注意:关于vars_files的优先级。本地创建<先调用文件<后调用文件

image.png

var变量循环

单循环

  1. vim loops.yml
  2. - name: loop one
  3. hosts: localhost
  4. gather_facts: no
  5. vars:
  6. test:
  7. - test1
  8. - test2
  9. - test3
  10. - test4
  11. tasks:
  12. - name: Test loop
  13. debug:
  14. msg: "{{item}}"
  15. verbosity: 0
  16. with_items: "{{test}}" #创建一个with_items,其中写入变量

image.png

多层循环

  1. - name: loop two
  2. hosts: localhost
  3. gather_facts: no
  4. vars:
  5. test:
  6. - test1
  7. - test2
  8. - test3
  9. - test4
  10. demo:
  11. - demo1
  12. - demo2
  13. - demo3
  14. tasks:
  15. - name: Test loop
  16. debug:
  17. msg: "{{item[0]}},{{item[1]}}"
  18. verbosity: 0
  19. #with_items: "{{test}}"
  20. with_nested: #可以以该格式,多次循环下去
  21. - "{{test}}"
  22. - "{{demo}}"

image.png

条件语句

  1. - name: when
  2. hosts: localhost
  3. gather_facts: no
  4. vars:
  5. seq:
  6. - 1
  7. - 2
  8. - 3
  9. - 4
  10. tasks:
  11. - name: Test when
  12. debug:
  13. msg: "{{item}}"
  14. verbosity: 0
  15. with_items: "{{seq}}"
  16. when: item >2 #当数值大于2时打印

image.png

Group和Host变量

在主机配置文件中,也可以设置变量,并且变量使多个服务器使用或重复利用。

方式1:在一个文件中设置

这种大多情况下是在配置几乎相同,没有差别变量时

  1. vim host #创建host文件,其中创建主机和所需变量
  2. [ans]
  3. ans2
  4. ans3
  5. [mydb]
  6. mydb1
  7. mydb2
  8. [ans:var] #此时创建的变量,就被ans中全部的服务器使用
  9. ansible_connection: ssh
  10. ansible_user: root
  11. ansible_password: mly118235
  12. [mydb:var] #此时创建的变量,就被var中全部的服务器使用
  13. ansible_connection: ssh
  14. ansible_user: root
  15. ansible_password: mydb123
  16. http_port: 3306
  17. vim main.yml #创建playbook文件
  18. - name: group
  19. hosts: all
  20. gather_facts: no
  21. tasks:
  22. - name: Test group
  23. debug:
  24. msg: "ansible_user={{ansible_user}},ansible_password={{ansible_password}}"
  25. ansible-playbook -i inventory/host playbook/main.yml

image.png

方式2:在不同文件中设置

  1. vim host
  2. [all]
  3. ans2
  4. ans3
  5. [mydb]
  6. mydb1
  7. mydb2
  8. #只需要创建服务器名称,必须要再创建变量了
  9. mkdir group_vars #创建文件夹,方便管理变量。文件夹名称没限制,但是需要和host文件在同一个文件夹中
  10. vim group_vars/ans.yml #文件名必须是host文件中的组名
  11. ansible_connection: ssh
  12. ansible_user: root
  13. ansible_password: mly118235
  14. vim group_vars/mydb.yml
  15. ansible_connection: ssh
  16. ansible_user: root
  17. ansible_password: mydb123
  18. http_port: 3306
  19. mkdir host_vars #创建文件夹,该文件夹存放不同的变量,依然会共用group_vars中的变量。
  20. vim host_vars/ans2.yml #文件名必须是host的名称
  21. http_port: 443 #此时就是单独创建的变量
  22. vim host_vars/ans3.yml
  23. http_port: 80
  24. #两个端口不一样
  25. vim main.yml
  26. - name: group
  27. hosts: all
  28. gather_facts: no
  29. tasks:
  30. - name: Test group
  31. debug:
  32. msg: "ansible_user={{ansible_user}},ansible_password={{ansible_password}},http_port={{http_port}}"
  33. #输出用户名,用户名密码,端口号

image.png

ansible.cfg 免去填写文件路径

  1. vim /root/playbook/ansible.cfg #将ansible.cfg放入到和main.yml一个文件夹
  2. [defaults]
  3. inventory= /root/inventory/host
  4. ansible-playbook main.yml

模块的使用

File 文件模块

Copy 从主控端复制文件到远程主机

  1. src : 源文件 指定拷贝文件的本地路径 (如果有/ 则拷贝目录内容,比拷贝目录本身)<br /> dest: 指定目标路径<br /> mode: 设置权限<br /> backup: 备份源文件<br /> content: 代替src 指定本机文件内容,生成目标主机文件<br />owner: 设置拥有者
  1. - name: copy file
  2. hosts: all
  3. gather_facts: no
  4. become: yes #设置是否以root用户执行操作
  5. - name: copy files from local to remote
  6. copy: #粘贴文件
  7. src: /root/test.txt #当前机器文件路径
  8. dest: /opt/test/test.txt #服务器文件路径
  9. backup: yes #如果文件同名或者更改内容再粘贴时,创建一个备份
  10. mode: 600 #设置权限位600

File 设置/创建文件

  1. path: 要管理的文件路径 (强制添加)<br /> recurse: 递归,文件夹要用递归<br /> src: 创建硬链接,软链接时,指定源目标,配合'state=link' 'state=hard' 设置软链接,硬链接<br /> state: 状态<br /> absent: 缺席,删除<br /> owner: 设置拥有者<br /> mode: 设置权限
  1. - name: create file
  2. hosts: all
  3. gather_facts: no
  4. become: yes #设置是否以root用户执行操作
  5. tasks:
  6. - name: create a directory if it does not exits
  7. file: #创建文件
  8. path: /opt/test #设置路径
  9. state: directory #文件类型为文件夹 touch 是文件
  10. ansible all -m file -a 'path=/app/test.txt state=touch' #创建文件
  11. ansible all -m file -a 'src=/data/testfile dest=/data/testfile-link state=link' #创建软链接
  1. - name: file module
  2. hosts: all
  3. gather_facts: no
  4. become: yes #设置是否以root用户执行操作
  5. tasks:
  6. - name: create a directory if it does not exits
  7. file: #创建文件
  8. path: /opt/test #设置路径
  9. state: directory #文件类型为文件夹 touch 是文件
  10. - name: copy files from local to remote
  11. copy: #粘贴文件
  12. src: /root/test.txt #当前机器文件路径
  13. dest: /opt/test/test.txt #服务器文件路径
  14. backup: yes #如果文件同名或者更改内容再粘贴时,创建一个备份
  15. mode: 600 #设置权限位600

template 创建模板

基础模板

使用的jinja语法

  1. vim site.yml
  2. - name: file module
  3. hosts: all
  4. gather_facts: no
  5. become: yes
  6. tasks:
  7. - name: test template
  8. template: #使用模板模块
  9. src: ../templates/test.j2
  10. dest: /opt/test/test.cfg
  11. mkdir templates #创建模板文件夹
  12. vim test.j2 #创建cfg模板
  13. [default]
  14. http_port = {{http_port}} #取出host文件中的变量
  15. ansible-playbook site.yml #运行

image.png

  1. vim test.j2 #创建cfg模板
  2. [default]
  3. http_port = {{http_port}}
  4. [demo]
  5. {% for id in range(201,211) %}
  6. {{ host_prefix }}{{ "%02d" | format(id-200) }} = {{ ip_prefix }}{{ id }}
  7. {% endfor %}

Unarchive 文件解压

  1. 1、将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes.<br /> 2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no<br />**copy=yes 当前主机压缩包到远程,copy=no 远程主机解压到远程**
  2. copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,<br /> 如果设置为copy=no,会在远程主机上寻找src源文件<br /> src 源路径,可以是ansible主机上的路径,也可以是远程主机上的路径,<br /> 如果是远程主机上的路径,则需要设置copy=no<br /> dest:远程主机上的目标路径<br /> mode:设置解压缩后的文件权限
  1. - name:
  2. unarchive: #根据后缀进行解压
  3. src: /root/Python-3.10.4.tgz #文件路径
  4. dest: /usr/local/ #解压位置
  5. remote_src: yes #是否使用的是服务器目录,默认是no,no就是使用本地路径文件,用本地就无须下载。

Fetch 远程拉取文件

  1. - name: fetch
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - name: fetch a file
  6. fetch: #调用远程拉取模块
  7. src: /etc/passwd #服务器的路径
  8. dest: ./tmp/ #当前路径
  9. flat: yes #是否创建文件夹

Archive 打包压缩

  1. 将远程主机目录打包 <br /> path: 指定路径<br /> dest: 指定目标文件<br /> format: 指定打包格式<br /> owner: 指定所属者<br /> mode: 设置权限
  1. - name: archive
  2. hosts: all
  3. gather_facts: no
  4. tasks:
  5. - name: archive
  6. archive: #设置打包压缩
  7. path: /etc/passwd #设置文件/设置文件夹
  8. dest: /opt/test.tar.bz2 #压缩包位置
  9. format: bz2 #设置压缩格式

System 系统模块

ping和get_facts

ping 上面演示过,这里就不错演示

  1. ansible all -m gather_facts #获取机器中的全部参数,API。其中包含的参数非常多
  2. ansible all -m gather_facts --tree ./facts #创建一个文件夹,会将打印的参数,添加到文件中。文件名就是设置的hosts名称
  3. #其中的变量,也是无需我们创建,能够直接访问的变量,此时我们来调用一下
  4. vim site.yml
  5. - name: file module
  6. hosts: all
  7. #gather_facts no #一定不要写这个,否则这些参数就无法使用了。
  8. become: yes
  9. tasks:
  10. - name: print facts
  11. debug:
  12. msg: "{{ ansible_date_time }}"
  13. - name: print ipv4
  14. debug:
  15. msg: "{{ ansible_default_ipv4 }}"

User的添加与删除

  1. home 指定家目录路径<br /> system 指定系统账号<br /> group 指定组<br /> remove 清除账户<br /> shell 指定shell类型
  1. ansible all -m user -a 'name=liao comment="创建liao" uid=2048 home=/home/liao1 group=root'
  2. #创建用户为liao 设置注释 uid设置为2048 home目录为/home/liao1 组为root
  3. tasks:
  4. - name: create system user
  5. user:
  6. name: sysuser1
  7. system: yes #指定是否为系统账号
  8. home: /app/sysuser1
  9. - name: create users
  10. user:
  11. name: app
  12. uid: 88
  13. system: yes #是否为系统用户
  14. home: /home/app
  15. groups: root
  16. shell: /sbin/nologin #设置为nologin
  17. passwd: "{{ 'appuser1' | password_hash('sha512') }}" #设置密码
  18. - name: remove user
  19. user:
  20. name: liao
  21. state: absent
  22. remove: yes
  1. 安装mkpasswd <br /> yum insatll expect <br /> mkpasswd 生成口令<br /> openssl passwd -1 生成加密口令

Group的创建与删除

  1. - name: group manager
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - name: create group
  6. group: #调用组模块
  7. name: liao118235 #组名称
  8. state: present #状态为创建
  9. - name: delete group
  10. group: #调用组模块
  11. name: liao118235 #组名称
  12. state: absent #状态为删除
  13. ansible-playbook site.yml #执行
  14. ansible all -m shell -a "tail /etc/passwd" #查看用户
  15. ansible all -m shell -a "tail /etc/group" #查看组

Service 服务的启动与关闭

  1. - name: install nginx and start nginx
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - name: install package
  6. yum:
  7. name:
  8. - epel* #安装epel工具包
  9. state: present
  10. - name: install nginx
  11. yum:
  12. name:
  13. - nginx #安装nginx
  14. state: present
  15. - name: start nginx
  16. service: #使用service模块
  17. name: nginx
  18. enabled: yes #是否设置开机自启
  19. state: started #启动nginx
  20. - name:
  21. service:
  22. name: nginx
  23. state: stopped
  • 重载 reloaded
  • 重新启动 restarted
  • 启动 started
  • 停止 stopped

Hostname 管理主机名

  1. ansible appsrvs -m hostname -a "name=app.adong.com" #更改一组的主机名
  2. ansible 192.168.38.103 -m hostname -a "name=app2.adong.com" #更改单个主机名

Cron 计划任务

支持时间:minute,hour,day,month,weekday

name: 任务计划名称
cron_file: 替换客户端该用户的任务计划的文件
minute: 分(0-59, /2)
hour: 时(0-23, /2)
day: 日(1-31, /2)
month: 月(1-12, /2)
weekday: 周(0-6或1-7, *)
job: 任何计划执行的命令,state要等于present
backup: 是否备份之前的任务计划
user: 新建任务计划的用户
state: 指定任务计划present、absent

  1. ansible all -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.16.0.1 &>/dev/null' name=Synctime" #创建任务
  2. ansible all -m cron -a 'state=absent name=Synctime' #删除任务
  3. ansible all -m cron -a 'minute=*/10 job='/usr/sbin/ntpdate 172.30.0.100" name=synctime disabled=yes"
  4. #注释任务,不在生效

Package 包模块

Yum安装工具

  1. - name: yum Install
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - name: yum install
  6. yum: #调用yum模块
  7. name: git #安装单个包git
  8. state: present #状态为创建
  9. - name: yum unstall
  10. yum:
  11. name: git
  12. state: absent #状态为删除
  13. - name: yum install more
  14. yum:
  15. name: {{packages}}
  16. vars: #安装多个包
  17. packages: #配置一个变量,方便管理
  18. - httpd
  19. - http-tools
  20. - name:
  21. yum:
  22. name:
  23. - wget
  24. - nginx
  25. - name: rpm install url
  26. yum:
  27. name: https://artifacts.elastic.co/downloads/kibana/kibana-6.0.0-x86_64.rpm #以网站的形式下载并安装rpm包
  28. stats: present
  29. - name: rpm install path
  30. yum:
  31. name: /root/kibana-6.0.0-x86_64.rpm #从路径查询包并安装
  32. stats: present
  33. - name: upgrade all packages
  34. yum:
  35. name: '*' #更新所有的包
  36. state: latest

apt安装工具

用法其实和yum差不多,我们只看当服务器有centos和ubuntu时,需要分开使用命令的情况

  1. - name: yum Install
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - name: yum install
  6. yum: #调用yum模块
  7. name: git #安装单个包git
  8. state: present #状态为创建
  9. when: ansible_faces["distribution"] == 'CentOS' #判定是否为Centos
  10. - name: apt get
  11. apt:
  12. name: git
  13. state: present #状态为创建
  14. when: ansible_faces["distribution"] == 'Ubuntu' #判定是否为Ubuntu

package 自动选择合适的安装命令

模块会自动识别服务器的发行版版本,进行不同的命令安装。
但是,部分包名称并不是一样的,所以还是需要进行上面的单独写。

  1. - name: package module
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - name: yum install
  6. package:
  7. name: git
  8. state: present
  9. force_apt_get: yes #强制使用apt get

pip安装

  1. - name: install python3
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - name: yum install python
  6. package:
  7. name: #安装python3和一些工具包
  8. - python3
  9. - python3-devel
  10. - python3-pip
  11. - python-setuptools
  12. state: present
  13. - name: yum install python
  14. pip:
  15. name: flask #需要安装的包
  16. #requirements: ~/flask-ansible-demo/requirements.txt #设置以文件-r 拉取pip包
  17. virtualenv: /root/vir/ #虚拟环境路径
  18. virtualenv_command: /usr/bin/python3 -m venv #进入虚拟路径的命令

git

拉取

  1. - name: get git
  2. git:
  3. repo: 'https://github.com/xiaopeng163/flask-ansible-demo' #填写git仓库的网址
  4. dest: ~/flask-ansible-demo #拉取到后 存放位置

Net tools 模块

get_url 通过url下载文件

  1. - name: download tar.gz
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - name: download python
  6. get_url:
  7. url: https://www.python.org/ftp/python/3.10.4/Python-3.10.4.tgz #填写下载地址
  8. dest: /root/ #下载路径
  9. checksum: md5:7011fa5e61dc467ac9a98c3d62cfe2be #检查md5
  10. - name:
  11. unarchive: #根据后缀进行解压
  12. src: /root/Python-3.10.4.tgz #文件路径
  13. dest: /usr/local/ #解压位置
  14. remote_src: yes #是否使用的是服务器目录,默认是no,no就是使用本地路径文件,用本地就无须下载。

uri 查看访问网页参数

  1. - name: curl web
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - name: check
  6. uri: #调用uri
  7. url: http://www.example.com #设置访问网页
  8. return_content: yes #设置是否返回网页内容
  9. register: result #注册返回值
  10. - debug:
  11. var: result #输出返回值

Command 命令模块

Command 命令模块

前面演示了shell命令的使用,shell模块与command模块的区别是,shell模块可以引用变量和使用一些比较符号。command模块建议使用一些单行命令

  1. - name: use command
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - name:
  6. command: cat /etc/passwd #执行的命令
  7. register: passwd_list #注册返回值,将命令的输入赋值到该变量中,此时变量就可以被引用了。
  8. - debug:
  9. msg: "{{passwd_list}}" #打印出返回值

Shell 命令模块

  1. ansible all -m shell -a 'getenforce' #查看SELINUX状态
  2. ansible all -m shell -a "sed -i 's/SELINUX=.*/SELINUX=disabled' /etc/selinux/config" #修改SELINUX
  3. vim /etc/ansible/ansible.cfg
  4. module_name = shell #修改配置文件,使shell作为默认模块
  5. ansible all -a 'cat /etc/passwd'

调用bash执行命令,可能依然出现错误,所以建议写到脚本时,copy到远程执行,再把需要的结果拉回执行命令的机器

  1. vim /etc/ansible/ansible.cfg
  2. module_name = shell #修改配置文件,使shell作为默认模块

Script 脚本模块

在远程主机上运行ansible服务器上的脚本

  1. ansible all -m script -a /tmp/data.sh #将当前服务器data.sh脚本咋在其他服务器上运行

Ansible Vault 加密

对文件进行加密解密

  • encrypt 加密
  • decrypt 解密
  • view 查看
  • edit 编辑
  1. ansible-vault encrypt /root/inventory/group_vars/all.yml #加密文件,设置密码
  2. ansible-vault decrypt /root/inventory/group_vars/all.yml #解密文件,输入密码解密

image.png

  1. ansible-vault view /root/inventory/group_vars/all.yml #输入密码,查看加密文件
  2. ansible-vault edit /root/inventory/group_vars/all.yml #输入密码,修改加密文件
  3. ansible-playbook site.yml --ask-vault-pass #执行加密的playbook

image.png

对变量进行加密

  1. ansible-vault encrypt_string "mly118235" --name "ansible_password"
  2. ansible_password: !vault |
  3. $ANSIBLE_VAULT;1.1;AES256
  4. 35626230313763323934623130636436666661396338616664303962383733663861656432316662
  5. 3631633730303232326138643162316364306239303238620a336637313737353732323138633866
  6. 33323665393036316138353633336234636132616238646137633263376462393965393538336462
  7. 6632373263333938360a313564666539346437363634373239363966383639306632353538383530
  8. 3962
  9. #只需将这段代码覆盖掉 ansible_password: mly118235 即可!
  10. #加密了执行时,需要输入密码

set_fact 模块

自定义

自定义变量,或者将获取的参数设置为变量。

  1. - name: file module
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - name: set facts
  6. set_fact: #创建fact
  7. LiAo_Name: 'LiAo' #创建key
  8. - debug:
  9. var: LiAo_Name #打印输出key

image.png

设置系统变量

  1. - name: file module
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - name: command get hosts
  6. command: cat /etc/hosts #执行命令
  7. register: host_results #注册返回值
  8. - name: set facts
  9. set_fact: #创建fact
  10. Ip_Host: "{{host_results['stdout_lines']}}" #创建key,设置值
  11. - debug:
  12. var: Ip_Host #打印值

image.png

Ansible工具

asnible-lint yml文件检查

对于ansible风格进行检查,类似python的PEP8。

  1. pip3 install ansible-lint -i https://pypi.tuna.tsinghua.edu.cn/simple #pip安装
  2. ansible-lint site.yml #检查yml 无任何输出就是书写规范。
  3. ansible-lint *.yml #检查当前文件夹全部的yml文件

Ansible-doc 获取模块信息

  1. ansible-doc -l | grep mysql

image.png

  1. ansible-doc -s mysql_info #查看该模块的用法

image.png

Blocks 区间 任务段

类似编程中的 try catch finally

  1. - name: error blocks
  2. hosts: all
  3. become: yes
  4. tasks:
  5. - block: #设置区间
  6. - name: excuting command
  7. command: /bin/tests #设置错误的命令
  8. rescue: #当发生错误时,执行的task,没发生错误就不执行
  9. - name: error message
  10. debug:
  11. msg: "命令产生错误,我执行了"
  12. always: #不管是否发生错误都执行的task
  13. - name: always excuting
  14. debug:
  15. msg: "管你错没错,我执行了"

Role 角色/函数

类似函数功能,目的是需要我们能够重复利用代码。

简单的项目案例

拉取github上的包。并且设置为一键搭建。
文件架构
image.png

  • 创建flask-demo 文件夹,存放项目
    • 创建inventory 文件夹 放服务器信息和变量
      • 创建group_vars 文件夹 存放变量
      • 创建 hosts 存放服务器host
    • 创建ansible.cfg 指定默认的host文件
    • 创建site.yml playbook文件
  1. vim site.yml
  2. - name: flask demo
  3. hosts: all
  4. gather_facts: no
  5. tasks:
  6. - name: yum install python
  7. package:
  8. name:
  9. - python3
  10. - python3-devel
  11. - python3-pip
  12. - python-setuptools
  13. - git
  14. state: present
  15. - name: yum install python
  16. pip:
  17. name: flask
  18. virtualenv: /root/vir/
  19. virtualenv_command: /usr/bin/python3 -m venv
  20. - name: get git
  21. git:
  22. repo: 'https://github.com/xiaopeng163/flask-ansible-demo'
  23. dest: ~/flask-ansible-demo
  24. - name: pip install
  25. pip:
  26. requirements: ~/flask-ansible-demo/requirements.txt
  27. state: present
  28. virtualenv: ~/flask-ansible-demo/.env
  29. virtualenv_command: /usr/bin/python3 -m venv
  30. - name: start flask app
  31. shell: nohup ~/flask-ansible-demo/.env/bin/python ~/flask-ansible-demo/wsgi.py &
  32. register: myoutput
  33. - name: print stdout
  34. debug:
  35. var: myoutput

Role的创建与调用

角色目录结构

jimage.png

  • roles 角色文件夹
    • deploy-code 角色名文件夹,yml调用时的名称
    • install-python 角色名文件夹,yml调用时的名称
  1. # playbooks
  2. site.yml
  3. webservers.yml
  4. fooservers.yml
  5. roles/
  6. common/
  7. tasks/
  8. handlers/
  9. library/
  10. files/
  11. templates/
  12. vars/
  13. defaults/
  14. meta/
  15. webservers/
  16. tasks/
  17. defaults/
  18. meta/
  • tasks/main.yml- 角色执行的任务的主列表。
  • handlers/main.yml- 处理程序,可以在此角色内部或外部使用。
  • library/my_module.py- 模块,可在此角色中使用(有关详细信息,请参阅在角色中嵌入模块和插件)。
  • defaults/main.yml- 角色的默认变量(有关详细信息,请参阅使用变量)。这些变量在所有可用变量中具有最低的优先级,并且可以很容易地被任何其他变量(包括库存变量)覆盖。
  • vars/main.yml- 角色的其他变量(有关详细信息,请参阅使用变量)。
  • files/main.yml- 角色部署的文件。
  • templates/main.yml- 角色部署的模板。
  • meta/main.yml- 角色的元数据,包括角色依赖关系。

文件内容配置

install-python/tasks/main.yml

  1. - name: yum install python
  2. package:
  3. name:
  4. - python3
  5. - python3-devel
  6. - python3-pip
  7. - python-setuptools
  8. - git
  9. state: present
  10. - name: into vir
  11. pip:
  12. name: flask
  13. virtualenv: /root/vir/
  14. virtualenv_command: /usr/bin/python3 -m venv

deploy-code/tasks/main.yml

  1. - name: get git
  2. git:
  3. repo: 'https://github.com/xiaopeng163/flask-ansible-demo'
  4. dest: ~/flask-ansible-demo
  5. - name: pip install
  6. pip:
  7. requirements: ~/flask-ansible-demo/requirements.txt
  8. state: present
  9. virtualenv: ~/flask-ansible-demo/.env
  10. virtualenv_command: /usr/bin/python3 -m venv

调用role

site.yml

  1. - name: flask demo
  2. hosts: all
  3. roles: #roles,第一种调用,直接写路径
  4. - role: '/root/flask-demo/inventory/roles/install-python/'
  5. gather_facts: no
  6. tasks:
  7. - include_role: #include_role 直接调用 但是name中 需要是site.yml和roles文件夹在同一级
  8. name: deploy-code
  9. - name: start flask app
  10. shell: nohup ~/flask-ansible-demo/.env/bin/python ~/flask-ansible-demo/wsgi.py &
  11. register: myoutput
  12. - name: print stdout
  13. debug:
  14. var: myoutput
  • roles 最经典的调用,填写文件夹名,简单,并且对于文件排版没要求,并且不写在tasks
  • include_role 常是动态调用,写在tasks中。对于排版有一定要求。

调用vars

vim /root/flask-demo/inventory/roles/deploy-code/tasks/main.yml

  1. - name: get git
  2. git:
  3. repo: '{{repo_url}}'
  4. dest: ~/flask-ansible-demo
  1. <a name="pESZZ"></a>
  2. ### 内部调用tasks
  3. 我们创建了main.yml文件夹,是直接会被调用。但是为了精简,我们可以写更多的yml文件。
  4. - 在install-python/tasks文件夹下创建pip.yml
  5. - pip.yml中只需要填写任务,而main.yml中只需用include 包含进去即可
  6. ```yaml
  7. vim pip.yml
  8. - name: into vir
  9. pip:
  10. name: flask
  11. virtualenv: /root/vir/
  12. virtualenv_command: /usr/bin/python3 -m venv
  13. vim main.yml
  14. - name: yum install python
  15. package:
  16. name:
  17. - python3
  18. - python3-devel
  19. - python3-pip
  20. - python-setuptools
  21. - git
  22. state: present
  23. - include: #直接包含即可,将文件+后缀输入
  24. pip.yml

Handler 的创建与使用

当tasks是changed时执行的tasks。比如说拉取了新的nginx配置文件,需要重启nginx。

  1. vim /root/flask-demo/inventory/roles/deploy-code/tasks/main.yml
  2. - name: get git
  3. git:
  4. repo: '{{repo_url}}'
  5. dest: ~/flask-ansible-demo
  6. notify: test handler #添加一个notify,拉取github时会覆盖原有的文件,所以需要handler做通知或者重启
  7. mkdir /root/flask-demo/inventory/roles/deploy-code/handlers
  8. vim /root/flask-demo/inventory/roles/deploy-code/handlers/main.yml
  9. - name: test handler
  10. debug:
  11. msg: "repo new install"

Ansible-galaxy 操作role模板

在当前目录一键创建/删除/列出/搜索/导入/安装等操作

  1. cd /root/flask-demo/inventory/roles #进入role模板目录
  2. ansible-galaxy role init ansible-gl-demo #创建模板
  3. - Role ansible-gl-demo was created successfully

image.png

创建的非常齐全,并且能够直接拿来使用。

从Github安装role到本地

ansible-galaxy install -r requirements.yml #拉取roles

  • extracting ansible-galaxy-demo to /root/.ansible/roles/ansible-galaxy-demo
  • ansible-galaxy-demo (master) was installed successfully ```

从Ansible Galaxy 安装Role到本地

Ansible Galaxy平台 该平台时Ansible团队搭建的,我们可以使用github账号登录,并且上传Role,一键下载。
image.png

或者从 Search 搜索别人的Role项目下载安装

image.png

image.png

  1. ansible-galaxy install geerlingguy.docker #就能直接下载
  2. #甚至在 requirements.yml 中 拉取也更方便了
  3. vim requirements.yml.
  4. roles:
  5. - src: https://github.com/xiaopeng163/ansible-galaxy-demo
  6. scm: git
  7. version: master
  8. - src: geerlingguy.docker
  9. version: 2.4
  10. ansible-galaxy install -r requirements.yml #能够直接拉取

Collection 集合

collection是一种可以包含playbook、role、模块和plugin的 Ansible 内容的发行格式。当模块从核心 Ansible 存储库移动到集合时

Ansible Tower 收费!!