설정 변경은 파일 한 줄을 바꾸는 일이 아니라, 저장된 버전이 각 프로세스의 유효한 설정 snapshot과 실제 호출 동작으로 이어지는 배포 과정입니다. 따라서 “객체가 바뀌었다”와 “모든 인스턴스가 새 계약을 사용한다”를 관측값으로 분리해야 부분 적용과 잘못된 조합을 진단할 수 있습니다.
저장 값과 실행 중 값의 상태 구분
ConfigMap의 pool_size를 20에서 40으로 바꿨지만 실행 중인 앱이 계속 20개 연결만 만든다고 합시다. API 객체가 40으로 저장됐다는 사실은 프로세스가 새 값을 읽고 기존 client pool을 교체했다는 뜻이 아니므로, 값이 env·파일·watch 중 어떤 경로로 전달됐는지부터 확인합니다. 그 다음 앱이 언제 다시 읽는지와 이미 생성한 pool을 새 pool로 바꾸고 옛 연결을 어떻게 끝내는지까지 확인해야 실제 적용으로 판단할 수 있습니다.
환경 변수는 보통 프로세스 시작 시 값이므로 기존 컨테이너 환경이 자동 변경되지 않습니다. 볼륨 파일은 플랫폼이 갱신할 수 있지만 앱이 캐시한 문자열이나 열린 옛 파일 핸들을 계속 쓰면 동작은 바뀌지 않습니다. ConfigMap은 비밀 저장소도 아니므로 자격 원문은 적절한 Secret 관리 경계로 분리합니다.
전달 방식별 앱 적용 지점
| 방식 | 새 값이 앱에 들어오는 경계 | 한계 |
|---|---|---|
| env·envFrom | 새 프로세스 시작 | 객체 수정만으로 기존 env 갱신 안 됨 |
| 일반 volume mount | kubelet 전파 후 파일 갱신 | 앱 재읽기·전파 지연 필요 |
| subPath mount | 일반 자동 갱신과 다른 제약 | 객체 수정 즉시 반영 기대 금지 |
| 앱의 API watch | 이벤트·재연결 후 처리 | RBAC·watch 유실·재동기화 |
| 버전별 ConfigMap | 새 Pod template rollout | 준비·혼합 버전·보관 정리 |
파일의 원자 교체·symlink 변경에서는 기존 열린 핸들이 이전 파일을 볼 수 있습니다. watcher가 실제 파일과 symlink 중 어느 경로를 감시하는지 확인하고, 변경 시 파일을 다시 열어 전체를 읽을지 정책을 정합니다. versioned ConfigMap이나 template checksum으로 재시작을 유도할 수는 있지만, checksum이 바뀌었다는 사실만으로 새 설정이 타입·범위·호환성 검사를 통과했다는 뜻은 아닙니다.
그림을 글로 읽기
- ConfigMap 버전 저장
- env 재시작·파일·watch 전달
- 앱의 전체 묶음 검증
- 설정 snapshot·client 교체
- 실제 적용 버전 관측
- ConfigMap 버전 저장 → env 재시작·파일·watch 전달: 플랫폼 반영
- env 재시작·파일·watch 전달 → 앱의 전체 묶음 검증: 새 입력 읽기
- 앱의 전체 묶음 검증 → 설정 snapshot·client 교체: 호환·범위 통과
- 설정 snapshot·client 교체 → 실제 적용 버전 관측: 실제 호출 확인
설정값 개별 적용과 잘못된 조합 가능성
timeout을 새 1초로 바꾸는 동안 retry가 옛 10회로 남으면, 두 값이 함께 정하는 전체 기한이 잠시 다른 계약으로 실행될 수 있습니다. 그래서 새 설정을 임시 객체로 모두 읽은 뒤 타입·범위·필드 간 제약·지원 버전을 차례로 확인하고, 통과한 값만 하나의 불변 snapshot으로 게시합니다. 요청을 처리하는 코드는 시작할 때 그 snapshot을 잡고 관련 값을 같은 버전에서 읽어 값 하나만 먼저 바뀌는 조합을 피합니다.
바인딩 포트와 저장소 형식처럼 프로세스 재시작이 필요한 값은 배포 경계로 분류하고, 동적으로 바꿀 수 있는 값은 재읽기 시점을 따로 정합니다. pool 설정을 바꾸는 경우에는 새 pool을 만든 뒤 신규 요청을 그쪽으로 옮기고 옛 pool의 진행 중 작업을 drain할지, 즉시 교체할지를 코드의 수명 정책으로 결정합니다. 설정 참조만 새 값으로 바꿔도 이미 맺은 장기 연결의 실제 동작까지 바뀌지는 않습니다.
실패 시 유지할 설정 상태
잘못된 값은 적용을 거절하고 마지막 정상 snapshot을 유지하며 경고할 수 있습니다. 그러나 보안 회수·강제 중단 설정처럼 옛 값을 유지하면 안 되는 정책은 별도입니다. 처음 시작한 앱에 정상값이 없으면 임의 기본값으로 Ready가 되지 않도록 합니다.
상태 endpoint에 원문 비밀 대신 observed config version·applied version·마지막 성공 시각·실패 사유를 노출합니다. Pod마다 다른 버전이 얼마나 오래 남았는지 확인하고 단일 인스턴스의 성공으로 전체 완료를 판정하지 않습니다. GitOps diff에서 제외한 필드는 별도 감사가 필요할 수 있습니다.
객체·파일·앱·호출의 설정 반영 상태 비교
테스트 클러스터에서 env·일반 mount·subPath·watch를 나눠 수정하고 실제 앱의 적용 버전과 호출 동작을 확인합니다. 잘못된 묶음·읽기 중 교체·Pod 재시작·watch 단절·옛 pool drain을 시험합니다.
현재 작업에서는 ConfigMap을 배포하거나 수정하지 않았습니다. 이 노트는 설정 전달과 적용의 설계 설명이며 실제 전파 시간을 측정한 보고서는 아닙니다.
재현 시에는 20에서 40으로 바꾼 버전이 API 객체, Pod가 읽은 값, applied version, 실제 pool 크기에 각각 언제 나타나는지 기록합니다. 잘못된 timeout·retry 조합을 게시했을 때 새 snapshot이 거절되고 마지막 정상 snapshot이 유지되어야 하며, 보안 회수처럼 즉시 적용해야 하는 값은 이 일반 fallback 정책의 예외로 별도 결과를 가져야 합니다.