728x90
반응형

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           ||
|  +------------------+  +------------------+|
+------------------+
반응형