쿠버네티스(Kubernetes)는 현대 DevOps 환경에서 가장 중요한 컨테이너 오케스트레이션 플랫폼입니다.
구글에서 개발된 이 오픈소스 시스템은 컨테이너화된 애플리케이션의 배포, 확장, 관리를 자동화하여 개발팀과 운영팀의 생산성을 혁신적으로 향상시켰습니다.
이 가이드에서는 쿠버네티스 초보자부터 중급자까지 단계별로 학습할 수 있는 실무 중심의 내용을 다룹니다.
쿠버네티스란 무엇인가?
쿠버네티스는 컨테이너 오케스트레이션 플랫폼으로, 여러 서버에 분산된 컨테이너들을 효율적으로 관리하는 시스템입니다.
Docker 컨테이너를 대규모로 운영할 때 발생하는 복잡성을 해결하기 위해 설계되었으며, 자동 스케일링, 로드 밸런싱, 서비스 디스커버리, 롤링 업데이트 등의 기능을 제공합니다.
쿠버네티스의 핵심 특징
자동화된 컨테이너 배포 및 스케줄링
쿠버네티스는 사용자가 정의한 리소스 요구사항과 제약 조건을 기반으로 컨테이너를 최적의 노드에 자동으로 배치합니다.
CPU, 메모리, 스토리지 등의 리소스를 효율적으로 활용하여 시스템 전체의 성능을 최적화합니다.
선언적 구성 관리
YAML이나 JSON 형식의 매니페스트 파일을 통해 원하는 상태를 선언하면, 쿠버네티스가 현재 상태를 목표 상태로 수렴시킵니다.
이러한 선언적 접근 방식은 인프라스트럭처 코드화(Infrastructure as Code)의 핵심 원칙을 실현합니다.
쿠버네티스 아키텍처 이해하기
쿠버네티스 클러스터는 마스터 노드와 워커 노드로 구성되며, 각각 고유한 역할과 컴포넌트를 가지고 있습니다.
마스터 노드 컴포넌트
API 서버 (kube-apiserver)
모든 쿠버네티스 API 요청을 처리하는 중앙 관리 컴포넌트입니다.
kubectl 명령어, 대시보드, 그리고 다른 쿠버네티스 컴포넌트들이 API 서버를 통해 클러스터와 상호작용합니다.
etcd
쿠버네티스 클러스터의 모든 구성 데이터와 상태 정보를 저장하는 분산 키-값 저장소입니다.
클러스터의 두뇌 역할을 하며, 고가용성과 일관성을 보장합니다.
컨트롤러 매니저 (kube-controller-manager)
다양한 컨트롤러들을 실행하여 클러스터의 상태를 지속적으로 모니터링하고 원하는 상태로 유지합니다.
레플리케이션 컨트롤러, 엔드포인트 컨트롤러, 네임스페이스 컨트롤러 등이 포함됩니다.
스케줄러 (kube-scheduler)
새로 생성된 파드를 적절한 워커 노드에 할당하는 역할을 담당합니다.
리소스 요구사항, 정책 제약, 친화성 규칙 등을 고려하여 최적의 배치 결정을 내립니다.
워커 노드 컴포넌트
kubelet
각 워커 노드에서 실행되는 에이전트로, 파드의 생명주기를 관리합니다.
API 서버로부터 파드 스펙을 받아 컨테이너 런타임과 협력하여 컨테이너를 실행하고 상태를 보고합니다.
kube-proxy
클러스터 내 네트워킹을 담당하며, 서비스 디스커버리와 로드 밸런싱을 구현합니다.
iptables나 IPVS를 이용하여 트래픽을 적절한 파드로 라우팅합니다.
컨테이너 런타임
실제 컨테이너를 실행하는 소프트웨어입니다.
Docker, containerd, CRI-O 등이 지원되며, 컨테이너 런타임 인터페이스(CRI)를 통해 kubelet과 통신합니다.
쿠버네티스 핵심 오브젝트 완벽 가이드
쿠버네티스에서 애플리케이션을 배포하고 관리하기 위해서는 다양한 오브젝트들을 이해해야 합니다.
각 오브젝트는 특정한 목적과 기능을 가지고 있으며, 이들을 조합하여 복잡한 애플리케이션 아키텍처를 구성할 수 있습니다.
파드(Pod) - 쿠버네티스의 기본 단위
파드는 쿠버네티스에서 배포 가능한 가장 작은 단위로, 하나 이상의 컨테이너를 포함합니다.
같은 파드 내의 컨테이너들은 네트워크와 스토리지를 공유하며, 항상 동일한 노드에 스케줄링됩니다.
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
위 예제는 nginx 컨테이너를 실행하는 간단한 파드 정의입니다.
리소스 요청량과 제한량을 명시하여 클러스터 리소스를 효율적으로 관리할 수 있습니다.
디플로이먼트(Deployment) - 애플리케이션 배포 관리
디플로이먼트는 파드의 선언적 업데이트를 제공하며, 레플리카 수, 롤링 업데이트 전략 등을 정의할 수 있습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
이 디플로이먼트는 nginx 파드 3개를 유지하며, 롤링 업데이트 시 최대 1개의 파드가 사용 불가능하고 최대 1개의 추가 파드를 생성할 수 있도록 설정합니다.
서비스(Service) - 네트워크 추상화
서비스는 파드 집합에 대한 안정적인 네트워크 엔드포인트를 제공합니다.
파드는 언제든지 재생성될 수 있지만, 서비스를 통해 일관된 접근 방법을 유지할 수 있습니다.
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
ClusterIP 타입의 서비스는 클러스터 내부에서만 접근 가능한 가상 IP를 제공합니다.
외부 접근이 필요한 경우 LoadBalancer나 NodePort 타입을 사용할 수 있습니다.
쿠버네티스 설치 및 환경 구성
쿠버네티스를 학습하고 실습하기 위해서는 적절한 환경을 구성해야 합니다.
개발 환경부터 프로덕션 환경까지 다양한 설치 옵션이 있으며, 각각의 장단점을 이해하고 상황에 맞는 선택을 해야 합니다.
로컬 개발 환경 구성
Minikube를 이용한 단일 노드 클러스터
Minikube는 로컬 환경에서 쿠버네티스를 학습하기에 가장 적합한 도구입니다.
VirtualBox, VMware, Docker 등 다양한 드라이버를 지원하며, 간단한 명령어로 클러스터를 시작할 수 있습니다.
# Minikube 설치 (macOS 기준)
brew install minikube
# 클러스터 시작
minikube start --driver=docker --cpus=2 --memory=4096
# 대시보드 실행
minikube dashboard
# 클러스터 상태 확인
kubectl cluster-info
Docker Desktop의 쿠버네티스 기능
Docker Desktop을 사용하는 경우 설정에서 쿠버네티스를 활성화하면 별도 설치 없이 사용할 수 있습니다.
Windows와 macOS에서 GUI를 통해 쉽게 관리할 수 있어 초보자에게 추천됩니다.
Kind (Kubernetes in Docker)
Kind는 Docker 컨테이너를 노드로 사용하여 쿠버네티스 클러스터를 생성하는 도구입니다.
멀티 노드 클러스터 구성이 가능하며, CI/CD 파이프라인에서도 자주 사용됩니다.
# Kind 설치
go install sigs.k8s.io/kind@latest
# 멀티 노드 클러스터 생성
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
kubectl 설치 및 설정
kubectl은 쿠버네티스 클러스터와 상호작용하기 위한 명령줄 도구입니다.
모든 쿠버네티스 운영 작업은 kubectl을 통해 수행되므로, 설치와 기본 사용법을 숙지해야 합니다.
# kubectl 설치 (Linux 기준)
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
# 버전 확인
kubectl version --client
# 클러스터 연결 확인
kubectl cluster-info
# 현재 컨텍스트 확인
kubectl config current-context
# 사용 가능한 컨텍스트 목록
kubectl config get-contexts
쿠버네티스 실습 예제 - 웹 애플리케이션 배포
실제 웹 애플리케이션을 쿠버네티스에 배포하는 전체 과정을 단계별로 살펴보겠습니다.
이 예제를 통해 쿠버네티스의 핵심 개념들이 실제로 어떻게 작동하는지 이해할 수 있습니다.
1단계: 애플리케이션 컨테이너화
먼저 간단한 Node.js 애플리케이션을 생성하고 Docker 이미지로 빌드합니다.
// app.js
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.json({
message: 'Hello Kubernetes!',
timestamp: new Date().toISOString(),
hostname: process.env.HOSTNAME
});
});
app.get('/health', (req, res) => {
res.status(200).json({ status: 'OK' });
});
app.listen(port, () => {
console.log(`App running on port ${port}`);
});
# Dockerfile
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
# Docker 이미지 빌드
docker build -t my-k8s-app:v1.0 .
# 로컬 레지스트리에 푸시 (실습용)
docker tag my-k8s-app:v1.0 localhost:5000/my-k8s-app:v1.0
docker push localhost:5000/my-k8s-app:v1.0
2단계: 쿠버네티스 매니페스트 작성
애플리케이션을 쿠버네티스에 배포하기 위한 YAML 파일들을 작성합니다.
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-k8s-app
labels:
app: my-k8s-app
spec:
replicas: 3
selector:
matchLabels:
app: my-k8s-app
template:
metadata:
labels:
app: my-k8s-app
spec:
containers:
- name: app
image: localhost:5000/my-k8s-app:v1.0
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
---
apiVersion: v1
kind: Service
metadata:
name: my-k8s-app-service
spec:
selector:
app: my-k8s-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer
3단계: 애플리케이션 배포 및 확인
작성한 매니페스트 파일을 사용하여 애플리케이션을 배포합니다.
# 애플리케이션 배포
kubectl apply -f deployment.yaml
# 배포 상태 확인
kubectl get deployments
kubectl get pods
kubectl get services
# 파드 로그 확인
kubectl logs -l app=my-k8s-app
# 서비스 포트 포워딩으로 접근 테스트
kubectl port-forward service/my-k8s-app-service 8080:80
# 다른 터미널에서 테스트
curl http://localhost:8080
4단계: 스케일링 및 업데이트
쿠버네티스의 핵심 기능인 스케일링과 롤링 업데이트를 실습해봅니다.
# 수평 확장
kubectl scale deployment my-k8s-app --replicas=5
# 스케일링 확인
kubectl get pods -w
# 이미지 업데이트
kubectl set image deployment/my-k8s-app app=localhost:5000/my-k8s-app:v1.1
# 롤아웃 상태 확인
kubectl rollout status deployment/my-k8s-app
# 롤아웃 히스토리 확인
kubectl rollout history deployment/my-k8s-app
# 이전 버전으로 롤백
kubectl rollout undo deployment/my-k8s-app
쿠버네티스 네트워킹 심화 이해
쿠버네티스의 네트워킹은 복잡하지만 매우 강력한 기능을 제공합니다.
클러스터 내 통신부터 외부 노출까지 다양한 네트워킹 개념을 이해해야 효과적으로 애플리케이션을 운영할 수 있습니다.
클러스터 네트워킹 모델
파드 네트워킹
모든 파드는 고유한 IP 주소를 가지며, NAT 없이 직접 통신할 수 있습니다.
같은 파드 내의 컨테이너는 localhost를 통해 통신하며, 포트만으로 구분됩니다.
서비스 네트워킹
서비스는 파드 집합에 대한 안정적인 네트워크 인터페이스를 제공합니다.
클러스터 DNS를 통해 서비스 이름으로 접근할 수 있으며, 자동으로 로드 밸런싱이 수행됩니다.
인그레스(Ingress) - HTTP/HTTPS 라우팅
인그레스는 클러스터 외부에서 내부 서비스로의 HTTP/HTTPS 라우팅을 관리합니다.
도메인 기반 라우팅, SSL 터미네이션, 로드 밸런싱 등의 기능을 제공합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-k8s-app-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
네트워크 정책(Network Policy)
네트워크 정책을 통해 파드 간 통신을 제어하고 보안을 강화할 수 있습니다.
마이크로서비스 아키텍처에서 서비스 간 통신을 세밀하게 제어하는 데 필수적입니다.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
쿠버네티스 스토리지 관리
상태를 가진 애플리케이션을 쿠버네티스에서 운영하기 위해서는 영구 스토리지에 대한 이해가 필요합니다.
볼륨, 영구 볼륨, 스토리지 클래스 등의 개념을 통해 데이터의 지속성을 보장할 수 있습니다.
볼륨(Volume) 타입별 활용법
emptyDir 볼륨
파드 내 컨테이너 간 임시 데이터 공유에 사용됩니다.
파드가 삭제되면 데이터도 함께 사라지므로 캐시나 임시 파일 저장에 적합합니다.
hostPath 볼륨
노드의 파일시스템을 직접 마운트하여 사용합니다.
로그 수집이나 시스템 모니터링 도구에서 주로 사용되지만, 포터빌리티가 떨어지는 단점이 있습니다.
persistentVolume과 persistentVolumeClaim
영구 스토리지를 추상화하여 관리하는 쿠버네티스의 핵심 스토리지 개념입니다.
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: fast-ssd
hostPath:
path: /mnt/data/mysql
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: fast-ssd
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc
스토리지 클래스와 동적 프로비저닝
스토리지 클래스를 통해 다양한 스토리지 타입을 정의하고 자동으로 볼륨을 생성할 수 있습니다.
클라우드 환경에서는 각 제공업체의 스토리지 서비스와 연동하여 효율적인 스토리지 관리가 가능합니다.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
iops: "3000"
throughput: "125"
encrypted: "true"
allowVolumeExpansion: true
reclaimPolicy: Delete
쿠버네티스 보안 강화 방법
쿠버네티스 클러스터의 보안은 다층적 접근 방식을 통해 구현해야 합니다.
인증, 권한 부여, 네트워크 보안, 파드 보안 등 다양한 측면에서 보안을 강화해야 합니다.
RBAC (Role-Based Access Control)
RBAC를 통해 사용자와 서비스 계정의 권한을 세밀하게 제어할 수 있습니다.
최소 권한 원칙을 적용하여 보안을 강화하는 것이 중요합니다.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: development
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: development
subjects:
- kind: User
name: developer
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
파드 보안 표준(Pod Security Standards)
파드 보안 표준을 통해 컨테이너의 보안 설정을 강제할 수 있습니다.
Privileged, Baseline, Restricted 등의 보안 레벨을 정의하여 클러스터 전반의 보안을 향상시킵니다.
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: app
image: nginx:1.21
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
volumeMounts:
- name: tmp-volume
mountPath: /tmp
volumes:
- name: tmp-volume
emptyDir: {}
시크릿(Secret) 관리
민감한 정보는 시크릿 오브젝트를 통해 안전하게 관리해야 합니다.
데이터베이스 패스워드, API 키, TLS 인증서 등을 암호화하여 저장하고 파드에 주입할 수 있습니다.
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
database-password: cGFzc3dvcmQxMjM= # base64 encoded
api-key: YWJjZGVmZ2hpams=
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: secure-app
spec:
replicas: 1
selector:
matchLabels:
app: secure-app
template:
metadata:
labels:
app: secure-app
spec:
containers:
- name: app
image: my-secure-app:latest
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: database-password
- name: API_KEY
valueFrom:
secretKeyRef:
name: app-secrets
key: api-key
쿠버네티스 모니터링 및 로깅
운영 환경에서 쿠버네티스 클러스터를 안정적으로 관리하기 위해서는 종합적인 모니터링과 로깅 시스템이 필요합니다.
Prometheus, Grafana, ELK 스택 등을 활용하여 가시성을 확보하고 문제를 사전에 감지할 수 있습니다.
Prometheus와 Grafana를 이용한 메트릭 모니터링
Prometheus는 쿠버네티스 환경에서 가장 널리 사용되는 모니터링 솔루션입니다.
시계열 데이터베이스를 기반으로 하며, 강력한 쿼리 언어인 PromQL을 제공하여 복잡한 메트릭 분석이 가능합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
spec:
replicas: 1
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
containers:
- name: prometheus
image: prom/prometheus:v2.40.0
ports:
- containerPort: 9090
volumeMounts:
- name: config-volume
mountPath: /etc/prometheus
- name: storage-volume
mountPath: /prometheus
args:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
volumes:
- name: config-volume
configMap:
name: prometheus-config
- name: storage-volume
persistentVolumeClaim:
claimName: prometheus-pvc
ServiceMonitor를 통한 자동 서비스 디스커버리
Prometheus Operator를 사용하면 ServiceMonitor 리소스를 통해 자동으로 모니터링 대상을 발견하고 설정할 수 있습니다.
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: app-metrics
labels:
app: my-k8s-app
spec:
selector:
matchLabels:
app: my-k8s-app
endpoints:
- port: metrics
interval: 30s
path: /metrics
중앙화된 로깅 시스템 구축
Fluentd를 이용한 로그 수집
Fluentd는 DaemonSet으로 배포하여 모든 노드의 로그를 수집하고 중앙 저장소로 전송합니다.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
namespace: kube-system
spec:
selector:
matchLabels:
name: fluentd
template:
metadata:
labels:
name: fluentd
spec:
serviceAccount: fluentd
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1-debian-elasticsearch
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "elasticsearch.logging.svc.cluster.local"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
알림 및 경고 시스템
Alertmanager 설정
Prometheus와 연동하여 메트릭 기반 알림을 관리합니다.
Slack, 이메일, PagerDuty 등 다양한 채널로 알림을 전송할 수 있습니다.
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: kubernetes-alerts
spec:
groups:
- name: kubernetes.rules
rules:
- alert: PodCrashLooping
expr: rate(kube_pod_container_status_restarts_total[15m]) > 0
for: 5m
labels:
severity: warning
annotations:
summary: "Pod {{ $labels.pod }} is crash looping"
description: "Pod {{ $labels.pod }} in namespace {{ $labels.namespace }} is restarting frequently"
- alert: HighMemoryUsage
expr: (container_memory_usage_bytes / container_spec_memory_limit_bytes) > 0.9
for: 10m
labels:
severity: critical
annotations:
summary: "High memory usage detected"
description: "Container {{ $labels.container }} in pod {{ $labels.pod }} is using {{ $value | humanizePercentage }} of its memory limit"
쿠버네티스 CI/CD 파이프라인 구축
쿠버네티스와 CI/CD를 통합하면 애플리케이션의 지속적 배포와 운영이 가능합니다.
GitOps, Helm, ArgoCD 등의 도구를 활용하여 현대적인 배포 파이프라인을 구성할 수 있습니다.
GitOps 워크플로우 구현
ArgoCD를 이용한 선언적 배포
ArgoCD는 Git 저장소의 매니페스트를 기준으로 쿠버네티스 클러스터의 상태를 동기화합니다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-k8s-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/company/k8s-manifests
targetRevision: HEAD
path: production/my-app
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
revisionHistoryLimit: 10
Helm을 이용한 패키지 관리
Helm은 쿠버네티스의 패키지 매니저로, 복잡한 애플리케이션을 템플릿화하여 관리할 수 있습니다.
# values.yaml
replicaCount: 3
image:
repository: my-k8s-app
pullPolicy: IfNotPresent
tag: "1.0.0"
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: myapp.example.com
paths:
- path: /
pathType: ImplementationSpecific
tls:
- secretName: myapp-tls
hosts:
- myapp.example.com
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 80
Helm 차트 구조
my-app/
├── Chart.yaml
├── values.yaml
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── configmap.yaml
│ ├── secret.yaml
│ ├── hpa.yaml
│ └── _helpers.tpl
└── charts/
GitHub Actions을 이용한 자동화 파이프라인
# .github/workflows/deploy.yml
name: Build and Deploy to Kubernetes
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Log in to Container Registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha,prefix={{branch}}-
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Set up Kubectl
uses: azure/setup-kubectl@v3
with:
version: 'v1.28.0'
- name: Configure kubectl
run: |
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig
export KUBECONFIG=kubeconfig
- name: Deploy to Kubernetes
run: |
export KUBECONFIG=kubeconfig
helm upgrade --install my-app ./helm/my-app \
--set image.tag=${{ github.sha }} \
--set image.repository=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} \
--namespace production \
--create-namespace \
--wait
쿠버네티스 성능 최적화 및 트러블슈팅
운영 환경에서 쿠버네티스 클러스터의 성능을 최적화하고 문제를 해결하는 것은 매우 중요합니다.
리소스 관리, 스케줄링 최적화, 네트워크 튜닝 등 다양한 측면에서 성능을 개선할 수 있습니다.
리소스 관리 최적화
Horizontal Pod Autoscaler (HPA) 설정
CPU, 메모리, 커스텀 메트릭을 기반으로 파드를 자동으로 확장하거나 축소할 수 있습니다.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-k8s-app
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
- type: Pods
pods:
metric:
name: requests_per_second
target:
type: AverageValue
averageValue: "100"
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
Vertical Pod Autoscaler (VPA) 활용
VPA는 파드의 CPU와 메모리 요청량을 자동으로 조정하여 리소스 효율성을 높입니다.
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-app-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: my-k8s-app
updatePolicy:
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: app
maxAllowed:
cpu: 1
memory: 2Gi
minAllowed:
cpu: 100m
memory: 128Mi
controlledResources: ["cpu", "memory"]
일반적인 문제 해결 방법
파드 스케줄링 문제 해결
파드가 Pending 상태에 머물러 있을 때의 일반적인 원인과 해결 방법을 알아봅시다.
# 파드 상태 확인
kubectl get pods -o wide
# 파드 이벤트 확인
kubectl describe pod <pod-name>
# 노드 리소스 상태 확인
kubectl top nodes
kubectl describe nodes
# 리소스 부족 시 노드 추가 또는 파드 리소스 요청량 조정
# PVC 문제 시 스토리지 클래스 및 볼륨 상태 확인
kubectl get pv,pvc
kubectl describe pvc <pvc-name>
네트워크 연결 문제 디버깅
서비스 간 통신 문제를 해결하는 체계적인 접근 방법입니다.
# 서비스 및 엔드포인트 확인
kubectl get svc,endpoints
kubectl describe svc <service-name>
# DNS 해석 테스트
kubectl run debug --image=busybox -it --rm -- nslookup <service-name>
# 네트워크 정책 확인
kubectl get networkpolicies
kubectl describe networkpolicy <policy-name>
# 파드 간 연결 테스트
kubectl exec -it <source-pod> -- wget -qO- <target-service>:80
성능 모니터링 및 분석
클러스터 성능 메트릭 수집
# 노드 리소스 사용량 확인
kubectl top nodes
# 파드별 리소스 사용량 확인
kubectl top pods --all-namespaces
# 네임스페이스별 리소스 사용량
kubectl top pods -n <namespace>
# 컨테이너별 상세 메트릭 (metrics-server 필요)
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes" | jq .
애플리케이션 성능 최적화
# 효율적인 리소스 설정 예시
apiVersion: apps/v1
kind: Deployment
metadata:
name: optimized-app
spec:
replicas: 3
selector:
matchLabels:
app: optimized-app
template:
metadata:
labels:
app: optimized-app
spec:
containers:
- name: app
image: my-app:latest
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
env:
- name: JAVA_OPTS
value: "-Xmx128m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- optimized-app
topologyKey: kubernetes.io/hostname
쿠버네티스 마이그레이션 전략
기존 애플리케이션을 쿠버네티스로 마이그레이션하는 것은 신중한 계획과 단계적 접근이 필요합니다.
레거시 시스템부터 클라우드 네이티브 애플리케이션까지 다양한 시나리오에 대한 마이그레이션 전략을 살펴보겠습니다.
마이그레이션 계획 수립
현재 상태 평가 (Assessment)
기존 인프라스트럭처와 애플리케이션을 분석하여 마이그레이션 우선순위를 결정합니다.
종속성 매핑, 리소스 사용량 분석, 보안 요구사항 검토 등을 통해 체계적인 계획을 수립해야 합니다.
단계적 마이그레이션 접근법
1단계: Lift and Shift (재호스팅)
- 기존 애플리케이션을 최소한의 변경으로 컨테이너화
- 모놀리식 애플리케이션을 단일 컨테이너로 패키징
2단계: Re-platforming (재플랫폼화)
- 쿠버네티스 네이티브 기능 활용
- ConfigMap, Secret, Service 등 도입
3단계: Refactoring (리팩토링)
- 마이크로서비스 아키텍처로 분해
- 클라우드 네이티브 패턴 적용
데이터베이스 마이그레이션
StatefulSet을 이용한 상태 있는 애플리케이션 배포
데이터베이스와 같은 상태 있는 애플리케이션은 StatefulSet을 사용하여 안정적으로 운영할 수 있습니다.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: root-password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
- name: mysql-config
mountPath: /etc/mysql/conf.d
volumes:
- name: mysql-config
configMap:
name: mysql-config
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 100Gi
storageClassName: fast-ssd
마이크로서비스 분해 전략
도메인 주도 설계 (Domain-Driven Design) 적용
비즈니스 도메인을 기준으로 모놀리식 애플리케이션을 마이크로서비스로 분해합니다.
각 서비스는 독립적인 데이터베이스를 가지고, API를 통해 통신합니다.
# 사용자 서비스
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
labels:
app: user-service
version: v1
spec:
replicas: 3
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
version: v1
spec:
containers:
- name: user-service
image: user-service:v1.0
ports:
- containerPort: 8080
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: user-db-secret
key: url
- name: ORDER_SERVICE_URL
value: "http://order-service:8080"
---
# 주문 서비스
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
labels:
app: order-service
version: v1
spec:
replicas: 3
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
version: v1
spec:
containers:
- name: order-service
image: order-service:v1.0
ports:
- containerPort: 8080
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: order-db-secret
key: url
- name: PAYMENT_SERVICE_URL
value: "http://payment-service:8080"
쿠버네티스 고급 패턴 및 운영 전략
엔터프라이즈 환경에서 쿠버네티스를 안정적으로 운영하기 위한 고급 패턴과 전략을 다룹니다.
멀티 클러스터 관리, 재해 복구, 보안 강화 등 프로덕션 환경에서 필요한 실무 지식을 제공합니다.
멀티 클러스터 아키텍처
클러스터 페더레이션과 관리
여러 클러스터를 효율적으로 관리하기 위해 GitOps와 클러스터 API를 활용합니다.
# Cluster API를 이용한 클러스터 정의
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
name: production-cluster
namespace: default
spec:
clusterNetwork:
pods:
cidrBlocks: ["192.168.0.0/16"]
services:
cidrBlocks: ["10.128.0.0/12"]
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: AWSCluster
name: production-cluster
controlPlaneRef:
kind: KubeadmControlPlane
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
name: production-cluster-control-plane
재해 복구 및 백업 전략
Velero를 이용한 클러스터 백업
Velero는 쿠버네티스 클러스터의 리소스와 영구 볼륨을 백업하고 복원하는 도구입니다.
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: daily-backup
spec:
schedule: "0 2 * * *" # 매일 오전 2시
template:
includedNamespaces:
- production
- staging
excludedResources:
- events
- events.events.k8s.io
storageLocation: default
volumeSnapshotLocations:
- default
ttl: 720h0m0s # 30일 보관
보안 강화를 위한 고급 설정
Pod Security Policy 및 OPA Gatekeeper
Open Policy Agent (OPA) Gatekeeper를 사용하여 클러스터 전반의 보안 정책을 강제할 수 있습니다.
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredsecuritycontext
spec:
crd:
spec:
names:
kind: K8sRequiredSecurityContext
validation:
openAPIV3Schema:
type: object
properties:
runAsNonRoot:
type: boolean
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredsecuritycontext
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.securityContext.runAsNonRoot
msg := "Container must run as non-root user"
}
violation[{"msg": msg}] {
not input.review.object.spec.securityContext.runAsNonRoot
msg := "Pod must run as non-root user"
}
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredSecurityContext
metadata:
name: must-run-as-nonroot
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
excludedNamespaces: ["kube-system", "gatekeeper-system"]
parameters:
runAsNonRoot: true
쿠버네티스 학습 로드맵 및 인증
쿠버네티스 전문가가 되기 위한 체계적인 학습 경로와 실무에서 인정받는 인증 과정을 안내합니다.
단계별 학습 목표를 설정하고 지속적인 성장을 위한 가이드라인을 제시합니다.
단계별 학습 경로
초급 단계 (1-3개월)
- 컨테이너와 Docker 기초 이해
- 쿠버네티스 아키텍처 및 핵심 개념 학습
- kubectl 기본 명령어 숙달
- Pod, Service, Deployment 실습
중급 단계 (3-6개월)
- 고급 워크로드 관리 (StatefulSet, DaemonSet, Job)
- 네트워킹 및 스토리지 심화 학습
- RBAC 및 보안 설정
- Helm을 이용한 패키지 관리
고급 단계 (6-12개월)
- 클러스터 운영 및 모니터링
- CI/CD 파이프라인 구축
- 커스텀 리소스 및 오퍼레이터 개발
- 멀티 클러스터 관리
인증 프로그램
CKA (Certified Kubernetes Administrator)
클러스터 관리, 네트워킹, 스토리지, 보안 등 운영 측면에 중점을 둔 인증입니다.
CKAD (Certified Kubernetes Application Developer)
애플리케이션 개발자를 위한 인증으로, 애플리케이션 배포 및 관리에 집중합니다.
CKS (Certified Kubernetes Security Specialist)
쿠버네티스 보안 전문가를 위한 고급 인증으로, 클러스터 보안 강화에 특화되어 있습니다.
실습 환경 추천
온라인 실습 플랫폼
- Play with Kubernetes (labs.play-with-k8s.com)
- Katacoda 쿠버네티스 시나리오
- Kubernetes 공식 튜토리얼
로컬 개발 환경
- Docker Desktop + Kubernetes
- Minikube
- Kind (Kubernetes in Docker)
클라우드 기반 실습
- Google Kubernetes Engine (GKE) 무료 티어
- Amazon EKS
- Azure AKS
마치며: 쿠버네티스로 시작하는 클라우드 네이티브 여정
쿠버네티스는 단순한 컨테이너 오케스트레이션 도구를 넘어서 현대적인 애플리케이션 개발과 운영의 패러다임을 바꾸고 있습니다.
이 가이드에서 다룬 내용들은 쿠버네티스 여정의 시작점일 뿐이며, 지속적인 학습과 실습을 통해 전문성을 기를 수 있습니다.
성공적인 쿠버네티스 도입을 위한 핵심 원칙
점진적 접근 방식
한 번에 모든 것을 바꾸려 하지 말고, 작은 프로젝트부터 시작하여 경험을 쌓아가는 것이 중요합니다.
팀의 역량과 조직의 준비도를 고려하여 단계적으로 도입하세요.
자동화 우선 사고
수동 작업을 최소화하고, Infrastructure as Code와 GitOps를 통해 모든 것을 자동화하려 노력하세요.
이는 오류를 줄이고 운영 효율성을 크게 향상시킵니다.
보안을 처음부터 고려
Security by Design 원칙에 따라 처음부터 보안을 염두에 두고 설계하세요.
RBAC, 네트워크 정책, 파드 보안 표준 등을 적극 활용하여 방어 계층을 구축해야 합니다.
관찰 가능성 확보
로깅, 메트릭, 트레이싱을 통해 시스템의 상태를 지속적으로 모니터링하고 문제를 사전에 감지할 수 있는 체계를 구축하세요.
미래 전망과 발전 방향
쿠버네티스 생태계는 빠르게 발전하고 있으며, 새로운 기술과 패턴들이 지속적으로 등장하고 있습니다.
서비스 메시 (Service Mesh)
Istio, Linkerd와 같은 서비스 메시 기술이 마이크로서비스 간 통신을 더욱 안전하고 효율적으로 만들어 가고 있습니다.
서버리스 및 FaaS
Knative, OpenFaaS 등을 통해 쿠버네티스에서도 서버리스 컴퓨팅이 가능해지고 있습니다.
AI/ML 워크로드
Kubeflow, MLflow 등을 활용하여 쿠버네티스에서 머신러닝 파이프라인을 구축하는 사례가 증가하고 있습니다.
엣지 컴퓨팅
K3s, MicroK8s 등 경량화된 쿠버네티스 배포판을 통해 엣지 환경에서도 컨테이너 오케스트레이션이 확산되고 있습니다.
실무 적용을 위한 마지막 조언
쿠버네티스를 학습할 때는 이론과 실습의 균형을 맞추는 것이 중요합니다.
공식 문서를 정기적으로 확인하고, 커뮤니티의 베스트 프랙티스를 따라가며, 실제 프로젝트에 적용해보는 경험을 쌓아가세요.
또한 DevOps 문화와 함께 쿠버네티스를 도입해야 진정한 효과를 얻을 수 있음을 잊지 마세요.
기술적인 도구는 수단일 뿐이며, 팀워크와 협업, 지속적인 개선 문화가 성공의 핵심입니다.
쿠버네티스와 함께하는 클라우드 네이티브 여정이 여러분의 개발 및 운영 역량을 한 단계 더 발전시키는 계기가 되기를 바랍니다.
'DevOps' 카테고리의 다른 글
Argo CD를 활용한 GitOps 구현: 쿠버네티스 자동 배포의 완벽 가이드 (0) | 2025.05.28 |
---|---|
Helm과 Istio의 역할과 차이점: 쿠버네티스 환경에서의 필수 도구 완벽 가이드 (0) | 2025.05.28 |
서버리스 아키텍처로 비용 효율적인 서비스 구축하기: 완벽한 가이드 (0) | 2025.05.25 |
GitOps로 CI/CD 파이프라인 자동화하기: 현대적 DevOps 워크플로우 구축 가이드 (0) | 2025.05.25 |
Docker를 활용한 Spring Boot + Nginx 리버스 프록시 설정 완벽 가이드 (0) | 2025.05.24 |