훈훈훈

Kubernetes :: 로컬 환경에서 웹 서버 구축하기 본문

인프라/Kubernetes

Kubernetes :: 로컬 환경에서 웹 서버 구축하기

훈훈훈 2020. 7. 6. 00:03

이번에는 쿠버네티스를 사용해서 웹 서버를 구축하려고 한다.

 

사실 AWS와 같은 클라우드 벤더사를 사용할 경우 로컬 내에서 웹 서버랑 데이터 베이스 서버를 동시에 실행 시킬 일은 없지만,

쿠버네티스에 대한 개념도 잡을 겸 해보았다.

 

예제로 사용한 웹 서버는 이전 글에서 Spring boot와 코틀린으로 작성한 코드를 사용하였다.

 

사용한 기술은 아래와 같다.

-  Spring boot

-  Postgresql

-  Docker

-  Kubernetes

-  Helm

 

구성도는 아래와 같다.

 

웹 서버(Spring boot)와 DB서버(Postgresql) 컨테이너를 각각 파드로 나누었다.

그 다음 서비스도 서로 다른 포트로 통신하기 때문에 서로 다른 서비스로 나누었다.

 

Service까지 설정이 되면 이제 파드에 접근할 수 있게 웹 서버 파드를 가지고 있는 서비스로 포트 포워딩 설정만 해주면 끝난다.

 

여담이지만, 실제 서버를 운영할 때 DB서버를 파드로 배포할 일은 흔치 않다.

왜냐하면 DB서버는 절대로 중단되서는 안되는 서버이기 때문이다.

AWS 운영 시 디비 서버는 RDS를 사용하고 그 외 서버들은 EKS와 같은 서비스로 운영하는게 좋다.

 

이제 각각의 코드들을 살펴보자.

 

 

프로젝트 구성

프로젝트 구성은 위와 같으며 kubernetes 관련 파일들은 devops 하위 디렉터리에 생성하였고, Helm으로 관리하였다.

Helm Create로 만든 파일 중 사용하지 않은 파일들은 모두 삭제했다,

 

 

DockerFile

FROM java:8

EXPOSE 8080

ARG JAR_FILE=build/libs/rest-exam-0.0.1.jar

ADD ${JAR_FILE} rest-exam.jar

ENTRYPOINT ["java","-jar", "/rest-exam.jar"]

-  도커 파일 빌드 및 레포지토리 푸쉬

아래 명령어는 본인 환경에 맞게 수정해서 사용하면 된다.

❯ docker build -t kk03187693/rest-exam:0.6 .
❯ docker push kk03187693/rest-exam:0.6

 

위 명령어를 사용하고 도커 허브로 들어가면 아래와 같이 푸쉬가 정상적으로 된 것을 볼 수 있다.

 

 

 

deployment-postgresql.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres-server-deployment
  labels:
    app: postgres-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres-server
  template:
    metadata:
      labels:
        app: postgres-server
    spec:
      containers:
        - name: postgresql
          image: postgres
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_USER
              value: kwanghoon.kim
            - name: POSTGRES_DB
              value: springexam
            - name: POSTGRES_PASSWORD
              value: password

테스트용으로 작성한 코드이기 때문에 replicas 는 1로 설정하였다.

containers 설정을 살펴보면 container port는 postgresql 디폴트 포트로 잡았고 env 설정은 application.yaml 설정과 동일하게 했다.

 

 

deployment-server.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-server-deployment
  labels:
    app: spring-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spring-server
  template:
    metadata:
      labels:
        app: spring-server
    spec:
      restartPolicy: Always
      containers:
        - name: spring
          image: kk03187693/rest-exam:0.6
          imagePullPolicy: Always
          ports:
            - containerPort: 8080

서버 파일도 위에서 작성한 postgresql 파일과 거의 동일하게 작성하였다.

 

 

service-postgres.yaml

apiVersion: v1
kind: Service
metadata:
  name: postgres-server-service
spec:
  clusterIP: None
  ports:
    - port: 8080
      targetPort: 5432
      protocol: TCP
      name: db-port
  selector:
    app: postgres-server

 

service-postgresql 파일은 위에서 작성한 deployment-postgresql 에서 설정한 label 을 selector로 설정하였다.

그리고 외부에서 로드 밸런싱을 할 필요가 없고 내부 Cluster IP도 필요하지 않아 headless service로 작성하였다. 

 

포트는 web-server port는 8080 이고 DB port는 5432이기 때문에 위와 같이 작성하였다.

 

 

service-server.yaml

apiVersion: v1
kind: Service
metadata:
  name: spring-server-service
spec:
  clusterIP: None
  ports:
    - port: 8080
      targetPort: 8080
      protocol: TCP
      name: server-port
  selector:
    app: spring-server

서버 파일도 위에서 작성한 postgresql 파일과 거의 동일하게 작성하였다.

 

 

application.yaml

spring:
  datasource:
    url: jdbc:postgresql://postgres-server-service.default.svc.cluster.local:5432/springexam
    username: kwanghoon.kim
    password: password
    driverClassName: org.postgresql.Driver

마지막으로 application.yaml에서 DB 서버에 관한 설정을 하였다.

쿠버네티스에서 파드는 영속적인 객체가 아니기 때문에 재시작 하는 경우가 생기는데 이때 IP가 바뀌게 된다.

이에 대한 해결책은 쿠버네티스에서 제공하는 DNS를 사용하여 URL을 만들었다.

 

 

파일이 세팅이 되었다면 이제 아래 명령어로 실행시켜 보자

helm install product-api .

 

이제 생성된 svc, deployment, pod를 조회해보자

❯ kubectl get svc        
NAME                      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
kubernetes                ClusterIP   10.96.0.1    none          443/TCP    19m
postgres-server-service   ClusterIP   None         none          8080/TCP   18m
spring-server-service     ClusterIP   None         none          8080/TCP   18m

❯ kubectl get deployments
NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
postgres-server-deployment   1/1     1            1           19m
spring-server-deployment     1/1     1            1           19m

❯ kubectl get pods -o wide
NAME                                          READY   STATUS    RESTARTS   AGE   IP          NODE             NOMINATED NODE   READINESS GATES
postgres-server-deployment-6887b5cdcb-r9ff4   1/1     Running   0          19m   10.1.1.50   docker-desktop   <none>           <none>
spring-server-deployment-5fcc9df984-4svf6     1/1     Running   0          19m   10.1.1.51   docker-desktop   <none>           <none>

 

웹 서버가 정상적으로 실행되었는데 웹 서버 컨테이너를 담고 있는 파드 로그를 조회해보았다.

❯ kubectl logs -f [PodName]

 

아래와 같이 정상적으로 실행된 것을 확인할 수 있다.

 

 

그 다음 DB가 정상적으로 생성되었는지 확인해보자.

❯ kubectl exec -it [PodName] bash

아래와 같이 정상적으로 생성된 것을 알 수 있다.

 

 

마지막으로 파드 끼리는 통신할 수 있지만 파드로 접근하기 위해서는 별로 설정이 필요하기 때문에

127.0.0.1:8080으로 접근할때 웹 서버 파드를 가지고 있는 서비스로 포트 포워딩 설정을 해주었다,

❯ kubectl port-forward [ServieName] 8080 8080

 

실행 결과는 아래와 같다.

-  post 요청

 

-  get 요청

Comments