自动化运维管理工具 - Ansible

本文参考文章


Ansible

Ansible部署

pip download ansible
pip install  *whl

默认没有创建 /etc/ansible 需要手动创建

Ansible配置说明

  • /etc/ansible/ansible.cfg 主配置文件, 配置ansible的工作特性.
  • /etc/ansible/ansible.cfg 主机列表清单.
  • /etc/ansible/roles/ 存放(roles)角色的目录.
  • /usr/local/bin/ansible 二进制执行文件, ansible 主程序.
  • /usr/local/bin/ansilbe-doc 配置文档, 模块功能查看工具.
  • /usr/local/bin/ansible-galaxy 用于上传/下载 roles 模块到官方平台的工具.
  • /usr/local/bin/ansible-playbook 自动化任务、编排剧本工具/usr/bin/ansible-pull 远程执行命令的工具.
  • /usr/local/bin/ansible-vault 文件(如: playbook 文件) 加密工具.
  • /usr/local/bin/ansible-console 基于 界面的用户交互执行工具.

Ansible执行过程

  1. load配置文件 /etc/ansible/ansible.cfg

  2. Load 模块配置文件

  3. 通过 Ansible 将调用的模块或PlayBook生成对应的临时 py文件, 并将该临时文件传输至远程服务器的对的执行用户目录下 $HOME/.ansible/tmp/ansible-tmp-2123/xxxxxxx.py >文件.

  4. 对生成的文件添加可执行权限.

  5. 执行生成文件,并返回对应的结果.

  6. 删除生成文件,退出.

    执行返回状态:

    • 绿色:执行成功,无更改操作。如 ping模块
    • 黄色:执行成功,更新过主机的操作。如执行shell模块执行ifconfig命令。
    • 红色:执行失败返回结果。如FAILED、UNREACHABLE状态。

Ansible-Doc

# 显示可用的模块
ansible-doc -l

ansible-doc ping 

# 显示指定模块的playbook阶段
ansible-doc -s ping 

Ansible

ansible <host-pattern> [-m module_name] [-a args]

  • host-pattern: 主机ip、主机名、主机组。
  • module_name: 模块的名称。默认为 -m command 。
  • args: 模块的参数, 需要加上 -a 进行指定模块的参数。如: ansible all -a 'hostname'
  • -v、-vv、-vvv: 显示详细的命令输出日志, v 越多越详细。如: ansible all -m ping -vvv
  • --list: 显示主机的列表。如: ansible all --list
  • -k / --ask-pass: 提示输入ssh连接密码, 默认为 ssh-key 认证。如: ansible all -m ping -k
  • -K / --ask-become-pass: 提示输入 sudo 的密码。
  • -C / --check: 检查命令操作, 并不会执行。如: ansible all -m ping -C
  • -T / --timeout: 执行命令的超时时间, 默认为 10s。如: ansible all -m ping -T=2
  • -u / --user: 执行远程操作的用户. 如: ansible all -m ping -u=root
  • -b / --become: 代替旧版的 sudo 切换。
  • -i 指定主机清单文件 ansible -i /data/ansible/hosts containers -m ping -o

/etc/ansible/ansible.cfg

# defaults 为默认配置
[defaults]

# 主机清单的路径, 默认为如下
# inventory = /etc/ansible/hosts

# 模块存放的路径 
# library = /usr/share/my_modules/

# utils 模块存放路径
# module_utils = /usr/share/my_module_utils/

# 远程主机脚本临时存放目录
# remote_tmp = ~/.ansible/tmp

# 管理节点脚本临时存放目录 
# local_tmp = ~/.ansible/tmp

# 插件的配置文件路径
# plugin_filters_cfg = /etc/ansible/plugin_filters.yml

# 执行并发数
# forks = 5

# 异步任务查询间隔 单位秒
# poll_interval  = 15

# sudo 指定用户
# sudo_user = root

# 运行 ansible 是否提示输入sudo密码
# ask_sudo_pass = True

# 运行 ansible 是否提示输入密码 同 -k
# ask_pass = True

# 远程传输模式
# transport = smart

# SSH 默认端口
# remote_port = 22

# 模块运行默认语言环境
# module_lang = C

# roles 存放路径
# roles_path = /etc/ansible/roles

# 不检查 /root/.ssh/known_hosts 文件 建议取消
# host_key_checking = False

# ansible 操作日志路径 建议打开
# log_path = /var/log/ansible.log

主机存活探测模块 ping

/etc/ansible/hosts主机资产配置

[containers]
172.17.0.4   # 主机1 
172.17.0.[5:7]  # 主机 172.17.0.5 - 172.17.0.7

# 设置containers的登陆用户及密码
[containers:vars]
ansible_ssh_user='root'
ansible_ssh_pass='666666'

跳过第一次登陆认证(输入yes的那个操作)

# uncomment this to disable SSH key host checking
host_key_checking = False

执行

ansible containers -m ping -o 
172.17.0.4 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"},"changed": false,"ping": "pong"}
172.17.0.5 | UNREACHABLE!: Failed to connect to the host via ssh: ssh: connect to host 172.17.0.5 port 22: No route to host
172.17.0.7 | UNREACHABLE!: Failed to connect to the host via ssh: ssh: connect to host 172.17.0.7 port 22: No route to host
172.17.0.6 | UNREACHABLE!: Failed to connect to the host via ssh: ssh: connect to host 172.17.0.6 port 22: No route to host

内置变量模块 setup

使用范例

ansible all  -m setup -a 'filter=ansible_hostname ' 
123.57.71.226 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "123-57-71-226",
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false
}
172.17.0.4 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "64076cdad7f4",
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}
172.17.0.5 | SUCCESS => {
    "ansible_facts": {
        "ansible_hostname": "eb3d371118b7",
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}

ansible_form_factor                     服务器类型  
ansible_virtualization_role             虚拟机角色(宿主机或者虚拟机)  
ansible_virtualization_type             虚拟机类型(kvm)  
ansible_system_vendor                   供应商(Dell)  
ansible_product_name                    产品型号(PowerEdge?R530)  
ansible_product_serial                  序列号(sn)  
ansible_machine                         计算机架构(x86_64)  
ansible_bios_version                    BIOS版本  
ansible_system                          操作系统类型(linux)  
ansible_os_family                       操作系统家族(RedHat)  
ansible_distribution                    操作系统发行版(CentOS)  
ansible_distribution_major_version      操作系统发行版主版本号(7)  
ansible_distribution_release            操作系统发行版代号(core)  
ansible_distribution_version            操作系统发行版本号(7.3.1611)  
ansible_architecture                    体系(x86_64)  
ansible_kernel                          操作系统内核版本号  
ansible_userspace_architecture          用户模式体系(x86_64)  
ansible_userspace_bits                  用户模式位数  
ansible_pkg_mgr                         软件包管理器  
ansible_selinux.status                  selinux状态  
ansible_processor                       CPU产品名称  
ansible_processor_count                 CPU数量  
ansible_processor_cores                 单颗CPU核心数量  
ansible_processor_threads_per_core      每个核心线程数量  
ansible_processor_vcpus                 CPU核心总数  
ansible_memtotal_mb                     内存空间  
ansible_swaptotal_mb                    交换空间  
ansible_fqdn                            主机的域名  
ansible_default_ipv4.interface          默认网卡  
ansible_default_ipv4.address            默认IP地址  
ansible_default_ipv4.gateway            默认网关  
ansible_devices                         硬盘设备名  
ansible_devices.vendor                  硬盘供应商  
ansible_devices.model                   硬盘整列卡型号  
ansible_devices.host                    硬盘整列卡控制器  
ansible_devices.size                    设备存储空间  
ansible_interfaces                      网卡  
ansible_{interfaces}.ipv4.address       网卡IP地址  
ansible_{interfaces}.ipv6.0.address     网卡IPv6地址  
ansible_{interfaces}.macaddress         网卡mac地址  

Ansible Palybook

变量引用 vars

定义变量文件

---
package_name: nginx
env_name: prod

palybook

  • register 用于接收
  • debug 用于输出
- hosts: 123.57.71.226
  remote_user: root

  # vars:
    # - package_name: nginx
    # - env_name: prod
  vars_files:
    - vars.yaml

  tasks:
    - name: "{{ env_name }} install {{ package_name }}"
      shell: echo {{ package_name  }}
      register: print_package_name

    - name: "输出{{ print_package_name }}信息"
      debug: var=print_package_name.stdout

    - name: "{{ inventory_hostname  }}"
      shell: echo {{ inventory_hostname   }}
      register: print_inventory_hostname

    - name: "输出{{ inventory_hostname }}信息"
      debug: var=print_inventory_hostname.stdout

服务安装 yum

ansible-playbook yum.yaml -C --limit 172.17.0.4,172.17.0.5
过程... 结果
172.17.0.4                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
172.17.0.5                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
  • -C 检查脚本运行情况,不在服务器执行
  • --limit 指定节点机器运行 --limit 172.17.0.4,172.17.0.5
- hosts: containers
  remote_user: root

  vars:
    - pak_name: httpd
    - env_name: prod

  tasks:
    - name: "{{ env_name}} install {{ pak_name }}"
      yum:
        name: '{{ pak_name }}'

二进制服务安装Nginx(例子)

目录结构

tree
.
├── index.html.j2    # nginx首页文件
└── install_nginx.yaml # 安装nginx的playbook

index.html.j2 文件内容

  • inventory_hostname 获取主机ipv4地址
<h1> {{ inventory_hostname  }} </h1>

安装Nginx剧本

  • 可以通过 -t tag 来进行配置文件检测、拷贝首页、 并触发重启动作。

ansible-playbook -t html,check install_nginx.yaml

- hosts: containers
  remote_user: root
  # 默认采集主机的信息,不采集执行会快一点
  gather_facts: False
  
  # 变量
  vars: 
    - nginx_user: nginx
    - nginx_group: nginx
    - nginx_version: 1.18.0
    - nginx_tmp_dir: /opt
    - nginx_listen_port: 80
    - nginx_prefix_dir: /usr/local/nginx
  # 任务列表
  tasks:
    # 安装nginx依赖包
    - name: "install nginx rely packages"
      yum:
        name:
          - net-tools
          - pcre 
          - pcre-devel
          - openssl
          - openssl-devel
          - zlib-devel
          - gcc
          - wget
    
    # 新建用户 
    - name: "Add nginx group"
      group: name={{ nginx_user  }} system=yes
   
    # 新增组 并关联用户
    - name: "Add nginx user"
      user: name={{ nginx_user }} shell=/sbin/nologin system=yes group={{ nginx_group }}
    
    # 下载nginx二进制包保存到 /opt
    - name: "Download nginx package" 
      get_url:
        url: http://nginx.org/download/nginx-{{ nginx_version }}.tar.gz
        dest: "{{ nginx_tmp_dir }}/nginx-{{ nginx_version }}.tar.gz"

    # 获取nginx的文件是否存在、以决定是否编译nginx
    - name: "nginx exists"
      stat:
        path: "{{ nginx_prefix_dir }}/sbin/nginx"
      register: file_status
   
    # 安装nginx  
    - name: "install nginx"
      shell: "cd {{ nginx_tmp_dir }};tar -xf nginx-{{ nginx_version }}.tar.gz;cd nginx-{{ nginx_version }};./configure --user={{ nginx_user }} --group={{ nginx_group }} --prefix={{ nginx_prefix_dir }} --with-http_stub_status_module --with-http_ssl_module --with-pcre --with-http_realip_module;make&& make install"
      when: file_status.stat.exists == False

    # 检查nginx的端口 并接收 shell返回的结果
    - name: "check nginx status"
      shell: netstat -anpt |grep {{ nginx_listen_port }}  |grep LISTEN  |wc -l
      register: port_result

    # 检查nginx配置文件
    - name: check config
      shell: "{{ nginx_prefix_dir  }}/sbin/nginx -t "
      register: status_result
      tags: check

    # 当接收的结果 == 0,此时80端口没有被占用, 启动nginx  否则直接跳过
    - name: startd nginx
      shell: "{{ nginx_prefix_dir  }}/sbin/nginx"
      # 这里返回的是字符串, 后面需要加双引号
      when: port_result.stdout == "0"


    # 拷贝本地j2文件模板到远程主机并触发nginx reload
    - name: "Copy html file"
      template: src=index.html.j2 dest={{ nginx_prefix_dir }}/html/index.html
      notify: reload nginx
      # 为任务设置tag 可以通过tag执行单个任务
      # ansible-playbook -t html install_nginx.yaml
      tags: html 

  # 触发器 任务中通过 notify 进行调用
  handlers:
    - name: reload nginx
      shell: "{{ nginx_prefix_dir }}/sbin/nginx -s reload"
      when: status_result.rc == 0

Roles 角色

roles角色结构如下

image-20220119143637446

roles目录结构

playbook.yml
roles/
 project/
   tasks/
   files/
   vars/       
   templates/
   handlers/
   default/    
   meta/  
  • files/ :存放由copy或script模块等调用的文件
  • templates/:template模块查找所需要模板文件的目录
  • tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
  • handlers/:至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
  • vars/:定义变量,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
  • meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含
  • default/:设定默认变量时使用此目录中的main.yml文件,比vars的优先级低

二进制服务安装Docker(例子)

目录结构

├── install_docker.yaml
└── roles
    └── docker
        ├── file
        │   ├── daemon.json
        │   └── docker.service
        ├── tasks
        │   ├── copybin.yaml
        │   ├── copyconfig.yaml
        │   ├── createdir.yaml
        │   ├── download.yaml
        │   ├── main.yaml
        │   └── service.yaml
        └── vars
            └── main.yaml

playbook调用角色

cat install_docker.yaml 
- hosts: localhost
  remote_user: root
  roles:
  - docker

file目录

more roles/docker/file/*
::::::::::::::
roles/docker/file/daemon.json
::::::::::::::
{
    "registry-mirrors":[
        "https://kfwkfulq.mirror.aliyuncs.com",
        "https://2lqq34jg.mirror.aliyuncs.com",
        "https://pee6w651.mirror.aliyuncs.com",
        "http://hub-mirror.c.163.com",
        "https://docker.mirrors.ustc.edu.cn",
        "https://registry.docker-cn.com"
    ]
}
::::::::::::::
roles/docker/file/docker.service
::::::::::::::
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd                         --graph /home/docker
ExecReload=/bin/kill -s HUP 
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target

tasks目录

more roles/docker/tasks/*
::::::::::::::
roles/docker/tasks/main.yaml
::::::::::::::
- include: download.yaml
- include: copybin.yaml
- include: createdir.yaml
- include: copyconfig.yaml
- include: service.yaml
::::::::::::::
roles/docker/tasks/copybin.yaml
::::::::::::::
- name: copy bin file
  copy: src="{{ docker_tmp_dir }}/docker/{{ item }}" dest="/usr/bin/{{ item }}" remote_src=yes mode=0755
  with_items:
    - containerd
    - containerd-shim
    - ctr
    - docker
    - dockerd
    - docker-init
    - docker-proxy
    - runc
::::::::::::::
roles/docker/tasks/copyconfig.yaml
::::::::::::::
- name: copy system file
  copy: src="file/docker.service" dest="/usr/lib/systemd/system/docker.service"


- name: copy config file
  copy: src="file/daemon.json" dest="/etc/docker/daemon.json"
::::::::::::::
roles/docker/tasks/createdir.yaml
::::::::::::::
- name: create directory
  file: path="{{item}}" state=directory
  with_items:
    - /home/docker
    - /etc/docker
    - /etc/systemd/system/docker.service.d/
::::::::::::::
roles/docker/tasks/download.yaml
::::::::::::::
- name: "Download docker package"
  get_url:
    url: https://download.docker.com/linux/static/stable/x86_64/docker-{{ docker_version}}.tgz
    dest: "{{ docker_tmp_dir }}/docker-{{docker_version}}.tgz"

- name: open tgz
  shell: "cd {{ docker_tmp_dir  }} ; tar xf docker-{{docker_version}}.tgz "
::::::::::::::
roles/docker/tasks/service.yaml
::::::::::::::
- name: start  docker service
  shell: systemctl daemon-reload && systemctl restart docker

- name: enable docker service
  shell: systemctl enable docker

vars目录

more roles/docker/vars/*
docker_version: "19.03.9"
docker_tmp_dir: "/opt"
posted @   郭培华  阅读(350)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示