k8s 발 들이기 (1): yaml 시작했다, yaml 끝났다

바람찬허파·2025년 9월 8일
post-thumbnail

Dart 이후 다시금 시작된 발 들이기 시리즈이다. 연초 k8s를 시작해보려 가볍게 수강한 강의를 이어 수강하고 있다. 큰 부담 없이, 빠르게 완주할 수 있도록!

(1) kubernetes Object

쿠버네티스 오브젝트는 영속성을 가지며, 클러스터에 대한 의도를 담은 레코드이다. 의도한 상태라는 표현이 추상적일 수 있으나, 사용자가 원하는 형태로 클러스터를 구성하는 방법이라 받아들여진다. 쿠버네티스는 이 의도를 실제 환경 (status)와 맞추기 위해 지속적으로 상태를 관리 하는 것이다.

대표적인 object는 Pod, Deployment, Service, Configmap, Secret 등이 있으며, 전부 yaml/json object로 정의되어 etcd에 저장된다.

또한, 쿠버네티스 오프젝트를 동작(생성/수정/삭제)시키려면 쿠버네티스 API를 이용해야 한다. 우리가 오브젝트에 대한 정보를 .yaml 파일에 적어 kubectl에 제공하면, API 요청이 이루어질 때 JSON 형식으로 정보를 변환시켜준다.

쿠버네티스 오브젝트를 생성하기 위한 .yaml 파일 내에는 다음 필드가 필요하다

  • apiVersion
  • kind
  • metadata
  • spec : 오브젝트에 대해 어떤 상태를 의도하는지

(2) 실습: Volumne

스프링 애플리케이션 3개 복제본과 단일 MySQL 인스턴스로 서비스를 쿠버네티스에서 구동해보자

다음을 k8s에서 구동시키기 위해 MySQL Pod를 먼저 띄우고자 한다.

(2)-1 MySQL Deployment

apiVersion: apps/v1
kind: Deployment

metadata:
  name: mysql-deployment

spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql-db
  template:
    metadata:
      labels:
        app: mysql-db
    spec:
      containers:
        - name:  mysql-container
          image: mysql:8.0
          ports:
            - containerPort: 3306
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: pw1234
            - name: MYSQL_DATABASE
              value: my_db
            
kubectl apply -f mysql-deployment.yaml

(2)-2 MySQL Service

apiVersion: v1
kind: Service

metadata:
  name: mysql-service

spec:
  type: NodePort
  selector:
    app: mysql-db
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
      nodePort: 30001

(2)-3 DB 접속 확인

(2)-4 Secret, ConfigMap

앞선 MySQL Deployment에서 MYSQL_ROOT_PASSWORDMYSQL_DATABASE를 환경변수로 분리하고자 한다. 별도 파일로 분리하는 이유는 환경(개발, 테스트, 프로덕션) 분리를 위함이다. 민감한 환경 변수는 Secret에서 별도로 관리한다.

apiVersion: v1
kind: Secret

metadata:
  name: mysql-secret

stringData:
  mysql-root-password: pw1234
    
apiVersion: v1
kind: ConfigMap

metadata:
  name: mysql-config

data:
  mysql-database: my_db
// Deployment 
// ...
    spec:
      containers:
        - name:  mysql-container
          image: mysql:8.0
          ports:
            - containerPort: 3306
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: mysql-root-password
            - name: MYSQL_DATABASE
              valueFrom:
                configMapKeyRef:
                  name: mysql-config
                  key: mysql-database

2-(5) 문제 발생

만약, 이 상황에서 deployment를 재시작해야 한다면 volume 내부의 데이터가 없어져버리는 문제가 생긴다.

my_db DB에 tmp_table을 생성한 뒤, kubectl rollout restart deployment mysql-deployment으로 Deployment를 재시작한다. DB 속 데이터가 사라진 것을 확인할 수 있다.


데이터가 보존되도록 사용하는 것이
PV(Persistent Volume)과 PVC(persistent volume claim)이다.

1개의 댓글

comment-user-thumbnail
2025년 9월 8일

저도 k8s 공부하고 있는데 재밌게 봤어요! secret으로 중요한 환경변수들을 모아서 관리하는 것도 맞지만 결국 api-server와 다른 노드의 kubelet이랑 통신하는 과정 또는 다른 해당 secret 값을 가져올려고 통신할 때 그대로 노출되기는 합니다. 그래서 관리할 때 암호화하여 통신과정에서 암복호화를 추가하기도 한답니다!

답글 달기