파이널 프로젝트 - 15주차 4일(3/30)

최수환·2023년 3월 30일
0

Kubernetes

목록 보기
69/75
post-thumbnail

Backend 와 Frontend 연결

  • Backend 파이프라인 구축 작업은 마무리한 상태에서 Frontend 도커라이징 테스트를 완료하였다. Frontend 파이프라인 구축 작업에 앞서 일단 생성한 Frontend 이미지로 배포한 웹과 Backend 서버가 연결이 잘 되는지 확인작업을 할 것이다.
  • 확인을 위해 이전에 했던 Frontend 도커라이징 작업을 조금 수정하여 다시 진행할 것이다.
vi vite.config.js

server:{
      proxy:{
        "/api":{
          target: "<Backend 주소>",
          rewrite: (path)=>path.replace(/^\/api/,""),
        },
      }
    }
  • 위의 코드와 같이 프론트엔드의 Dockerfile을 빌드하기 이전에 구파일에서 target에 Backend의 퍼블릭 주소를 등록해준다.

1 . Dockerfile 수정

FROM node:lts-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:stable-alpine
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx",  "-g", "daemon off;"]

2 . Dockerfile에서 빌드될 nginx.conf 작성

server {
  listen 80;
  client_max_body_size 5M;
  server_name _;

  location / {
    root /usr/share/nginx/html/;
    index index.html;
    try_files $uri $uri/ /index.html;
  }
}
  • nginx.conf파일 추가 및 Dockerfile을 빌드한다.
  • 빌드를 통해 생성된 이미지를 태깅 후 DockerHub에 Push한다.
  • 이후 해당 이미지를 ArgoCD와 연동중인 Git의 Front-deployment 기존 이미지와 교체한다.
  • ArgoCD에서 정상적으로 Frontend가 배포되는 것을 확인

Backend와 RDS 연결

vi src/main/resources/application-aws.yml

spring:
  datasource:
    url: jdbc:mysql://<RDS 엔드포인트 주소>:<포트 번호>/<데이터베이스>?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
    username: <RDS 사용자이름>
    password: <RDS 패스워드>
    driver-class-name: com.mysql.cj.jdbc.Driver
  • Backend의 경우 이미 파이프라인이 구축되어있기 때문에 WorkDIR에서 해당 코드를 수정후 add, commit, Push를 한다.
  • 아직 Jenkinsfile에 pollSCM을 설정하지는 않았기 때문에 수동으로 Jenkins에서 빌드한다.
  • 파이프라인의 과정을 거치고 자동으로 ArgoCD에서 RDS가 연동된 새로운 백엔드 서버의 이미지를 파드로 배포한다.

결과 테스트

  • 아직 Frontend의 파이프라인은 구축하지 않았지만 어쨋든 Frontend를 이미지화 시키는 것에 성공했다.
  • 이후 Frontend - Backend - DB를 연동 시키는 작업을 마무리했고, 브라우저에 https://도메인 을 입력했을 때 아래와 같이 웹페이지가 정상적으로 나타난다.
  • 하지만 로그인창에 id/passwd를 입력했을 때, 회원가입에 정보를 입력했을 때 다음 페이지로 넘어가지 않고 405에러가 발생하였다.
  • 이후 포스트맨을 통해 3-tier중 어디에 문제가 발생하였는지 알고자했다.
    • 포스트맨에서 백엔드서버주소/admin/auth/signup 경로에 회원가입 정보와 함께 요청을 보냈다.
      ( = Frontend가 하는 일을 임의로 수행)
    • 이후 mysql -u admin -p -h <RDS 주소>를 입력하여 RDS에 접속 후 아래와 같이 명령어를 입력하였다

      show databases; # test 데이터베이스 확인
      use test; # test 데이터베이스 사용
      show tables; # test데이터베이스가 가진 table 확인
      select * from admin; # admin table의 저장된 정보 확인

    • 정보를 확인한 결과 포스트맨에서 보낸 회원가입 정보가 저장되어 있는 것을 확인하였다. 즉, 백엔드 서버와 DB가 정상적으로 연결되어 작동하는 것이였다.
    • 마찬가지로 포스트맨에서 백엔드주소/admin/auth/login 경로에 이전에 회원가입한 정보와 함께 요청했다.
    • 이미 DB에 회원가입한 정보가 존재하므로 정상적으로 login이 되는 것 또한 확인하였다.
    • 결과적으로, 405에러는 프론트엔드의 에러인 것이다.
  • 405에러는 http 메소드를 사용할 수 없다는 오류인데 이것에 대해서는 정확한 원인을 아직 찾지 못하였기 때문에 충분한 자료조사와 테스트를 거쳐서 해결해나갈 에정이다.

📒 사실 이전에 3-tier 연결을 했을 때는 404에러가 발생했었고, nginx에 문제인거 같아서 위와같이 nginx.conf파일을 생성하고 이 파일을 default.conf로 지정하는 Dockerfile을 작성해서 새로 이미지를 빌드한것 이였다

Deploy Strategy

vi front-deployment

. . .
spec:
  strategy:
      type: RollingUpdate
      rollingUpdate:
        maxUnavailable: 1
        maxSurge: 0
    minReadySeconds: 20
. . .


vi back-deployment

. . .
spec:
  strategy:
      type: RollingUpdate
      rollingUpdate:
        maxUnavailable: 1
        maxSurge: 0
    minReadySeconds: 20
. . .
  • 위에서 새로 배포하는 과정에서 자꾸 새로운 파드에 Pending이 걸렸다. 이 파드의 로그를 확인해보니 Affinity룰이 위반되었다는 로그였다.
  • Rolling Upadte를 통해 배포하는데 maxSurge의 기본값은 파드 개수의 25%의 올림이다. 즉 maxSurge는 1이다. 따라서 배포과정에서 replicas = 2를 유지하지않고 일시적으로 초과할 수 있는 파드의 개수가 1개라는 것이다.
  • 따라서 새로운 이미지가 적용된 파드가 하나 생성되고, 순간 파드의 개수는 3개가 된다. 이 파드가 정상적으로 작동하면 기존의 이미지가 적용된 파드를 삭제하면서 다시 파드의 개수가 2를 유지하게 되는 것이다.
  • 문제는 이렇게 초과된 1개의 파드는 Affinity룰에 의해서 노드에 스케줄링될때 반드시 Backend / Frontend 파드와 같이 배치되어야 하며 Backend파드가 이미 존재하는 노드에는 배치될 수 없다. 쉽게말해, Backend 파드가 Rolling Update에 의해 초과되어 생성되고 노드에 스케줄링 될때 이미 노드에는 Backend파드가 각각 배치되어 있기 때문에 새로운 Backend 파드는 Affinity룰에 의해 더이상 배치될 수 있는 노드가 존재하지않는다. 따라서 새로운 파드는 스케줄링되지 않고, 더이상 Rolling Update는 진행되지 않는다.

이러한 문제를 해결하기 위해 deployment에 위의 코드와 같이 strategy를 적용하였다.

  • maxSurge값을 0으로 지정함에 따라 Rolling Update과정중에 임시적으로 초과할 수 있는 파드의 개수를 0개로 지정했다. 따라서 새로운 이미지가 적용된 파드가 먼저 생성되는 것이아니라 기존의 이미지가 적용된 파드를 삭제하고 이에 따라 replica개수가 하나가 줄었음으로 그제서야 새로운 이미지가 적용된 파드를 하나 생성한다.
  • 이런 strategy를 적용하니 새로운 버전의 파드가 정상적으로 배포되는 것을 확인한다.
  • 다만, Rolling Update는 새로운 이미지가 적용된 파드를 우선적으로 생성해보고 문제가 없다면 그제서야 기존의 이미지가 적용된 파드를 삭제하면서 새로운 버전으로 배포하는 방식이다. 이것은 잘못된 배포를 할 경우에 새로운 배포를 중단하고 기존의 파드를 유지할 수 있다는 장점이 있다. 따라서 maxSurge 값을 0으로 지정하면서 기존의 이미지가 적용된 파드를 먼저 삭제하는 것은 잘못된 배포를 하는 경우에 기존의 서비스에 다운타임이 발생할 수 있다는 위험이 있을 수 있을 것 같다.
profile
성실하게 열심히!

0개의 댓글