데이터베이스 기반 쿠버네티스 자동화가 실제로 작동하는 방식
Source: Dev.to
Mental Model
- LynqHub – 데이터베이스에 연결하고 변경 사항을 감시합니다.
- LynqForm – 생성할 Kubernetes 리소스를 정의합니다(템플릿).
- LynqNode – 실제 인스턴스로, 템플릿당 데이터베이스 행 하나씩 생성됩니다.
데이터베이스에 행이 생기면 hub가 LynqNode를 생성합니다. 노드 컨트롤러가 템플릿을 렌더링하고 리소스를 적용합니다. 행이 사라지거나 비활성화되면 자동으로 정리됩니다.
LynqHub
hub는 Lynq에 데이터가 어디에 있는지와 컬럼을 템플릿 변수에 매핑하는 방법을 알려줍니다.
apiVersion: operator.lynq.sh/v1
kind: LynqHub
metadata:
name: my-saas-hub
spec:
source:
type: mysql
mysql:
host: mysql.default.svc.cluster.local
port: 3306
database: nodes
table: node_data
username: node_reader
passwordRef:
name: mysql-secret
key: password
syncInterval: 30s
valueMappings:
uid: node_id # unique identifier for each node
activate: is_active # boolean controlling resource existence
extraValueMappings:
planId: subscription_plan
region: deployment_region
valueMappings– 필수 컬럼(uid,activate).extraValueMappings– 템플릿 변수로 변환되는 선택적 사용자 정의 필드.
hub는 syncInterval에 따라 데이터베이스를 폴링합니다. activate=true이면 Lynq가 리소스를 생성하고, false가 되면 정리가 시작됩니다.
LynqForm
폼은 각 데이터베이스 행에 대해 어떤 리소스를 생성할지 정의하는 청사진입니다.
apiVersion: operator.lynq.sh/v1
kind: LynqForm
metadata:
name: web-app
spec:
hubId: my-saas-hub
deployments:
- id: app
nameTemplate: "{{ .uid }}-app"
labelsTemplate:
app: "{{ .uid }}"
plan: "{{ .planId | default \"basic\" }}"
spec:
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 2
template:
spec:
containers:
- name: app
image: "{{ .deployImage | default \"nginx:latest\" }}"
services:
- id: svc
nameTemplate: "{{ .uid }}-svc"
dependIds: ["app"]
spec:
apiVersion: v1
kind: Service
# …
템플릿은 Sprig 함수가 포함된 Go text/template 구문을 사용하며, 200개 이상의 헬퍼 함수를 기본 제공합니다. 흔히 사용하는 변수:
{{ .uid }}– 고유 이름 접미사.{{ .planId | default "basic" }}– nullable 컬럼에 대한 안전한 기본값.{{ .uid | trunc63 }}– Kubernetes 이름 길이 제한을 준수합니다.
Resource Policies
각 리소스는 자체 생성, 삭제, 충돌 처리 정책을 정의할 수 있습니다.
Creation Policy
deployments:
- id: app
creationPolicy: WhenNeeded # default
deletionPolicy: Delete
conflictPolicy: Stuck
patchStrategy: apply
- WhenNeeded – 지속적인 동기화; 수동 삭제가 있으면 복구되고, 템플릿 업데이트가 적용됩니다.
- Once – 한 번만 생성하고 이후에는 건드리지 않음(초기 작업에 이상적).
jobs:
- id: init-job
creationPolicy: Once
nameTemplate: "{{ .uid }}-init"
spec:
apiVersion: batch/v1
kind: Job
spec:
template:
spec:
containers:
- name: init
command: ["sh", "-c", "echo 'one-time setup'"]
restartPolicy: Never
Deletion Policy
- Delete (default) –
OwnerReference가 설정되어 Kubernetes 가비지 컬렉션이 리소스를 제거합니다. - Retain – 리소스를 유지하고, Lynq가 나중에 찾을 수 있도록 orphan 라벨을 추가합니다(PVC에 유용).
persistentVolumeClaims:
- id: data-pvc
deletionPolicy: Retain
nameTemplate: "{{ .uid }}-data"
Conflict Policy
- Stuck (default) – 충돌 시 조정이 중단되고 이벤트가 발생합니다.
- Force –
force=true옵션을 사용한 Server‑Side Apply로 소유권을 강제로 가져옵니다(마이그레이션 시 유용).
Dependency Management
리소스는 서로 의존성을 가질 수 있어 올바른 생성 순서와 선택적 준비 상태 확인을 보장합니다.
secrets:
- id: db-creds
nameTemplate: "{{ .uid }}-creds"
deployments:
- id: db
dependIds: ["db-creds"]
waitForReady: true
- id: app
dependIds: ["db"]
waitForReady: true
Lynq는 dependIds를 기반으로 DAG(Directed Acyclic Graph)를 구축하고 위상 정렬하여 리소스를 적용합니다. 사이클이 있으면 즉시 실패합니다.
waitForReady: true– 의존 리소스가 준비될 때까지 대기합니다.skipOnDependencyFailure(기본값true) – 의존 리소스가 실패하면 종속 리소스를 건너뜁니다;false로 설정하면 강제로 실행합니다.
jobs:
- id: cleanup-job
dependIds: ["main-app"]
skipOnDependencyFailure: false
Full Reconciliation Flow
- Hub controller가
syncInterval마다 데이터베이스를 폴링합니다. - 활성 행마다
LynqNodeCR을 생성/업데이트합니다. - Node controller가
LynqNode를 잡아냅니다. - 행 데이터를 사용해 모든 템플릿을 렌더링합니다.
- 의존성 그래프를 만들고 리소스를 정렬합니다.
- Server‑Side Apply로 순차적으로 리소스를 적용합니다.
- 설정된 경우 준비 상태를 기다립니다.
- 결과를
LynqNode상태에 업데이트합니다.
Deactivation / Deletion
- Hub가 행 비활성화 또는 삭제를 감지합니다.
- 해당
LynqNodeCR이 삭제됩니다. - Finalizer가 각 리소스의
deletionPolicy에 따라 정리를 수행합니다.Delete→ 리소스가 제거됩니다.Retain→ orphan 라벨이 추가됩니다.
실시간으로 과정을 확인할 수 있습니다:
kubectl get lynqnodes -w
kubectl describe lynqnode
샘플 상태 출력:
status:
desiredResources: 5
readyResources: 5
failedResources: 0
appliedResources:
- "Deployment/default/acme-app@app"
- "Service/default/acme-svc@svc"
When to Use This Pattern
- 비즈니스 데이터를 관계형 데이터베이스(사용자, 테넌트, 조직 등)에 이미 저장하고 있는 경우.
- 전통적인 commit‑sync‑reconcile 루프 없이 빠른 프로비저닝이 필요할 때.
- 동일한 리소스 집합을 값만 달라지게 여러 번 복제해야 할 때.
- 인스턴스별 버전 관리보다 템플릿 버전 관리가 더 중요한 경우.
소수의 고유 환경에 전통적인 IaC 도구가 충분한 경우에는 적합하지 않습니다. 대규모, 데이터‑드리븐 프로비저닝에는 Lynq가 간결하고 선언적인 접근 방식을 제공합니다.
References & Hands‑On
- Killercoda quick‑start (≈10 min)
- Documentation
- GitHub repository
댓글로 질문을 자유롭게 남겨 주세요!