환경 구성

local volume 디렉터리 생성
mkdir -p /root/k8s-local-volume/1231

일단 다음 환경에서 사용할 디렉터리를 만들고 시작하겠습니다.

namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: anotherclass-123
  labels:
    part-of: k8s-anotherclass
    managed-by: dashboard

Namespace는 Kubernetes 클러스터 안의 Object를 논리적으로 묶는 그룹입니다.

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: anotherclass-123
  name: api-tester-1231
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
spec:
  selector:
    matchLabels:
      part-of: k8s-anotherclass
      component: backend-server
      name: api-tester
      instance: api-tester-1231
  replicas: 2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        part-of: k8s-anotherclass
        component: backend-server
        name: api-tester
        instance: api-tester-1231
        version: 1.0.0
    spec:
      nodeSelector:
        kubernetes.io/hostname: k8s-master
      containers:
        - name: api-tester-1231
          image: 1pro/api-tester:v1.0.0
          ports:
            - name: http
              containerPort: 8080
          envFrom:
            - configMapRef:
                name: api-tester-1231-properties
          startupProbe:
            httpGet:
              path: /startup
              port: 8080
            periodSeconds: 5
            failureThreshold: 36
          readinessProbe:
            httpGet:
              path: /readiness
              port: 8080
            periodSeconds: 10
            failureThreshold: 3
          livenessProbe:
            httpGet:
              path: /liveness
              port: 8080
            periodSeconds: 10
            failureThreshold: 3
          resources:
            requests:
              memory: 100Mi
              cpu: 100m
            limits:
              memory: 200Mi
              cpu: 200m
          volumeMounts:
            - name: files
              mountPath: /usr/src/myapp/files/dev
            - name: secret-datasource
              mountPath: /usr/src/myapp/datasource
      volumes:
        - name: files
          persistentVolumeClaim:
            claimName: api-tester-1231-files
        - name: secret-datasource
          secret:
            secretName: api-tester-1231-postgresql
service.yaml
apiVersion: v1
kind: Service
metadata:
  namespace: anotherclass-123
  name: api-tester-1231
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
spec:
  selector:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
  ports:
    - port: 80
      targetPort: http
      nodePort: 31231
  type: NodePort
configmap-secret.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: anotherclass-123
  name: api-tester-1231-properties
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
data:
  spring_profiles_active: dev
  application_role: ALL
  postgresql_filepath: /usr/src/myapp/datasource/postgresql-info.yaml
---
apiVersion: v1
kind: Secret
metadata:
  namespace: anotherclass-123
  name: api-tester-1231-postgresql
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
stringData:
  postgresql-info.yaml: |
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://postgresql:5431
    username: dev
    password: dev123
  • ConfigMap은 환경 변수나 설정값처럼 Pod에 주입할 데이터를 저장합니다.
  • Secret은 비밀번호, 토큰, 인증서처럼 민감한 데이터를 저장합니다.
pv-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  namespace: anotherclass-123
  name: api-tester-1231-files
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: kubectl
spec:
  resources:
    requests:
      storage: 2G
  accessModes:
    - ReadWriteMany
  selector:
    matchLabels:
      part-of: k8s-anotherclass
      component: backend-server
      name: api-tester
      instance: api-tester-1231-files
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: api-tester-1231-files
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231-files
    version: 1.0.0
    managed-by: dashboard
spec:
  capacity:
    storage: 2G
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  local:
    path: /root/k8s-local-volume/1231
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
                - k8s-master
  • PersistentVolumeClaim: Pod가 사용할 스토리지를 요청하는 Object입니다.
  • PersistentVolume: 클러스터에서 실제 스토리지 자원을 표현하는 Object입니다.
hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  namespace: anotherclass-123
  name: api-tester-1231-default
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-tester-1231
  minReplicas: 2
  maxReplicas: 4
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 120

해당 HPA는 CPU 사용률 같은 메트릭에 따라 Pod 수를 늘릴지 줄일지 조절해 주는 Object입니다.

현재 설정에서는 최소 2개에서 최대 4개까지 가능하며, CPU 평균 사용률 60%를 기준으로 조절합니다. 스케일 업 시에는 120초의 안정화 대기 시간을 갖습니다.

Object란?

Kubernetes Object는 클러스터에 배포하고 관리할 상태를 선언한 리소스이다.

예를 들어 Deployment, Service, ConfigMap, Secret, PersistentVolume, PersistentVolumeClaim, HorizontalPodAutoscaler 등이 모두 Object에 해당한다. 사용자는 YAML 매니페스트로 원하는 상태를 선언하고, Kubernetes는 현재 상태를 원하는 상태에 맞추기 위해 계속 조정한다.

Object 핵심 기능

  • apiVersion: Object가 사용하는 Kubernetes API 버전을 지정한다.
  • kind: 생성할 Object의 종류를 지정한다.
  • metadata: Object의 이름, 네임스페이스, 라벨, 애너테이션 같은 식별 정보를 담는다.
  • spec: 사용자가 원하는 최종 상태를 선언한다.
  • status: Kubernetes가 관찰한 현재 상태를 기록한다. 일반적으로 사용자가 직접 작성하지 않고 컨트롤러가 갱신한다.

Kubernetes Component가 Object를 실행하는 흐름

  1. 사용자가 kubectl apply -f <manifest.yaml> 명령으로 Object를 API Server에 전달한다.
  2. API Server는 요청을 검증한 뒤 Object 정보를 etcd에 저장한다.
  3. Controller Manager는 spec에 선언된 원하는 상태와 현재 상태를 비교한다.
  4. Scheduler는 새로 생성해야 하는 Pod가 있다면 실행할 Node를 선택한다.
  5. 각 Node의 kubelet은 자신에게 할당된 Pod를 생성하고 컨테이너 런타임을 통해 컨테이너를 실행한다.
  6. kube-proxy와 CNI는 Service, 네트워크 라우팅, Pod 간 통신이 가능하도록 설정한다.

즉, Object는 단순한 설정 파일이 아니라 Kubernetes가 클러스터 상태를 조정하기 위해 사용하는 선언형 기준이다.