0. Contents
1. Overview
배경
- Kukie 는 채팅으로 고객의 EKS 를 운영하는 서비스다
- 변경 요청은 승인 카드를 거쳐 kubectl 로 실행한다
- ArgoCD 를 쓰는 클러스터에서는 이 방식에 문제가 생긴다 — 클러스터의 원본이 Git 이기 때문이다
이 글의 질문
- kubectl 변경은 언제 되돌아가고, 언제 남는가
- 어떤 리소스를 ArgoCD 가 관리하는지 코드가 어떻게 아는가
- ArgoCD 정보를 읽으려면 고객 클러스터에 어떤 권한이 필요한가
- PR 을 올리기 전 단계에서 사용자에게 무엇을 보여 줄 수 있는가
범위
- 매니페스트 레포에 PR 을 올리는 흐름과 Helm values 는 이 글에 없다
- 시험은 ArgoCD 가 설치된 시험 전용 EKS 에서 했고, 화면 캡처는 앱의 픽스처 데이터로 띄운 것이다
2. Source of Truth — Git 과 클러스터
2.1 원하는 상태와 지금 상태
- GitOps 에서는 레포에 적힌 YAML 이 원하는 상태다
- 클러스터에 실제로 떠 있는 값이 지금 상태다
- ArgoCD 는 이 두 값을 계속 비교한다 — Infra.05 4장의 sync 루프가 이 일을 한다
2.2 Application 과 sync 정책
ArgoCD 는 앱 하나를 Application 이라는 쿠버네티스 리소스로 표현한다. 어느 레포의 어느 폴더를 어느 namespace 에 배포할지가 여기에 적혀 있다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: sandbox-plain
namespace: argocd
spec:
project: sandbox
source:
repoURL: git@github.com:example-org/kukie-gitops-sandbox.git
targetRevision: main
path: apps/plain # 이 폴더의 YAML 이 원하는 상태다
destination:
server: https://kubernetes.default.svc
namespace: sandbox-plain
syncPolicy:
automated: {prune: true, selfHeal: true} # 달라졌을 때의 동작
두 값이 달라졌을 때의 동작은 syncPolicy 가 정한다.
| 설정 | 뜻 | kubectl 로 바꾼 값 |
|---|---|---|
automated 없음 | 사람이 sync 를 눌러야 반영된다 | 누가 sync 할 때까지 남는다 |
automated | Git 이 바뀌면 자동으로 반영한다 | 다음 Git 변경이 sync 될 때 덮어써진다 |
automated.selfHeal | 클러스터가 달라져도 자동으로 sync 한다 | 곧 되돌아간다 |
automated.prune | Git 에서 지운 리소스를 클러스터에서도 지운다 | 값 변경과는 관계없다 |
ArgoCD 문서에 따르면 selfHeal 은 기본으로 꺼져 있다. 자동 sync 를 켜도 클러스터에서 직접 바꾼 값은 그것만으로는 자동 sync 를 일으키지 않는다.
2.3 kubectl 이 성공하는 이유
- ArgoCD 는 API server 로 가는 요청을 가로채지 않는다
- kubectl 요청은 평소처럼 API server 에 들어가고, 값은 정상으로 바뀐다
- ArgoCD 는 그 뒤에 달라진 값을 발견한다
- 그래서 명령은 성공으로 끝나고, 에이전트도 완료라고 답한다
- 사용자는 나중에 값이 돌아간 것을 보게 된다. 오류가 없어서 원인을 찾기 어렵다
2.4 시험 환경
- 실서비스 클러스터와 GPU 클러스터는 시험장으로 쓰지 않았다. 시험 전용 EKS
kukie-gitops-test를 따로 만들었다 - 노드는
t3.medium2대이고, 비용은 한 달 약 $160 이다. 시험이 끝나면 지우는 클러스터다 - ArgoCD 는 Terraform 밖에서 helm 으로 설치했다. 지우면 “ArgoCD 없는 클러스터"도 시험할 수 있기 때문이다
- 시험 앱의 원본은 별도 레포
kukie-gitops-sandbox에 두고, ArgoCD 는 읽기 전용 deploy key 로 읽는다 - 이 인프라 레포에는 Claude 리뷰 봇을 두지 않았다. 고객 클러스터를 흉내 내는 레포이기 때문이다
2.5 되돌림 시험
ArgoCD v3.5.3 에 형식이 다른 앱 셋을 올렸다.
| 앱 | 형식 | selfHeal | 시험 전 값 |
|---|---|---|---|
sandbox-plain | Directory | 켜짐 | web 1개 |
sandbox-kustomize | Kustomize | 켜짐 | api 2개 |
sandbox-helm | Helm | 꺼짐 | worker 1개 |
kubectl config use-context kukie-gitops-test
# selfHeal 켜짐
kubectl -n sandbox-plain scale deploy web --replicas=3
kubectl -n sandbox-kustomize scale deploy api --replicas=5
# selfHeal 꺼짐
kubectl -n sandbox-helm scale deploy worker --replicas=2
# 잠시 뒤 확인
kubectl -n sandbox-plain get deploy web # READY 1/1 로 돌아왔다
kubectl -n sandbox-kustomize get deploy api # READY 2/2 로 돌아왔다
kubectl -n sandbox-helm get deploy worker # READY 2/2 로 남아 있다
kubectl -n argocd get application sandbox-helm \
-o jsonpath='{.status.sync.status}' # OutOfSync
- ArgoCD 문서는 selfHeal 재시도 대기 기본값을 5초로 적는다. 시험의 되돌림도 같은 수 초 단위였다
- Git 을 다시 읽는 주기는 기본 약 3분으로, 되돌림 시간과는 다른 값이다
- 시험은 한 번이었고, 이 시간은 컨트롤러 설정에 따라 달라진다
- 자동 sync 는
operationState.operation.initiatedBy.automated값으로 사람이 시작한 sync 와 구분된다
3. Warn then Allow — 경고 후 허용
3.1 세 가지 선택지
| 선택 | 좋은 점 | 문제 |
|---|---|---|
| kubectl 차단 | 되돌림이 사라진다 | 장애 대응처럼 PR 을 기다릴 수 없을 때 막힌다 |
| 아무것도 안 함 | 구현할 것이 없다 | 변경이 조용히 사라진다 |
| 경고 후 허용 | 사용자가 결과를 알고 고른다 | 경고를 보고 실행해도 되돌아간다 |
Kukie 는 경고 후 허용을 골랐다. 장애 중에 임시로 값을 바꾸는 일은 실제로 필요하고, 그 판단은 사용자가 할 수 있기 때문이다.
3.2 승인 카드

- kubectl 명령과 dry-run 결과는 일반 승인 카드와 같다
- 그 위에 ArgoCD 경고와 관리하는 앱의 이름·경로가 붙는다
- 버튼 문구는 “승인하고 실행"에서 “그래도 실행"으로 바뀐다
- 승인하면 Action Plan 에 “ArgoCD 관리 리소스 직접 변경"이 남는다
3.3 Plan 에 싣는 값
변경 툴 4종(apply_manifest 등)은 실행 직전에 가드레일 훅을 지난다. 훅이 판별 결과를 승인 카드와 Plan 의 argocd 칸에 싣는다.
{
"summary": "ArgoCD 관리 리소스 직접 변경",
"level": "self_heal",
"warning": "몇 분 안에 ArgoCD가 되돌려요. 유지하려면 sync를 멈추거나 PR을 같이 올리세요.",
"applications": [{ "name": "guestbook", "path": "apps/guestbook", "self_heal": true }],
"resources": [{ "kind": "deployment", "name": "guestbook-ui", "namespace": "study", "application": "guestbook" }]
}
applications칸은 레포 주소와 sync 설정도 함께 담는다. 위 예시는 일부만 적었다- 서버는 Plan 의 payload 를 자유 형식으로 저장하므로, 카드에 이 칸을 더할 때 서버를 바꾸지 않았다
- 앱은 이 칸을
api/argocd.ts한 곳에서 검사한 뒤 읽는다 - 리뷰에서 모양이 이상한
argocd칸 때문에 화면 전체가 깨지는 문제가 나와, 배열이 아닌 값과 이름 없는 줄을 걸러내도록 고쳤다 - 칸을 읽지 못해도 승인 카드는 그대로 떠야 한다
3.4 경고 수준
경고는 sync 정책에 따라 네 단계로 나뉜다. 대상 리소스가 여럿이면 가장 센 단계를 카드에 싣는다.
| 수준 | 조건 | 카드 문구 |
|---|---|---|
self_heal | selfHeal 켜짐 | 몇 분 안에 ArgoCD가 되돌려요. 유지하려면 sync를 멈추거나 PR을 같이 올리세요. |
auto_sync | 자동 sync 만 켜짐 | 다음 git 변경이 반영될 때 덮어써져요. |
unknown | 관리 표시는 있는데 앱을 못 읽음 | ArgoCD 앱 설정을 읽지 못해 되돌려질지는 알 수 없어요. 유지하려면 git 에도 같은 변경을 반영하세요. |
manual | 자동 sync 꺼짐 | 자동 sync 는 꺼져 있어요. ArgoCD 화면에 OutOfSync 로 보이고, 누가 sync 하면 git 내용으로 돌아가요. |
문구는 에이전트가 만들고, 앱은 그대로 표시한다. 앱은 self_heal 만 노란 상자로 더 눈에 띄게 그린다.
3.5 남는 한계
- selfHeal 이 켜져 있으면 경고를 보고 실행해도 값은 되돌아간다
- 카드 문구가 말하는 “sync 멈추기"는 아직 버튼으로 구현되지 않았다
- “같은 내용으로 PR 올리기” 선택지도 아직 구현 전이다
- 지금은 사용자가 ArgoCD 쪽에서 직접 sync 를 멈추거나, 레포를 따로 고쳐야 한다
4. Ownership Detection — ArgoCD 관리 판별
4.1 판단 단위
- 처음에는 클러스터마다 “변경 방식” 설정을 두려고 했다
- 한 클러스터에도 ArgoCD 가 관리하는 리소스와 아닌 리소스가 섞여 있다
- 대화 도중 설정이 바뀌면 그 대화를 어떻게 처리할지도 문제가 됐다
- 그래서 설정을 없애고, 변경 직전에 리소스마다 판단하도록 바꿨다
4.2 tracking-id 의 구조
ArgoCD 는 자기가 만든 리소스에 추적 표시를 남긴다. ArgoCD 문서의 기본 추적 방식은 argocd.argoproj.io/tracking-id 어노테이션이다.
kubectl -n sandbox-plain get deploy web \
-o jsonpath='{.metadata.annotations.argocd\.argoproj\.io/tracking-id}'
# sandbox-plain:apps/Deployment:sandbox-plain/web
- 시험 앱의 Deployment 와 Service 에는 모두 이 어노테이션이 있었다
app.kubernetes.io/instance레이블은 없었다- Service 처럼 core 그룹의 리소스는
sandbox-plain:/Service:sandbox-plain/web처럼 group 자리가 비어 있다
4.3 복사된 표시와 Helm 레이블
추적 표시가 있다고 바로 ArgoCD 관리 리소스로 보면 두 경우에 틀린다.
레이블은 다른 도구도 붙이는 값이라 Application 까지 확인한다. 코드에서는 이렇게 갈린다.
# kukie_agent/argocd.py
item = find_application(items, tracking)
if tracking.source == "label" and (item is None or not manages(item, resource)):
continue # Helm 의 instance 라벨일 뿐이다
어노테이션은 ArgoCD 만 붙이는 값으로 본다. 그래서 어노테이션이 있는데 Application 을 못 찾으면 관리 리소스로 보고, 경고 수준을 unknown 으로 둔다. 다른 클러스터의 ArgoCD 가 이 클러스터를 관리하는 허브형 구성에서 이런 일이 생긴다.
4.4 읽기 실패의 구분
Application 목록을 못 읽는 이유는 세 가지로 나눈다.
| 상태 | 뜻 | 동작 |
|---|---|---|
absent | applications.argoproj.io CRD 가 없다 | ArgoCD 없음으로 처리 |
forbidden | 읽을 권한이 없다 (403) | 있는지 알 수 없어 판별을 건너뜀 |
error | 닿지 않음, 시간 초과, 응답 모양 이상 | 연결 문제로 구분 |
- 세 경우는 화면 안내가 다르다. “ArgoCD 가 없어요"와 “읽을 권한이 없어요"는 사용자가 할 일이 다르다
- kubectl 은 API server 에 닿지 못할 때도 “그런 리소스 종류가 없다"처럼 보이는 오류를 낼 수 있다
- 그래서
connection refused,unauthorized같은 연결 실패 문구를 먼저 걸러낸다
4.5 시간 제한
- 판별은 변경 툴을 부를 때마다 돈다. 오래 걸리면 승인 카드가 늦게 뜬다
- kubectl 한 번은 5초, 판별 전체는 10초로 제한한다
- 한 번의 제한은 남은 시간으로 줄인다. 끝 무렵에 시작한 조회가 전체 제한을 넘지 못하게 하기 위해서다
- 대상 리소스는 앞의 5개까지만 본다
- 어떤 실패도 위로 올리지 않는다. 판별은 경고를 붙이는 일이고 실행의 조건이 아니다
4.6 리뷰에서 바뀐 판별 코드
| 처음 코드 | 문제 | 바꾼 코드 |
|---|---|---|
| 표시의 앱 이름만 확인 | 다른 namespace 로 복사한 리소스도 관리로 판단 | kind · namespace · name 대조 |
| kubectl 호출마다 5초 | 리소스가 많으면 전체 시간이 늘어남 | 전체 10초 예산, 호출마다 남은 시간 사용 |
판별 코드는 kukie_agent/argocd.py 한 곳에 있고, 가드레일과 앱 목록 API, 앱 상세 API 가 함께 쓴다. 그래서 화면에 보이는 관리 여부와 승인 카드의 판단이 어긋나지 않는다.
읽기 툴의 결과에도 같은 판별로 만든 한 줄을 덧붙인다. 모델이 리소스를 바꾸기 전에 “ArgoCD 앱 guestbook 이 관리하는 리소스다"를 알게 하기 위해서다.
앱 이름이 <namespace>_<name> 꼴이면 ArgoCD 의 “apps in any namespace” 기능으로 만든 Application 으로 해석한다. 쿠버네티스 이름에는 _ 를 쓸 수 없어서 이 표기를 구분자로 쓸 수 있다.
5. Access Level — 연결 권한
5.1 연결 구조
Infra.07에서 만든 AWS 계정 연결은 영구 키를 받지 않는다. 고객 계정의 역할을 필요할 때만 빌려 쓴다.
- 역할(출입증)은 계정에 하나다. 들어오기 위한 조건은 팀마다 다른 ExternalId 다
- 접근 항목(이름표)은 클러스터마다 하나다
- 접근 정책은 접근 항목에 붙어서 그 클러스터 안의 권한을 정한다
5.2 템플릿 v4 의 한계
- v4 는
AmazonEKSEditPolicy를kukie-*namespace 안에서만 줬다 kube-*namespace 는 템플릿이 거부했다- GPU 정보를 읽으려면 고객이 선택 그룹을 켜고 RBAC 파일을 직접 적용해야 했다
- ArgoCD 의 Application 은 보통
argocdnamespace 에 있어서 이 권한으로는 읽을 수 없다 - 새 기능이 생길 때마다 고객에게 RBAC 파일을 하나씩 더 받아야 하는 구조였다
변경은 어차피 승인 카드를 거치므로, 복잡함에 비해 얻는 안전이 작다고 판단했다.
5.3 전체 권한과 제한 권한
템플릿 v5 는 AccessLevel 파라미터 하나로 두 수준을 고른다.

| 구분 | 전체 full (기본) | 제한 limited |
|---|---|---|
| 접근 정책 | AmazonEKSClusterAdminPolicy | AmazonEKSEditPolicy |
| 범위 | 클러스터 전체 | AllowedNamespaces 안 |
kube-* | 열림 (변경은 승인 카드로만) | 거부 |
| ArgoCD · GPU 화면 | 쓸 수 있음 | 쓸 수 없음 |
- 수준은 계정마다 하나만 고른다. 역할 하나에 두 수준을 다 허락하면 제한의 의미가 없어지기 때문이다
- 역할에는 둘 중 한 문장만 들어간다
# kukie-access-v5.yaml
- Fn::If:
- FullAccess
- Sid: ClusterAdminWholeCluster
Effect: Allow
Action: "eks:AssociateAccessPolicy"
Resource: "*"
Condition:
StringEquals:
"eks:policyArn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
"eks:accessScope": "cluster"
- Sid: EditAllowedNamespacesOnly
# AmazonEKSEditPolicy, namespace 범위, AllowedNamespaces 조건
등록할 때는 서버가 수준에 맞는 정책과 범위를 접근 항목에 붙인다.
// kukie-server AwsEksAccessGateway.kt
val scope = when (accessLevel) {
AccessLevel.FULL -> AccessScope.builder().type(AccessScopeType.CLUSTER).build()
AccessLevel.LIMITED ->
AccessScope.builder().type(AccessScopeType.NAMESPACE).namespaces(namespaces.distinct().sorted()).build()
}

제한된 권한의 클러스터는 설정 화면에 표시가 붙고, ArgoCD · GPU 화면에서는 “제한된 권한이라 쓸 수 없어요” 묶음으로 내려간다. 그 namespace 안의 대화와 변경은 그대로 쓸 수 있다.
5.4 전체 권한의 실제 범위
처음 쓴 템플릿 설명은 “등록한 클러스터의 관리자"에 가까웠다. 리뷰에서 이 설명이 실제 권한보다 좁다는 지적이 나왔다.
그래서 템플릿 설명을 “이 계정의 어느 EKS 클러스터에든 자기를 관리자로 붙일 수 있고, 실제로 붙이는 것은 등록한 클러스터뿐"으로 고쳤다. 고객은 코드의 동작이 아니라 역할의 권한을 보고 동의하기 때문이다.
| 얻는 것 | 잃는 것 |
|---|---|
| 기능마다 RBAC 파일을 더 받지 않아도 된다 | Kukie 자격증명이 털리면 연결된 클러스터의 관리자 권한이 넘어간다 |
| ArgoCD · GPU · 이후 기능이 바로 동작한다 | Kukie 쪽 역할 경계의 중요성이 더 커진다 |
보안 정책이 있는 고객을 위해 제한 수준을 남겨 두었다.
5.5 권한 전환 순서
스택을 업데이트해 수준을 바꾸면 서버가 스택 알림을 받아 등록된 클러스터의 정책을 교체한다.
- 새 정책을 먼저 붙이면 정책이 하나도 없는 순간이 생기지 않는다
- 전환이 끝까지 실패하면 어느 쪽이 덜 나쁜지를 정해야 한다
- 제한으로 낮추려는데 관리자 권한이 남는 경우를 더 나쁘게 봤다
- IAM 변경이 퍼지는 데 시간이 걸려 첫 시도가 거부될 수 있으므로, 실패로 정하기 전에 재시도한다
5.6 전환 시험
full → limited는 실제 스택 변경으로 시험했다- 서버가 알림을 받아 등록된 클러스터를 Edit 정책으로 바꿨다
- 기본 namespace 가
default인 시험 클러스터는 허용 목록 밖이라 Edit 정책 연결이 거부됐다 - 허용 목록과 등록 namespace 가 어긋나면 실제 운영에서도 같은 실패가 생길 수 있다
limited → full전환과 에이전트의 403 처리는 아직 시험하지 못했다- v4 고객이 v5 로 올리면 기본값
full이 들어가 권한이 넓어진다. 갱신 화면에서 수준을 고르게 하는 작업은 남아 있다
6. Read Features — 화면과 읽기 도구
6.1 읽기 구조
6.2 ArgoCD 앱 목록

- 데이터는 ArgoCD API 가 아니라 클러스터의 Application 리소스에서 읽는다
- 그래서 ArgoCD API 토큰을 따로 받지 않아도 된다
- 사이드바에는 ArgoCD 가 있는 클러스터만 나온다
- 카드에는 Synced · OutOfSync 수, selfHeal 앱 수, 연결한 레포를 보여 준다
- 표에서는 문제가 있는 앱을 위로 올린다
처음 화면은 ArgoCD 앱이 가리키는 출처 레포를 보여 줬다. 사용자가 이것을 “Kukie 에 연결된 레포"로 착각해서, 카드와 요약줄을 Kukie 에 연결한 레포 기준으로 바꿨다. 두 레포가 다르면 “레포 미연결 → 연결하기"가 나온다.
6.3 앱 상세

앱 상세의 칸은 대부분 Application 의 status 에서 나온다.
| 화면 칸 | Application 필드 |
|---|---|
| 소스 | spec.source · status.sourceType |
| sync 설정 | spec.syncPolicy.automated |
| 리소스 목록, 왜 OutOfSync | status.resources[] |
| 마지막 sync | status.operationState |
| 배포 기록 | status.history[] |
| 쓰는 이미지 | status.summary.images |
| 오류와 경고 | status.conditions[] |
- “왜 OutOfSync"는
status.resources[]에서 동기화 상태가 OutOfSync 인 줄만 고른 것이다 - ArgoCD 의 condition 은 이름에 따라 나눈다.
*Warning은 경고로,*Error는 오류로 표시한다 - 지워진 namespace 의 앱은 클러스터 연결 실패(502)가 아니라 앱 없음(404)으로 돌려준다. 처음에는 502 로 나가 사용자가 연결 문제로 오해할 수 있었다
6.4 Kukie 기록

- 앱의 배포 기록에는 Git 을 거친 변경만 있다. 채팅에서 kubectl 로 바꾼 값은 없다
- Action Plan 목록에서 이 앱의 리소스를 건드린 것만 골라 함께 보여 준다
- 그러면 OutOfSync 의 원인이 채팅에서 한 변경인지 바로 알 수 있다
- 서버에 새 저장소를 만들지 않고 이미 받아 오는 Plan 을 걸러서 만든다
- Kukie 밖에서 생긴 변경은 Plan 에 없다. 그래서 “Kukie 로 한 변경만 보여요” 문구를 함께 둔다
6.5 kubectl 조회 공유
- 화면을 켜 둔 사람이 많으면 같은 클러스터에 같은 조회가 반복된다
- 같은 연결의 앱 목록과 상세는 결과를 10초 동안 나눠 쓴다
- 나눠 쓰려면 응답에 사람마다 다른 값이 없어야 한다
- “다시 읽기"를 누르면 새로 읽되, 2초 안의 결과는 그대로 쓴다. 화면이 계속 새로 읽어도 kubectl 이 2초보다 자주 돌지 않는다
6.6 레포 보기

레포를 연결하면 ArgoCD 화면에 레포 탭이 생긴다. 어느 폴더를 어느 앱이 쓰는지와, 앱이 클러스터에 실제로 넣는 YAML 을 볼 수 있다.
| 항목 | 방식 |
|---|---|
| 폴더 | 펼칠 때 그 폴더만 읽는다. 항목은 300개까지다 |
| 파일 | GitHub Contents API 로 읽는다. 1MB 를 넘으면 내용 없이 이유만 보여 준다 |
| 렌더 결과 | plain 은 그대로, Kustomize 는 kustomize build. 리소스 500개, 2MB 까지다 |
| 기억 | 브랜치를 커밋 id 로 바꾼 뒤 (레포, 커밋, 경로)로 기억한다 |
| 미지원 | Helm 과 플러그인 앱은 지원 전으로 표시한다 |
커밋 id 가 같으면 내용도 같으므로, 같은 커밋의 폴더와 렌더 결과는 다시 받지 않는다.
6.7 Secret 가림
레포에는 비밀값이 섞여 있을 수 있다. 화면과 채팅에 나가기 전에 내용을 가린다.
| 판단 기준 | 예 |
|---|---|
| 파일 이름 | .env, *.pem, *.key, id_rsa, *.enc, 이름에 sops |
| 리소스 내용 | kind: Secret, stringData, sops 칸 |
| 글자 패턴 | -----BEGIN … PRIVATE KEY-----, AWS 키, GitHub 토큰 형식 |
- 이름과 위치는 보여 주고 값만 가린다. 그래야 레포 구조를 이해할 수 있다
- 렌더 결과에서도 Secret 리소스의 값은 가린다
6.8 채팅 읽기 도구
레포 탭의 빠른 질문은 “이 파일이 무엇을 하는지 설명해 줘” 같은 문장을 입력창에 넣는다. 처음에는 에이전트에 레포를 읽는 도구가 없어서 클러스터 상태만 보고 짐작해 답했다. 그래서 읽기 도구 셋을 더했다.
| 도구 | 하는 일 |
|---|---|
list_repo_dir | 폴더 목록과 그 경로를 쓰는 ArgoCD 앱 |
read_repo_file | 파일 내용 (가림과 크기 상한 적용) |
render_app | ArgoCD 앱의 렌더 결과 |
- 읽기 도구이므로 승인 카드 없이 돌고, Private · Shared 대화 모두에서 쓸 수 있다
- 모델에 넘기는 결과는 24,000자로 자른다
- 레포 연결 여부와 상관없이 도구 목록은 항상 같다. 프롬프트 캐시는 앞부분이 같아야 재사용되는데, 연결 상태에 따라 도구를 숨기면 앞부분이 달라진다
- 레포가 연결돼 있지 않으면 “레포를 연결하면 볼 수 있어요"를 결과로 돌려준다
7. Discussion
7.1 확인 범위
| 내용 | 확인 방법 |
|---|---|
selfHeal 되돌림과 OutOfSync | 시험 클러스터에서 실측 |
| tracking-id 형식 | 시험 클러스터에서 실측 |
| ArgoCD 화면의 앱 표시 | 시험 클러스터에서 확인 |
| 판별과 경고 카드 | 단위 테스트와 픽스처. 실제 클러스터 시험 기록은 찾지 못했다 |
| 레포 보기와 채팅 도구 | 단위 테스트와 픽스처. 실제 클러스터 시험 기록은 찾지 못했다 |
full → limited | 실제 스택 변경 |
limited → full, 403 처리 | 아직 시험하지 않았다 |
7.2 경고 문구와 시험 결과
- 카드는 “몇 분 안에 되돌려요"라고 적는다
- 시험에서는 약 6초 만에 되돌아갔다
- 사용자가 “몇 분은 유지된다"로 읽을 수 있어서, “곧 되돌려요"가 시험 결과에 더 가깝다
7.3 판별의 한계
- 허브형 ArgoCD 는 Application 이 대상 클러스터에 없어 sync 정책을 읽지 못한다. 경고 수준이
unknown에 머문다 - Application 을 읽을 권한이 없는 클러스터는 판별을 건너뛴다. 이 경우 경고 없이 kubectl 로 실행된다
- 레이블 추적 방식의 클러스터는 Application 까지 읽어야 판별할 수 있다
핵심 메시지
- 판단 단위: 클러스터가 아니라 리소스
- 한 클러스터에도 ArgoCD 가 관리하는 리소스와 아닌 리소스가 섞여 있다
- 추적 표시: 믿기 전에 대조
- 어노테이션은 복사될 수 있고, 레이블은 Helm 도 붙인다
- 경고: 성공처럼 보이는 실패를 미리 알리는 장치
- kubectl 은 성공하므로, 되돌림은 실행 전에 알려야 한다
- 권한 설명: 코드의 약속과 역할의 범위 구분
- 코드가 등록한 클러스터에만 붙여도, 역할이 할 수 있는 범위는 계정의 모든 EKS 다
