Ansible详解

CentOS 7环境

一、简介

ansible是一款自动化运维工具,基于python开发,可以实现批量系统设置、批量程序部署、批量执行命令等功能,默认通过SSH协议管理机器,客户端需要有Python环境,其他无需配置,只需管理终端即可。

  1. 特性
  • 只需要在主控机安装ansible即可,被控端需要有python环境
  • 默认使用SSH协议对被控机器进行管理
  • 可以基于任何语言开发新模块
  • 部分模块具有幂等性,执行同一动作多次,对被执行对象的影响状态总是一致的,但是shell、command等一些模块是没有幂等性的,执行时不会检查状态。
  1. 工作过程
  • ansible命令执行
  • 读取ansible.cfg配置文件
  • 通过规则过滤inventory(hosts)中定义的主机列表
  • 加载对应的模块
  • 通过ansible core将模块或命令打包成python脚本文件
  • 将python脚本文件传输至目标主机.ansible/tmp/xxx/xxx.py
  • 给文件加执行权限
  • 执行python脚本并返回结果
  • 删除执行过的脚本

二、安装及简单使用

主机用途
192.168.0.81ansible主控机器
192.168.0.207被控机器
192.168.0.215被控机器
  1. 安装
$ yum install ansible -y
$ ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
  1. 配置文件路径
$ pwd
/etc/ansible

$ ls
ansible.cfg  hosts  roles

# 解释:
ansible.cfg:配置文件
hosts:ansible管理的inventory主机资产清单
roles:存放角色目录
  1. 配置主机清单
# 配置过后不能正常使用,需要配置ssh登录被控机器
$ vim /etc/ansible/hosts
192.168.0.207
192.168.0.215
  1. 配置ssh登录

任选其一

  • 通过ssh免密实现
$ ssh-keygen
$ ssh-copy-id root@192.168.0.207
$ ssh-copy-id root@192.168.0.215
  • 通过ansible主机清单实现
$ vim /etc/ansible/hosts
192.168.0.207 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='xxx'
192.168.0.215 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='xxx'
  1. 命令使用方法
$ ansible 主机/主机组/all(所有主机)  -m 模块名  -a 模块参数
-m:模块
-a:模块参数
-syntax-check:检查剧本语法,但不执行


$ ansible-doc 模块名  #查看模块使用方法及参数
  1. 通过ping模块测试,检查主机是否能ping通
$ ansible all -m ping
192.168.0.215 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.0.207 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
  1. 至此,已实现ansible批量化管理被控主机

三、配置文件解析

# 以下是部分配置解析

$ cat /etc/ansible/ansible.cfg
[defaults]
inventory      = /etc/ansible/hosts #指定主机清单文件
forks          = 5 #并发连接数,并行执行5个任务
roles_path    = /etc/ansible/roles #指定剧本位置
host_key_checking = False #是否检查SSH主机的密钥
timeout = 10 #ssh连接超时时间
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]

四、资产清单文件解析

  1. 主机与组
$ vim  /etc/ansible/hosts

192.168.0.1 #未分组主机

[group_name1] #组名,可以将主机归属到不通的组,到时通过组对被控端进行批量化操作
192.168.0.2 
192.168.0.3

[group_name2]
192.168.0.2 #一个主机可以属于不同的组


# 配置192.168.0.4主机别名为test1
test1 ansible_ssh_host=192.168.0.4 ansible_ssh_port=22

  1. 把一个组作为另一个组的子成员
$ vim  /etc/ansible/hosts
[group_name1]
192.168.0.1

[group_name2]
192.168.0.2

[group_name3:children]
group_name1
group_name2
  1. 主机变量
$ vim  /etc/ansible/hosts
[group_name1]
192.168.0.2 var1=app
  1. 组变量
$ vim  /etc/ansible/hosts
[group_name1]
192.168.0.1
192.168.0.2

[group_name1:vars]  #配置组变量格式
port=80
name=nginx
  1. 资产清单相关参数
# 远程主机
ansible_ssh_host

# 远程主机ssh端口
ansible_ssh_port

# 远程主机ssh用户密码
ansible_ssh_pass

五、模块

ping

检查被控主机是否能进行通信。

$ ansible all -m ping 

192.168.0.207 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.0.215 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

shell

在被控主机上执行shell命令。

$ ansible all -m shell -a 'date'

192.168.0.215 | CHANGED | rc=0 >>
Fri Jan  5 08:45:56 CST 2024
192.168.0.207 | CHANGED | rc=0 >>
Fri Jan  5 08:45:56 CST 2024

script

在被控主机上执行主控机器上的脚本。

# 在主控机器上创建脚本
$  cat /root/test.sh 
#!/bin/sh
date

$ ansible all -m script -a '/root/test.sh' 
192.168.0.207 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.0.207 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.0.207 closed."
    ], 
    "stdout": "Fri Jan  5 08:50:07 CST 2024\r\n", 
    "stdout_lines": [
        "Fri Jan  5 08:50:07 CST 2024"
    ]
}
192.168.0.215 | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 192.168.0.215 closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 192.168.0.215 closed."
    ], 
    "stdout": "Fri Jan  5 08:50:07 CST 2024\r\n", 
    "stdout_lines": [
        "Fri Jan  5 08:50:07 CST 2024"
    ]
}

copy

复制文件到被控主机。

$ ansible all -m copy -a 'src=/root/test.sh dest=/tmp'

相关参数:

  • src:源文件路径,可以指定文件或目录。当目录以/结尾时,只复制目录里边的内容,不带时,包含目录直接全部复制。
  • dest:复制文件到被控主机的文件路径。
  • backup:覆盖被控主机文件时,是否进行备份,选项有yes/no。
  • forces:被控主机上又相同文件时,强制覆盖,选项有yes/no。
  • mode:设置文件或目录的权限。
  • owner:设置文件或目录的属主。
  • group:设置文件或目录的属组。

unarchive

复制压缩文件到远程机器并解压。

$ ansible all -m unarchive -a 'src=/root/nginx-1.20.2.tar.gz dest=/tmp copy=yes'

相关参数:

  • src:压缩文件路径,可以是被控主机上的路径,也可以是中控机上的路径,如果是被控主机上的路径,则需设置copy=no。
  • dest:压缩文件复制到被控主机上的路径
  • copy:默认为yes,复制中控机上的文件到远程主机,为no时,复制被控主机上的文件到对应路径。
  • owner:解压后文件或目录的属主。
  • group:解压后文件或目录的属组。
  • mode:设置解压后的文件权限。

template

将变量传入配置jinja2文件并将文件复制到远程机器。
jinja2文件:可代替配置文件,里边可以传参。

$ cat nginx.conf.j2
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       {{ port }};  #设置变量
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

$ ansible all -m template -a "src=/root/nginx.conf.j2 dest=/tmp"

#被控主机查看
$ cat /tmp/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       82; #已改为82
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

fetch

从被控主机上拉取(即复制,不会删除被控主机上的文件)文件到本地。

$ ansible all -m fetch -a 'src=/tmp/test.sh dest=/opt'


$ tree /opt/
/opt/
├── 192.168.0.207
│   └── tmp
│       └── test.sh
└── 192.168.0.215
    └── tmp
        └── test.sh

4 directories, 2 files

相关参数:

  • src:被控主机文件路径。
  • dest:主控机文件存储路径。
  • flat:拉取文件到本地时,是否只需要文件或者文件所在的目录都拉取,选项有yes/no,默认为no。

cron

在被控主机上设置计划任务。

# 创建一个名为clean_mem的每天凌晨一点清理buff/cache的计划任务
$ ansible all -m cron -a 'name=clean_mem minute=0  hour=1 day=* month=* weekday=* job="echo 3 > /proc/sys/vm/drop_caches"' 

相关参数:

  • minute:分钟
  • hour:小时
  • day:日
  • month:月
  • weekday:周
  • job:计划任务内容
  • name:计划任务名称
  • disabled:注释计划任务
  • state:对计划任务执行的操作。选项有absent(删除计划任务),present(创建计划任务),默认为present。

yum

安装软件。

# 在被控主机上安装iftop命令

$ ansible all -m yum -a 'name=iftop state=present'

相关参数:

  • name:软件名
  • state:安装或卸载,选项有present或absent。

systemd

管理托管到systemd的服务。

$ ansible all -m systemd -a 'name=mysql state=stopped'

相关参数:

  • name:服务名称
  • daemon-reload:重载服务,选项有yes/no,默认为no。
  • enabled:是否配置开机自启,选项有yes/no,默认为no。
  • state:期望服务状态,选项有reloaded, restarted, started, stopped.

六、playbook(剧本)

当需要对被控主机一次下发多个指令时,可以通过playbook实现。playbook由YAML语言编写。
示例:
nginx编译安装,设置端口为82并启动

  1. 相关文件准备
$ ls
nginx-1.20.2.tar.gz  nginx.conf.j2  nginx.service  nginx.yml

$ nginx.conf.j2
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       {{ port }};
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}


$ cat nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
ExecStartPre=/data/nginx/sbin/nginx -t
ExecStart=/data/nginx/sbin/nginx -c /data/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target



  1. 执行playbook
$ cat nginx.yml 
--- 
- hosts: 192.168.0.215
  remote_user: root
  gather_facts: no
  vars:
  - version: 1.20.2
  - port: 82
  
  tasks:
  - name: install lib
    yum:
      name:
      - gcc
      - gcc-c++
      - gd
      - gd-devel
      - gperftools
      - libxml2
      - libxslt-devel
      - openssl
      - openssl-devel
      - pcre-devel
      - perl-ExtUtils-Embed
      state: present

  - name: create nginx group
    group: 
      name: nginx
      state: present

  - name: create nginx user
    user:
      name: nginx
      group: nginx
      shell: /sbin/nologin
      create_home: no
      state: present
  
  - name: unarchive nginx
    unarchive:
      src: "./nginx-{{ version }}.tar.gz"
      dest: "/tmp"
      copy: yes

  - name: make install nginx
    shell: |
      cd /tmp/nginx-{{ version }} && ./configure --prefix=/data/nginx --user=nginx --group=nginx --with-file-aio  --with-http_ssl_module --with-http_v2_module  --with-http_realip_module --with-stream_ssl_preread_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug && make && make install

  -name: copy nginx conf
   copy: 
     src: "/root/nginx.conf.j2"
     dest: "/data/nginx/conf"
     
  - name: to systemd
    copy:
      src: "/root/nginx.service"
      dest: "/usr/lib/systemd/system"
    notify: daemon-reload
  
  - name: start nginx
    systemd:
      name: nginx
      state: started

  handlers:
  - name: daemon-reload
    systemd:
      daemon-reload: yes

# 剧本语法检查
$ ansible-playbook nginx.yml --syntax-check

#执行剧本
$ ansible-playbook nginx.yml

七、role(角色)

role(角色),用于层次性、结构化的组织playbook,使结构层次更分明,更加方便的进行管理。像上述的Nginx安装playbook,如果有MySQL、Kafka等的安装,配置文件、安装包都放在一个目录,就会显得凌乱,无法管理。
示例:

  1. 初始化
# 初始化一个nginx安装的role
$ cd /etc/ansible/roles 
$ ansible-galaxy init nginx

#查看角色
$ ansible-galaxy role list
# /etc/ansible/roles
- nginx, (unknown version)


$ tree -L 1 nginx
nginx
├── defaults #填写默认变量
├── files  #要传输到被控主机的文件
├── handlers  #触发器
├── meta  #定义依赖关系
├── README.md  #角色描述文件
├── tasks  #创建任务信息
├── templates  #Jinja2模版存放目录
├── tests  
└── vars  #变量存放目录
  1. 存放相关文件
$ tree /etc/ansible/roles/nginx
nginx
├── defaults
│   └── main.yml
├── files
│   ├── nginx-1.20.2.tar.gz #安装包
│   └── nginx.service  #托管到systemd的配置文件
├── handlers
│   └── main.yml  #触发器
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml  #任务列表
├── templates
│   └── nginx.conf.j2  #nginx jinja2模版文件
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml  #变量文件
  1. role角色相关文件编写
# 执行任务
$ cat /etc/ansible/roles/nginx/tasks/main.yml
---
# tasks file for nginx
- name: install lib
  yum:
    name:
    - gcc
    - gcc-c++
    - gd
    - gd-devel
    - gperftools
    - libxml2
    - libxslt-devel
    - openssl
    - openssl-devel
    - pcre-devel
    - perl-ExtUtils-Embed
    state: present

- name: create nginx group
  group: 
    name: nginx
    state: present

- name: create nginx user
  user:
    name: nginx
    group: nginx
    shell: /sbin/nologin
    create_home: no
    state: present

- name: unarchive nginx
  unarchive:
    src: "./nginx-{{ version }}.tar.gz"
    dest: "/tmp"
    copy: yes

- name: make install nginx
  shell: |
    cd /tmp/nginx-{{ version }} && ./configure --prefix=/data/nginx --user=nginx --group=nginx --with-file-aio  --with-http_ssl_module --with-http_v2_module  --with-http_realip_module --with-stream_ssl_preread_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug && make && make install

- name: to systemd
  copy:
    src: "nginx.service"
    dest: "/usr/lib/systemd/system"
  notify: daemon-reload

- name: start nginx
  systemd:
    name: nginx
    state: started



# 触发器
$ cat /etc/ansible/roles/nginx/handlers/main.yml
---
# handlers file for nginx
- name: daemon-reload
  systemd:
    daemon-reload: yes


# 变量
$ cat /etc/ansible/roles/nginx/vars/main.yml
---
# vars file for nginx
---
# vars file for nginx
port: '82'
version: '1.20.2'


  1. 编写调用角色的剧本
$ vim /etc/ansible/roles/nginx.yml
--- 
- hosts: all
  remote_user: root
  gather_facts: no
  
  roles:
    - nginx   # 对应的角色名称

# 执行角色
$ ansible-playbook /etc/ansible/roles/nginx.yml
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

real向往

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值