이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
- Config drift는 무엇이고 왜 같은 artifact를 환경마다 다르게 실패하게 만드는가?
- 재현 가능한 배포를 위해 어떤 설정 출처를 고정해야 하는가?
- 운영 장애 중 drift를 의심할 때 어떤 증거를 모아야 하는가?
개요
Config drift는 기대한 설정과 실제 적용된 설정이 시간이 지나며 달라지는 현상이다.
repository에는 timeout=3s라고 되어 있는데 운영 서버 환경 변수는 30s일 수 있다.
staging은 새 Redis endpoint를 보고 prod는 예전 endpoint를 볼 수 있다.
같은 artifact라도 config drift가 있으면 환경마다 다르게 동작하고, 장애 중 재현이 어려워진다.
Drift가 생기는 지점
설정은 여러 곳에 흩어질 수 있다.
- repository의
application.yml - profile별 설정 파일
- 서버의 environment variable
- systemd
EnvironmentFile - Docker Compose
.env - CI/CD variable
- Secret manager
- cloud console 설정
- 운영자가 임시로 넣은 command line argument
이 중 하나만 달라도 실제 동작은 달라질 수 있다.
문제는 “어디가 source of truth인가”가 불분명할 때 커진다.
예시
같은 image가 두 서버에서 다르게 동작하는 상황을 보자.
artifact: order-api:3f21a9c
server-a:
SPRING_PROFILES_ACTIVE=prod
PAYMENT_TIMEOUT=3s
server-b:
SPRING_PROFILES_ACTIVE=prod
PAYMENT_TIMEOUT=30sserver-b는 외부 결제 지연 때 thread를 오래 잡아 p99 latency를 악화시킬 수 있다.
artifact가 같기 때문에 코드 차이로는 원인을 찾을 수 없다.
실제 environment snapshot을 봐야 한다.
재현 가능한 배포
재현 가능한 배포는 같은 입력에서 같은 실행 상태를 만들 수 있어야 한다.
입력은 source code만이 아니다.
- artifact digest
- active profile
- environment variables
- Secret version
- config file version
- migration version
- JVM options
- port와 health check 설정
이 정보를 release 단위로 묶어야 한다.
그렇지 않으면 rollback 후에도 설정은 그대로 남아 장애가 계속될 수 있다.
설정 Inventory
서비스별로 중요한 설정 목록을 유지한다.
key: PAYMENT_TIMEOUT
type: config
default: 3s
prod: 3s
owner: payment-team
source: /etc/order-api/order-api.env
restart_required: true
failure_mode: 외부 결제 지연 시 request thread 점유 증가이런 inventory는 문서 장식이 아니라 drift를 찾는 기준이다.
설정마다 owner, source, 변경 절차, 재시작 필요 여부, 실패 양상이 있어야 운영 중 판단이 빨라진다.
Drift 확인 명령
서버에서 실제 환경 변수를 확인한다.
systemctl show order-api --property=Environment
cat /etc/order-api/order-api.env
printenv | grep -E 'SPRING|PAYMENT|DB_|REDIS'Docker Compose라면 실행 중인 container 환경도 확인한다.
docker inspect order-api --format '{{json .Config.Env}}'단, Secret 값은 출력과 공유에 주의한다.
값 전체가 아니라 key 존재 여부, version, source, hash 비교를 활용할 수 있다.
운영 체크리스트
- 설정 source of truth가 정해져 있는가?
- 서버 수동 변경이 기록 없이 남지 않는가?
- release note에 config version 또는 변경 목록이 있는가?
- Secret version과 config version을 구분하는가?
- 설정 변경 후 재시작 필요 여부가 문서화되어 있는가?
- 인스턴스별 environment 차이를 비교할 수 있는가?
- rollback 시 artifact와 config를 함께 되돌리는가?
장애 신호
- 같은 release인데 특정 인스턴스만 실패한다.
- staging에서 재현되지 않는 prod 장애가 반복된다.
- rollback 후에도 장애가 계속된다.
- 운영 콘솔 값과 repository 설정이 다르다.
- 일부 서버만 다른 외부 API endpoint를 호출한다.
- timeout, pool size, feature flag가 문서와 다르다.
안전한 완화 조치
drift가 의심되면 먼저 artifact와 config를 분리해 본다.
artifact가 같은지 확인하고, 그 다음 인스턴스별 active profile, environment, Secret version을 비교한다.
설정을 바로 맞추기 전에 어떤 값이 source of truth인지 결정한다.
장애 중에는 모든 인스턴스를 동시에 바꾸지 말고 한 인스턴스에서 값 변경과 health/smoke test를 확인할 수 있다.
Secret 값은 출력하지 않고 key, version, 적용 시각으로 대화한다.
인프라 담당자와 공유할 자료
서비스: order-api prod
증상: instance-2만 payment timeout 증가
artifact: 모든 인스턴스 동일 digest sha256:...
차이: instance-2 PAYMENT_TIMEOUT=30s, 나머지 3s
source 후보: /etc/order-api/order-api.env 수동 변경
요청: 인스턴스별 env file 변경 이력과 배포 도구 변수 확인drift 분석은 “코드가 같다”는 증거와 “설정이 다르다”는 증거를 함께 줘야 한다.
실전 팁
- 설정 변경도 코드 변경처럼 리뷰와 이력을 남긴다.
- 운영 콘솔 수동 변경은 임시 조치로 끝내고 source of truth에 반영한다.
- 환경별 차이는 표로 관리한다.
- drift 확인 명령은 Secret 값을 노출하지 않게 만든다.
- rollback 절차에는 config rollback을 별도로 넣는다.
위험 신호!
- 운영 서버에서 직접 환경 파일을 수정하고 기록하지 않는다.
- rollback을 artifact만 되돌리는 것으로 생각한다.
- 인스턴스별 설정 비교 방법이 없다.
- staging과 prod의 설정 차이를 아무도 설명하지 못한다.
- Secret version과 config value를 같은 방식으로 다룬다.
확인 질문
확인 질문
- Config drift가 장애를 어렵게 만드는 이유는 무엇인가?
- 같은 artifact라도 실제 설정이 다르면 환경별로 다른 동작을 하므로 코드와 로그만으로는 원인을 재현하기 어렵기 때문이다.
- 재현 가능한 배포의 입력에는 무엇이 포함되는가?
- source code뿐 아니라 artifact digest, profile, environment, Secret version, config file, JVM option, migration version이 포함된다.
- drift가 의심될 때 가장 먼저 나눌 것은 무엇인가?
- artifact 차이인지 config 차이인지 나누고, 그 다음 인스턴스별 active profile과 environment를 비교해야 한다.