target-tracking-service를 c4i 네임스페이스에 배포하며 새로 만든 postgres.yaml, redis.yaml, kafka.yaml, deployment.yaml을 예시로 각 오브젝트가 왜 필요한지 정리.
kubectl create namespace c4i
같은 물리 클러스터 안에서 리소스를 그룹으로 나누는 단위. 네임스페이스가 다르면 이름이 같아도 별개 리소스로 취급된다.
Deployment는 "이 파드 스펙(template)으로 항상 replicas개가 떠 있게 유지해달라"는 선언적 명령이다. 직접 파드를 만드는 게 아니라, 내부적으로 ReplicaSet을 만들고 그 ReplicaSet이 실제 파드 개수를 감시·조정한다. 파드가 죽으면 ReplicaSet이 자동으로 새 파드를 띄운다 — 이게 docker run으로 컴테이너 하나 띄우는 것과 근본적으로 다른 점이다.
selector.matchLabels와 template.metadata.labels가 반드시 같아야 한다 — Deployment가 "내가 관리해야 할 파드가 어떤 것들인지"를 라벨로 식별하기 때문이다.
imagePullPolicy: Always로 설정한 이유: IfNotPresent면 노드에 같은 태그(v1)의 이미지가 이미 있을 때 재사용해버려서, Docker Hub에 새 이미지를 v1로 다시 push해도 클러스터가 옷날 이미지를 계속 쓸 수 있다.
파드는 재시작될 때마다 IP가 바뀌다. Service는 라벨 셀렉터로 파드 집합을 묶고, 그 앞에 바뀌지 않는 가상 IP(ClusterIP)와 DNS 이름을 붙여준다.
apiVersion: v1
kind: Service
metadata:
name: postgres-service
namespace: c4i
spec:
selector: { app: postgres }
ports: [{ port: 5432, targetPort: 5432 }]
이번 작업에서 중요했던 점: 기존 target-tracking-config ConfigMap이 이미 kafka-service.c4i.svc.cluster.local, redis-service.c4i.svc.cluster.local라는 이름을 참조하고 있었기 때문에, 새로 만드는 Kafka/Redis의 Service 이름을 정확히 맞챠야 했다. 이름이 하나라도 다르면 DNS 조회 자체가 실패한다(UnknownHostException).
기능적으로는 둘 다 "키-값을 담아서 파드에 주입"하는 같은 메커니즘이다. 차이는: Secret은 기본적으로 base64 인코딩되어 저장된다(암호화는 아니고 단순 인코딩 — RBAC으로 접근을 막는 게 실질적 보호). 도구들이 Secret 값은 기본적으로 마스킹해서 보여준다.
public 레포면 "git에 커밋하느냐"가 진짜 경계선이다 — ConfigMap도 민감한 값이면 커밋하면 안 되고, Secret이라고 자동으로 암호화되는 것도 아니다. 그래서 DB 비밀번호/GEMINI_API_KEY는 아예 YAML로 만들지 않고 kubectl create secret으로 클러스터에 직접 주입하고 git에는 남기지 않았다.
env:
- name: GEMINI_API_KEY
valueFrom:
secretKeyRef: { name: target-tracking-secrets, key: gemini-api-key }
컴테이너는 기본적으로 일시적(ephemeral)이다. Postgres처럼 데이터가 남아있어야 하는 컴포넌트는 파드 생명주기와 분리된 저장소가 필요하다.
apiVersion: v1
kind: PersistentVolumeClaim
metadata: { name: postgres-pvc }
spec:
accessModes: [ReadWriteOnce]
storageClassName: local-path
resources: { requests: { storage: 2Gi } }
우리 클러스터는 local-path(Rancher의 local-path-provisioner)를 쓰는데, 노드의 로컬 디스크 경로를 그대로 볼륨으로 쓰는 가장 단순한 방식이다 — 한 번 특정 노드에 프로비저닝되면 그 파드는 항상 그 노드에서만 뜵 수 있다(replicas를 여러 개로 못 늘리는 이유, postgres는 replicas: 1).