[쿠버네티스/스프링부트] 스프링부트 프로젝트 파드에 배포하기

    728x90
    반응형

    Web Application On k8s Pod

    도커 환경의 데이터베이스 구성

    DB는 높은 I/O 성능과 안정성이 필요하다. 
    k8s클러스터에서 DB를 실행할 경우, 네트워크나 리소스의 가용성 문제로 성능이 저하될 수 있다.

     

    #MySQL docker-compose yaml파일을 생성
    [root@]$ vi mysql-docker-compose.yml

     

    version: '3.8'
    
    services:
      mysql:
        image: mysql:8.0 # MySQL 버전 설정 (8.0 버전 사용)
        container_name: mysql
        environment:
          MYSQL_ROOT_PASSWORD: root # MySQL root 계정의 비밀번호
        ports:
          - "43306:3306" # 로컬 머신의 43306 포트를 컨테이너의 3306 포트와 연결
        volumes:
          - ${HOME}/docker/volume/mysql:/var/lib/mysql # 데이터 영속성을 위해 로컬 볼륨을 MySQL 데이터 디렉토리에 마운트
        networks: # 다른 컨테이너와의 통신을 위해 사용되는 네트워크 브릿지
          - mysql_network
    
    networks:
      mysql_network:
        driver: bridge

     

    #docker-compose를 사용해 MySQL컨테이너 생성
    [root@]$ docker-compose -f mysql-docker-compose.yml up -d
    
    
    #컨테이너 생성여부 확인
    [root@]$ docker ps
    CONTAINER ID   IMAGE           COMMAND                  CREATED       STATUS       PORTS                                NAMES
    e7ad17baf741   mysql:8.0       "docker-entrypoint.s…"   13 days ago   Up 3 hours   33060/tcp, 0.0.0.0:43306->3306/tcp   mysql

    Dockerfile 작성

    Dockerfile은 Docker 이미지를 자동으로 빌드하기 위한 설정 파일이다.
    Dockerfile로 환경을 자동화하고 일관된 배포 환경을 만들 수 있다.

     

    #Dockerfile 작성
    [root@]$ vi Dockerfile

     

    # 1. OpenJDK 기반 이미지 사용
    FROM openjdk:17-jdk-slim
    
    # 2. 작업 디렉토리 설정
    WORKDIR /app
    
    # 3. 로컬의 bootJar 파일을 Pod의 /app 디렉토리로 복사
    COPY sample-1.0.0-boot.jar /app/sample-1.0.0-boot.jar
    COPY application.yml /app/application.yml
    
    # 4. 애플리케이션 실행
    # java -jar sample-1.0.0-boot.jar --server.port=8080 --spring.config.location=/app/application.yml --spring.profiles.active=local
    CMD ["java", "-jar", "sample-1.0.0-boot.jar", "--server.port=8080", "--spring.config.location=/app/application.yml", "--spring.profiles.active=local"]

     

    도커이미지 빌드

    #도커 이미지 빌드
    [root@]$ docker build -t sample .
    
    
    #도커 빌드 이미지 확인
    [root@]$ docker images
    REPOSITORY                       TAG       IMAGE ID       CREATED        SIZE
    sample                           latest    01062cab75d8   1 days ago    769MB

     

    #도커 이미지 빌드
    [root@]$ docker build -t sample .
    
    #도커 이미지빌드 실행 옵션
    docker build: 
    Docker 이미지를 빌드(생성)하는 명령어.
    주로 Dockerfile이라는 파일을 기반으로 이미지를 생성할 때 사용된다.
    
    -t:
    태그(tag) 옵션.
    이미지를 빌드할 때 이미지에 이름과 태그를 지정할 수 있다.
    -t 뒤에 오는 값은 생성할 이미지의 이름과 태그.
    
    sample:
    빌드할 이미지의 이름. 이미지를 실행하거나 관리할 때 사용된다.
    태그를 생략하면 기본적으로 latest라는 태그가 붙는다.
    
    .: 
    .은 현재 디렉토리를 의미한다.
    docker build 명령은 현재 디렉토리(여기서는 .)에 있는 Dockerfile을 기반으로 이미지를 빌드한다.

     

    도커 이미지 로드

    k8s에서 Pod를 실행하려면 해당 이미지를 Docker Hub나 Harbor와 같은 외부 저장소에서 이미지 pull 이 필요하다.
    오프라인 환경에서 로컬에 이미지를 저장하고 가져오는 작업이 필요하다.

     

    #도커 이미지 로컬 save
    [root@]$ docker save -o sample.tar sample:latest
    
    #도커 이미지 pull
    [root@]$ docker load -i sample.tar
    
    #도커 이미지 save 실행 옵션
    docker save:
    Docker 이미지를 tar 파일로 저장하는 명령어.
    저장된 파일은 다른 시스템으로 이미지를 옮길 때나 백업할 때 유용하다.
    
    -o sample.tar:
    -o는 output의 약자. 저장될 파일 이름을 지정한다.
    
    sample:latest:
    sample:latest는 저장할 대상 이미지명.

    Deployment를 사용해 도커 이미지를 Pod에서 실행

    Deployment는 애플리케이션의 상태를 정의하고 관리하여 원하는 수의 Pod 복제본을 자동으로 생성, 업데이트, 확장 또는 롤백하는 방식으로 애플리케이션을 배포하고 유지하는 리소스

     

    #deployment.yaml 작성
    [root@]$ vi sample-deployment.yaml

     

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sample                        #Deployment의 이름
      labels:
        app: sample                       #'app'='sample' 레이블을 가진 리소스들과 연결됩니다.
    spec:
      replicas: 1                         #파드의 복제본 수(=인스턴스 갯수)
      selector:
        matchLabels:
          app: sample                     #Deployment가 관리하는 Pod들을 찾기 위한 레이블
                                          #'app'='sample' 레이블을 가진 파드들만 Deployment가 관리합니다.
      template: #파드의 템플릿
        metadata:
          labels:
            app: sample                   #파드에 레이블을 추가
                                          #서비스에서 파드를 특정하는(=찾는)데 사용됩니다.
        spec:
          containers:
          - name: sample                  #파드 내 컨테이너의 이름
            image: sample                 #파드 내 컨테이너의 이미지 
            ports:
              - containerPort: 8080       #파드 내 컨테이너 내에서 리슨하는 포트
            imagePullPolicy: IfNotPresent #이미지 풀 정책
                                          #로컬에 이미지가 이미 존재하면 이미지를 다운로드하지 않습니다.

     

    #도커 이미지를 파드 컨테이너로 배포
    [root@]$ kubectl apply -f sample-deployment.yaml
    deployment.apps/sample-deployment created
    
    #apply 실행 옵션
    kubectl:
    k8s클러스터와 상호작용하는 명령어.
    kubectl을 사용하여 클러스터에서 작업을 수행하고, 배포, 서비스, 파드 등의 k8s리소스를 관리할 수 있다.
    
    apply:
    k8s리소스 정의 파일을 클러스터에 적용하는 명령어.
    kubectl apply는 리소스를 생성하거나 업데이트한다.
    예를 들어, 이미 배포된 리소스가 있으면 정의 파일에 변경 사항이 있을 경우, 그 변경 사항을 적용하여 업데이트한다.
    
    -f:
    파일(file)을 의미하는 옵션.
    -f 뒤에 YAML 파일을 지정하면, 해당 파일에 정의된 리소스를 클러스터에 적용한다.
    
    sample-deployment.yaml:
    k8s리소스를 정의한 YAML 파일.
    k8s클러스터에서 배포할 애플리케이션의 구성, 파드 설정, 레플리카 수 등 여러 정보를 포함하고 있다.

     

    #Pod 배포 확인
    [root@]$ kubectl get po
    NAME                                    READY   STATUS    RESTARTS         AGE
    sample-7db6d8ff4d-dxfbx                 1/1     Running   20 (3h44m ago)   41d
    
    
    #Pod 상태 확인
    [root@]$ kubectl describe po 파드명

     

    #로그를 확인해 Pod가 정상적으로 실행이 되었는지 확인
    [root@]$ kubectl logs -f 파드명

    Service를 통해 외부에서 접근

    여러 Pod에 대한 안정적인 네트워크 액세스를 제공하고, 로드 밸런싱과 서비스 디스커버리를 통해 클러스터 내에서 애플리케이션 간의 통신을 관리하는 리소스

     

    #service.yaml 작성
    [root@]$ vi sample-service.yaml

     

    apiVersion: v1
    kind: Service
    metadata:
      name: sample-service      #Service의 이름
    spec:
      selector:
        app: sample             #'app'='sample' 레이블을 가진 파드들과 연결
                                #레이블은 Deployment에서 정의된 파드들과 반드시 일치!
      ports:
        - protocol: TCP
          port: 18080           #외부에서 접근할 포트
          targetPort: 8080      #파드 내 컨테이너에서 리슨하는 포트
      type: LoadBalancer        #외부에서 접근할 수 있도록 NodePort 타입 사용

     

    #서비스 리소스 실행
    [root@]$ kubectl apply -f sample-service.yaml
    service/sample-service created
    
    #서비스 상태 확인
    [root@]$ kubectl get service
    NAME             TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)           AGE
    sample-service   LoadBalancer   10.97.74.254   localhost     18080:18083/TCP   9s

     

    배포 및 외부 접근 확인

    728x90
    반응형

    댓글