Ansible自动化和Playbook

Ansible 自动化介绍

Ansible 部署

实验环境 /etc/hosts
10.1.8.10 controller.han.cloud controller
10.1.8.11 node1.han.cloud node1
10.1.8.12 node2.han.cloud node2
10.1.8.13 node3.han.cloud node3
10.1.8.14 node4.han.cloud node4

配置控制节点 han 用户使用han用户免密登录所有节点,并免提sudo提权执行任何命令。

# 所有节点配置/etc/hosts
[root@all-node ~]# cat >> /etc/hosts <<EOF
################ ansible #################
10.1.8.10 controller.han.cloud controller
10.1.8.11 node1.han.cloud node1
10.1.8.12 node2.han.cloud node2
10.1.8.13 node3.han.cloud node3
10.1.8.14 node4.han.cloud node4
EOF
# 所有节点添加用户
[root@all-node ~]# useradd han
# 所有节点,配置免密提权
[root@all-node ~]# echo 'han ALL=(ALL) NOPASSWD:ALL' > 
/etc/sudoers.d/han
# 创建密钥对
[han@centos7 ~]$ [ -d ~/.ssh ] || mkdir -m 700 .ssh
[han@centos7 ~]$ ssh-keygen -t rsa -f .ssh/id_rsa -N ''
# 推送公钥到目标主机
[han@centos7 ~]$ sudo yum install -y sshpass
[han@centos7 ~]$ for host in controller node{1..4}
do
 sshpass -p 123 ssh-copy-id han@$host
done
# 验证免密登录
[han@centos7 ~]$ for host in controller node{1..4}
do
  ssh han@$host hostname
done
控制节点

安装 ansible

[han@controller ~]$ sudo yum install -y ansible
[han@controller ~]$ ansible --version
ansible 2.9.27
 config file = /etc/ansible/ansible.cfg
 configured module search path =
[u'/home/han/.ansible/plugins/modules', 
u'/usr/share/ansible/plugins/modules']
......

Ansible 基本使用

Ansible 清单

ansible-inventory 命令

通过不同的格式查看清单文件

[han@controller ~]$ ansible-inventory --help
Usage: ansible-inventory [options] [host|group]
Options:
  --ask-vault-pass     ask for vault password
  --export             When doing an --list, represent in a way that 
is
                       optimized for export,not as an accurate
                         of how Ansible has processed it
  -h, --help           show this help message and exit
  -i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY
                       specify inventory host path or comma separated 
host
                       list. --inventory-file is deprecated     
......                       

示例清单:

app1.example.com
[webservers]
web1.example.com
web2.example.com
192.168.3.7
[dbservers]
db1.example.com
db2.example.com
192.0.2.42
[eastdc]
web1.example.com
db1.example.com
[westdc]
web2.example.com
db2.example.com
[dc:children]
eastdc
westdc

验证:

# 树形结构显示
[han@controller ~]$ ansible-inventory -i inventory --graph
@all:
 |--@dbservers:
 | |--192.0.2.42
 | |--db1.example.com
 | |--db2.example.com
 |--@dc:
 | |--@eastdc:
 | | |--db1.example.com
 | | |--web1.example.com
 .....

管理 ANSIBLE 配置文件

配置文件位置和优先级

  1. 环境变量 ANSIBLE_CONFIG
  2. ./ansible.cfg,当前位置中的 ansible.cfg,当前位置一般是项目目录。
  3. ~/.ansible.cfg
  4. /etc/ansible/ansible.cfg

从上到下,优先级越来越低。

建议:在当前目录下定义ansible.cfg文件。

验证优先级
# 环境准备
[han@controller ~]$ mkdir web && cd web
# 查看ansible命令当前使用的配置文件
[han@controller web]$ ansible --version
ansible 2.9.27
 config file = /opt/ansible.cfg
 .....
#验证优先级效果
[han@controller web]$ ansible --version |grep 'config file'
 config file = /etc/ansible/ansible.cfg
[han@controller web]$ touch ~/.ansible.cfg
[han@controller web]$ ansible --version |grep 'config file'
 config file = /home/han/.ansible.cfg
[han@controller web]$ touch ansible.cfg
[han@controller web]$ ansible --version |grep 'config file'
 config file = /home/han/han/ansible.cfg
[han@controller web]$ export ANSIBLE_CONFIG=/opt/ansible.cfg
[han@controller web]$ sudo touch /opt/ansible.cfg
[han@controller web]$ ansible --version |grep 'config file'
 config file = /opt/ansible.cfg
配置文件示例

对于基本操作, 使用 [defaults][privilege_escalation] 即可。

配置文件示例

[defaults]
inventory = ./inventory
remote_user = han
[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False

最终效果:

[han@controller webapp]$ ansible all -a id
node3 | CHANGED | rc=0 >>
uid=0(root) gid=0(root) groups=0(root)
node2 | CHANGED | rc=0 >>
uid=0(root) gid=0(root) groups=0(root)
node1 | CHANGED | rc=0 >>
uid=0(root) gid=0(root) groups=0(root)
node4 | CHANGED | rc=0 >>
uid=0(root) gid=0(root) groups=0(root)
ansible-config 命令

用于分析ansible命令的配置。

[han@controller ~]$ ansible-config -h
usage: ansible-config [-h] [--version] [-v] {list,dump,view} ...
View ansible configuration.
positional arguments:
 {list,dump,view}
   list           Print all config options
   dump           Dump configuration
   view           View configuration file
optional arguments:
  --version         show program's version number, config file 
location,
                   configured module search path, module location, 
executable
......
ansible-config view

查看当前ansible配置文件内容。

[han@controller web]$ ansible --version|grep file
 config file = /home/han/web/ansible.cfg
[han@controller web]$ ansible-config view
[defaults]
remote_user = han
inventory = ./inventory
[privilege_escalation]
become = True
......

运行 AD HOC 命令

实验环境
[han@controller ~]$ mkdir web && cd web
[han@controller web]$ cat > ansible.cfg <<'EOF'
[defaults]
remote_user = han
inventory = ./inventory
[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False
EOF
Ansible 部分模块
  • 文件模块

    • copy: 将控制主机上的文件复制到受管节点,类似于scp

    • file: 设置文件的权限和其他属性

    • lineinfile: 确保特定行是否在文件中

    • synchronize: 使用 rsync 将控制主机上的文件同步到受管节点

  • 软件包模块

    • package: 自动检测操作系统软件包管理器
    • yum: 使用 YUM 软件包管理器管理软件包
    • apt: 使用 APT
    • 软件包管理器管理软件包
    • gem: 管理 Rubygem
    • pip: 从 PyPI 管理 Python 软件包
  • 系统模块

    • firewalld: 使用firewalld管理任意端口和服务
    • reboot: 重新启动计算机
    • service: 管理服务
    • user、group: 管理用户和组帐户
  • NetTools模块

    • get_url: 通过HTTP、HTTPS或FTP下载文件
    • nmcli: 管理网络
    • uri: 与 Web 服务交互
ansible-doc 命令
[han@controller ~]$ ansible-doc -h
Usage: ansible-doc [-l|-F|-s] [options] [-t <plugin type> ] [plugin]
plugin documentation tool
Options:
  -h, --help           show this help message and exit
  -j, --json           **For internal testing only** Dump json 
metadata for
                       all plugins.
  -l, --list           List available plugins
.....

示例:

# 查看模块清单及说明
[han@controller ~]$ ansible-doc -l
fortios_router_community_list               Configure community lists 
i...
azure_rm_devtestlab_info                     Get Azure DevTest Lab 
facts
......
command 模块

要运行的命令通过-a选项指定为该模块的参数。

[han@controller web]$ ansible node1 -m command -a 'hostname'
node1 | CHANGED | rc=0 >>
node1.han.cloud
[han@controller web]$ ansible node1 -m command -a 'hostname' -o
node1 | CHANGED | rc=0 | (stdout) node1.han.cloud
shell 模块
#与command对比效果
[han@controller web]$ ansible node1 -m command -a set
node1 | FAILED | rc=2 >>
[Errno 2] No such file or directory: 'set': 'set'
[han@controller web]$ ansible node1 -m shell -a set
node1 | CHANGED | rc=0 >>
BASH=/bin/sh
BASHOPTS=cmdhist:complete_fullquote:extquote:force_fignore:hostcomplete
:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
......

ansible AD HOC 命令选项

临时命令选项优先级高于配置文件中配置。

配置文件指令 命令行选项
inventory -i
remote_user -u
ask_pass -k, --ask-pass
become –become, -b
become_method –become_method
become_user –become-user
become_ask_pass –ask-become-pass, -K

编写和运行Playbook

实验环境

[han@controller ~]$ mkdir web && cd web
[han@controller web]$ cat > ansible.cfg <<'EOF'
[defaults]
remote_user = han
inventory = ./inventory
[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False
EOF

Vim 编辑器设置

如果使用vim编辑器,设置vim环境便于编辑Playbooks。

在$HOME/.vimrc文件中添加以下内容:

set ai ts=2 number

效果:

  • “ai”,即 “autoindex”,表示自动缩进。
  • “ts”,即 “tabstop”,表示tab键使用2个空格代替。
  • “number”,显示行号。
  • autocmd FileType yam,代表文件类型是yaml时,自动执行“set ai ts=2”。

Playbook 编写

Playbook 示例

playbook.yaml 内容如下:

# yaml格式起始行,一般不省略
---
# Playbook中第一个play
# play具有属性:name,hosts,become,tasks,缩进一致
# name属性,用于简要描述play
- name: debploy WebSite
  
  # hosts属性,用于定义要在哪个受管理节点执行
 hosts: webs
  
  # tasks属性,用于描述play中任务,属性是列表格式
 tasks:
    
    # 第一个任务
    # 任务具有属性:涵name和模块名等。
    # name属性,用于简要描述任务
   - name: latest version of httpd and firewalld installed
      # 指明模块名,也就是要执行的任务
     yum:
        # 指定要操作的rpm包名称
       name:
          # rpm包名称是-开头的列表格式,或者逗号分隔的列表格式
         - httpd
         - firewalld
        
        # 定义软件包的状态,lastet代表升级为最新版本
       state: latest
    
    # 第二个任务
   - name: prepare index.html
      # copy 模块,用于将content属性值写入到目标文件
     copy:
       content: "Welcome to han WebSite!\n"
       dest: /var/www/html/index.html
    
    # 第三个任务
   - name: enable and start httpd
      # service模块,用于启用并启动httpd服务
     service:
       name: httpd
       enabled: true
       state: started
    # 第四个任务
     - name: enable and start firewalld
      # service模块,用于启用并启动firewalld服务
     service:
       name: firewalld
       enabled: true
       state: started
    # 第五个任务
   - name: firewalld permits access to httpd service
      # firewalld,用于放行http服务
     firewalld:
       service: http
       permanent: true
       state: enabled
       immediate: yes
# Playbook中第二个play,-开头表示列表
- name: Test WebSite
 hosts: localhost
 become: no
 tasks:
   - name: connect to intranet web server
      # uri模块,用于测试网站是否可以访问
     uri:
       url: http://{{item}}
     loop:
       - node1
       - node2
# yaml格式结束行,一般省略
...
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐