Guide_Spring Boot Kubernetes

Dev.Hammy·2024년 1월 30일
0

Spring Guides

목록 보기
42/46

이 가이드는 Kubernetes에 Spring Boot 애플리케이션을 배포하는 과정을 안내합니다. Spring Boot 및 Kubernetes를 사용하여 작업을 수행하는 다양한 방법 중에서 선택할 수 있습니다. 이 가이드의 목적은 모든 대안을 논의하거나 프로덕션에 도달하는 방법에 대한 모든 세부 사항을 설명하는 것이 아니라 가능한 한 빨리 진행하도록 하는 것입니다.


쿠버네티스의 주요 요소

쿠버네티스(Kubernetes)에서 애플리케이션을 배포하고 관리하기 위해 사용되는 주요 요소들과 그들 간의 상호작용 과정을 간략히 설명하겠습니다.

  1. 파드(Pod):

    • 파드는 쿠버네티스에서 가장 작은 배포 가능한 단위입니다.
    • 하나 이상의 컨테이너를 그룹화하며, 동일한 호스트에서 실행됩니다.
    • 파드는 동일한 IP 주소와 네트워크 네임스페이스를 공유하므로 컨테이너 간에 네트워크 통신이 가능합니다.
  2. 서비스(Service):

    • 서비스는 파드의 집합에 대한 네트워크 엔드포인트를 제공하는 추상화입니다.
    • 클러스터 내의 다른 파드나 외부 클라이언트가 서비스를 통해 파드에 접근할 수 있습니다.
    • 서비스 유형에는 ClusterIP, NodePort, LoadBalancer, ExternalName 등이 있습니다.
  3. 인그레스(Ingress):

    • 인그레스는 클러스터 내부 또는 외부에서 애플리케이션에 접근할 수 있는 HTTP 및 HTTPS 라우팅 규칙을 정의하는 API 객체입니다.
    • 서비스와 함께 사용되어 외부에서 애플리케이션으로의 트래픽을 라우팅합니다.
    • 단일 IP 주소 및 포트를 사용하여 여러 서비스에 대한 가상 호스트 기반 라우팅을 제공합니다.
  4. 쿠버네티스 이벤트 순환 과정:

    • 사용자는 kubectl 또는 API를 통해 쿠버네티스 클러스터에 명령을 제출합니다.
    • API 서버는 요청을 받아들이고, 이를 etcd 데이터베이스에 저장합니다.
    • 스케줄러는 새로운 파드를 클러스터 내의 어떤 노드에 배치할지 결정하고, API 서버에 배치 결과를 전송합니다.
    • kubelet은 노드에서 실행 중인 파드 상태를 확인하고, 필요에 따라 파드를 생성하거나 제거합니다.
    • 생성된 파드는 클러스터 네트워크와 연결되고, 서비스와 인그레스 등의 다른 리소스에 의해 라우팅될 수 있습니다.

이러한 주요 요소들과 과정을 통해 쿠버네티스는 애플리케이션을 배포하고 관리하는 데 필요한 기능을 제공합니다.


무엇을 구축할 것인가

Kubernetes는 컨테이너화된 애플리케이션의 배포(deployment), 확장(scaling) 및 관리(management)를 자동화하기 위한 오픈 소스 시스템입니다. 쉽게 관리하고 검색할 수 있도록 애플리케이션을 구성하는 컨테이너를 논리 단위로 그룹화합니다. 이 가이드에서는 간단한 Spring 부팅 애플리케이션을 구축하고 배포합니다.

컨테이너 이미지 빌드에 대한 배경 지식을 다루는 시작 가이드 및 Docker 관련 주제 가이드도 찾을 수 있습니다.

What You Will Need

Linux 또는 Linux와 유사한 명령줄이 필요합니다. 이 가이드의 명령줄 예제는 Linux, 셸이 있는 MacOS 터미널 또는 Windows의 WSL에서 작동합니다.


Install kubectl on Linux

https://kubernetes.io/docs/tasks/tools/

https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/

1. curl로 kubectl binary 설치하기

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

2. binary 검증(validate) 하기

kubectll 체크섬 파일 다운로드

 curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"

체크섬 파일에 대해 kubectl 바이너리의 유효성을 검사합니다.

echo "$(cat kubectl.sha256)  kubectl" | sha256sum --check

3. kubectl 설치하기

sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

4. 설치한 버전이 최신인지 테스트하십시오.

kubectl version --client

Verify kubectl configuration

kubectl이 Kubernetes 클러스터를 찾고 액세스하려면 kube-up.sh를 사용하여 클러스터를 생성하거나 Minikube 클러스터를 성공적으로 배포할 때 자동으로 생성되는 kubeconfig 파일이 필요합니다. 기본적으로 kubectl 구성(configuration)은 ~/.kube/config에 있습니다.

클러스터 상태(cluster state)를 가져와서 kubectl이 올바르게 구성되었는지 확인하세요.

kubectl cluster-info

URL 응답이 표시되면 kubectl이 클러스터에 액세스하도록 올바르게 구성된 것입니다. 다음과 유사한 메시지가 표시되면 kubectl이 올바르게 구성되지 않았거나 Kubernetes 클러스터에 연결할 수 없는 것입니다.

The connection to the server <server-name:port> was refused - did you specify the right host or port?

예를 들어, 노트북에서 (로컬로) Kubernetes 클러스터를 실행하려는 경우 먼저 Minikube와 같은 도구를 설치한 다음 위에 설명된 명령을 다시 실행해야 합니다.

kubectl cluster-info가 URL 응답을 반환하지만 클러스터에 액세스할 수 없는 경우 클러스터가 올바르게 구성되었는지 확인하려면 다음을 사용하세요.

kubectl cluster-info dump

minikube 설치

minikube는 Kubernetes를 쉽게 배우고 개발할 수 있도록 하는 데 중점을 둔 로컬 Kubernetes입니다. 필요한 것은 Docker(또는 이와 유사하게 호환되는) 컨테이너 또는 가상 머신 환경뿐이며 Kubernetes는 단 하나의 명령 minikube start 으로 사용할 수 있습니다.

What you’ll need

  • 2 CPUs or more
  • 2GB of free memory
  • 20GB of free disk space
  • Internet connection
  • Container or virtual machine manager, such as: Docker, QEMU, Hyperkit, Hyper-V, KVM, Parallels, Podman, VirtualBox, or VMware Fusion/Workstation

바이너리 다운로드를 사용하여 x86-64 Linux에 최신 minikube 안정 릴리스를 설치하려면:

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

start your cluster

관리자 액세스 권한이 있는 터미널(root로 로그인하지 않음)에서 다음을 실행합니다.

minikube start

Minikube가 시작되지 않으면 드라이버 페이지에서 호환 가능한 컨테이너 또는 가상 머신 관리자 설정에 대한 도움말을 참조하세요.

Interact with your cluster

이미 kubectl을 설치했다면(문서 참조) 이제 이를 사용하여 반짝이는 새 클러스터에 액세스할 수 있습니다.

kubectl get po -A


Kubernetes 클러스터와 명령줄 도구 Kubectl도 필요합니다. Kind(Docker에서) 또는 Minikube를 사용하여 로컬로 클러스터를 생성할 수 있습니다. 또는 Google Cloud Platform, Amazon Web Services 또는 Microsoft Azure와 같은 클라우드 공급자를 사용할 수 있습니다. 계속 진행하기 전에 셸에서 kubectl 명령을 실행할 수 있는지 확인하세요. 다음 예에서는 kind를 사용합니다.

$ kubectl cluster-info
Kubernetes master is running at https://127.0.0.1:46253
KubeDNS is running at https://127.0.0.1:46253/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

또한 다음 명령을 실행해야 합니다.

$ kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.43.0.1    <none>        443/TCP   7m13s

Create a Spring Boot Application

먼저 Spring Boot 애플리케이션을 만듭니다. 이미 github에서 사용하고 싶은 것이 있다면 터미널에서 복제할 수 있습니다(gitjava는 이미 설치되어 있습니다). 또는 start.spring.io를 사용하여 처음부터 애플리케이션을 생성할 수 있습니다.

curl https://start.spring.io/starter.tgz -d dependencies=webflux,actuator | tar -xzvf -

그런 다음 애플리케이션을 빌드할 수 있습니다.


그레이들(Gradle)을 사용하여 애플리케이션을 빌드할 수 있어요! ./gradlew 명령어는 프로젝트 루트 디렉토리에서 Gradle 래퍼(wrapper)를 실행하여 빌드하는 데 사용됩니다. 이 명령어를 실행하면 프로젝트의 Gradle 스크립트가 실행되어 프로젝트를 빌드하고 필요한 의존성을 다운로드합니다. 만약 Gradle을 사용하여 Java 또는 Kotlin 기반의 애플리케이션을 빌드하려면 ./gradlew build 명령어를 사용할 수 있어요.


그러면 빌드 결과를 볼 수 있습니다. 빌드가 성공하면 다음과 유사한 JAR 파일이 표시됩니다.

ls -l target/*.jar
-rw-r--r-- 1 root root 19463334 Nov 15 11:54 target/demo-0.0.1-SNAPSHOT.jar


./gradlew build로 빌드한 파일은 build/libs 디렉토리에 저장되어있습니다.


JAR은 실행 가능합니다.

java -jar 파일이름.jar

프로젝트를 다운로드할 때 추가한 액추에이터 종속성 때문에 애플리케이션에는 몇 가지 기본 제공 HTTP 엔드포인트가 있습니다. 시작 시 로그에 다음과 유사한 출력이 표시됩니다.

...
2019-11-15 12:12:35.333  INFO 13912 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2019-11-15 12:12:36.448  INFO 13912 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8080
...

그런 다음 다른 터미널에서 endpoint을 curl할 수 있습니다.

$ curl localhost:8080/actuator | jq .
{
  "_links": {
    "self": {
      "href": "http://localhost:8080/actuator",
      "templated": false
    },
    "health-path": {
      "href": "http://localhost:8080/actuator/health/{*path}",
      "templated": true
    },
    "health": {
      "href": "http://localhost:8080/actuator/health",
      "templated": false
    },
    "info": {
      "href": "http://localhost:8080/actuator/info",
      "templated": false
    }
  }
}

  • curl: 커맨드 라인에서 URL을 통해 데이터를 전송하고 받을 수 있는 도구입니다.
  • localhost:8080/actuator: 로컬 호스트의 8080 포트에서 액추에이터 엔드포인트에 요청을 보냅니다. 액추에이터는 스프링 부트 애플리케이션의 모니터링 및 관리를 위한 엔드포인트를 제공합니다.
  • jq .: curl로 받은 JSON을 파싱하고, 보기 좋게 출력하는데 사용되는 도구입니다. .은 jq에게 입력을 그대로 출력하도록 지시합니다.

이 단계를 완료하려면 Ctrl+C를 눌러 애플리케이션을 중지하세요.

Containerize the Application

Spring Boot 애플리케이션을 컨테이너화하는 데는 여러 가지 옵션이 있습니다. 이미 Spring Boot jar 파일을 빌드하고 있는 경우에는 플러그인을 직접 호출하기만 하면 됩니다.

$ ./gradlew bootBuildImage

컨테이너를 로컬로 실행할 수 있습니다.

$ docker run -p 8080:8080 demo:0.0.1-SNAPSHOT

그런 다음 다른 터미널에서 작동하는지 확인할 수 있습니다.

$ curl localhost:8080/actuator/health

컨테이너를 중지하여 완료합니다.
Dockerhub(docker login)로 인증하지 않으면 이미지를 푸시할 수 없지만 작동해야 하는 이미지가 이미 있습니다. 인증을 받은 경우 다음을 수행할 수 있습니다.

$ docker tag demo:0.0.1-SNAPSHOT springguides/demo
$ docker push springguides/demo

실제로는 Kubernetes가 일반적으로 로컬 docker 데몬에 연결되지 않는 Kubelets(노드) 내부에서 이미지를 가져오기 때문에 이미지를 Dockerhub(또는 다른 액세스 가능한 저장소)에 푸시해야 합니다. 이 시나리오의 목적에 따라 푸시를 생략하고 이미 있는 이미지를 사용할 수 있습니다.

테스트를 위해 안전하지 않은 (예를 들어,)로컬 레지스트리에서 docker push가 작동하도록 하는 해결 방법이 있지만 이는 이 가이드의 범위를 벗어납니다.

Deploy the Application to Kubernetes


쿠버네티스에 애플리케이션을 배포하는 것은 당신이 개발한 애플리케이션을 쿠버네티스 클러스터에서 실행할 수 있도록 설정하는 과정을 의미합니다. 이는 애플리케이션을 컨테이너 이미지로 패키징하고, 쿠버네티스가 이 이미지를 사용하여 클러스터 내에서 여러 노드에 분산하여 실행하도록 지시하는 것을 포함합니다.

일반적으로 쿠버네티스에서 애플리케이션을 배포하는 단계는 다음과 같습니다:

  1. 컨테이너 이미지 준비: 먼저 애플리케이션을 실행할 수 있는 컨테이너 이미지를 준비합니다. 이 이미지에는 애플리케이션 코드, 실행에 필요한 종속성 및 설정이 포함됩니다.

  2. 쿠버네티스 리소스 정의: 쿠버네티스는 YAML 또는 JSON 포맷의 매니페스트 파일을 사용하여 애플리케이션 배포를 정의합니다. 이 매니페스트 파일은 애플리케이션을 실행할 파드, 서비스, 인그레스 등의 쿠버네티스 리소스를 정의합니다.

  3. 쿠버네티스 클러스터에 배포: 정의된 쿠버네티스 리소스를 사용하여 쿠버네티스 클러스터에 애플리케이션을 배포합니다. 이 단계에서 쿠버네티스는 애플리케이션을 실행하고 네트워킹 및 로드 밸런싱을 구성합니다.

  4. 상태 모니터링 및 관리: 배포된 애플리케이션의 상태를 모니터링하고 필요한 경우 스케일링, 롤링 업데이트 등의 작업을 수행하여 애플리케이션을 관리합니다.

따라서 쿠버네티스에 애플리케이션을 배포한다는 것은 애플리케이션을 실행할 환경을 설정하고, 클러스터 내에서 안정적으로 실행되도록 하는 과정을 의미합니다.


이제 포트 8080을 실행하고 노출하는 컨테이너가 있으므로 Kubernetes를 실행하는 데 필요한 것은 YAML뿐입니다. YAML을 보거나 편집할 필요가 없도록 지금은 kubectl에 YAML 생성을 요청할 수 있습니다. 여기서 변경될 수 있는 유일한 것은 --image 이름입니다. 컨테이너를 자체 리포지토리에 배포한 경우 다음 태그 대신 해당 태그를 사용하세요.

$  kubectl create deployment demo --image=springg--image=springguides/demo --dry-run=client -o=yaml > deployment.yaml
$ echo --- >> deployment.yaml
$ kubectl create service clusterip demo --tcp=8080:8080 --dry-run -o=yaml >> deployment.yaml

해당 명령어는 먼저 쿠버네티스에 애플리케이션을 배포하기 위해 YAML 매니페스트 파일을 생성하는 과정을 수행합니다.

  1. kubectl create deployment demo --image=springg--image=springguides/demo --dry-run=client -o=yaml > deployment.yaml: 이 명령은 쿠버네티스 클러스터에 demo라는 이름의 배포(deployment)를 생성하고, 해당 배포에 springguides/demo라는 이미지를 사용하도록 지정합니다. --dry-run=client -o=yaml 옵션은 실제로 클러스터에 배포를 만들지 않고 YAML 형식으로 출력하도록 지시합니다. 이를 deployment.yaml 파일에 리다이렉션하여 파일로 저장합니다.

  2. echo --- >> deployment.yaml: 이 명령은 deployment.yaml 파일에 구분을 위해 ---를 추가합니다. 이는 다음 명령어의 결과를 구분하기 위한 것입니다.

  3. kubectl create service clusterip demo --tcp=8080:8080 --dry-run=client -o=yaml >> deployment.yaml: 이 명령은 demo라는 이름의 ClusterIP 서비스를 생성하며, 이 서비스는 8080 포트로 들어오는 트래픽을 배포된 파드의 8080 포트로 전달합니다. 이 또한 --dry-run=client -o=yaml 옵션을 사용하여 YAML 형식으로 출력하고, 이를 deployment.yaml 파일에 추가합니다.

따라서 위 명령어를 실행하면 deployment.yaml 파일에 배포 및 서비스에 대한 정의가 YAML 형식으로 저장됩니다. 이 파일을 사용하여 쿠버네티스 클러스터에 애플리케이션을 배포할 수 있습니다.


위에서 생성된 YAML을 가져와 원하는 경우 편집하거나 그대로 적용할 수 있습니다.

$ kubectl apply -f deployment.yaml
deployment.apps/demo created
service/demo created

애플리케이션이 실행 중인지 확인합니다.

$ kubectl get all
NAME                             READY     STATUS      RESTARTS   AGE
pod/demo-658b7f4997-qfw9l        1/1       Running     0          146m

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/kubernetes   ClusterIP   10.43.0.1       <none>        443/TCP    2d18h
service/demo         ClusterIP   10.43.138.213   <none>        8080/TCP   21h

NAME                   READY     UP-TO-DATE   AVAILABLE   AGE
deployment.apps/demo   1/1       1            1           21h

NAME                              DESIRED   CURRENT   READY     AGE
replicaset.apps/demo-658b7f4997   1         1         1         21h
d

데모 팟(Pod)이 Running 상태로 표시될 때까지 kubectl get all을 반복하십시오.

이제 Kubernetes에서 서비스로 노출한 애플리케이션에 연결할 수 있어야 합니다. 개발 시에 잘 작동하는 한 가지 방법은 SSH 터널을 만드는 것입니다.

$ kubectl port-forward svc/demo 8080:8080

이제 다른 터미널에서 해당 앱이 실행 중인지 확인할 수 있습니다.

$ curl localhost:8080/actuator/health
{"status":"UP"}

0개의 댓글