TT Lab
시작하기
배우기 러닝패스 코스

CGOA — GitOps 인증 어소시에이트

설정은 바뀌었는데 프로세스는 왜 그대로일까

TT Lab 에서 이어서 보기

한 줄 요약

설정을 저장한 위치뿐 아니라 프로세스가 그 설정을 언제 소비하는지 알아야 복구가 끝납니다.

왜 이게 필요했나

업무 경로가 500을 내는 설정을 찾았습니다. Git에서 200으로 고쳤고 Argo CD도 새 커밋에 Synced입니다. 쿠버네티스 API로 ConfigMap을 읽으면 분명히 새 값이 있습니다. 그런데 curl은 계속 500을 받습니다. 이때 “GitOps가 말을 안 듣는다”며 Pod를 지우면 잠깐은 문제가 사라질 수 있습니다. 하지만 어떤 설정이 어떤 과정으로 프로세스에 전달됐는지 놓치면 다음 변경에서 같은 장애를 반복합니다. 원본·전달된 파일·실행 중 프로세스라는 세 층을 먼저 나눠 봅시다.

ConfigMap 값이 프로세스에 닿기까지 세 층

Git 에서 설정을 고쳐 Synced 가 되었는데도 응답이 그대로인 사례를 푸는 본문의 틀이다. 원본, 전달된 파일, 실행 중 프로세스를 나누어 어느 층에서 멈췄는지 본다.

  1. 원본: 쿠버네티스 API 에 저장된 ConfigMapAPI 로 읽으면 분명히 새 값이 들어 있다. Git 의 수정이 반영된 곳은 여기까지이다.
  2. 전달된 파일: 소비 방식이 갱신 동작을 정한다환경변수로 주입한 값은 기존 프로세스의 환경변수를 자동으로 갈아 끼우지 않는다. 일반 볼륨 파일은 갱신될 수 있지만 전파에 시간이 걸린다. subPath 로 파일 하나를 마운트한 컨테이너는 후속 갱신을 받지 않는다.
  3. 실행 중 프로세스: 다시 읽는지는 별도 문제파일이 바뀌더라도 애플리케이션이 그것을 다시 읽는지는 따로 확인해야 한다.

여기서 구분할 것 ConfigMap 은 자동 갱신된다는 문장을 소비 방식을 빼고 외우면 틀린다. 응답이 옛 값일 때 sleep 시간을 늘려도 소비 방식이 바뀌지는 않는다.

잠깐, 예측해 보세요 ConfigMap 의 값을 환경변수로 주입한 Deployment 가 있다. Git 에서 값을 고쳐 Synced 가 됐다. 컨테이너를 그대로 두어도 프로세스가 새 값을 보게 될까?

설명 확인 · 채점 없는 자가 점검

본문 기준으로 보장되지 않는다. 환경변수 주입은 기존 프로세스의 값을 자동으로 갈아 끼우지 않는다. ConfigMap 에 새 값이 있다는 관측과 프로세스가 실제로 어떤 값을 쓰는지는 따로 확인해야 한다.

근거 문서

어떻게 동작하나

ConfigMap은 쿠버네티스 API에 저장된 설정 데이터입니다. 소비 방식에 따라 갱신 동작이 다릅니다. 환경변수로 주입한 값은 기존 프로세스의 환경변수를 자동으로 갈아 끼우지 않습니다. 일반 볼륨으로 투영한 파일은 갱신될 수 있지만 전파에 시간이 걸릴 수 있습니다. 파일이 바뀌더라도 애플리케이션이 다시 읽는지는 별도 문제입니다. 특히 이번처럼 subPath로 파일 하나를 마운트한 컨테이너는 ConfigMap의 후속 갱신을 받지 않습니다. “ConfigMap은 자동 갱신된다”라는 문장을 소비 방식을 생략한 채 외우면 바로 이 실험에서 틀립니다. 공식 ConfigMap 갱신 조건.

이번 Deployment는 nginx.conf 한 파일을 /etc/nginx/nginx.conf에 subPath로 마운트합니다. 첫 설정 커밋은 ConfigMap의 nginx.conf만 고칩니다. Deployment의 spec.template은 보존합니다. 따라서 새 Pod가 만들어질 이유가 없습니다. 이전 Pod UID와 컨테이너가 남고, 컨테이너 안에서 읽은 파일도 이전 값이며 HTTP 응답도 여전히 500입니다. 이는 단순히 “캐시가 느려서 그렇다”고 추측한 결과가 아니라 파일과 신원의 비교로 확인한 전달 경계입니다. 무작정 sleep 시간을 늘리는 것이 이 소비 방식을 바꾸지는 않습니다.

두 번째 커밋은 새 설정 바이트의 SHA-256을 계산하여 Pod 템플릿의 checksum/config 주석에 넣습니다. 이 주석 이름에 쿠버네티스 내장 마법이 있는 것은 아닙니다. spec.template의 값이 달라져 Deployment가 새 ReplicaSet과 Pod를 만들도록 하는 규약입니다. 체크섬을 Deployment 최상위 metadata에만 붙이면 템플릿이 바뀌지 않으므로 같은 효과를 얻을 수 없습니다. 새 Pod는 현재 ConfigMap으로 마운트를 만들고 nginx를 시작합니다. ConfigMap만 바꾼 커밋과 템플릿까지 바꾼 커밋을 분리하면 이 차이를 눈으로 따라갈 수 있습니다. 공식 Deployment 갱신.

체크섬은 문자열을 눈대중으로 적는 값이 아닙니다. 실제 설정 바이트를 계산해야 하며 마지막 줄바꿈 유무도 결과를 바꿉니다. 이번 도우미는 저장한 ConfigMap 관측의 nginx.conf 값을 그대로 인코딩해 계산합니다. 실제 운영에서는 설정 파일·템플릿 생성 파이프라인이 같은 규칙을 공유해야 합니다. 다른 파일의 체크섬이나 임의의 타임스탬프도 롤아웃을 유발할 수 있지만, 그것은 우리가 어떤 설정을 배포했는지 설명하는 근거가 아닙니다.

현장에서 만나는 모습

응급조치와 영구 복구를 구분해야 합니다. 수동으로 Pod를 지워 새 설정을 읽게 할 수 있더라도 그 조치는 원하는 배포 상태와 변경 의도를 Git에 남기지 않습니다. selfHeal이 켜진 리소스의 직접 수정은 Git의 상태로 다시 조정될 수 있습니다. 이번 실습에서는 플랫폼 운영 설정을 바꾸지 않고 학생 전용 저장소의 두 커밋으로 복구 과정을 남깁니다. 자동 동기화가 모든 잘못된 설정을 고치는 기능은 아니며, 사람의 검토와 테스트가 필요합니다. 공식 자동 동기화.

롤아웃 완료 확인에도 이름만으로는 부족합니다. 새 Pod의 UID는 바뀌어야 하지만 Application과 Deployment는 같은 UID를 유지해야 합니다. 이전 Pod를 지웠다가 같은 이름으로 자원을 통째로 다시 만든 것은 같은 복구 과정이 아닙니다. 원하는 템플릿의 체크섬, observedGeneration, updatedReplicas, Ready, 새 Pod 안의 파일, 실제 응답을 함께 확인해야 “새 설정을 읽은 새 프로세스가 응답했다”는 주장을 할 수 있습니다.

실습의 단계별 JSON은 보고서 작성 편의를 위한 학습 자료입니다. 원자료와 해시를 보존하여 실수로 이전 관측을 덮어쓰면 실패하도록 했지만, 같은 VM의 root가 모든 파일을 바꿀 수 있다는 한계는 남습니다. 해시가 있다는 이유로 원격 증명이나 위변조 불가능한 감사 시스템이라고 부르지 않습니다. 운영 감사라면 신뢰 경계 밖으로 보내는 로그와 접근 제어, 보존 정책을 별도로 설계해야 합니다.

응급조치와 영구 복구는 남기는 것이 다르다

본문의 현장 대목이다. 같은 500 을 고치는 두 방법을, 무엇이 Git 에 남는가의 관점에서 견준다.

  • Pod 를 지워 새 설정을 읽게 한다잠깐은 문제가 사라질 수 있다. 그러나 원하는 배포 상태와 변경 의도가 Git 에 남지 않는다. selfHeal 이 켜진 리소스의 직접 수정은 Git 의 상태로 다시 조정될 수도 있다.
  • Git 에 두 커밋으로 남긴다설정 커밋 다음에 Pod 템플릿의 checksum/config 주석을 바꾸는 커밋을 배포한다. 템플릿이 바뀌므로 Deployment 가 새 ReplicaSet 과 Pod 를 만들고, 두 변경을 분리하면 차이를 눈으로 따라갈 수 있다.

여기서 구분할 것 복구의 증거는 이름이 아니라 신원이다. 새 Pod 의 UID 는 바뀌어야 하고 Application 과 Deployment 는 같은 UID 를 유지해야 한다. 이전 Pod 를 지우고 자원을 통째로 다시 만든 것은 같은 복구 과정이 아니다.

잠깐, 예측해 보세요 복구 뒤 curl 이 200 을 준다. Pod 이름이 이전과 달라 보인다는 이유만으로 롤아웃이 끝났다고 보고해도 될까?

설명 확인 · 채점 없는 자가 점검

부족하다. 본문은 이름만으로는 안 된다고 한다. 원하는 템플릿의 체크섬, observedGeneration, updatedReplicas, Ready, 새 Pod 안의 파일, 실제 응답, 그리고 UID 를 함께 확인해야 새 설정을 읽은 새 프로세스가 응답했다고 말할 수 있다.

근거 문서

다음 실습에서 할 것

설정 변경 전후와 템플릿 변경 후를 각각 보존합니다. 가운데 관측의 ConfigMap은 새 값인데 마운트 파일과 응답은 옛 값인지 조사하세요. 마지막으로 Git 커밋의 부모 관계까지 따라가며 두 변경을 구분하고, 새 Pod의 200 응답을 확인합니다. 과거 단계 재채점은 과거 기록을 읽어야지 장애를 다시 주입해서는 안 됩니다. 현재 상태 확인도 함께 통과했을 때 조사 범위 내 복구를 선언하고, 외부 경로 및 지속 관측은 남은 작업으로 기록합니다.