Recording/멋쟁이사자처럼 BE 13기

[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_76일차_"쿠버네티스 Kubernetes"

LEFT 2025. 3. 28. 17:17

🦁멋쟁이사자처럼 백엔드 부트캠프 13기 🦁
TIL 회고 - [76]일차

🚀76차에는 도커와 쿠버네티스에 대해 더 자세히 학습할 수 있었다.

학습 목표 : 쿠버네티스로 포트포워딩이나 PV, PVC 등을 배워 활용할 수 있어야함

학습 과정 : 회고를 통해 작성


커스텀 deployment 만들기

  • kubectl create deployment juunb --image=nginx
    ➡️기본으로 deployment가 하나 만들어지면 pods도 하나 만들어진다.

    deployment로 인해서 pods 생성되고, deployment를 생성했을때 사용했던 이미지로 ,컨테이너가 새로 생성되는것

  • kubectl delete pods [pod ID]
    pods를 삭제해도, deployment에서는 pods를 가지고 있어야하기에 다시 바로 재생성된다.
  • kubectl get pods 를 해보면 deployment가 존재하는한 계속해서 pods도 존재하는 것을 확인 가능
    (=직원 결근 시 바로 본사에서 보충하는 느낌)

  • kubectl describe deployment juunb
    ➡️deployment의 상세정보 출력

포트포워딩 Port-Forwarding

  • 만든 컨테이너를 외부로 노출시킬 수 있는 방법
  • nginx 브라우저로 확인하기 (포트 포워딩 / NodePort)
    nginx는 기본적으로 80번 포트에서 동작
# 1) 만약 방금 삭제했다면 다시 생성
kubectl create deployment hello-kubectl --image=nginx

# 2) Pods 이름 확인
kubectl get pods

# 3) 포트 포워딩
kubectl port-forward <파드이름> 31770:80
  • hello-kubectl 배포를 했다면 그 위에 Service를 추가
  • kubectl expose deployment hello-kubectl --type=NodePort --port=80 --target-port=80
    ➡️kubectl get svc
    로 노출된 NodePort 번호(ex. 31000~32767 범위)를 확인

  • 31770으로 접속해본 예
  • 포트포워딩 후 localhost:80 에 접속해보면 nginx 출력 확인 가능

서비스 추가

  • --target-port : nginx포트, 실제로 동작하고 있는 포트
  • --port=80 : 쿠버네티스에서 80으로 이 nginx포트에 접속할 것을 의미
  • 실제로 외부에 전달되는 포트는 아니고 외부에 전달되는 포트는 NodePort
    NodePort는 kubectl get svc로 노출된 NodePort번호 중 사용이 가능

  • kubectl get svc : 서비스 목록 출력
  • port(s)에 80:30941/TCP
    ➡️30941이 실제 외부로 연결된 포트를 의미
    로컬호스트에 요청할때는 이 포트번호로 접근해야하는 것

  • kubernetes / ClusterIP : 쿠버네티스가 동작할때 기본으로 생성(=자동으로 생성)되는 서비스
    ➡️ClusterIP : 내부에서 사용하는 IP주소로 “사내전화”같은 느낌, 내부에서 사용하는 망이 하나 만들어져있는 것

  • NodePort 포트번호는 쿠버네티스가 자동 배정. 정해주는 범위는 (31000~32767) 내

커스텀 이미지

  • 커스텀 이미지를 만들어 여기에 커스텀 index.html을 배치가능
  • 디렉토리 새로 생성 (k8s-projects)
  • 작업할 디렉토리 생성 (custom-nginx)
  • 해당 디렉토리에 이미지 생성

Dockerfile

FROM nginx:alpine
COPY ./myindex.html /usr/share/nginx/html/index.html

myindex.html

<h1>커스텀 이미지와 커스텀 index.html</h1>
<h3>쿠버네티스 실습</h3>

  • deployment를 생성하는데 custom-nginx 이름으로 생성하고
  • 이미지는 커스텀으로 만들어낸 my-nginx:1.0 을 사용

  • target-port는 명시하지 않으면 (생략하면) 앞의 port=80 옵션과 같은 포트로 서비스가 만들어진다.
    ex. 32341 외부포트로 만들어졌으므로 접근 가능
  • NodePort자체가 외부랑 연결이 가능하도록 해주는 서비스

Pod & Deployment

  • 쿠버네티스에서 가장 기본이 되는 리소스가 Pod
  • Pod을 단독으로 운영하기보다 Deployment라는 상위 개념을 사용해 Pod을 생성하고 관리
  • Pod
    ➡️컨테이너(들)가 실행되는 최소 배포 단위
    보통 하나의 Pod 안에 한 개의 컨테이너가 들어감

    Pod 단독으로 관리하기에는 불편하기 때문에 Deployment 같은 상위 오브젝트로 Pod을 관리하는 것이 일반적

  • 사이드카(Sidecar)
    ➡️Kubernetes에서 Pod 내부의 주 컨테이너(Main Container)를 보조 하는 역할을 하는 컨테이너를 의미

  • Deployment
    ➡️Pod를 생성하고 운영(배포, 롤링 업데이트, 스케일링 등)을 자동으로 관리하는 쿠버네티스 리소스
    Deployment에 원하는 상태(ex. 3개의 Pod 실행)를 정의하면, 쿠버네티스가 Pod이 항상 그 상태를 유지하도록 관리

 

hello-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
	name: hello-deployment
spec:
	replicas: 1
	selector:
		matchLabels:
			app: hello-nginx
	template:
		metadata:
			labels:
				app: hello-nginx
		spec:
			containers:
			- name: nginx-container
				image: nginx:alpine
				ports:
				- containerPort: 80
  • spec.replicas: 원하는 Pod 개수 (초기값 1)
  • spec.template.spec.containers: 실제 컨테이너 정의 image: nginx:alpine 컨테이너 이미지를 사용
    ports.containerPort: 컨테이너 내부에서 80포트 사용 (nginx 기본 포트)

  • yaml을 적용하기위해 apply 명령어 사용

scale 업 / 다운

  • 원하는 POD개수 조정
  • Pod 스케일 업/다운 스케일 업: replicas 수를 늘려서 Pod 개수를 늘리는 작업


서비스 Service

  • 쿠버네티스에서 Pod(또는 여러 Pod)에게 네트워크 접근을 제공해주는 중요한 리소스
  • Pod은 동적으로 생성되고, IP 주소도 언제든 바뀔 수 있다.
  • Pod IP를 직접 사용해 접근하면 관리가 어려우므로 Service가 Pod에
    고정된 접근 지점(가상 IP, 포트)을 부여하고Load Balancing까지 담당

Service 종류

  • ClusterIP (기본값) : 클러스터 내부에서만 접근 가능한 가상 IP를 할당 외부(인터넷)에서는 접근 불가
  • NodePort : 각 노드(Worker Node)의 특정 포트를 개방해 외부에서도 접근 가능하게 함
  • LoadBalancer :
    클라우드 환경에서 자동으로 로드밸런서를 생성 외부(인터넷) IP를 할당받아 외부 트래픽을 분산 처리

ConfigMap & Secret

  • 어떤 애플리케이션이든 환경에 따라 달라지는 설정값 (DB연결정보, 외부 API키 등)은
    코드나 컨테이너 이미지와는 분리해서 관리하는 것이 바람직
  • 쿠버네티스에서는 분리를 위해 ConfigMap과 Secret 리소스를 제공

  • ConfigMap : 비민감한 설정 데이터를 관리
    ➡️쿠버네티스에서 평문(Plain Text) 설정 정보를 저장하는 리소스
    여러 Key:Value 형태로 환경변수를 지정하고, Pod에서 이 값을 읽어 쓸 수 있음

  • Secret : 비밀번호, 인증토큰 등 민감 데이터를 안전하게 저장

 

my-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  WELCOME_MESSAGE: "Hello from ConfigMap!"
  APP_MODE: "development"

ConfigMap 사용방법

1. 환경변수로 ConfigMap 사용

  • Pod 내부의 컨테이너에서 환경변수로 ConfigMap값을 사용할 수 있음

Pod에 대한 YAML (=my-app.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
    - name: app-container
      image: busybox
      command:
        [
          "/bin/sh",
          "-c",
          "echo $WELCOME_MESSAGE && echo $APP_MODE && sleep 3600",
        ]
      env:
        - name: WELCOME_MESSAGE
          valueFrom:
            configMapKeyRef:
              name: my-config
              key: WELCOME_MESSAGE
        - name: APP_MODE
          valueFrom:
            configMapKeyRef:
              name: my-config
              key: APP_MODE
        - name: JUUNB_NAME
          valueFrom:
            configMapKeyRef:
              name: my-config
              key: JUUNB_NAME

  • 설정 적용 후 echo로 각 매개변수의 값들을 출력 가능

Secret

  • 민감 정보(비밀번호, 토큰, API 키 등) 를 저장하기 위한 리소스 내부적으로 base64 인코딩되어 보관

윈도우 Powershell 기준

  • 암호화하고싶은 문자열을 넣으면 암호화된 문자열을 반환해줌
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("secretpassword"))

 

my-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  DB_PASSWORD: "c2VjdXJldHBhc3N3b3Jk" # base64 인코딩된 문자열
  • data: 인코딩 된 값을 여러개 넣어줄수도 있다.
    DB_PASSWORD: “…”
    TEST: “…”
    MY_NAME: “…” 등등

볼륨 Volume

  • 쿠버네티스의 Pod와 컨테이너는 기본적으로 휘발성 스토리지를 사용
  • ⚠️ Pod이 재시작되거나 새로 생성·삭제되는 과정에서 컨테이너 내부 데이터가 사라짐
    ✅이때 볼륨(Volume) 을 사용하면 데이터 영속화(Persistence) 가 가능해지거나,
    여러 컨테이너가 공유 스토리지 사용가능

볼륨의 종류

  • Ephemeral Volume(일회성 볼륨)
    ➡️Pod이 죽으면 데이터도 함께 사라지는 일시적 볼륨 (ex. emptyDir, configMap/secret 볼륨 등)

  • Persistent Volume (PV) + Persistent Volume Claim (PVC)
    ➡️
    영구적인 스토리지를 쿠버네티스에 등록(PV)하고,
    사용자는 PVC를 통해 그 스토리지를 청구(Claim)해서 Pod에 연결
    ⭐Pod이 삭제되어도, PVC/PV가 유지되는 한 데이터가 보존됨

  • Persistent Volume(PV) : 미리 등록해놓은공간 (준비해놓은공간)
  • Persistent Volume Claim (PVC) : 공간을 요청하는 개념

  • 파일들을 생성하고, deployment를 내렸다가 다시 올려도 pv, pvc를 삭제하지 않는한
    이 데이터들은 남아있다는 것 알 수 있음
  • hostPath: Pod가 실행되는 노드의 로컬 파일 시스템의 특정 경로를 PV로 제공
    ➡️따라서 데이터는 파드가 실행되었던
    특정 노드의 해당 경로에 저장

  • 데이터 유지 원리:
    1) PV 생성: hostPath 타입의 PV를 생성할 때, 특정 노드의 로컬 파일 시스템 경로를 지정
    2) PVC 생성: PVC를 생성하고, 이 PVC가 생성된 PV와 바인딩
    3) Pods 설정: Deployment의 파드 템플릿에서 PVC를 볼륨으로 마운트하고,
    컨테이너 내의 특정 경로에 해당 볼륨을 연결

    4) 파일 생성: 파드 내의 컨테이너에서 마운트된 경로에 파일을 생성하면,
    실제로는 PV가 가리키는 노드의 로컬 파일 시스템에 파일이 저장

    5) Deployment 삭제 및 재생성: Deployment를 삭제하면 해당 파드도 삭제되지만,
    PV와 PVC는 기본적으로 삭제되지 않고 유지
    ➡️다시 Deployment를 생성하면, 쿠버네티스는 기존 PVC를 만족하는 PV를 찾아 다시 파드에 연결하려고 시도

❓쿠버네티스 활용법

  • 개발과 운영의 협업 강화 (DevOps):
    ➡️
    도커 이미지라는 표준화된 배포 단위를 통해 개발자는 개발 환경과 동일한 환경을 운영팀에 제공할 수 있어
    배포 과정에서의 오류를 줄이고 협업 효율성을 높임

  • 클라우드 환경과의 통합 용이성: 대부분의 클라우드 플랫폼에서 쿠버네티스 서비스를 제공하며,
    도커 컨테이너를 기반으로 애플리케이션을 구축하면 클라우드 환경으로의 이전 및 확장이 용이
  • 쿠버네티스 활용 흐름:
    1) 도커를 사용하여 웹 서버 애플리케이션과 필요한 환경을 컨테이너 이미지로 만듦

    2) 쿠버네티스 Deployment를 설정하여 원하는 웹 서버(Pods)의 개수를 지정

    3) 쿠버네티스 서비스 설정을 통해 외부 트래픽을 여러 웹 서버 Pods에 자동으로 분산

    4) 만약 웹 서버 파드 중 하나에 문제가 발생하면, 쿠버네티스는 자동으로 새로운 Pods를 생성하여 서비스를 유지

    5) 트래픽이 증가하면 Deployment 설정을 변경하여 웹 서버 Pods의 개수를 쉽게 늘릴 수 있음

    6) 데이터를 영구적으로 저장해야 한다면 PV와 PVC를 활용하여 웹 서버 Pods가 재시작되거나
    다른 노드로 이동하더라도 데이터 손실 없이 서비스를 제공 가능

정리하자면

✅쿠버네티스는 복잡한 분산 시스템을 효율적으로 관리하고, 애플리케이션의 안정성과 확장성을 크게 향상시키는 도구


🚀회고 결과 :

쿠버네티스에 대하여 더 배우면서 포트포워딩과 PV, PVC까지 내부 개념에 대해 공부할 수 있었다.

docker로 이미지를 만들고 run으로 실행하는 과정을 넘어 kubectl 명령어를 활용하여

deployment, pods 등을 생성하는 것까지 연습해볼 수 있었다.

향후 계획 : 

- 쿠버네티스에 react 프로젝트 올리는 연습