K8s 실습하기

Yuno·2025년 4월 2일

쿠버네티스 K8s

목록 보기
2/7

💻 Spring Boot 애플리케이션으로 K8s 실습해보기

🛠️ 로컬 실습 툴 설치하기

항목용도
Docker개발자가 로컬에서 이미지 만들 때 사용
Minikube로컬 K8s 클러스터 구성
kubectlK8s 제어 CLI

1️⃣ Docker 설치

brew install --cask docker

설치 후에 Docker Desktop 실행

2️⃣ kubectl 설치 (K8s CLI) 및 확인

brew install kubectl
kubectl version --client

3️⃣ Minikube 설치 (로컬 K8s 클러스터) 및 확인

brew install minikube
minikube version

4️⃣ MiniKube 시작하기

  • ❗️ 처음 실행 시 Docker Desktop 실행 상태여야 함
minikube start --driver=docker

👉 실행에 성공하면 확인하기

kubectl get nodes
NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   20s   v1.32.0

🧑‍💻 Java17 + Gradle 기반으로 간단한 프로젝트 생성

1️⃣ Spring Boot 프로젝트 생성 의존성은 Spring Web 추가

2️⃣ 간단한 GET /hello API 만들기

package com.springk8sdemo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

  @GetMapping("/hello")
  public String hello() {
    return "Hello K8s!";
  }
}

3️⃣ API 실행 결과 확인


🐳 Docker 에 이미지 띄우기

1️⃣ 프로젝트 루트에 Dockerfile 작성

FROM openjdk:17-slim
VOLUME /tmp
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
  • FROM openjdk:17-slim
    • Docker 이미지의 기반 이미지(Base image) 를 설정
    • OpenJDK 17 버전이 설치된 최소한의 크기(slim) 를 가진 리눅스 이미지
      → 필요 없는 라이브러리나 틀이 제거된 가벼운 버젼이기 때문에 더 빠르게 실행되고, 보안상 안전함
  • VOLUME /tmp
    • 컨테이너에서 /tmp 폴더를 외부와 연결된 볼륨(임시 저장소) 으로 설정
    • Spring Boot 는 내부적으로 임시 파일을 /tmp 에 저장할 수 있음
      → 이를 볼륨으로 설정하면, 컨테이너가 재시작되더라도 이 경로는 유지되거나 공유할 수 있음
  • ARG JAR_FILE=build/libs/*.jar
    • JAR_FILE 이라는 빌드 시 전달받을 수 있는 변수를 선언
    • Gradle로 빌드한 Spring Boot JAR 파일이 위치한 기본 경로
      → *.jar 로 하면, 해당 디렉토리에 있는 하나의 JAR 파일을 가져오겠다는 뜻
  • COPY ${JAR_FILE} app.jar
    • 위에서 설정한 ${JAR_FILE} 경로의 파일을 컨테이너 내부로 복사
    • 복사된 JAR 파일을 app.jar 라는 이름으로 저장
      → 실제로는 /app.jar 로 컨테이너 안에 생김
  • ENTRYPOINT ["java", "-jar", "/app.jar"]
    • 컨테이너가 실행될 때 기본적으로 실행할 명령어를 설정
    • java -jar /app.jar 명령어를 실행해서, JAR 파일을 기반으로 애플리케이션을 바로 실행

2️⃣ 도커 이미지 빌드 및 확인

./gradlew build
docker build -t spring-k8s-demo .
docker images
REPOSITORY          TAG        IMAGE ID       CREATED         SIZE
spring-k8s-demo     latest     257ebb3705d2   1 minutes ago   423MB

🚀 K8s 에 Spring 애플리케이션 배포하기

1️⃣ Minikube 에 이미지 넣기
Minikube 는 자기만의 도커 환경을 따로 가지고 있어서 로컬에서 만든 이미지를 바로 못 씀
👉 Minikube Docker 환경에서 직접 빌드하기

eval ${minikube docker-env} # 도커 빌드 타겟을 Minikube로 변경

다시 빌드하기

docker build -t spring-k8s-demo .

2️⃣ K8s Deployment & Service 설정 파일 만들기
- 📄 루트에서 spring-k8s-deployment.yaml 생성

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-k8s-demo
spec:
  selector:
    matchLabels:
      app: spring-k8s-demo
  template:
    metadata:
      labels:
        app: spring-k8s-demo
    spec:
      containers:
        - name: spring-k8s-demo
          image: spring-k8s-demo
          imagePullPolicy: Never
          ports:
            - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: spring-k8s-service
spec:
  type: NodePort
  selector:
    app: spring-k8s-demo
  ports:
    - port: 8080
      targetPort: 8080
      nodePort: 30080

🧱 1. Deployment 설정

  • apiVersion: apps/v1 : Deployment 리소스의 버전
  • kind: Deployment : 앱을 여러 개의 Pod 로 실행 & 관리 하는 K8s 리소스
  • metadata.name : 이 Deployment 의 이름
  • spec : Deployment 내용 정의
    • selector.matchLabels : 어떤 Pod 들을 이 Deployment 가 관리할지 결정
      → 아래 template 에 있는 label과 일치해야 함
    • template : Pod 템플릿 정의
      • metadata.labels : 생성될 Pod 에 붙일 라벨 정의
        • 위 selector 와 맞춰야 함
      • spec : 컨테이너 정의
        • name : 컨테이너 이름
        • image : 사용할 도커 이미지 이름
          → 로컬에서 직접 만든 이미지 사용 시 imagePullPolicy: Never 필요
        • containerPort : 컨테이너가 사용하는 포트 (Spring Boot 의 기본 포트)

🌐 2. Service 설정 (외부에서 접근 가능하게)

  • kind: Service → Pod 들을 외부 또는 클러스터 내에서 접근할 수 있도록 해주는 리소스
  • metadata.name : 서비스 이름
  • spec : Service 내용
    • type: NodePort → 외부에서 클러스터 노드의 IP + 포트로 접근 가능
    • selector : 연결할 Pod 들을 찾을 때 사용하는 라벨
      → Deployment 의 라벨과 같아야 함
    • ports : 포트 매핑
      • port : 클러스터 내부에서 이 서비스에 접근할 때 사용할 포트
      • targetPort : 실제 컨테이너(Pod) 내부에서 열려 있는 포트
      • nodePort : 외부에서 접근할 수 있는 포트 (호스트 IP:30080 으로 접근 가능)

3️⃣ 배포 및 확인

✅ 배포하기

kubectl apply -f spring-k8s-deployment.yaml

→ 반환

deployment.apps/spring-k8s-demo unchanged
service/spring-k8s-service created

✅ Pod 확인하기

kubectl get pods

→ 반환

NAME                               READY   STATUS    RESTARTS   AGE
spring-k8s-demo-74d78f9565-jdlz7   1/1     Running   0          12s

✅ Service 확인하기

kubectl get services

→ 반환

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes           ClusterIP   10.96.0.1        <none>        443/TCP          44m
spring-k8s-service   NodePort    10.111.105.105   <none>        8080:30080/TCP   14m

4️⃣ Minikube 로 포트 확인 & 접속

minikube service spring-k8s-service

→ 반환

|-----------|--------------------|-------------|---------------------------|
| NAMESPACE |        NAME        | TARGET PORT |            URL            |
|-----------|--------------------|-------------|---------------------------|
| default   | spring-k8s-service |        8080 | http://192.168.49.2:30080 |
|-----------|--------------------|-------------|---------------------------|
🏃  spring-k8s-service 서비스의 터널을 시작하는 중
|-----------|--------------------|-------------|------------------------|
| NAMESPACE |        NAME        | TARGET PORT |          URL           |
|-----------|--------------------|-------------|------------------------|
| default   | spring-k8s-service |             | http://127.0.0.1:52696 |
|-----------|--------------------|-------------|------------------------|
🎉  Opening service default/spring-k8s-service in default browser...
❗  darwin 에서 Docker 드라이버를 사용하고 있기 때문에, 터미널을 열어야 실행할 수 있습니다

🔍 반환된 값 요약

항목내용
서비스 이름spring-k8s-service
클러스터 IP URLhttp://192.168.49.2:30080
터널 URL (로컬 포트)http://127.0.0.1:52696

👉 제공받은 http://127.0.0.1:52696/hello 로 브라우저 에서 접근

profile
Hello World

0개의 댓글