Kubernetes 오브젝트
Kubernetes는 다양한 오브젝트를 사용하여 애플리케이션을 배포하고 관리합니다. 주요 오브젝트에는 Pod, Service, Deployment, ConfigMap, Secret, PersistentVolumeClaim(PVC) 등이 있습니다.
1. Pod
Pod는 Kubernetes에서 가장 작은 배포 단위로, 하나 이상의 컨테이너를 포함합니다.
2. Service
Service는 Pod에 대한 네트워크 접근을 추상화하여, 로드 밸런싱과 서비스 디스커버리를 제공합니다. 주요 타입에는 ClusterIP, NodePort, LoadBalancer가 있습니다.
ClusterIP
: 기본 서비스 타입으로, 클러스터 내부에서만 접근할 수 있는 가상의 IP 주소를 할당받습니다.NodePort
: 클러스터 외부에서 각 노드의 특정 포트를 통해 접근할 수 있습니다.LoadBalancer
: 클라우드 제공자의 로드 밸런서를 통해 외부에서 접근할 수 있습니다.
3. Deployment
Deployment는 Pod와 ReplicaSet을 관리하여, 애플리케이션의 배포와 업데이트를 간소화합니다.
4. ConfigMap
ConfigMap은 애플리케이션 설정을 외부에서 관리할 수 있도록 도와줍니다.
5. Secret
Secret은 민감한 정보를 안전하게 저장하고 전달하는 데 사용됩니다.
6. PersistentVolumeClaim (PVC)
PVC는 스토리지 리소스를 요청하는 오브젝트로, Pod가 데이터를 영구적으로 저장할 수 있도록 합니다.
Minikube를 사용한 로컬 예제
이 섹션에서는 Minikube를 사용하여 로컬 환경에서 Kubernetes 오브젝트를 실행하는 예시 코드를 제공합니다.
1. 환경 설정
먼저, Minikube를 시작합니다:
minikube start
Minikube 클러스터의 Docker 데몬을 사용하도록 환경 변수를 설정합니다:
eval $(minikube -p minikube docker-env)
2. Docker 이미지 빌드
프로젝트 디렉토리에서 Docker 이미지를 빌드합니다:
docker build -t my-nestjs-image:latest .
3. 예시 코드
Dockerfile
## [1. Build Stage]
# Use an official Node.js runtime as a parent image
FROM node:20.9.0 AS builder
# Set the working directory
WORKDIR /app
# Bundle app source
COPY package*.json ./
COPY yarn.lock ./
# Install Node.js dependencies
RUN yarn install
# Copy all files from the current directory to the working directory (/app)
COPY . .
# Build application
RUN yarn build
## [2. Runtime Stage]
# Use an official Node.js as runtime image
FROM node:20.9.0
# Set the working directory
WORKDIR /app
# Copy the application build from the previous stage
COPY --from=builder /app .
# Expose application's port
EXPOSE ${PORT}
# Start application
CMD yarn start:prod
app-env-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-env-configmap
data:
NODE_ENV: "local" # .env 파일의 내용에 따라 추가
app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nest-minikube-study
spec:
replicas: 1
selector:
matchLabels:
app: my-nest-minikube-study
template:
metadata:
labels:
app: my-nest-minikube-study
spec:
containers:
- name: my-nest-minikube-study
image: my-nestjs-image:latest
imagePullPolicy: Never
env:
- name: NODE_ENV
valueFrom:
configMapKeyRef:
name: app-env-configmap
key: NODE_ENV
ports:
- containerPort: 3000
apiVersion
: 오브젝트의 API 버전을 정의합니다.apps/v1
은 Deployment 오브젝트의 버전입니다.kind
: 생성할 Kubernetes 리소스의 종류를 정의합니다. 여기서는 Deployment입니다.metadata
: 오브젝트의 메타데이터를 정의합니다.name
필드에는 오브젝트의 이름이 지정됩니다.spec
: 오브젝트의 스펙(구체적인 설정)을 정의합니다.replicas
: 실행할 Pod의 복제본 수를 정의합니다.selector
: 이 Deployment가 관리하는 Pod를 선택하는 라벨입니다.template
: Pod 템플릿을 정의합니다.metadata.labels
: 생성된 Pod에 적용할 라벨을 정의합니다.spec.containers
: 컨테이너 목록을 정의합니다.name
: 컨테이너의 이름입니다.image
: 컨테이너 이미지입니다.imagePullPolicy
: 이미지를 외부에서 가져오지 않도록 설정합니다.ports
: 컨테이너에서 사용하는 포트를 정의합니다.
app-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nest-minikube-study-service
spec:
selector:
app: my-nest-minikube-study
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer
apiVersion
: 오브젝트의 API 버전을 정의합니다.v1
은 Service 오브젝트의 버전입니다.kind
: 생성할 Kubernetes 리소스의 종류를 정의합니다. 여기서는 Service입니다.metadata
: 오브젝트의 메타데이터를 정의합니다.name
필드에는 오브젝트의 이름이 지정됩니다.spec
: 오브젝트의 스펙(구체적인 설정)을 정의합니다.selector
: 이 Service가 연결할 Pod를 선택하는 라벨입니다.ports
: 서비스 포트 설정을 정의합니다.protocol
: 사용할 프로토콜입니다. 여기서는 TCP입니다.port
: 서비스의 포트입니다.targetPort
: Pod의 포트입니다.
type
: 서비스 타입을 정의합니다. 여기서는 LoadBalancer입니다.
mariadb-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mariadb-deployment
spec:
replicas: 1
selector:
matchLabels:
app: mariadb
template:
metadata:
labels:
app: mariadb
spec:
containers:
- name: mariadb
image: mariadb
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mariadb-secret
key: password
- name: MYSQL_DATABASE
value: mydb
- name: MYSQL_USER
value: user
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mariadb-secret
key: password
ports:
- containerPort: 3306
volumeMounts:
- mountPath: /var/lib/mysql
name: mariadb-storage
volumes:
- name: mariadb-storage
persistentVolumeClaim:
claimName: mariadb-pvc
apiVersion
: 오브젝트의 API 버전을 정의합니다.apps/v1
은 Deployment 오브젝트의 버전입니다.kind
: 생성할 Kubernetes 리소스의 종류를 정의합니다. 여기서는 Deployment입니다.metadata
: 오브젝트의 메타데이터를 정의합니다.name
필드에는 오브젝트의 이름이 지정됩니다.spec
: 오브젝트의 스펙(구체적인 설정)을 정의합니다.replicas
: 실행할 Pod의 복제본 수를 정의합니다.selector
: 이 Deployment가 관리하는 Pod를 선택하는 라벨입니다.template
: Pod 템플릿을 정의합니다.metadata.labels
: 생성된 Pod에 적용할 라벨을 정의합니다.spec.containers
: 컨테이너 목록을 정의합니다.name
: 컨테이너의 이름입니다.image
: 컨테이너 이미지입니다.env
: 환경 변수를 정의합니다.name
: 환경 변수 이름입니다.valueFrom
: Secret에서 값을 가져옵니다.
ports
: 컨테이너에서 사용하는 포트를 정의합니다.volumeMounts
: 컨테이너에 볼륨을 마운트합니다.mountPath
: 컨테이너 내의 마운트 경로입니다.name
: 볼륨의 이름입니다.
volumes
: Pod에 사용할 볼륨을 정의합니다.name
: 볼륨의 이름입니다.persistentVolumeClaim
: PVC를 참조합니다.claimName
: 참조할 PVC의 이름입니다.
mariadb-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mariadb-service
spec:
selector:
app: mariadb
ports:
- protocol: TCP
port: 3306
type: ClusterIP
apiVersion
: 오브젝트의 API 버전을 정의합니다.v1
은 Service 오브젝트의 버전입니다.kind
: 생성할 Kubernetes 리소스의 종류를 정의합니다. 여기서는 Service입니다.metadata
: 오브젝트의 메타데이터를 정의합니다.name
필드에는 오브젝트의 이름이 지정됩니다.spec
: 오브젝트의 스펙(구체적인 설정)을 정의합니다.selector
: 이 Service가 연결할 Pod를 선택하는 라벨입니다.ports
: 서비스 포트 설정을 정의합니다.protocol
: 사용할 프로토콜입니다. 여기서는 TCP입니다.port
: 서비스의 포트입니다.
type
: 서비스 타입을 정의합니다. 여기서는 ClusterIP입니다.
mariadb-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mariadb-secret
type: Opaque
data:
password: cGFzc3dvcmQ= # "password"의 base64 인코딩 값
apiVersion
: 오브젝트의 API 버전을 정의합니다.v1
은 Secret 오브젝트의 버전입니다.kind
: 생성할 Kubernetes 리소스의 종류를 정의합니다. 여기서는 Secret입니다.metadata
: 오브젝트의 메타데이터를 정의합니다.name
필드에는 오브젝트의 이름이 지정됩니다.type
: Secret의 타입을 정의합니다.Opaque
는 일반적인 키-값 쌍을 저장할 때 사용됩니다.data
: Secret에 저장할 데이터를 정의합니다. Base64로 인코딩된 값을 사용합니다.
mariadb-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mariadb-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
apiVersion
: 오브젝트의 API 버전을 정의합니다.v1
은 PVC 오브젝트의 버전입니다.kind
: 생성할 Kubernetes 리소스의 종류를 정의합니다. 여기서는 PersistentVolumeClaim입니다.metadata
: 오브젝트의 메타데이터를 정의합니다.name
필드에는 오브젝트의 이름이 지정됩니다.spec
: 오브젝트의 스펙(구체적인 설정)을 정의합니다.accessModes
: 접근 모드를 정의합니다.ReadWriteOnce
는 하나의 노드에서 읽고 쓸 수 있음을 의미합니다.resources.requests.storage
: 요청하는 스토리지의 크기입니다. 이 예제에서는 1GiB를 요청합니다.
4. 매니페스트 파일 적용
다음 명령어를 사용하여 매니페스트 파일을 적용합니다:
kubectl apply -f app-env-configmap.yaml
kubectl apply -f mariadb-secret.yaml
kubectl apply -f mariadb-pvc.yaml
kubectl apply -f mariadb-deployment.yaml
kubectl apply -f mariadb-service.yaml
kubectl apply -f app-service.yaml
kubectl apply -f app-deployment.yaml
5. 애플리케이션 상태확인
kubectl get pods
kubectl get services
6. Minikube 터널링
minikube tunnel
명령어를 사용하여 LoadBalancer 서비스를 외부에 노출합니다:
minikube tunnel
7. 서비스 접근
브라우저 또는 curl
명령어를 사용하여 서비스에 접근합니다:
curl http://127.0.0.1:80
구조 다이어그램
Minikube 내에서 Kubernetes 클러스터가 어떻게 구성되고 동작하는지를 시각적으로 이해하기 위해, 아래와 같은 구조 다이어그램을 참고할 수 있습니다.
+------------------+
| Docker Desktop |
| +--------------+|
| | Minikube ||
| | (Container) ||
| +--------------+|
| (K8s Cluster)|
| +------------------+ +------------------+|
| | Pod | | Pod ||
| | - Container | | - Container ||
| +------------------+ +------------------+|
| +------------------+ +------------------+|
| | Service | | Service ||
| +------------------+ +------------------+|
+------------------+
'DevOps' 카테고리의 다른 글
AWS EKS 클러스터 구축하기(1) - EKS 클러스터 생성 (4) | 2024.08.30 |
---|---|
Minikube 및 Kubectl 자주 사용하는 명령어와 옵션 (0) | 2024.06.24 |
Kubernetes(k8s) 기본 개념 정리 (0) | 2024.06.23 |
Docker 이미지, 컨테이너, 볼륨에 대한 이해 (0) | 2024.06.23 |
Github Webhook, Jenkins를 이용한 CI/CD 파이프라인 설정 (0) | 2024.05.26 |