본문으로 건너뛰기

K8s YAML 생성

KIWI의 [서비스 관리] 페이지에서는 Kubernetes 배포에 필요한 YAML 파일을 직접 작성하지 않고, 폼에서 옵션을 선택하여 자동으로 생성할 수 있습니다. 이 가이드에서는 생성 가능한 리소스 종류(Kind)별 옵션과, 실제 프로젝트에서 YAML을 어떻게 구성하는지 예시를 통해 설명합니다.

YAML을 직접 작성할 필요가 없습니다

KIWI는 입력한 옵션을 기반으로 표준 Kubernetes YAML을 자동 생성합니다. 생성된 YAML은 미리보기에서 확인하고, 필요하면 직접 편집할 수도 있습니다.

YAML 생성 페이지 진입

  1. [서비스 관리] 페이지에서 서비스를 선택합니다.
  2. 파이프라인의 Deploy 단계를 클릭합니다.
  3. 배포 환경 설정에서 K8s 배포를 선택하면 YAML 생성 화면이 표시됩니다.

Part 1: Kind별 옵션 설명

KIWI에서 생성할 수 있는 Kubernetes 리소스는 6가지입니다. 프로젝트 구성에 따라 필요한 Kind를 조합하여 사용합니다.

Kind용도필수 여부
Deployment애플리케이션 Pod 배포✅ 거의 항상
ServicePod 네트워크 접근✅ 거의 항상
Ingress외부 도메인 라우팅선택
ConfigMap설정값 분리 관리선택
PVC영구 스토리지선택
Job일회성 작업 (마이그레이션 등)선택
네트워크 노출 방식 선택
  • Ingress Controller (권장): Service를 ClusterIP로 설정하고 Ingress를 함께 생성합니다. 도메인 기반 라우팅에 적합하며 가장 일반적인 방식입니다.
  • NodePort (외부 Nginx): 외부 리버스 프록시에서 NodePort를 통해 접근합니다. Ingress가 필요 없습니다.
  • LoadBalancer (외부 IP): 외부 IP를 직접 할당받습니다. 클라우드 환경에서 주로 사용하며 Ingress가 필요 없습니다.

Deployment

애플리케이션 Pod의 배포 방식을 정의합니다.

왜 Deployment가 필요한가요?

컨테이너를 직접 실행하면 장애 시 자동 복구가 되지 않습니다. Deployment는 원하는 수만큼 Pod를 유지하고, 장애가 발생하면 자동으로 재시작하며, 새 버전 배포 시 무중단 업데이트를 처리합니다.

기본 옵션

옵션필수기본값설명
이름-Deployment 리소스 이름. 예: my-app
네임스페이스default배포 대상 네임스페이스
레플리카 수1동시에 실행할 Pod 수. 프로덕션은 3개 이상 권장
imagePullPolicyAlways이미지 풀 정책. Always, IfNotPresent, Never 중 선택
레이블-key-value 쌍. Service의 selector와 매칭됨. 예: app: my-app

컨테이너 (1개 이상 필수)

Pod 내에서 실행할 컨테이너를 정의합니다.

옵션필수기본값설명
이름-컨테이너 식별자. 예: frontend
이미지-컨테이너 이미지 주소. 빌드 목록에서 선택 또는 직접 입력
포트80컨테이너가 수신하는 포트 번호
환경 변수-직접 입력(key-value), secretKeyRef, configMapKeyRef 방식 지원
커맨드 / Args-시작 시 실행할 명령어와 인자. 예: ["node", "server.js"]
볼륨 마운트-PVC를 컨테이너 내부 경로에 마운트. name, mountPath, claimName 지정

배포 전략

새 버전 배포 시 Pod 교체 방식을 결정합니다.

전략설명추가 옵션
RollingUpdate (기본)점진적 교체. 무중단 배포에 적합maxSurge (기본 1), maxUnavailable (기본 0)
Recreate모든 Pod를 종료한 후 새로 생성. 다운타임 발생 가능-

리소스 (선택)

Pod에 할당할 CPU와 메모리를 설정합니다.

구분설명예시
requests최소 보장량. 스케줄링 기준이 됨cpu: 100m, memory: 128Mi
limits최대 상한. 초과 시 제한됨cpu: 500m, memory: 512Mi

헬스체크 (선택)

Pod 상태를 확인하는 프로브를 설정합니다.

프로브역할실패 시 동작
Liveness ProbePod가 살아있는지 확인Pod 재시작
Readiness Probe트래픽을 받을 준비가 되었는지 확인트래픽 차단

각 프로브에서 설정하는 항목:

옵션설명
path헬스체크 요청 경로. 예: /health
port헬스체크 요청 포트
initialDelaySecondsPod 시작 후 첫 검사까지 대기 시간(초)
periodSeconds검사 주기(초)
timeoutSeconds응답 대기 시간(초)
failureThreshold연속 실패 허용 횟수

Service

Pod에 접근하기 위한 네트워크 엔드포인트를 정의합니다.

왜 Service가 필요한가요?

Pod는 재시작될 때마다 IP가 바뀝니다. Service는 고정된 주소를 제공하여 다른 Pod나 외부에서 안정적으로 접근할 수 있게 합니다.

기본 옵션

옵션필수기본값설명
이름-Service 리소스 이름. 예: my-app-svc
네임스페이스default배포 대상 네임스페이스
Selector-트래픽을 전달할 Pod의 레이블. Deployment 레이블과 일치해야 함

타입

네트워크 노출 방식에 따라 선택합니다.

타입설명사용 시나리오
ClusterIP (기본)클러스터 내부에서만 접근 가능Ingress와 함께 사용
NodePort노드의 특정 포트를 통해 외부 접근외부 리버스 프록시(Nginx 등)와 사용
LoadBalancer외부 IP를 할당받아 직접 노출클라우드 환경에서 주로 사용

포트 (1개 이상)

옵션필수기본값설명
name-포트 식별자. 예: http
protocolTCP프로토콜
port-Service가 수신하는 포트
targetPort-트래픽을 전달할 컨테이너 포트
nodePort-NodePort 타입일 때 노드에서 열리는 포트

Ingress

외부 트래픽을 클러스터 내부 Service로 라우팅하는 규칙을 정의합니다.

왜 Ingress가 필요한가요?

Service만으로는 도메인 기반 라우팅이나 HTTPS 처리가 어렵습니다. Ingress는 app.example.com 같은 도메인으로 들어오는 요청을 경로별로 적절한 Service에 전달하고, TLS 인증서도 관리합니다.

기본 옵션

옵션필수기본값설명
이름-Ingress 리소스 이름. 예: my-app-ingress
네임스페이스default배포 대상 네임스페이스
Annotations-Ingress Controller의 세부 동작을 제어하는 key-value 쌍

Ingress Class

사용할 Ingress Controller를 선택합니다.

Ingress Class설명
traefik (기본 권장)자동 인증서, 미들웨어 체인 지원
nginx커뮤니티 프로젝트. 2026년 3월 EOL 예정으로 마이그레이션 권장
haproxy고성능 로드밸런싱. 엔터프라이즈 환경에 적합
kongAPI Gateway 통합, 플러그인 확장 지원
contourEnvoy 프록시 기반 CNCF 프로젝트
albAWS Application Load Balancer. AWS 클라우드 환경 전용

Rules (1개 이상)

도메인별 라우팅 규칙을 정의합니다.

옵션설명
host도메인명. 예: app.example.com
paths경로별 라우팅 설정. path, pathType(Prefix), serviceName, servicePort 지정

TLS (선택)

HTTPS를 활성화합니다. hosts(도메인 목록)와 secretName(인증서 Secret)을 지정합니다.


ConfigMap

애플리케이션의 설정값을 key-value 형태로 저장하는 리소스입니다.

왜 ConfigMap을 사용하나요?

환경 변수를 Deployment에 직접 입력하면 값이 YAML에 그대로 노출됩니다. ConfigMap으로 분리하면 환경별로 설정만 교체할 수 있고, 여러 Deployment에서 동일한 설정을 공유할 수 있습니다. 비밀번호나 API 키 같은 민감 정보는 ConfigMap 대신 Secret을 사용하세요.

옵션필수기본값설명
이름-ConfigMap 리소스 이름. 예: app-config
네임스페이스default배포 대상 네임스페이스
데이터-key-value 쌍. 예: DATABASE_HOST: postgres, LOG_LEVEL: info
레이블-key-value 쌍

PersistentVolumeClaim (PVC)

Pod에서 사용할 영구 스토리지를 요청하는 리소스입니다. Pod가 재시작되거나 삭제되어도 데이터가 유지됩니다.

왜 PVC가 필요한가요?

Pod의 파일 시스템은 일시적입니다. Pod가 재시작되면 내부 데이터가 사라집니다. 데이터베이스나 업로드 파일처럼 영구 보존이 필요한 데이터는 PVC로 외부 스토리지에 저장해야 합니다.

옵션필수기본값설명
이름-PVC 리소스 이름. 예: app-data-pvc
네임스페이스default배포 대상 네임스페이스
스토리지 용량10Gi요청할 디스크 크기
스토리지 클래스nfs-client사용할 스토리지 프로비저너

스토리지 클래스 선택

nfs-client, local-path, longhorn, ceph-rbd, default 등을 선택할 수 있습니다.

접근 모드

모드설명사용 시나리오
ReadWriteOnce (기본)단일 노드에서 읽기/쓰기대부분의 경우 적합
ReadWriteMany다중 노드에서 동시 읽기/쓰기NFS 등 공유 스토리지 필요
ReadOnlyMany다중 노드에서 읽기 전용설정 파일 공유 등
PVC 삭제 주의

PVC를 삭제하면 연결된 데이터가 영구적으로 손실될 수 있습니다. 삭제 전 반드시 백업 여부를 확인하세요.


Job

일회성 또는 배치 작업을 실행하는 리소스입니다. 작업이 완료되면 Pod가 종료됩니다.

언제 Job을 사용하나요?

DB 마이그레이션, 초기 데이터 삽입, 일회성 스크립트 실행 등 한 번 실행하고 끝나는 작업에 사용합니다. Deployment와 달리 작업 완료 후 Pod가 자동 종료됩니다.

기본 옵션

옵션필수기본값설명
이름-Job 리소스 이름. 예: db-migrate-job
네임스페이스default배포 대상 네임스페이스
이미지-Job에서 실행할 컨테이너 이미지
커맨드 / Args-실행할 명령어와 인자. 예: ["python"], ["manage.py", "migrate"]
환경 변수-key-value 형태로 직접 입력
backoffLimit3실패 시 재시도 횟수. 초과 시 Job 실패로 처리

Job 유형

유형설명
DB 마이그레이션데이터베이스 스키마 변경 시 사용
초기화 작업최초 데이터 세팅, 시드 데이터 삽입 등
커스텀사용자 정의 일회성 작업

envFrom (선택)

ConfigMap 또는 Secret 전체를 환경 변수로 주입합니다.

참조 방식설명
configMapRefConfigMap의 모든 키를 환경 변수로 로드
secretRefSecret의 모든 키를 환경 변수로 로드

restartPolicy

정책설명
OnFailure (기본)실패 시 동일 Pod 내에서 컨테이너를 재시작
Never실패해도 재시작하지 않고 새 Pod를 생성

Part 2: YAML 생성 예시

예시 1: 기본 웹 서비스 (Frontend + Backend + Database)

React 프론트엔드 + Node.js API 백엔드 + PostgreSQL 데이터베이스로 구성된 일반적인 웹 서비스입니다.

서비스 구성도

사용자 → Ingress (app.example.com)
├─ / → frontend-svc(:80) → frontend Pod (React/Nginx)
└─ /api → backend-svc(:3000) → backend Pod (Node.js)

postgres-svc(:5432) → postgres Pod

생성되는 리소스

  • Deployment 3개 (frontend, backend, postgres)
  • Service 3개 (frontend-svc, backend-svc, postgres-svc)
  • Ingress 1개 (app-ingress)

파일 구성

k8s/
├── deployment.yaml ← frontend + backend + postgres Deployment
├── service.yaml ← frontend-svc + backend-svc + postgres-svc
└── ingress.yaml ← app-ingress

YAML 생성 시 Kind별로 파일이 분리됩니다. 같은 Kind의 리소스가 여러 개이면 하나의 파일에 --- 구분자로 합쳐집니다.

Frontend — Deployment & Service

KIWI 설정 요약:

옵션
이름frontend
네임스페이스my-web-app
레플리카2
이미지harbor.example.com/my-project/frontend:v1.0
포트80
전략RollingUpdate (maxSurge: 1, maxUnavailable: 0)
리소스requests: 100m/128Mi, limits: 300m/256Mi
Service 타입ClusterIP
  • 빌드된 React 앱을 Nginx로 서빙하므로 포트 80을 사용합니다.
  • 프론트엔드는 정적 파일 서빙이므로 리소스를 작게 설정합니다.
생성되는 YAML 확인
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: my-web-app
labels:
app: frontend
spec:
replicas: 2
selector:
matchLabels:
app: frontend
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: harbor.example.com/my-project/frontend:v1.0
ports:
- containerPort: 80
imagePullPolicy: Always
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 300m
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: frontend-svc
namespace: my-web-app
spec:
type: ClusterIP
selector:
app: frontend
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80

Backend — Deployment & Service

KIWI 설정 요약:

옵션
이름backend
네임스페이스my-web-app
레플리카2
이미지harbor.example.com/my-project/backend:v1.0
포트3000
전략RollingUpdate (maxSurge: 1, maxUnavailable: 0)
환경 변수DATABASE_HOST, DATABASE_PORT, DATABASE_NAME + Secret 참조
리소스requests: 200m/256Mi, limits: 500m/512Mi
헬스체크Liveness + Readiness (/health:3000)
Service 타입ClusterIP
  • DATABASE_HOST에 postgres Service 이름을 사용합니다. 같은 네임스페이스 내에서 DNS로 자동 해석됩니다.
  • 비밀번호는 secretKeyRef를 통해 Secret에서 가져옵니다. YAML에 직접 노출하지 않습니다.
  • 헬스체크를 설정하여 비정상 Pod를 자동으로 감지합니다.
생성되는 YAML 확인
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: my-web-app
labels:
app: backend
spec:
replicas: 2
selector:
matchLabels:
app: backend
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: harbor.example.com/my-project/backend:v1.0
ports:
- containerPort: 3000
imagePullPolicy: Always
env:
- name: DATABASE_HOST
value: postgres-svc
- name: DATABASE_PORT
value: "5432"
- name: DATABASE_NAME
value: myapp
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: backend-svc
namespace: my-web-app
spec:
type: ClusterIP
selector:
app: backend
ports:
- name: http
protocol: TCP
port: 3000
targetPort: 3000

Database — Deployment & Service

KIWI 설정 요약:

옵션
이름postgres
네임스페이스my-web-app
레플리카1
이미지postgres:15
포트5432
전략Recreate
imagePullPolicyIfNotPresent
환경 변수POSTGRES_DB + Secret 참조
Service 타입ClusterIP
  • 데이터베이스는 replicas 1로 설정합니다. 데이터 정합성을 위해 단일 인스턴스로 운영합니다.
  • 전략을 Recreate로 설정합니다. 데이터베이스는 동시에 여러 Pod가 같은 볼륨에 접근하면 문제가 발생할 수 있습니다.
  • 외부 노출이 불필요하므로 ClusterIP를 사용합니다.
생성되는 YAML 확인
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: my-web-app
labels:
app: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
strategy:
type: Recreate
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15
ports:
- containerPort: 5432
imagePullPolicy: IfNotPresent
env:
- name: POSTGRES_DB
value: myapp
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
---
apiVersion: v1
kind: Service
metadata:
name: postgres-svc
namespace: my-web-app
spec:
type: ClusterIP
selector:
app: postgres
ports:
- name: tcp
protocol: TCP
port: 5432
targetPort: 5432

Ingress

KIWI 설정 요약:

옵션
이름app-ingress
네임스페이스my-web-app
Ingress Classtraefik
호스트app.example.com
TLSapp-tls-secret
라우팅/api → backend-svc:3000, / → frontend-svc:80
  • /api 경로를 /보다 먼저 정의합니다. Ingress는 순서대로 매칭하므로, /api 요청이 프론트엔드로 가지 않도록 합니다.
  • TLS를 설정하여 HTTPS를 활성화합니다.
생성되는 YAML 확인
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
namespace: my-web-app
spec:
ingressClassName: traefik
tls:
- secretName: app-tls-secret
hosts:
- app.example.com
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: backend-svc
port:
number: 3000
- path: /
pathType: Prefix
backend:
service:
name: frontend-svc
port:
number: 80

예시 2: 고급 프로젝트 (Volume + Job + ConfigMap)

Spring Boot API + PostgreSQL로 구성된 프로젝트에 ConfigMap으로 설정 분리, PVC로 데이터 영구 저장, Job으로 DB 마이그레이션을 추가한 예시입니다.

서비스 구성도

[ConfigMap: app-config]           ← 환경 설정 (DB 접속 정보, 로그 레벨 등)

├── envFrom ──→ [Job: db-migrate] ← 마이그레이션 실행 후 종료

└── envFrom ──→ [Deployment: api-server]

└──→ [Service: api-svc] → [Ingress: api-ingress]

[PVC: postgres-data] ← 10Gi 영구 스토리지

└── mount ──→ [Deployment: postgres]

└──→ [Service: postgres-svc]

생성되는 리소스

  • ConfigMap 1개 (app-config)
  • PVC 1개 (postgres-data)
  • Job 1개 (db-migrate)
  • Deployment 2개 (api-server, postgres)
  • Service 2개 (api-svc, postgres-svc)
  • Ingress 1개 (api-ingress)

파일 구성

k8s/
├── configmap.yaml ← app-config
├── pvc.yaml ← postgres-data
├── job.yaml ← db-migrate
├── deployment.yaml ← api-server + postgres Deployment
├── service.yaml ← api-svc + postgres-svc
└── ingress.yaml ← api-ingress

ConfigMap

KIWI 설정 요약:

옵션
이름app-config
네임스페이스my-api-project
데이터DATABASE_HOST, DATABASE_PORT, DATABASE_NAME, LOG_LEVEL, SERVER_PORT, SPRING_PROFILES_ACTIVE
  • DB 접속 정보, 로그 레벨, 서버 설정 등을 한곳에서 관리합니다.
  • Deployment와 Job이 동일한 ConfigMap을 참조하므로 설정 불일치를 방지합니다.
생성되는 YAML 확인
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: my-api-project
labels:
app: app-config
data:
DATABASE_HOST: postgres-svc
DATABASE_PORT: "5432"
DATABASE_NAME: myapi
LOG_LEVEL: info
SERVER_PORT: "8080"
SPRING_PROFILES_ACTIVE: production

PersistentVolumeClaim

KIWI 설정 요약:

옵션
이름postgres-data
네임스페이스my-api-project
용량10Gi
스토리지 클래스nfs-client
접근 모드ReadWriteOnce
  • ReadWriteOnce로 설정합니다. 데이터베이스는 단일 노드에서만 접근하면 됩니다.
  • nfs-client를 사용하면 NFS 서버에 데이터가 저장되어 노드 장애에도 데이터가 유지됩니다.
생성되는 YAML 확인
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
namespace: my-api-project
labels:
app: postgres-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: nfs-client
resources:
requests:
storage: 10Gi

Job — DB 마이그레이션

KIWI 설정 요약:

옵션
이름db-migrate
네임스페이스my-api-project
이미지harbor.example.com/my-project/api-server:v1.0
커맨드java -jar app.jar --spring.flyway.enabled=true --spring.main.web-application-type=none
envFromapp-config (ConfigMap) + db-credentials (Secret)
backoffLimit3
restartPolicyOnFailure
  • 애플리케이션과 동일한 이미지를 사용하되, Flyway 마이그레이션만 실행하고 웹 서버는 시작하지 않습니다.
  • envFrom으로 ConfigMap과 Secret 전체를 환경 변수로 주입합니다. 개별 키를 하나씩 매핑할 필요가 없습니다.
  • backoffLimit: 3으로 설정하여 DB 연결 실패 등 일시적 오류에 대비합니다.
Job 실행 순서

Job은 Deployment와 동시에 생성됩니다. 마이그레이션이 완료되기 전에 애플리케이션이 시작될 수 있으므로, 애플리케이션에서 DB 연결 재시도 로직이 필요합니다. 또는 initContainers를 활용하여 마이그레이션 완료를 대기하도록 구성할 수 있습니다.

생성되는 YAML 확인
apiVersion: batch/v1
kind: Job
metadata:
name: db-migrate
namespace: my-api-project
labels:
app.kubernetes.io/part-of: db-migrate
app.kubernetes.io/component: db-migrate
spec:
backoffLimit: 3
template:
spec:
restartPolicy: OnFailure
containers:
- name: db-migrate
image: harbor.example.com/my-project/api-server:v1.0
command:
- java
args:
- -jar
- app.jar
- --spring.flyway.enabled=true
- --spring.main.web-application-type=none
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: db-credentials

API Server — Deployment & Service

KIWI 설정 요약:

옵션
이름api-server
네임스페이스my-api-project
레플리카3
이미지harbor.example.com/my-project/api-server:v1.0
포트8080
전략RollingUpdate (maxSurge: 1, maxUnavailable: 0)
envFromapp-config (ConfigMap) + db-credentials (Secret)
리소스requests: 300m/512Mi, limits: 1/1Gi
헬스체크Liveness + Readiness (/actuator/health:8080)
Service 타입ClusterIP
  • envFrom으로 ConfigMap과 Secret을 통째로 주입합니다. Job과 동일한 설정을 공유합니다.
  • Spring Boot의 Actuator 헬스체크 엔드포인트(/actuator/health)를 사용합니다.
  • JVM 기반 애플리케이션은 시작이 느리므로 initialDelaySeconds를 넉넉하게 설정합니다.
생성되는 YAML 확인
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
namespace: my-api-project
labels:
app: api-server
spec:
replicas: 3
selector:
matchLabels:
app: api-server
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api-server
image: harbor.example.com/my-project/api-server:v1.0
ports:
- containerPort: 8080
imagePullPolicy: Always
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: db-credentials
resources:
requests:
cpu: 300m
memory: 512Mi
limits:
cpu: "1"
memory: 1Gi
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: api-svc
namespace: my-api-project
spec:
type: ClusterIP
selector:
app: api-server
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 8080

Database — Deployment & Service (PVC 연결)

KIWI 설정 요약:

옵션
이름postgres
네임스페이스my-api-project
레플리카1
이미지postgres:15
포트5432
전략Recreate
환경 변수POSTGRES_DB, PGDATA + Secret 참조
볼륨 마운트postgres-data PVC → /var/lib/postgresql/data
Service 타입ClusterIP
  • volumeMountsvolumes로 PVC를 연결합니다. Pod가 재시작되어도 /var/lib/postgresql/data의 데이터가 유지됩니다.
  • PGDATA 환경 변수로 데이터 디렉토리를 하위 폴더(pgdata)로 지정합니다. NFS 마운트 시 루트 디렉토리에 숨김 파일이 있으면 PostgreSQL 초기화가 실패할 수 있기 때문입니다.
생성되는 YAML 확인
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: my-api-project
labels:
app: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
strategy:
type: Recreate
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15
ports:
- containerPort: 5432
imagePullPolicy: IfNotPresent
env:
- name: POSTGRES_DB
value: myapi
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-data
---
apiVersion: v1
kind: Service
metadata:
name: postgres-svc
namespace: my-api-project
spec:
type: ClusterIP
selector:
app: postgres
ports:
- name: tcp
protocol: TCP
port: 5432
targetPort: 5432

Ingress

KIWI 설정 요약:

옵션
이름api-ingress
네임스페이스my-api-project
Ingress Classtraefik
호스트api.example.com
TLSapi-tls-secret
라우팅/ → api-svc:8080
생성되는 YAML 확인
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
namespace: my-api-project
spec:
ingressClassName: traefik
tls:
- secretName: api-tls-secret
hosts:
- api.example.com
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 8080

관련 가이드