JWT 인증 토큰이 간헐적으로 거부된다는 문제 신고가 들어왔습니다. 로그를 보니 token issued in the future 에러입니다. 코드 변경은 없었는데 왜 갑자기? 원인을 추적해보니 서버 중 한 대의 시계가 다른 서버보다 30초 빠르게 맞춰져 있었습니다. 클라우드 VM이 마이그레이션된 이후 NTP 데몬이 재시작되지 않아 시계가 조금씩 벗어났던 겁니다. 분산 시스템에서는 서버마다 시간이 같아야 한다는 전제 조건이 있고, 그게 깨지면 인증과 로그 분석이 모두 엉킵니다.
시간 동기화 (NTP & chrony)
서버의 시스템 시계가 몇 초만 틀려도 JWT 인증 토큰 검증 실패, TLS 핸드셰이크 오류, 로그 순서 뒤집힘 같은 장애가 발생합니다. 클라우드 환경에서는 VM이 일시 정지(sleep/migrate)된 후 시계가 수십 초~수 분씩 틀어지는 일이 흔합니다. NTP(Network Time Protocol)와 chrony를 이용해 서버 시간을 정확하게 유지하는 방법을 배웁니다.
1. 서버 시간이 왜 중요한가
- 1서버 시간 불일치가 JWT·TLS·로그에 미치는 영향을 설명할 수 있다
- 2NTP Stratum 계층 구조와 시간 동기화 원리를 이해할 수 있다
- 3chrony가 ntpd를 대체한 이유와 차이점을 설명할 수 있다
- 4chrony를 설치하고 /etc/chrony.conf에 타임서버를 설정할 수 있다
- 5chronyc tracking / sources로 동기화 상태를 모니터링할 수 있다
- 6timedatectl로 타임존을 변경하고 hwclock을 동기화할 수 있다
timedatectl statussystemctl status chronyd && chronyc trackingsudo apt-get install -y chrony # 또는 sudo yum install -y chronyexport TZ=Asia/Seoul 은 현재 셸 세션에만 임시 적용되므로, 영구 변경은 반드시 timedatectl set-timezone 을 사용할 것
시간 불일치가 만드는 장애 시나리오
서버 운영에서 시간 동기화는 '있으면 좋은 것'이 아니라 필수 인프라입니다. 시간이 틀렸을 때 발생하는 실제 장애 유형을 살펴보겠습니다.
JWT / OAuth 토큰 만료
JWT(JSON Web Token)에는 iat(발급 시각)와 exp(만료 시각)가 Unix timestamp로 저장됩니다. 인증 서버와 애플리케이션 서버 간 시계가 30초 이상 차이 나면 방금 발급된 토큰도 "이미 만료"로 처리됩니다.
AuthServer time: 10:00:00 → JWT exp = 10:30:00
AppServer time: 10:31:00 → "토큰 만료!" (실제 5분밖에 안 지남)
TLS 인증서 유효성 검증 실패
TLS 인증서에는 Not Before와 Not After 필드가 있습니다. 클라이언트 시계가 서버보다 1시간 앞서 있으면, 아직 유효한 인증서도 "미래 인증서"로 거부됩니다. HTTPS 연결 자체가 실패합니다.
분산 시스템 로그 추적 불가
마이크로서비스 환경에서 서비스 A → B → C 순서로 호출이 일어났는데 각 서버 시계가 제각각이면 로그를 시간순으로 정렬해도 실제 호출 순서와 다르게 보입니다. Jaeger, Zipkin 같은 분산 트레이싱 도구도 타임스탬프 기반이므로 시간 불일치 시 추적 그래프가 왜곡됩니다.
Kerberos / Active Directory 도메인 조인 실패
Kerberos 프로토콜은 보안상 클라이언트와 KDC(Key Distribution Center) 간 시계 차이가 5분 이내여야 한다고 강제합니다. 시간이 5분 이상 벗어나면 도메인 조인, 로그인, Kerberos 티켓 갱신이 모두 실패합니다.
KRB5KRB_AP_ERR_SKEW: Clock skew too great
데이터베이스 복제 및 분산 합의
PostgreSQL 스트리밍 복제, Cassandra, etcd, CockroachDB 등은 노드 간 시계 차이를 기반으로 이벤트 순서를 결정합니다. 시계 차이가 크면 데이터 충돌 해결이 틀려지거나 복제가 중단될 수 있습니다.
2. NTP 프로토콜과 계층 구조
NTP Stratum 계층 구조 원리
확대
chronyc tracking을 실행했을 때 "Stratum: 2"가 뜨는데, 이게 좋은 건지 나쁜 건지, 왜 Stratum 값이 낮을수록 더 정확한 건지 궁금합니다. 또 사내 NTP 서버를 따로 구성해야 한다는 말을 들었는데 왜 Google이나 AWS의 공개 NTP 서버를 바로 쓰면 안 되는지도 의문입니다. Stratum 계층 구조를 이해하면 이 질문들에 답이 생기고, timedatectl 출력에서 시간 동기화 품질을 판단할 수 있게 됩니다.
NTP(Network Time Protocol, RFC 5905)는 인터넷을 통해 클라이언트가 정확한 시각을 얻을 수 있게 해주는 프로토콜입니다. 계층(Stratum) 구조로 정확도를 등급화합니다.
Stratum 번호가 낮을수록 더 정확합니다. Stratum 16은 "동기화 안 됨"을 의미합니다.
NTP 동기화 메커니즘
클라이언트는 서버에 요청 패킷을 보내고 4개의 타임스탬프를 이용해 오프셋(offset)과 왕복 지연(round-trip delay)을 계산합니다:
T1 : 클라이언트가 요청 전송한 시각
T2 : 서버가 요청을 받은 시각
T3 : 서버가 응답을 전송한 시각
T4 : 클라이언트가 응답을 받은 시각
왕복 지연 = (T4 - T1) - (T3 - T2)
오프셋 = ((T2 - T1) + (T3 - T4)) / 2
계산된 오프셋만큼 로컬 시계를 천천히 조정합니다. 급격한 시계 점프는 오히려 장애를 유발하므로, chrony는 시계를 slew(조금씩 당기거나 미루기) 방식으로 부드럽게 보정합니다.
사용 포트
NTP는 UDP 123번 포트를 사용합니다. 방화벽에서 이 포트가 막혀 있으면 동기화가 전혀 작동하지 않습니다.
시계가 NTP로 맞춰지기까지 — 질의부터 drift 보정 반복까지 5단계
chronyc tracking에서 "System time"이 수 ms로 수렴하는 걸 보면 시계가 저절로 맞는 것처럼 보이지만, 그 뒤에는 질의 → 오차 계산 → 보정 → 하드웨어 반영이라는 정해진 절차가 돌고 있습니다. 이 흐름을 알면 "왜 동기화가 안 되지", "왜 재부팅하면 또 틀어지지", "왜 시각은 맞는데 표시가 UTC지"를 각각 어느 단계의 문제인지로 좁혀 진단할 수 있습니다.
chronyd ──질의(T1)──▶ 타임서버
◀──응답(T4)──
│
① 왕복 4개 타임스탬프 수집 (iburst면 부팅 직후 몰아서 질의)
│
② 오프셋 계산 + 소스 교차검증 (여러 소스 중 truechimer 채택, 튀는 소스=falseticker 배제)
│
── 오차 크기? ──
│ 작다 → ③a slew (주파수를 미세조정해 서서히 당김/늦춤 — 시각이 뒤로 안 튐)
│ 크다 → ③b step (makestep 임계 초과 → 즉시 점프)
│
④ rtcsync → 하드웨어 클록(RTC)에 반영 (재부팅 후에도 시각 유지)
│
⑤ driftfile에 주파수 오차 기록 → 폴링 반복
▼
chronyc tracking: System time 0.000015s ... (수 ms 이내 수렴)
각 단계에서 무슨 일이 일어나고, 어긋나면 어떤 증상인가:
| 단계 | 하는 일 | 여기서 어긋나면 (증상) |
|---|---|---|
| ① 질의 | 클라이언트가 UDP 123으로 타임서버에 패킷을 보내고 응답의 4개 타임스탬프를 모음. iburst는 부팅 직후 몰아 보내 첫 동기화를 앞당김 | 123/udp 아웃바운드가 막히면 응답이 안 옴 → chronyc sources의 Reach 0·^?, 영영 동기화 안 됨 |
| ② 오차 계산 | 왕복 지연을 빼고 오프셋(내 시계가 얼마나 틀렸는지)을 산출. 소스가 여럿이면 겹치는 다수를 truechimer로 채택 | 소스가 1개뿐이면 교차검증 불가 → 그 소스가 조용히 틀어져도 못 거르고 함께 틀어짐(소스 3~4개 권장) |
| ③ slew·step | 오차가 작으면 주파수를 미세조정해 서서히(slew), 크면 즉시 점프(step)로 보정. makestep이 임계·횟수를 정함 | makestep 미설정이면 부팅 초기 큰 오차도 slew만 → 수렴이 몇 시간씩 느림. 운영 중 잦은 step은 로그·DB 시각을 뒤로 튀게 함 |
| ④ RTC 반영 | rtcsync가 보정된 시스템 시각을 하드웨어 RTC에 주기적으로 기록 | rtcsync가 없으면 재부팅 직후 RTC의 옛 시각으로 시작 → NTP가 다시 맞출 때까지 잠깐 틀어짐 |
| ⑤ drift·반복 | 시계 고유의 주파수 오차를 driftfile에 저장하고 폴링을 반복 → 다음 부팅·동기화가 빠름 | 타임존은 별개 — 시각(UTC)이 맞아도 표시가 UTC면 timedatectl set-timezone으로 KST 매핑을 따로 해야 함 |
즉 NTP synchronized: yes는 ①②가 성공해 어떤 소스와 맞았다는 뜻일 뿐, 그 소스가 옳은지(②의 교차검증)와 재부팅 후에도 유지되는지(④)는 별개입니다. 그래서 진단은 세 지점을 봅니다: chronyc sources로 ^* 소스와 Reach가 살아있는지(①), chronyc tracking의 System time 오프셋이 수 ms 이내인지(②③), 시각은 맞는데 표시가 UTC면 타임존(⑤)을 확인합니다. 대부분의 "동기화가 안 돼요"는 ①의 123/udp 방화벽에서 끝납니다.
3. chrony vs ntpd
chrony가 ntpd를 대체한 이유
확대
새 Ubuntu 22.04 서버에서 시간 동기화 설정을 하려는데, 이전 팀원 문서는 전부 ntpd 기반이고 현재 운영 중인 일부 서버도 ntpd를 씁니다. 검색하면 chrony를 쓰라는 글이 나오는데, 그냥 두 개 다 설치해서 쓰면 안 되냐는 생각이 드는 상황입니다. 실제로 혼용하면 UDP 123 포트 충돌이나 시계 엇갈림으로 더 큰 문제가 생깁니다. chrony가 ntpd를 대체하게 된 배경을 알면 어떤 도구를 선택해야 하는지, 기존 ntpd 서버를 언제 마이그레이션해야 하는지 기준이 생깁니다.
과거에는 ntpd(NTP daemon)가 표준이었지만, RHEL 7 / CentOS 7부터 chrony가 기본으로 채택되었고, Ubuntu 18.04+, Debian 10+ 등 대부분의 최신 배포판이 chrony를 기본 NTP 클라이언트로 사용합니다.
| 항목 | chrony | ntpd |
|---|---|---|
| 개발 연도 | 1990s (현재도 활발히 개발) | 1980s (개발 축소) |
| 빠른 초기 동기화 | 매우 빠름 (수 초) | 느림 (수 분) |
| 불안정한 네트워크 | 잘 처리 | 취약 |
| VM / 컨테이너 환경 | 최적화 | 문제 많음 |
| 간헐적 인터넷 연결 | 지원 | 미지원 |
| 설정 파일 | /etc/chrony.conf | /etc/ntp.conf |
| 제어 도구 | chronyc | ntpq, ntpdc |
| 메모리 사용 | 적음 | 많음 |
| RHEL 8/9 기본 | O | X (제거됨) |
VM과 컨테이너 환경에서 chrony가 특히 중요한 이유:
가상 머신은 하이퍼바이저가 CPU 자원을 다른 VM과 나누어 사용하기 때문에 VM 내부 시계가 실제보다 느리게 흐릅니다. VM이 일시 정지(suspend/migrate)된 후 깨어나면 몇 초~수 분의 시계 드리프트가 발생합니다. chrony는 이런 큰 오프셋도 빠르게 보정할 수 있도록 설계되어 있습니다.
3-1. NTP 포트 표 & 데몬 1개 원칙
NTP 포트/프로토콜 표 — 방화벽 규칙 작성 기준
확대
시간 동기화 트러블슈팅의 절반은 방화벽 문제입니다. 어떤 포트를 열어야 하는지 정확히 알아야 합니다.
| 서비스 | 프로토콜/포트 | 방향 | 설명 |
|---|---|---|---|
| NTP (chrony/ntpd) | UDP 123 | Outbound | 외부 NTP 서버와 동기화 (필수) |
| NTP 서버로 동작 | UDP 123 | Inbound | 내부 클라이언트에게 시간 제공 |
| chronyc 원격 관리 | UDP 323 | Inbound (선택) | chronyc로 원격에서 chrony 관리 |
| NTS-KE (키 교환) | TCP 4460 | Outbound (선택) | Network Time Security — 인증된 NTP |
실무 포인트: 대부분의 서버는 UDP 123 Outbound 만 열면 됩니다. NTS는 최신 보안 기능이며 아직 범용 사용은 드뭅니다.
# 방화벽에서 NTP 허용 확인 (클라이언트)
sudo firewall-cmd --list-all | grep ntp
# 또는
sudo iptables -L OUTPUT -n | grep 123
# UDP 123 포트 테스트 (서버 도달 여부)
nc -uzv pool.ntp.org 123
# 결과: Connection to pool.ntp.org 123 port [udp/ntp] succeeded!
동기화 데몬 1개 원칙 — timesyncd vs chrony vs ntpd 충돌 방지
확대
한 서버에서 NTP 데몬은 반드시 1개만 실행해야 합니다. 두 데몬이 동시에 UDP 123 포트를 소유하려 해서 충돌하거나, 서로 다른 서버를 참조해 시계가 엇갈릴 수 있습니다.
3가지 데몬 비교:
| 데몬 | 패키지 | 기본 탑재 배포판 | 권장 여부 |
|---|---|---|---|
| systemd-timesyncd | systemd 내장 | Ubuntu 18.04+, Debian 12+ | 단순 클라이언트 용도로 적합 |
| chrony | chrony | RHEL 8+, Ubuntu 20.04+ | 권장 — VM/클라우드 환경에 최적화 |
| ntpd | ntp | 구형 배포판 | 신규 설치 비권장 (chrony로 대체) |
충돌 징후 진단:
# 동시에 실행 중인 NTP 관련 데몬 확인
systemctl is-active systemd-timesyncd chrony ntpd 2>/dev/null
# 충돌 로그 확인 (chrony가 시작 실패하는 경우)
journalctl -u chrony --since "10 min ago" | grep -E "error|fail|conflict"
# 흔한 메시지: "Could not open /dev/pps0" 또는 "Already running as NTP daemon"
# UDP 123 포트를 점유한 프로세스 확인
sudo ss -ulnp | grep 123
올바른 전환 절차 (timesyncd → chrony):
# Step 1: timesyncd 중지 및 비활성화 (충돌 방지)
sudo systemctl disable --now systemd-timesyncd
# Step 2: chrony 설치 및 시작
sudo apt install -y chrony # Ubuntu/Debian
sudo dnf install -y chrony # RHEL/CentOS
sudo systemctl enable --now chronyd
# Step 3: 데몬 1개만 실행 중인지 확인
systemctl is-active systemd-timesyncd # → inactive
systemctl is-active chronyd # → active
# Step 4: 동기화 확인
chronyc tracking | grep "System time"
클라우드 환경 주의: AWS EC2, GCP, Azure는 각자 내부 NTP 서버(169.254.169.123 등)를 제공합니다. 인스턴스 내 chrony 설정에서 이 주소를 우선 사용하면 외부 UDP 123 포트를 열지 않아도 됩니다.
4. chrony 설치 및 기본 설정
실습 전 디렉토리와 예제 파일을 먼저 준비합니다.
# 실습 디렉토리 준비
mkdir -p /tmp/linux/part5/exam_233 && cd /tmp/linux/part5/exam_23
# NTP 설정 샘플 파일
cat > chrony.conf.sample << 'EOF'
# /etc/chrony.conf 예제
# 공개 NTP 풀 서버 사용
pool 2.pool.ntp.org iburst maxsources 4
# 한국 NTP 서버 (KT, KRISS)
server time.bora.net iburst
server ntp.kornet.net iburst
# 로컬 시계 허용 오차 (초)
makestep 1.0 3
# 하드웨어 타임스탬프 사용 (지원하는 경우)
# hwtimestamp *
# 동기화 로그
logdir /var/log/chrony
log measurements statistics tracking
EOF
이제 실습을 진행합니다.
RHEL / CentOS / Rocky Linux / AlmaLinux:
# 설치 (RHEL 8/9는 기본 설치되어 있음)
sudo dnf install -y chrony
# 서비스 시작 및 부팅 자동 시작 등록
sudo systemctl enable --now chronyd
# 서비스 상태 확인
sudo systemctl status chronyd
Ubuntu / Debian:
# 설치
sudo apt update && sudo apt install -y chrony
# 서비스 활성화
sudo systemctl enable --now chrony
# Ubuntu에서는 서비스 이름이 'chrony' (d 없음)
sudo systemctl status chrony
기존 timesyncd 비활성화 (Ubuntu):
Ubuntu 18.04+는 systemd-timesyncd라는 가벼운 NTP 클라이언트가 기본으로 실행됩니다. chrony와 충돌하므로 비활성화합니다:
# systemd-timesyncd 중지 및 비활성화
sudo systemctl disable --now systemd-timesyncd
# 비활성화 확인
systemctl is-active systemd-timesyncd
# 출력: inactive
ntpd가 있다면 충돌 방지:
# ntpd가 실행 중인지 확인
systemctl is-active ntpd 2>/dev/null || echo "ntpd 없음"
# ntpd가 있다면 중지
sudo systemctl disable --now ntpd 2>/dev/null
- systemctl status chronyd 에서 'active (running)' 상태가 확인된다
- timedatectl status 에서 'NTP synchronized: yes' 항목이 표시된다
- chronyc tracking 에서 'System time' 오프셋이 수 밀리초 이내로 줄어들어 있다
- chronyc sources -v 에서 타임서버 목록이 나타나고 * 표시가 현재 동기화 중인 서버를 가리킨다
- 읽기 순서: timedatectl → 'NTP synchronized: yes' 확인 → chronyc sources 에서 * 마크 서버 확인 → chronyc tracking 으로 오프셋 정밀도 확인
- chronyc sources 에서 * 마크가 있어야 현재 동기화 중인 것 — ? 마크이면 해당 서버에 연결 불가, 모두 ? 이면 방화벽 UDP 123 차단 의심
- chronyc tracking 의 System time 오프셋 기준: 50ms 이하 정상 / 500ms 이상이면 주의 / 1s 이상이면 심각 — JWT 인증 오류나 TLS 핸드셰이크 실패가 발생할 수 있는 수준
- chronyc tracking 의 Stratum 값이 16이면 동기화 서버를 찾지 못한 상태 — chronyd 설정 또는 네트워크 연결을 확인한다
- 오프셋이 크면서 CPU도 정상이라면 VM 마이그레이션 후 makestep 미적용 가능성 — sudo chronyc makestep 으로 즉시 강제 보정
5. chrony.conf 타임서버 설정
chrony의 핵심 설정 파일은 /etc/chrony.conf입니다. 기본 설정을 확인하고 한국 환경에 맞게 수정합니다.
# 현재 설정 확인
sudo cat /etc/chrony.conf
기본 설정 파일 구조 (RHEL 계열):
# /etc/chrony.conf
# -- 타임서버 설정 --
# pool: 여러 서버를 자동으로 선택 (권장)
# iburst: 초기 동기화를 빠르게 (첫 연결 시 패킷을 연속 전송)
pool 2.rhel.pool.ntp.org iburst
# -- 한국/아시아 권장 타임서버 --
# pool.ntp.org: 지역 기반 서버 자동 선택
pool kr.pool.ntp.org iburst
# KT 한국 타임서버
server time.bora.net iburst
# Google 공개 NTP (IPv4/IPv6 지원, Stratum 1)
server time.google.com iburst
# AWS Time Sync Service (EC2 인스턴스에서 권장)
# 링크-로컬 주소, 외부 네트워크 불필요
server 169.254.169.123 prefer iburst
# Cloudflare NTP
server time.cloudflare.com iburst
# -- 드리프트 파일 --
# 시계 주파수 오차를 저장, 재시작 후 빠른 보정에 사용
driftfile /var/lib/chrony/drift
# -- 큰 시간 차이 자동 수정 --
# 오프셋이 1초 이상이면 즉시 수정 (최초 3회만)
makestep 1.0 3
# -- 하드웨어 클럭 동기화 --
rtcsync
# -- 로컬 네트워크에 NTP 서버로 제공 --
# (내부 NTP 서버로 운용할 때만 활성화)
# allow 192.168.0.0/16
# -- 로그 설정 --
logdir /var/log/chrony
AWS EC2 환경 전용 설정:
# EC2에서는 AWS Time Sync를 우선 사용
sudo tee /etc/chrony.conf > /dev/null <<'EOF'
# AWS Time Sync Service (링크-로컬, 항상 사용 가능)
server 169.254.169.123 prefer iburst
# 백업 서버
pool kr.pool.ntp.org iburst
server time.google.com iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
logdir /var/log/chrony
EOF
설정 변경 후 chrony 재시작:
sudo systemctl restart chronyd
# 문법 오류 확인 (재시작 실패 시)
sudo chronyd -Q 'server time.bora.net iburst'
6. 동기화 상태 확인
chronyc는 chronyd와 통신하는 명령줄 도구입니다. 동기화 상태를 확인하는 두 가지 핵심 명령을 살펴봅니다.
chronyc sources — 타임서버 목록 및 상태:
chronyc sources -v
.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = synced, '+' = combined, '-' = not combined,
| / '?' = unreachable, 'x' = time may be in error, '~' = time too variable.
|| .- xxxx [ yyyy ] +/- zzzz
|| Reachability register (octal) -. | xxxx = adjusted offset,
|| Log2(Polling interval) --. | | yyyy = measured offset,
|| \ | | zzzz = estimated error.
|| | | \
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 169.254.169.123 3 6 377 42 +15us[ +8us] +/- 473us
^+ time.bora.net 2 7 377 107 -2ms[ -2ms] +/- 12ms
^+ time.google.com 1 8 255 43 +1ms[ +1ms] +/- 15ms
^- kr.pool.ntp.org 2 9 177 212 -5ms[ -5ms] +/- 25ms
상태 기호 해석:
| 기호 | 의미 |
|---|---|
* | 현재 동기화 중인 서버 (최적 서버) |
+ | 보조로 함께 사용 중인 서버 |
- | 선택되지 않은 서버 |
? | 연결 불가 서버 |
x | 시간 오류 가능성 있는 서버 |
Reach 컬럼: 최근 8번의 폴링 성공 여부를 8진수로 표현합니다. 377은 8번 모두 성공, 0은 연결 안 됨.
chronyc tracking — 전체 동기화 상태:
chronyc tracking
Reference ID : A9FEA97B (169.254.169.123)
Stratum : 4
Ref time (UTC) : Thu Mar 26 01:23:45 2026
System time : 0.000015372 seconds fast of NTP time
Last offset : +0.000015372 seconds
RMS offset : 0.000018521 seconds
Frequency : 2.345 ppm fast
Residual freq : +0.012 ppm
Skew : 0.234 ppm
Root delay : 0.000946234 seconds
Root dispersion : 0.001234567 seconds
Update interval : 64.2 seconds
Leap status : Normal
핵심 항목 해석:
| 항목 | 의미 | 정상 범위 |
|---|---|---|
Reference ID | 현재 동기화 서버 | - |
Stratum | 현재 계층 번호 | 1~4 |
System time | NTP 기준 대비 로컬 오프셋 | 수 ms 이내 |
Frequency | 시계 주파수 오차 (ppm) | ±100 ppm 이내 |
Leap status | 윤초 상태 | Normal |
chronyc makestep — 즉시 시간 강제 보정:
# 큰 오프셋이 있을 때 즉시 시계를 맞춤 (서비스 재시작 없이)
sudo chronyc makestep
# 확인
chronyc tracking | grep "System time"
기타 유용한 chronyc 명령:
# 현재 NTP 소스 간단 요약
chronyc sourcestats
# chrony 서버 활동 통계
chronyc activity
# 특정 서버 정보 상세 확인
chronyc ntpdata 169.254.169.123
7. timedatectl로 시간대 및 NTP 관리
timedatectl의 대안: 로우레벨 시스템 타임존 수동 강제 매핑
timedatectl 도구가 유실되었거나 레거시 컨테이너 환경에서는 아래와 같이 타임존 zoneinfo 정보를 시스템 로컬타임 경로에 심볼릭 링크로 맵핑해야 합니다.
# 1. 기존 localtime 매핑 링크 제거
$ sudo rm -f /etc/localtime
# 2. zoneinfo DB에서 원하는 타임존(Asia/Seoul)을 /etc/localtime으로 심볼릭 링크 생성
$ sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
이러면 timedatectl 없이도 시스템 전체 트랜잭션 타임이 한국 표준시(KST)로 수동 강제 고정됩니다.
timedatectl은 systemd가 제공하는 시간 관리 통합 도구입니다. 시간대 변경, NTP 활성화/비활성화, 현재 상태 확인을 한 도구에서 처리합니다.
현재 시간 설정 상태 확인:
timedatectl
Local time: Thu 2026-03-26 10:23:45 KST
Universal time: Thu 2026-03-26 01:23:45 UTC
RTC time: Thu 2026-03-26 01:23:45
Time zone: Asia/Seoul (KST, +0900)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
항목 설명:
| 항목 | 의미 |
|---|---|
Local time | 현재 시간대 기준 로컬 시각 |
Universal time | UTC 기준 시각 |
RTC time | 하드웨어(BIOS) 시계 |
Time zone | 현재 시간대 |
System clock synchronized | NTP 동기화 완료 여부 |
NTP service | NTP 클라이언트 동작 여부 |
RTC in local TZ | HW 시계가 로컬 시간대 사용 여부 (no = UTC 권장) |
Asia/Seoul 시간대 설정:
# 사용 가능한 시간대 목록 검색
timedatectl list-timezones | grep -i seoul
# 출력: Asia/Seoul
timedatectl list-timezones | grep -i asia | head -20
# 시간대 설정
sudo timedatectl set-timezone Asia/Seoul
# 확인
timedatectl | grep "Time zone"
# 출력: Time zone: Asia/Seoul (KST, +0900)
다른 시간대 예시:
# UTC (국제 표준)
sudo timedatectl set-timezone UTC
# 미국 동부
sudo timedatectl set-timezone America/New_York
# 일본 (한국과 같은 UTC+9, 하지만 JST)
sudo timedatectl set-timezone Asia/Tokyo
NTP 동기화 활성화/비활성화:
# NTP 동기화 활성화
sudo timedatectl set-ntp true
# NTP 동기화 비활성화 (수동 시간 설정 시 필요)
sudo timedatectl set-ntp false
# 상태 확인
timedatectl show | grep NTP
수동으로 시간 설정 (NTP 비활성화 상태에서만):
# NTP 먼저 비활성화
sudo timedatectl set-ntp false
# 날짜+시간 설정
sudo timedatectl set-time "2026-03-26 10:30:00"
# 날짜만 설정
sudo timedatectl set-time "2026-03-26"
# NTP 다시 활성화
sudo timedatectl set-ntp true
8. date 명령어와 hwclock
date와 hwclock은 NTP 없이도 시간을 확인하고 조정할 수 있는 전통적인 도구입니다.
date 명령어 — 현재 시간 확인:
# 현재 시간 (기본: 로컬 시간대)
date
# 출력: Thu Mar 26 10:23:45 KST 2026
# UTC로 출력
date -u
# 출력: Thu Mar 26 01:23:45 UTC 2026
# 포맷 지정 출력
date "+%Y-%m-%d %H:%M:%S"
# 출력: 2026-03-26 10:23:45
# Unix timestamp 출력
date +%s
# 출력: 1774687425
# Unix timestamp를 날짜로 변환
date -d @1774687425
date 명령어 — 시간 수동 설정 (NTP 비활성화 상태에서):
# 날짜와 시간 설정 (MMDDHHmmYYYY.ss 형식)
sudo date 032610302026.00
# 2026년 3월 26일 10시 30분 00초
# 또는 문자열 형식 (GNU date)
sudo date -s "2026-03-26 10:30:00"
sudo date -s "Thu Mar 26 10:30:00 KST 2026"
hwclock — 하드웨어(RTC) 시계 관리:
하드웨어 시계(RTC, Real-Time Clock)는 서버 전원이 꺼져도 배터리로 계속 작동하는 BIOS 내장 시계입니다. 시스템 시계(커널이 관리)와 별개로 존재합니다.
# 하드웨어 시계 현재 값 읽기
sudo hwclock --show
# 출력: 2026-03-26 01:23:45.234567+00:00
# 시스템 시계 → 하드웨어 시계 동기화 (-w: write to hw)
sudo hwclock --systohc
# 하드웨어 시계 → 시스템 시계 동기화 (-s: set system)
sudo hwclock --hctosys
# 하드웨어 시계를 UTC 기준으로 설정 (서버 권장)
sudo hwclock --systohc --utc
# 하드웨어 시계를 로컬 시간 기준으로 설정 (비권장)
sudo hwclock --systohc --localtime
서버 권장 구성: HW 시계를 UTC로 유지
# /etc/adjtime 파일로 HW 시계 모드 확인
cat /etc/adjtime
# 마지막 줄이 UTC → 하드웨어 시계가 UTC 사용 중
# 마지막 줄이 LOCAL → 로컬 시간 사용 중 (Windows 듀얼부팅 환경)
부팅 시 시간 복원 순서:
1. BIOS/UEFI: HW 시계(RTC) 읽기
2. 커널: HW 시계 → 시스템 시계 설정
3. systemd: chronyd 시작
4. chronyd: NTP 서버와 동기화 → 시스템 시계 보정
5. chronyd: rtcsync 설정 시 HW 시계도 갱신
# chrony의 rtcsync 옵션으로 HW 시계 자동 갱신 확인
grep rtcsync /etc/chrony.conf
# 출력: rtcsync
9. 실무 활용: JobContext
신규 서버 투입 체크리스트
새 서버를 프로덕션에 투입하기 전 시간 설정 확인은 기본 점검 항목입니다:
#!/bin/bash
# 신규 서버 시간 동기화 점검 스크립트
echo "=== 시간대 확인 ==="
timedatectl | grep "Time zone"
echo "=== NTP 서비스 상태 ==="
timedatectl | grep "NTP service"
echo "=== 동기화 상태 ==="
timedatectl | grep "synchronized"
echo "=== chrony 소스 ==="
chronyc sources 2>/dev/null || echo "chrony 미설치"
echo "=== 시스템 오프셋 ==="
chronyc tracking 2>/dev/null | grep "System time"
AWS EC2 AMI 빌드 시 chrony 설정 포함
EC2 인스턴스를 AMI로 만들 때 AWS Time Sync Service(169.254.169.123)를 최우선 타임서버로 설정하는 것이 AWS 공식 권장사항입니다. 이 링크-로컬 주소는 인터넷 접속 없이도 항상 사용 가능합니다.
Ansible로 다수 서버 시간 설정 배포:
# time-sync.yml
---
- name: NTP 시간 동기화 설정
hosts: all
become: true
tasks:
- name: chrony 설치
package:
name: chrony
state: present
- name: chrony.conf 배포
template:
src: chrony.conf.j2
dest: /etc/chrony.conf
backup: yes
notify: restart chronyd
- name: 시간대 설정
community.general.timezone:
name: Asia/Seoul
- name: chronyd 활성화
service:
name: chronyd
state: started
enabled: true
handlers:
- name: restart chronyd
service:
name: chronyd
state: restarted
Kubernetes Pod 시간 동기화
컨테이너(Pod)는 호스트 노드의 시스템 시계를 공유합니다. 별도의 NTP 클라이언트 불필요. 따라서 Kubernetes 노드의 chrony 설정이 중요합니다. 노드 시계가 틀리면 모든 Pod의 시각이 틀립니다.
# 노드 시간 확인 (kubectl exec으로 파드 내부)
kubectl exec -it <pod-name> -- date
# 노드와 동일한 시각이 출력되어야 함
모니터링: Prometheus + Alertmanager로 시간 드리프트 경보
# Prometheus 알람 규칙 예시
groups:
- name: time-sync
rules:
- alert: NTPNotSynchronized
expr: node_timex_sync_status != 1
for: 5m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} NTP 동기화 실패"
- alert: ClockOffsetTooLarge
expr: abs(node_timex_offset_seconds) > 0.1
for: 2m
labels:
severity: critical
annotations:
summary: "시계 오프셋 100ms 초과: {{ $value }}s"
10. 트러블슈팅
증상:
chronyc sources
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^? time.bora.net 0 8 0 - +0ns[ +0ns] +/- 0ns
^? time.google.com 0 8 0 - +0ns[ +0ns] +/- 0ns
^? 169.254.169.123 0 8 0 - +0ns[ +0ns] +/- 0ns
모든 서버에 ? 표시, Reach가 0 — 연결이 전혀 안 됨.
원인 진단:
# NTP 서버에 UDP 123 포트 연결 테스트
# ntpdate로 단발성 쿼리 (진단 목적)
sudo ntpdate -q time.google.com 2>&1 | head -5
# tcpdump로 NTP 패킷 확인
sudo tcpdump -i any port 123 -n
# firewalld 규칙 확인 (RHEL 계열)
sudo firewall-cmd --list-all
# iptables 규칙 확인
sudo iptables -L OUTPUT -n | grep 123
sudo iptables -L INPUT -n | grep 123
# nmap으로 외부에서 포트 확인 (다른 서버에서 실행)
nmap -sU -p 123 <서버IP>
해결 방법:
# firewalld에서 NTP 허용 (RHEL/CentOS/Rocky)
sudo firewall-cmd --permanent --add-service=ntp
sudo firewall-cmd --reload
# 또는 포트 번호로 직접 허용
sudo firewall-cmd --permanent --add-port=123/udp
sudo firewall-cmd --reload
# ufw에서 허용 (Ubuntu)
sudo ufw allow 123/udp
sudo ufw reload
# iptables 직접 규칙 추가
sudo iptables -A OUTPUT -p udp --dport 123 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 123 -j ACCEPT
# 규칙 저장
sudo service iptables save # RHEL
sudo iptables-save > /etc/iptables/rules.v4 # Debian/Ubuntu
# AWS EC2: Security Group에서 Outbound UDP 123 허용 확인
# AWS Management Console → EC2 → Security Groups → Outbound Rules
# 또는 AWS CLI:
aws ec2 describe-security-groups --group-ids sg-xxxxxxxx \
--query 'SecurityGroups[].IpPermissionsEgress'
방화벽 해결 후 chrony 재시작:
sudo systemctl restart chronyd
sleep 10
chronyc sources
# Reach 값이 점점 올라가야 함: 1, 3, 7, 17, 37, 77, 177, 377
증상:
서버를 재시작하거나 VM 마이그레이션 후 시계가 수 분씩 틀어집니다. chronyc tracking에서 오프셋이 수 초 이상으로 나타납니다.
chronyc tracking | grep "System time"
# System time : 45.234567890 seconds slow of NTP time
# ← 45초나 느림!
원인 분석:
VM 환경에서 시간 드리프트가 발생하는 원인:
- CPU Steal Time: 하이퍼바이저가 CPU를 다른 VM과 공유하면서 VM의 타이머 인터럽트가 지연됨
- VM 일시 정지: 스냅샷, 라이브 마이그레이션, 절전 모드 후 복구 시 시계가 멈췄다 재개됨
- 시계 소스 불안정: VM 내부의 가상 시계(TSC)가 불안정
해결 방법:
# 1. chrony.conf에 makestep 설정 확인 및 조정
sudo grep makestep /etc/chrony.conf
# makestep 1.0 3 ← 1초 이상 오프셋이면 즉시 수정 (최초 3회)
# 큰 드리프트 허용을 위해 수정 (VM 환경 권장)
sudo sed -i 's/^makestep.*/makestep 1.0 -1/' /etc/chrony.conf
# -1: 횟수 제한 없이 항상 즉시 수정
# 2. 지금 당장 시계 강제 보정
sudo chronyc makestep
chronyc tracking | grep "System time"
# 3. VM 환경에서 빠른 폴링 설정 (chrony.conf 추가)
# maxpoll 6 → 최대 64초마다 폴링 (기본값보다 자주)
echo "maxpoll 6" | sudo tee -a /etc/chrony.conf
sudo systemctl restart chronyd
# 4. KVM/QEMU 게스트: 호스트 시계 사용 (가장 안정적)
# /etc/chrony.conf에 refclock 추가
echo "refclock PHC /dev/ptp0 poll 3 dpoll -2 offset 0" | sudo tee -a /etc/chrony.conf
sudo systemctl restart chronyd
# 5. 시스템 클럭 소스 확인
cat /sys/devices/system/clocksource/clocksource0/current_clocksource
# kvm-clock → KVM 최적화 시계 (좋음)
# tsc → TSC (VM에서 불안정 가능)
# hpet → HPET (느리지만 안정)
# TSC를 사용 중이라면 kvm-clock으로 변경 (KVM 환경)
echo kvm-clock | sudo tee /sys/devices/system/clocksource/clocksource0/current_clocksource
Docker/컨테이너 환경 주의사항:
# 컨테이너는 호스트 커널 공유 → 컨테이너 내부에서 NTP 실행 불필요/불가
# 호스트 노드의 시계를 동기화해야 함
# 컨테이너 내부에서 시간 확인
docker exec my-container date
# 호스트와 동일해야 함
# 다르다면 호스트 chrony 상태 확인
chronyc tracking
증상:
Linux 서버를 Active Directory 도메인에 조인할 때 다음 오류 발생:
realm join example.com
# 오류:
# adcli: joining domain failed: kinit: Clock skew too great
# KRB5KRB_AP_ERR_SKEW: Clock skew too great while getting initial credentials
또는 이미 조인된 서버에서 SSH 로그인, sudo, samba 인증이 실패:
pam_krb5: TGT expired
kinit: Clock skew too great while renewing credentials
원인:
Kerberos 프로토콜 사양(RFC 4120)에 따라 클라이언트와 KDC(도메인 컨트롤러) 간 시계 차이가 5분(300초)을 초과하면 보안상 모든 인증을 거부합니다. 이는 재전송 공격(Replay Attack) 방지를 위한 필수 보안 설계입니다.
진단 절차:
# 1. 현재 서버 시각과 도메인 컨트롤러 시각 비교
date -u
# 현재 서버 UTC 시각
# 도메인 컨트롤러에 NTP 쿼리 (DC 주소로 변경)
ntpdate -q dc01.example.com 2>&1
# 출력에서 offset 값 확인
# offset 320.456789 sec ← 5분 20초 차이, Kerberos 거부
# 또는 chronyc로 DC를 임시 타임서버로 테스트
chronyc -a 'server dc01.example.com iburst'
chronyc sources | grep dc01
# 2. 현재 오프셋 확인
chronyc tracking | grep "System time"
# 3. DC와 직접 시간 비교
ssh dc01.example.com "date -u" # Windows DC라면 원격 PowerShell 사용
# 또는 smbclient로 DC 시각 확인
smbclient -N -L dc01.example.com 2>/dev/null | grep -i time
해결 방법:
# 방법 1: DC를 NTP 서버로 설정 (도메인 환경 표준)
sudo tee /etc/chrony.conf > /dev/null <<EOF
# 도메인 컨트롤러를 타임서버로 사용 (Kerberos 동기화 보장)
server dc01.example.com iburst prefer
server dc02.example.com iburst
# 백업: 공개 NTP
pool kr.pool.ntp.org iburst
driftfile /var/lib/chrony/drift
makestep 1.0 -1
rtcsync
EOF
sudo systemctl restart chronyd
# 방법 2: 즉시 강제 동기화 (큰 오프셋 수정)
sudo chronyc makestep
# 방법 3: ntpdate로 즉시 수동 동기화 (긴급 시)
sudo ntpdate dc01.example.com
# 동기화 후 도메인 조인 재시도
chronyc tracking | grep "System time"
# System time: 0.002345678 seconds fast of NTP time ← OK
sudo realm join example.com -U Administrator
Windows DC의 NTP 설정 확인:
도메인 환경에서 시간 권위 체계: DC(PDC Emulator) → 외부 NTP → 도메인 멤버
# Windows DC에서 NTP 소스 확인
w32tm /query /source
w32tm /query /status
# PDC Emulator를 외부 NTP와 동기화 (Windows PowerShell)
w32tm /config /manualpeerlist:"time.google.com,0x8 time.bora.net,0x8" /syncfromflags:manual /reliable:yes /update
net stop w32tm && net start w32tm
w32tm /resync /force
예방: 도메인 환경 NTP 정책
- PDC Emulator: 외부 Stratum 1/2 서버와 동기화
- 다른 DC들: PDC Emulator와 동기화
- 도메인 멤버 서버: DC와 동기화 (
w32tm /resync또는 chrony) - 비도메인 Linux: 공개 NTP pool 사용
심화 — chrony는 어떻게 '거짓말하는 시계'를 걸러내나
심화: 소스 선택과 falseticker — 왜 NTP 서버는 최소 3~4개여야 하나
stratum이 '기준 시계에서 얼마나 먼가'를 말한다면, 이제 그 위층 질문이 남습니다 — 여러 시계가 서로 다른 시각을 주장하면 chrony는 무엇을 믿을까요? chrony가 소스를 하나만 믿지 않는 데는 이유가 있고, 이 원리를 알아야 '동기화됐다는데 왜 틀리지'를 설명할 수 있습니다.
- chrony는 다수결로 진실한 시계를 고릅니다: 각 NTP 소스는 시각을 '점'이 아니라 왕복 지연을 고려한 '구간'으로 제시합니다. chrony는 이 구간들이 겹치는 다수 그룹을 찾아 **truechimer(참된 시계)**로 보고, 겹치지 않고 튀는 소스는 **falseticker(거짓 시계)**로 판단해 배제합니다.
- 그래서 소스 개수가 내구성을 정합니다: 소스가 2개면 둘이 갈릴 때 누가 옳은지 판정할 수 없습니다. 하나의 잘못된 소스를 '투표로' 걸러내려면 최소 3~4개가 필요합니다(비잔틴 내성과 같은 논리). NTP 풀을 쓰면 자동으로 여러 서버가 잡혀 이 조건을 만족합니다.
chronyc sources의 상태 문자가 판정 결과입니다: 맨 앞 기호가 곧 chrony의 결정입니다 —*는 현재 동기화 기준으로 선택된 소스,+는 조합에 함께 쓰이는 후보,-는 truechimer지만 조합에서 제외됨,x는 falseticker로 배제됨,?는 응답 없음·도달 불가입니다.- 단일 소스는 조용히 위험합니다: 소스가 하나뿐이면 그 소스가 틀려도 chrony는 비교 대상이 없어 그대로 따라갑니다. 'NTP synchronized: yes'는 '내가 참조하는 것과 맞다'일 뿐 '실제 시각이 맞다'의 보증이 아닙니다.
핵심은 NTP의 정확성이 한 서버의 정확성이 아니라 여러 서버의 교차 검증에서 나온다는 것입니다. chronyc sources의 기호와 chronyc sourcestats의 오차·지터를 함께 읽어야 '지금 무엇을, 왜 믿고 있는지'가 보입니다.
상황: 로그 타임스탬프가 실제와 미묘하게 어긋나고, JWT·인증서 검증이 간헐적으로 실패합니다. 그런데 각 서버에서 timedatectl은 'NTP synchronized: yes'라 문제가 없어 보입니다. 여러 대가 '똑같이' 틀어져 있는 것이 단서입니다.
원인: 내부 표준화를 이유로 모든 서버를 사내 NTP 서버 한 대만 참조하도록 설정해 뒀는데, 그 상위 서버가 조용히 틀어졌습니다(상위 참조 실패 후 로컬 시계로 표류). 클라이언트들은 비교할 다른 소스가 없어 falseticker 판정을 할 수 없었고, 그래서 '틀린 기준'에 충실히 동기화된 채 다 함께 틀어졌습니다. 'synchronized: yes'는 그 한 소스와 맞다는 뜻이었을 뿐입니다.
진단: 얼마나 틀렸는지가 아니라 '무엇을 믿고 있는지'를 봅니다.
chronyc sources -v
# 상태 문자와 소스 개수 확인
# ^* internal-ntp 3 ... ← 참조 소스가 이것 하나뿐이면 교차검증 불가
# (falseticker를 걸러낼 다른 소스가 없음)
chronyc tracking | grep -E 'Reference|Stratum|System time'
# Reference ID가 그 사내 서버 하나로 고정, Stratum이 비정상적으로 높지 않은지
# 상위 서버 자체를 외부 기준과 비교
chronyc -a 'server time.google.com iburst'
chronyc sources
소스가 하나뿐이고, 그 소스를 외부 기준과 대보니 offset이 크면 확정입니다.
해결: 클라이언트가 최소 3~4개 소스(사내 서버 + 공개 풀 백업)를 참조하도록 바꿔, 한 소스가 틀어져도 falseticker로 걸러지게 합니다. 사내 NTP 서버 자체는 신뢰할 수 있는 상위(외부 stratum 1~2 또는 GPS)와 여러 개로 동기화하고, 그 서버의 상위 참조 상태를 모니터링합니다. 즉 '표준화'를 단일 소스로 오해하지 말고, 표준 서버를 이중화하고 클라이언트에 백업 풀을 남겨 교차 검증이 항상 성립하게 만드는 것이 핵심입니다.
11. 빠른 참조
필수 명령어 요약
# 현재 시간 상태 전체 확인
timedatectl
# 동기화 서버 목록 확인
chronyc sources -v
# 동기화 상세 상태 확인
chronyc tracking
# 시간대 변경 (한국)
sudo timedatectl set-timezone Asia/Seoul
# NTP 활성화
sudo timedatectl set-ntp true
# 즉시 시계 강제 보정
sudo chronyc makestep
# chrony 서비스 재시작
sudo systemctl restart chronyd
# HW 시계 → 시스템 시계 동기화
sudo hwclock --hctosys
# 시스템 시계 → HW 시계 저장
sudo hwclock --systohc
# 현재 시각 확인 (UTC)
date -u
# chrony 로그 확인
sudo journalctl -u chronyd -f
시간대(Timezone) 자주 쓰는 목록
timedatectl list-timezones | grep -E "Seoul|Tokyo|Shanghai|Singapore|UTC|London|New_York"
# Asia/Seoul → KST (UTC+9)
# Asia/Tokyo → JST (UTC+9)
# Asia/Shanghai → CST (UTC+8)
# Asia/Singapore → SGT (UTC+8)
# UTC → UTC (UTC+0)
# Europe/London → GMT/BST
# America/New_York → EST/EDT (UTC-5/-4)
chrony.conf 타임서버 빠른 선택 가이드
# 한국 서버 (권장)
server time.bora.net iburst # KT (Stratum 1)
pool kr.pool.ntp.org iburst # 한국 NTP 풀
# 글로벌 서버
server time.google.com iburst # Google (Stratum 1)
server time.cloudflare.com iburst # Cloudflare (Stratum 1)
# AWS EC2 전용
server 169.254.169.123 prefer iburst # AWS Time Sync (링크-로컬)
# GCP 전용
server metadata.google.internal iburst # GCP 메타데이터 서버
# Azure 전용
server time.windows.com iburst # Microsoft Azure
동기화 확인 자동화 스크립트
#!/bin/bash
# /usr/local/bin/check-ntp-sync.sh
OFFSET=$(chronyc tracking 2>/dev/null | grep "System time" | awk '{print $4}')
THRESHOLD=1.0 # 1초 이상이면 경고
if [ -z "$OFFSET" ]; then
echo "ERROR: chrony not running"
exit 2
fi
# Python으로 부동소수점 비교
OVER=$(python3 -c "print(1 if abs(float('$OFFSET')) > $THRESHOLD else 0)" 2>/dev/null)
if [ "$OVER" = "1" ]; then
echo "WARNING: NTP offset ${OFFSET}s exceeds ${THRESHOLD}s threshold"
exit 1
else
echo "OK: NTP offset ${OFFSET}s"
exit 0
fi
chmod +x /usr/local/bin/check-ntp-sync.sh
# cron으로 5분마다 실행
echo "*/5 * * * * root /usr/local/bin/check-ntp-sync.sh >> /var/log/ntp-check.log 2>&1" \
| sudo tee /etc/cron.d/ntp-check
정리
서버 시간 동기화는 인증, 보안, 로깅, 분산 시스템 모두에 영향을 미치는 인프라 기초입니다.
| 작업 | 명령어 |
|---|---|
| 현재 상태 확인 | timedatectl |
| 한국 시간대 설정 | timedatectl set-timezone Asia/Seoul |
| NTP 활성화 | timedatectl set-ntp true |
| 동기화 서버 확인 | chronyc sources -v |
| 오프셋 확인 | chronyc tracking |
| 즉시 시계 보정 | chronyc makestep |
| 설정 파일 | /etc/chrony.conf |
명령어·단축키 빠른 참조
이 모듈에서 다룬 시간 동기화 명령을 실전 옵션과 함께 모았습니다. 상태 확인 → 소스 점검 → 보정 순서로 쓰면 됩니다.
| 명령어/단축키 | 용도 | 자주 쓰는 예 |
|---|---|---|
timedatectl | 시간·시간대·NTP 동기화 상태 한눈에 | timedatectl → System clock synchronized: yes 확인 |
timedatectl set-timezone | 시스템 시간대 영구 변경 | sudo timedatectl set-timezone Asia/Seoul |
timedatectl set-ntp | NTP 자동 동기화 켜기/끄기 | sudo timedatectl set-ntp true (수동 설정은 false) |
chronyc sources -v | 타임서버 목록·선택 상태 확인 | chronyc sources -v → ^* 마크가 현재 동기화 소스 |
chronyc tracking | NTP 기준 대비 현재 오차(offset) 확인 | chronyc tracking | grep "System time" |
chronyc makestep | 큰 오차를 즉시 강제 보정 | sudo chronyc makestep (VM 마이그레이션 후) |
systemctl restart chronyd | chrony 데몬 재시작 | sudo systemctl restart chronyd (설정 변경 후) |
systemctl disable --now systemd-timesyncd | 충돌 데몬 정지(데몬 1개 원칙) | sudo systemctl disable --now systemd-timesyncd |
hwclock | 하드웨어(RTC) 시계 읽기·저장 | sudo hwclock --systohc (시스템→HW 저장) |
date | 현재 시각 확인·포맷 출력 | date -u (UTC) / date +%s (Unix 타임스탬프) |
nc -uzv <서버> 123 | UDP 123 포트 도달 여부 테스트 | nc -uzv pool.ntp.org 123 |
journalctl -u chronyd | chrony 로그 실시간 추적 | sudo journalctl -u chronyd -f |
관련 모듈로 더 깊이:
- 리눅스 부팅 시 데몬 프로세스 자동 실행 및 관리 가이드 — chronyd를 서비스로 등록·관리하고 부팅 시 자동 동기화시키는 법
- CIS 벤치마크 기반의 리눅스 OS Hardening 및 취약점 방어 — 시간 오차가 인증 토큰·로그 무결성에 미치는 보안 영향
다음 모듈에서는 OS 하드닝을 통해 SSH 설정, 계정 보안, fail2ban으로 브루트포스를 차단하는 리눅스 보안 체크리스트를 다룹니다.