DevOps 및 감사 2026년 4월 17일

2026 결정표: Mac mini M4 CI Runner의 타임존, 로케일, 시계 동기화 플레이크

NodeMac Team

인프라 아키텍트

셀프호스티드 Mac mini M4 Runner는 빠르지만 여전히 「특정 리전에 있는 컴퓨터」입니다. 기본 타임존, 12/24시간제, 주 시작 요일, 정렬 규칙은 노트북과 다릅니다. CI에서 이 차원을 선언하지 않으면 자정, DST 전환, 홍콩 호스트에서 미국 호스트로 옮긴 순간 테스트가 뒤집힙니다. 이 글은 두 개의 의사결정 매트릭스, 8단계 롤아웃, Runbook에 붙일 수 있는 수치 가드레일로 XCTest·스냅샷·서버 날짜 연산을 Runner와 맞춥니다.

플레이크 격리 및 재시도, Xcode 고정 및 업그레이드 드리프트, 디스패치 가능한 Mac mini M4 노드와 함께 다리전 행렬을 설계하세요. 대화형 디버깅은 VNC를 사용합니다. 요금은 가격, 운영 기본값은 도움말을 참고하세요.

타임존과 로케일이 「하드웨어 플레이크」처럼 보이는 이유

Apple Silicon은 달력의 비결정성을 없애지 않습니다. 청구 창 가장자리에서 Date()를 호출하는 테스트는 Runner 벽시계가 경계를 넘기 전까지 녹색입니다. 로케일은 NumberFormatter의 그룹 구분자를 바꾸어 녹화 시와 다른 LANG에서 스냅샷을 깨뜨립니다. POSIX 순서를 가정한 파일 목록 정렬도 CI가 언어별 콜레이션을 물려받으면 조용히 실패합니다.

  • 자정 경계:23:55에 시작해 00:05에 끝나는 야간 작업은 시계를 고정하지 않은 채 「오늘」을 쓰면 날짜를 이중 집계하거나 건너뛸 수 있습니다.
  • DST 점프:앞으로 돌리는 날의 23:30 작업은 실제 분 수가 기대보다 적고, cron과 「3600초 sleep」 가정이 깨집니다.
  • 인증서 창:TLS와 코드 서명은 notBefore/notAfter를 벽시계와 비교합니다. 스큐는 간헐적 장애가 됩니다.
  • 다중 리전 풀:동일 커밋이라도 싱가포르와 캘리포니아에서 「현지 금요일」이 다릅니다. 참조 시각을 중앙화하지 않으면 글로벌 릴리스 열차가 충돌합니다.

매트릭스 A: 노드 리전과 권장 CI 환경 계약

NodeMac은 홍콩·일본·한국·싱가포르·미국에서 베어메탈 Mac mini M4를 운영합니다. 아래 표는 OS 기본값의 법적 보장은 아니지만 무인 Runner의 현실적인 출발점입니다. 오케스트레이터에 계약을 인코딩하여 「SG에서 녹색」을 「어디서나 녹색」으로 오독하지 마세요.

대표 Runner 리전 기본 벽시계 리스크 권장 CI 기준선 추가 행렬 작업
홍콩·싱가포르 아시아 달력 경계. 공휴일은 미국과 다름 컴파일은 TZ=UTCLC_ALL=C.UTF-8 주간으로 TZ=Asia/Hong_Kong에서 영수증 검증
일본·한국 로케일 팩 완비. UI 주 번호 표기 차이 CLI 로그는 LANG=C.UTF-8로 고정 한국어·일본 UI 출하 시 스냅샷 단계에 ja_JP.UTF-8 또는 ko_KR.UTF-8
미국 12시간 기본값. 주별 DST 규칙 차이 테스트에서 24시간 표기 강제. 로케일 없이 「오후 3시」 파싱 금지 DST 주에 XCTest로 합성 시각 두 개
크로스 리전 동일 커밋도 「현지 오늘」 불일치 업무일을 UTC에 집중. UI 경계에서만 변환 timezone-matrix 라벨이 빨강이면 릴리스 차단

매트릭스 B: 증상·프로브·수정 패턴

증상 빠른 프로브 수정 패턴
UTC 자정 근처에서만 실패 Runner TZ, 시스템 시계, 시작 시각 히스토그램 기록 의존성 주입으로 지금 고정. 경계 XCTest 추가
숫자 스냅샷이 호스트마다 다름 작업 시작 시 유효 LANG/LC_NUMERIC 출력 launchd plist 또는 CI 래퍼에서 LC_ALL=C.UTF-8
TLS나 공증이 무작위로 실패 sntp 오프셋을 기준 시계와 비교 NTP 규율 강제. 임계 초과 시 빠른 실패
파일 목록 정렬 불안정 pre-job 배너에서 locale 덤프 Swift에서 명시 POSIX 비교기 또는 sort에 LC_ALL=C

정책에 넣을 수 있는 수치 가드레일

  1. NTP 절대 오프셋:정상 상태에서 250 ms 미만 유지. Runner가 연속 세 번 2 s를 넘기면 온콜에 알림.
  2. 점검 동결:고객 대면 날짜 로직을 돌리는 리전에서는 DST 전후 72시간 동안 TZ 실험 중단.
  3. 타임아웃 여유:달력을 다루는 스위트는 벽시계로 15% 여유를 추가. 시뮬레이션 시간 점프는 XCTest를 비선형으로 늘립니다.

감사 팁:junit.xml 업로드마다 유효 TZ, LANG, 측정 NTP 오프셋을 함께 저장하세요. 무음 OS 패치 후 플레이크가 사라져도 설명할 수 있습니다.

8단계 롤아웃

  1. 목록화:실시계·로케일 인식 포매터·명시 비교기 없는 파일 정렬 테스트를 모두 나열합니다.
  2. preflight 배너:CI 로그에 타임존, 로케일, OS 빌드, Xcode 버전 출력——드리프트 감사와 같은 행.
  3. 기본값을 launchd EnvironmentVariables에 기록하여 GUI 없는 세션과 SSH가 동일 계약을 상속합니다.
  4. 작은 XCTest 헬퍼로 의존성 주입 시각 고정. 비즈니스 로직 테스트에서 순수 Date() 금지.
  5. 주간 행렬로 판매 타임존 최소 두 곳에서 상위 20개 날짜 테스트 재생.
  6. NTP 스파이크와 TLS 실패 상관 알림——대부분 패킷 캡처 재독보다 빠릅니다.
  7. 예외 문서화:POS 등 의도적 로컬 시각은 라벨 Runner에 격리.
  8. 스케일 아웃:대기열 깊이가 「거의 자정」 창을 공유하게 하면 리전별 전용 Mac mini M4를 추가합니다.

자주 묻는 질문

서버와 시뮬레이터가 같은 TZ 변수를 공유해야 하나요?

아니요. 서버 작업은 UTC 기본. UI 시뮬레이터는 로케일별 실행이 필요할 수 있습니다. 격리 없이 한 XCTest 프로세스에 섞으면 이중 실패의 전형입니다.

Apple Silicon이 NTP 동작을 바꾸나요?

본질적으로 아니요. 규율 데몬이 중요합니다. 바뀌는 것은 빌드 속도로, 짧은 작업은 스큐를 숨기고 30분 통합만 드러냅니다.

오늘 레거시 테스트를 고칠 수 없다면?

명시 라벨로 격리하고 일시적으로 단일 리전에 고정하며 플레이크 가이드에 따라 재작성 예산을 잡으세요. 지리적 중립인 척하지 마세요.

달력에 민감한 스위트에 결정적인 금속이 필요하고 노트북 절전이나 카페 Wi‑Fi와 싸우고 싶지 않다면, NodeMac의 Mac mini M4네이티브 macOS, SSH와 VNC, 베어메탈에서 읽기 쉬운 시계, 홍콩·일본·한국·싱가포르·미국 선택지를 제공합니다. Apple Silicon은 와트당 처리량이 높고, 전용 기기 임대는 과구독 공유 VM의 이웃 소음을 피합니다. 행렬이 다른 리전 호스트를 요구하면 YAML을 추측하기 전에 가격으로 리전을 매핑하세요.

실제 Mac mini M4에서 결정적 CI 실행

SSH 자동화로 리전 Runner 추가——HK·JP·KR·SG·US——선매입 없이.

NM
NodeMac Cloud Mac
5분 배포

전용 Apple Silicon Mac을 클라우드에서. SSH/VNC, HK·JP·KR·SG·US 노드.

시작하기