[Kubernetes] 파드? 다양한 서버 띄워보자

Gaeng·2024년 12월 5일
post-thumbnail

파드

도커에서는 하나의 프로그램을 컨테이너라고 불름.
쿠버네티스느 하나의 프로그램을 실행시키는 단위를 파드(Pod)라고 부름.
즉, 파드는 일반적으로 쿠버네티스에서 하나의 프로그램을 실행시키는 단위. 예외적으로 하나의 파드가 여러 개의 컨테이너를 가지는 경우도 있음.

EX.

  • 2개의 결제 서버가 있다.
    => 2개의 결제 서버 파드가 띄어짐.
  • 1개의 결제 서버가 죽음
    => 1개의 결제 서버 파드가 죽음
  • 업로드 서버를 하나 띄우자
    => 업로드 서버 하나를 파드로 뜨우자

쿠버네티스도 도커처럼 이미지를 기반으로 파드를 띄워 실행 시킴


웹 서버(Nginx)를 파드로 띄우는 법.

파드를 생성하는 법(현업에서 yaml)파일 사용

  • CLI 활용하는 방법
  • yaml 파일 활용하는 방법 -> 매니페스트 파일이라고 부름.

매니페스트(Manifest File)

매니페스트파일은 쿠버네티스에서 다양한 리소스(파드, 서비스, 볼륨) 생성하고 관리하기 위해 사용하는 파일

코드

apiVersion: v1  # API 버전: 현재 사용하는 Kubernetes API 버전 (v1은 기본 Core API 버전).
kind: Pod       # 리소스 종류: 이 파일은 Pod 리소스를 정의합니다.
metadata:       # 메타데이터 섹션: 리소스에 대한 정보를 포함합니다.
  name: nginx   # Pod의 이름: 이 Pod의 이름은 "nginx"입니다.
spec:           # 스펙 섹션: Pod의 설정 및 구성 정의.
  containers:   # 컨테이너 목록: 이 Pod 안에 포함된 컨테이너를 정의
  - name: nginx  # 컨테이너 이름: 컨테이너의 이름은 "nginx"
    image: nginx # 사용 이미지: 이 컨테이너는 "nginx" 이미지를 사용
    ports:       # 컨테이너 포트 설정: 컨테이너에서 사용할 포트를 정의
    - containerPort: 80  # 컨테이너 포트: 컨테이너 내부에서 80번 포트를 사용 -> 8080라고 써도 80에 띄워짐, 문서화 역할임, 영향 X

실행


실행을 다음과 같이 하면 kubectl apply -f nginx-pod.yaml, nginx created가 일어남

  • Name : Pod의 이름
  • Ready - 파드 내 준비 완료 컨테이너 수 / 파드 내 컨테이너 수
  • Status - 파드의 상태
  • RESTARTS - 해당 파드의 컨테이너가 재시작된 수
  • AGE : 파드가 생성되어 실행된 시간

직접 접속

localhost:80에 접속하면 접속이 안됨?

왜 접속이 안되었는가?

파드로 띄운 프로그램에 접속이 안 되는 이유?

  • Docker는 컨테이너 내부와 컨테이너 외부의 네트워크가 서로 독립적으로 분리
  • 쿠버네티스에서는 파드(Pod) 내부의 네트워크를 컨테이너가 공유해서 같이 사용하기 때문이다.
  • 그래서 파드 안 컨테이너끼는 문제없이 통신 가능.
  • 파드의 네트워크는 로컬 컴퓨터의 네트워크와는 독립적으로 분리
  • 응답에 대한 요청이 없음음.

예시

  1. 컴퓨터에 방 하나(파드)가 있다고 생각해 보세요. 이 방 안에 여러 명(컨테이너)이 있는데, 이들은 같은 방 안에서만 쉽게 대화할 수 있습니다.
    • 방 안에서 서로 대화할 때는 특별한 연결 설정 없이도 자유롭게 말할 수 있습니다.
  2. 하지만 방 밖(컴퓨터)에서는 방 안에 있는 사람들과 대화하려면:
    • 방의 문을 열고 (네트워크 포트 열기)
    • 그 방과 연결된 통로(쿠버네티스의 서비스 또는 Ingress)를 설정해야만 가능

접속하려면? 2가지 방법

파드(Pod)내부로 들어가서 접근

터미널 창에서
kubectl exec -it nginx -- bash
curl localhost:80 입력하면 다음과 같이 나옴

파드(Pod) 내부 네트워크를 외부에서도 접속 할 수 있도록 포트 포워딩)

`kubuctl port-forward pod/nginx 80:80


다음과 같은 실행화면이 나오게됨.

Pod삭제

kubectl delete pod nginx


SpringBoot 서버에 파드로 띄우기

스프링 서버를 만들기

간단한 Hello World를 반환하는 것을 만들기

@RestController
public class AppController {
  @GetMapping("/")
  public String home() {
    return "Hello, World!";
  }
}

Docker 파일 만들기

# OpenJDK 17 기반의 JDK 이미지를 사용
FROM openjdk:17-jdk

# 로컬에서 빌드된 .jar 파일을 컨테이너 내의 /app.jar 위치로 복사
COPY build/libs/*SNAPSHOT.jar app.jar

# 컨테이너가 실행될 때 'java -jar /app.jar' 명령어를 실행하도록 설정
ENTRYPOINT ["java", "-jar", "/app.jar"]

Spring Boot 빌드

$ ./gradlew clean build

Dockerfile 바탕으로 이미지 빌드

$ docker build -t spring-server .

이미지 생성되었는지 확인

$ docker image ls

매니페스트 파일 작성

apiVersion: v1
kind: Pod
metadata:
  name: spring-pod
spec:
  containers:
    - name: spring-container
      image: spring-server
      ports:
        - containerPort: 8080

매니페스트 파일을 기반으로 파드 생성

$ kubectl apply -f spring-pod.yaml

파드 생성이 되었는지

$ kubectl get pods

What is ImagePullBackOff ???

오류가 발생하였다.

ImagePullPolicy?

Image Pull Policy는 Kubernetes에서 컨테이너 이미지를 어떻게 가져올지를 정의하는 정책입니다.
이 정책은 Pod 또는 Deployment와 같은 리소스를 정의할 때 설정할 수 있습니다.
주로 Docker 이미지가 업데이트되었는지 여부에 따라 새로운 이미지를 가져올지 말지를 결정하는 데 사용됩니다.

이미지 태그를 생략한 경우
태그를 생략하면 기본적으로 :latest로 간주되며, 따라서 ImagePullPolicy: Always가 적용됩니다.

Image Pull Policy설명사용 사례
Always이미지를 항상 최신 상태로 가져옵니다.로컬에서 가져오지 않고, 자주 업데이트되는 이미지를 사용할 때 유용 (예: 최신 버전의 latest 태그 사용 시)
IfNotPresent이미 로컬에 이미지가 있으면 다운로드를 피하고, 없으면 이미지를 가져옵니다.로컬에 이미지가 있는 경우 다운로드를 방지하고 싶을 때
Never이미 로컬에 이미지가 반드시 존재해야 하며, 로컬에 없으면 이미지를 가져오지 않습니다.로컬 이미지만 사용하고 외부에서 이미지를 다운로드하지 않도록 할 때
apiVersion: v1
kind: Pod

metadata:
  name: spring-pod

spec:
  containers:
    - name: spring-container
      image: kube-spring-testserver
      ports:
        - containerPort: 8080
      imagePullPolicy: IfNotPresent

다음과 같이 IfnotPresent를 설정하고 실행하면 됨.

그렇기에 기존에 있던 것을 삭제하고 실행을 해보면 됨.
삭제하는 법은 아까했듯이 삭제하면 됨.

스프링서버를 실행하면

SpringBoot 서버 3개 띄우기

기존과 동일하며 yaml파일을 다음과 같이 실행하면 됨.

apiVersion: v1
kind: Pod

metadata:
  name: spring-pod-1

spec:
  containers:
    - name: spring-container
      image: kube-spring-testserver
      ports:
        - containerPort: 8080
      imagePullPolicy: IfNotPresent

---
apiVersion: v1
kind: Pod

metadata:
  name: spring-pod-2

spec:
  containers:
    - name: spring-container
      image: kube-spring-testserver
      ports:
        - containerPort: 8080
      imagePullPolicy: IfNotPresent

---
apiVersion: v1
kind: Pod

metadata:
  name: spring-pod-3

spec:
  containers:
    - name: spring-container
      image: kube-spring-testserver
      ports:
        - containerPort: 8080
      imagePullPolicy: IfNotPresent

---

하지만 서버가 100개 이상이라고 가정하면, 실시간 관리하기 때문에, Deployment에 대해 공부해야함.

profile
문제를 해결하면서 나온 문제를 기록하는 노트

0개의 댓글