temp0825g

Young-Kyoo Kim·2025년 8월 25일
# time_sync_correction.yml
# 시간 동기화 문제 해결 태스크
---
# ========================================
# 시간 차이 분석 및 교정
# ========================================

- name: Calculate time drift from reference
  set_fact:
    time_drift_seconds: |
      {% if time_reference is defined %}
      {% set ref_time = time_reference | to_datetime('%Y-%m-%dT%H:%M:%SZ') %}
      {% set node_time = node_result.current_time | to_datetime('%Y-%m-%dT%H:%M:%SZ') %}
      {{ (node_time - ref_time).total_seconds() }}
      {% else %}
      0
      {% endif %}
  
- name: Determine time correction strategy
  set_fact:
    time_correction_needed: "{{ (time_drift_seconds | float | abs) > max_time_drift_seconds }}"
    drift_level: |
      {% set drift = time_drift_seconds | float | abs %}
      {% if drift > 300 %}
      CRITICAL
      {% elif drift > 60 %}
      HIGH
      {% elif drift > 30 %}
      MODERATE
      {% else %}
      MINOR
      {% endif %}

- name: Display time analysis
  debug:
    msg: |
      🕐 TIME DRIFT ANALYSIS - {{ inventory_hostname }}
      ================================================
      Current Time: {{ node_result.current_time }}
      Reference Time: {{ time_reference | default('N/A') }}
      Time Drift: {{ time_drift_seconds | float | round(2) }}s
      Drift Level: {{ drift_level }}
      Correction Needed: {{ time_correction_needed }}
      NTP Synchronized: {{ node_result.ntp.ntp_synchronized }}
      Active NTP Service: {{ node_result.ntp.active_service }}

# ========================================
# NTP 서비스 상태 확인 및 수정
# ========================================

- name: Fix NTP synchronization issues
  block:
    - name: Install chrony if no time service is available
      package:
        name: chrony
        state: present
      when: node_result.ntp.active_service == 'none'
      register: chrony_installed
      
    - name: Configure chrony with reliable NTP servers
      copy:
        content: |
          # Chrony configuration
          # Generated by Ansible on {{ ansible_date_time.iso8601 }}
          # Host: {{ inventory_hostname }}
          
          # NTP Server Configuration
          pool {{ ntp_server_pool | default('pool.ntp.org') }} iburst
          pool 0.pool.ntp.org iburst
          pool 1.pool.ntp.org iburst
          pool 2.pool.ntp.org iburst
          
          # Record the rate at which the system clock gains/losses time
          driftfile /var/lib/chrony/drift
          
          # Allow the system clock to be stepped in the first three updates
          # if its offset is larger than 1 second
          makestep 1.0 3
          
          # Enable kernel synchronization of the real-time clock (RTC)
          rtcsync
          
          # Increase the minimum number of selectable sources required to adjust
          # the system clock
          minsources 2
          
          # Allow NTP client access from local network
          {% if ansible_default_ipv4.network is defined %}
          allow {{ ansible_default_ipv4.network }}/{{ ansible_default_ipv4.netmask }}
          {% endif %}
          allow 127.0.0.1
          
          # Serve time even if not synchronized to a time source
          local stratum 10
          
          # Get TAI-UTC offset and leap seconds from the system tz database
          leapsectz right/UTC
          
          # Specify directory for log files
          logdir /var/log/chrony
        dest: /etc/chrony.conf
        backup: yes
      when: node_result.ntp.chronyd_exists or chrony_installed.changed | default(false)
      register: chrony_config_changed
      
    - name: Start and enable chronyd
      systemd:
        name: chronyd
        state: started
        enabled: yes
        daemon_reload: yes
      when: node_result.ntp.chronyd_exists or chrony_installed.changed | default(false)
      register: chronyd_started
      
    - name: Restart chronyd if config changed
      systemd:
        name: chronyd
        state: restarted
      when: chrony_config_changed is defined and chrony_config_changed.changed
      
    - name: Force immediate time synchronization (gradual)
      command: chrony -q 'server {{ ntp_server_pool }} iburst'
      when: time_correction_needed and drift_level in ['MINOR', 'MODERATE']
      register: gradual_sync_result
      failed_when: false
      
    - name: Force immediate time synchronization (step for critical drift)
      block:
        - name: Stop chronyd for manual time step
          systemd:
            name: chronyd
            state: stopped
            
        - name: Force time step with chronyd
          command: chronyd -q 'server {{ ntp_server_pool }} iburst'
          register: step_sync_result
          
        - name: Start chronyd after manual sync
          systemd:
            name: chronyd
            state: started
            
      when: time_correction_needed and drift_level == 'CRITICAL'
      
    - name: Wait for synchronization to stabilize
      wait_for:
        timeout: 30
      when: chronyd_started is changed or gradual_sync_result is defined or step_sync_result is defined
      
    - name: Verify time synchronization after correction
      command: timedatectl status
      register: time_verify_result
      
    - name: Get updated chrony status
      command: chronyc tracking
      register: chrony_tracking_updated
      failed_when: false
      when: node_result.ntp.chronyd_exists or chrony_installed.changed | default(false)
      
    - name: Display time correction results
      debug:
        msg: |
          ✅ TIME SYNCHRONIZATION CORRECTION COMPLETED
          ================================================
          Previous Drift: {{ time_drift_seconds | float | round(2) }}s
          Correction Method: {{ 'Step' if drift_level == 'CRITICAL' else 'Gradual' }}
          
          Updated Status:
          {{ time_verify_result.stdout }}
          
          {% if chrony_tracking_updated.stdout is defined %}
          Chrony Tracking:
          {{ chrony_tracking_updated.stdout }}
          {% endif %}
          
  when: time_correction_needed or not node_result.ntp.ntp_synchronized

# ========================================
# 시간 동기화 모니터링 설정
# ========================================

- name: Setup time synchronization monitoring
  block:
    - name: Create time sync monitoring script
      copy:
        content: |
          #!/bin/bash
          # Time synchronization monitoring script
          # Generated by Ansible on {{ ansible_date_time.iso8601 }}
          
          LOG_FILE="/var/log/time_sync_monitor.log"
          MAX_DRIFT=30
          
          # Get current time sync status
          TIMEDATECTL_OUTPUT=$(timedatectl status)
          NTP_SYNC=$(echo "$TIMEDATECTL_OUTPUT" | grep "NTP synchronized" | awk '{print $3}')
          
          if [[ "$NTP_SYNC" != "yes" ]]; then
              echo "$(date): WARNING - NTP not synchronized" >> $LOG_FILE
              systemctl restart chronyd
          fi
          
          # Check chrony tracking if available
          if command -v chronyc &> /dev/null; then
              CHRONY_TRACKING=$(chronyc tracking)
              OFFSET=$(echo "$CHRONY_TRACKING" | grep "Last offset" | awk '{print $4}')
              
              if [[ $(echo "$OFFSET > $MAX_DRIFT" | bc -l) -eq 1 ]] 2>/dev/null; then
                  echo "$(date): WARNING - Time offset too large: ${OFFSET}s" >> $LOG_FILE
                  chrony -q 'server {{ ntp_server_pool }} iburst'
              fi
          fi
        dest: /usr/local/bin/time_sync_monitor.sh
        mode: '0755'
        
    - name: Create cron job for time sync monitoring
      cron:
        name: "Time synchronization monitoring"
        minute: "*/15"
        job: "/usr/local/bin/time_sync_monitor.sh"
        user: root
        
    - name: Create systemd timer for time sync monitoring (alternative)
      copy:
        content: |
          [Unit]
          Description=Time Sync Monitor Timer
          
          [Timer]
          OnCalendar=*:0/15
          Persistent=true
          
          [Install]
          WantedBy=timers.target
        dest: /etc/systemd/system/time-sync-monitor.timer
        
    - name: Create systemd service for time sync monitoring
      copy:
        content: |
          [Unit]
          Description=Time Sync Monitor Service
          
          [Service]
          Type=oneshot
          ExecStart=/usr/local/bin/time_sync_monitor.sh
          User=root
        dest: /etc/systemd/system/time-sync-monitor.service
        
    - name: Enable time sync monitoring timer
      systemd:
        name: time-sync-monitor.timer
        enabled: yes
        state: started
        daemon_reload: yes
        
  when: time_correction_needed or (node_result.ntp.ntp_synchronized | default(false)) == false

# ========================================
# 시간 동기화 권장사항
# ========================================

- name: Generate time sync recommendations
  set_fact:
    time_recommendations: |
      {% set drift = time_drift_seconds | float | abs %}
      {% if drift > 300 %}
      CRITICAL TIME DRIFT ({{ drift | round(2) }}s):
      1. 즉시 수동 시간 동기화 수행
      2. NTP 서버 연결 상태 확인
      3. 방화벽 설정 점검 (UDP 123 포트)
      4. 네트워크 연결성 확인
      5. 시스템 클럭 하드웨어 점검 권장
      {% elif drift > 60 %}
      HIGH TIME DRIFT ({{ drift | round(2) }}s):
      1. NTP 서비스 재시작 수행
      2. 더 가까운 NTP 서버로 변경 고려
      3. 정기적인 시간 동기화 모니터링 설정
      {% elif drift > 30 %}
      MODERATE TIME DRIFT ({{ drift | round(2) }}s):
      1. NTP 동기화 강제 수행
      2. 시간 동기화 빈도 증가
      {% else %}
      MINOR TIME DRIFT ({{ drift | round(2) }}s):
      1. 정상 범위 내 차이
      2. 정기 모니터링 유지
      {% endif %}

- name: Display time sync recommendations
  debug:
    msg: |
      
      ================================================
      🔧 TIME SYNCHRONIZATION RECOMMENDATIONS
      ================================================
      Host: {{ inventory_hostname }}
      {{ time_recommendations }}
      
      추가 점검 사항:
      - 네트워크 지연: ping {{ ntp_server_pool }}
      - NTP 포트 확인: netstat -ulnp | grep :123
      - 시스템 로그: journalctl -u chronyd -f
      - 하드웨어 클럭: hwclock --show
  when: time_correction_needed

0개의 댓글