Ansible 2.5.0下将服务启动时间转Epoch并筛选超时服务
解决方案:批量转换服务启动时间并筛选超时服务
以下是适配Ansible 2.5.0、Python 3.7.*且无需额外安装远程工具的Playbook实现,核心解决批量时间转换和超时服务筛选问题:
完整Playbook代码
--- - name: Filter and delete expired services hosts: your_target_hosts gather_facts: yes # 需要获取ansible_date_time计算阈值 tasks: # 步骤1:计算超时阈值的Epoch时间(示例:筛选7天前启动的服务,可调整天数) - name: Calculate threshold epoch time (7 days ago) set_fact: threshold_epoch: "{{ (ansible_date_time.epoch | int) - (7 * 86400) }}" # 步骤2:获取运行中服务的启动时间列表(输出格式匹配"Fri 2024-10-18 22:26:53 CEST : nginx-reactive") - name: Fetch running services with start time command: > systemctl list-units --type=service --state=running --no-pager --output='short-full' | awk '{print $1, $2, $3, $4, $5, $6, $7}' | grep -E '^[A-Za-z]{3} [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} [A-Z]{3} :' register: service_start_raw # 步骤3:批量转换启动时间为Epoch格式,同时保留服务名 # 依赖系统自带date命令处理时区,无需额外安装工具 - name: Convert service start times to epoch format shell: | while read line; do # 拆分时间字符串和服务名 time_part=$(echo "$line" | awk -F ' : ' '{print $1}') service_name=$(echo "$line" | awk -F ' : ' '{print $2}') # 转换为Epoch(指定TZ确保CEST时区识别正确) epoch_time=$(TZ="Europe/Paris" date -d "$time_part" +%s 2>/dev/null) # 仅输出转换成功的条目 if [ -n "$epoch_time" ]; then echo "$epoch_time : $service_name" fi done << 'EOF' {{ service_start_raw.stdout }} EOF register: service_epoch_results # 步骤4:筛选出启动时间早于阈值的服务 - name: Filter expired services set_fact: expired_services: "{{ expired_services | default([]) + [item.split(' : ')[1]] }}" loop: "{{ service_epoch_results.stdout_lines }}" when: (item.split(' : ')[0] | int) < (threshold_epoch | int) # 步骤5:循环触发删除操作(替换为你现有的删除逻辑,这里示例调用任务文件) - name: Delete expired services sequentially include_tasks: delete_service_tasks.yml vars: service_name: "{{ item }}" loop: "{{ expired_services }}" when: expired_services | length > 0
关键细节说明
- 时区处理:通过
TZ="Europe/Paris"指定时区,确保date命令能正确识别CEST夏令时,避免转换误差。 - 批量转换效率:通过shell循环一次性处理所有服务时间,比逐个调用
date命令更高效。 - 错误过滤:添加
2>/dev/null和非空判断,跳过转换失败的无效条目,避免干扰后续筛选。 - 兼容性适配:使用
include_tasks而非import_playbook循环,确保兼容Ansible 2.5.0的循环调用限制。
配套删除任务示例(delete_service_tasks.yml)
--- # 替换为你现有的删除逻辑:停止服务、删除容器、删除镜像 - name: Stop service {{ service_name }} service: name: "{{ service_name }}" state: stopped - name: Delete associated Docker container command: docker rm -f "{{ service_name }}" ignore_errors: yes # 容器不存在时忽略错误 - name: Delete associated Docker image command: docker rmi "{{ service_name }}_image" ignore_errors: yes # 镜像不存在时忽略错误
内容的提问来源于stack exchange,提问作者skyho
相关产品推荐
相关产品推荐

