티스토리 뷰

 


1. Ingress External IP로 접속 시 502 Bad gateway 에러 해결 

저번 2주 차 회고에서 인그레스의 external IP로 접속했을 때 프론트엔드 파드 통신조차 동작하지 않았다. (원인은 502 gateway)

원인을 풀어보자면 Ingress ➡️ 프론트엔드 서비스 ➡️ 프론트엔드 파드로 포워딩이 이뤄지지 않은 것인데 구체적으로 어떤 걸 고쳐야 하는지 전혀 알 수 없어서 정말 많이 헤맸다. 

크롬의 개발자 도구를 띄워보아도 도움 될만한 힌트는 찾을 수 없었다.

 

이 과정에서 Kubectl이 제공하는 기능 중 '파드의 로그'를 확인할 수 있는 명령어가 있어서 프론트엔드 파드를 확인해 보았다.

kubectl logs -f [파드 명]

-f를 붙이면 로그가 실시간으로 출력된다.

여기서 빨간 박스로 표시한 'App running at' 부분에 주목해 보자. 로컬과 네트워크 부분으로 나뉘어 있는데, 여기서 주목할 것은 네트워크 부분이다.  

네트워크 주소의 IP 부분은 클러스터 내 파드의 IP 주소이고 포트 번호가 8080으로 열려있는 것을 알 수 있다.

당시 프론트엔드 디플로이먼트에서 파드에 할당하는 주소는 3300이었고 따라서 프론트엔드 서비스가 파드를 향해 보고 있는 포트 번호도 3300이었다. 그런데 웬걸 로그를 찍어보니 파드가 실제로 동작하고 있던 포트 번호는 8080이었다. 실제 포트 번호를 제대로 확인하지 않은 실수를 저지르고 헤매고 있던 것이다.

 

그래서 프론트엔드 서비스와 디플로이먼트 매니페스트를 3300➡️ 8080으로 수정하고 apply 해보니..!

짜잔

프론트엔드 화면을 드디어 만날 수 있었다. 

2. 백엔드 파드와 통신 실패: 또다시 만난 502 Bad Gateway

하지만 로그인이나 회원가입처럼 백엔드 파드와 통신이 필요한 기능에 대해서는 먹통이었다. (산 넘어 산..⛰️)

백엔드 파드와 프론트엔드 파드가 인그레스를 통해 통신할 수 있도록 하기 위해 아래와 같은 과정을 진행했다.

 

[1] 기존 서비스 코드 수정

기존 서비스는 로컬에서만 돌려도 됐기 때문에 프론트엔드 소스 코드 중 get이나 post로 api request를 요청하는 url 부분에 localhost IP가 적혀있었다. 이제 클러스터에서 작동해야 하니 이를 수정하는 게 당연하다.

 

첫 번째 시도: backend-service 네임 DNS 사용하기

프론트엔드 파드와 백엔드 파드는 같은 클러스터 내부에 존재하기 때문에 서로의 DNS나 Cluster IP로 접근할 수 있다. 그러니까 우리의 첫 번째 아이디어는 'api url에 "http://sc-backend-service"이렇게 구성해서 api를 쏴주면 클러스터 내에서 알아서 요청을 서로 주고받지 않을까?'였다. 

하지만 여전히 서버는 sc-backend-service:8080을 찾지 못했다..

 

두 번째 시도: 그때 문득 든 생각. 생각해 보니 이건 클러스터 내부에서 서로 통신을 주고받는 것이 아니다. 외부에서 "api/" 경로로 요청을 보내면 인그레스는 그걸 백엔드 서비스에 포워딩하고, "/" 경로에 대한 요청은 프론트엔드 서비스에 포워딩하는 것이다. 그러니까 애초에 백엔드 서비스 DNS를 클러스터 외부에서 요청하면 서버는 어디에서도 찾을 수 없는 것이다. 

 

그래서 생각해 낸 방법은 우리 서비스의 DNS를 생성하고 거기서 뒤에 붙는 경로가 "/"인지, "/api"인지에 따라 인그레스가 포워딩할 수 있도록 하는 것이다.


그러기 위해선 우선 임시로 DNS를 로컬에 등록해 주는 과정이 필요하다. 실제 DNS를 구매하거나 무료로 할당하는 방법도 있지만 우선 테스트를 위해 로컬에만 임시 등록하는 방법을 사용했다.

(이후에 최종 발표때 시연을 위해 무료 DNS를 할당받을 예정이다. 그러므로 현재 임시 등록한 DNS는 변동될 수 있다.)

 

Window 기준 etc/hosts 파일 수정 방법

1) CMD 관리자 권한으로 실행하기

 

2)  C:\Windows\System32\drivers\etc 경로로 이동

cd drivers/etc

(디폴트로 C:\Windows\System32 위치에서 CMD가 실행되므로 아래 명령어만 사용하면 이동할 수 있다.)

 

3) `notepad hosts` 명령어로 hosts 파일 열기

4) hosts 파일에 IP 주소와 DNS 작성하기

 

[5] Ping을 날려서 잘 등록됐는지 확인한다

 


기존 소스코드 api url 수정 

이제 DNS를 등록해 줬으니 프론트엔드 소스 코드의 api url을 수정해 주자.

우리 서비스의 DNS인 sc-chatting.com/api/[나머지 경로]로 수정해 주었다. 아래는 수정한 회원가입 코드 중 일부이다. 

await axios
    .post("http://sc-chatting.com/api/signup", data, {
      headers: {
        "Content-Type": "application/json",
      },
    })
    .then(function () {
      inject_alert("회원가입에 성공하셨습니다!");
      router.push("/login");
    })
    .catch((error) => {
      console.log("Error " + error.response.status);
      console.log("Log " + error);
      inject_alert("회원가입 실패");
    });

Ingress manifest 파일 수정

host 태그를 추가해서 아까 임시로 생성했던 나의 DNS "sc-chatting.com"을 등록했다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sc-ingress
spec:
  ingressClassName: nginx
  rules:
    - host: sc-chatting.com			# DNS 설정하기
      http:
        paths:
          - path: "/api"
            pathType: Prefix
            backend:
              service:
                name: sc-backend-service
                port:
                  number: 5000
          - path: "/"
            pathType: Prefix
            backend:
              service:
                name: sc-frontend-service
                port:
                  number: 80

호기롭게 시도한 DNS 생성해서 인그레스에 호스트 할당하기!

하지만 결과는.... 여전히 백엔드 파드와 통신을 전혀 못하고 있었다.

결국 교수님께 도움을 요청했고 교수님께서는 정말 근본적이고 단순한 문제점을 지적해 주셨다.

 

바로 현재 우리는 '어떤 게 문제인지 모른다는 것이 문제'라는 것이다.

문제를 해결하기 위해서는 인그레스의 로그를 확인해 보라는 힌트를 주셨다.

이번 과제로 '로그'의 중요성을 크게 깨달았다.

 

다른 클러스터 오브젝트들의 로그를 찍는 명령어는 아래와 같이 간단하다.

kubectl logs [파드 명]

그런데 Ingress에는 logs 명령어가 적용되지 않았다. 그래서 인그레스의 로그를 확인하는 명령어를 찾는 것에도 꽤 시간이 걸렸는데 결국 찾아낸 명령어는 아래와 같다. 아래 명령어는 인그레스 컨트롤러를 'ingress-nginx-controller'로 사용하는 경우에만 적용 가능 하다. 

 

인그레스 로그 확인 명령어

kubectl logs -n ingress-nginx deployments/ingress-nginx-controller -f

해당 명령어를 입력하니 오류 메시지가 와라락 출력되었다. (어찌나 반갑던지.. 😂)

 

로그인 버튼 클릭 시 출력된 오류 메시지

2023/12/08 15:58:22 [error] 99#99: *8543 connect() failed (111: Connection refused) while connecting to upstream, client: 118.129.174.58, server: sc-chatting.com, request: "POST /api/login/enter HTTP/1.1", upstream: "http://10.48.1.13:3300/api/login/enter", host: "sc-chatting.com", referrer: "http://sc-chatting.com/login"
118.129.174.58 - - [08/Dec/2023:15:58:22 +0000] "POST /api/login/enter HTTP/1.1" 502 552 "http://sc-chatting.com/login" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36" 458 0.004 [default-sc-backend-service-5000] [] 10.48.1.13:3300, 10.48.1.13:3300, 10.48.1.13:3300 0, 0, 0 0.002, 0.001, 0.000 502, 502, 502 d3d0343f98649f9fe09d040fba1a7ec2

이렇게 끝도 없이 길고 복잡한 에러 메시지가 출력돼도 두렵지 않다. 나에겐 만능 통역사 GPT가 있으니까!

해당 오류 메시지를 가지고 GPT에게 물어보니

 

서버 다운...?! 설마 

하고 백엔드 파드에 bash로 직접 들어가 보니 도커파일에 분명히 작성해 둔 백엔드 서버를 실행하는 명령어인 'node server.js'가 작동하지 않는 것을 확인했다.

 

이때 파드에 bash로 직접 접속하는 명령어는 아래와 같다.

kubectl exec -it [파드 명] -- bash

 

그래서 백엔드 파드 bash 접속 후 직접 서버 실행 명령어를 입력하고

Server runnung on port:3300 예감이 좋다

 

홈페이지에 접속해 보니..!!

!!!!!

 

로그인에 성공해야지만 들어올 수 있는 메인 보드 화면

 

드디어 인그레스를 통한 프론트엔드 파드와 백엔드 파드의 통신에 성공했다!!!

 


3. 앞으로

최종 발표를 일주일도 안 남기고 드디어 정말 큰 산을 넘어서 너무 마음이 놓인다. 하지만 아직 해결해야 할 과제들이 남아있다.  남은 기간 동안 더 열심히 달려보자!

- 백엔드 파드에서 자동으로 서버를 동작시키도록 도커 파일 수정하기

- 실시간 채팅 기능을 지원하는 웹소켓 연결 구현하기

- DB 디플로이먼트에 시크릿 적용해 수정하기

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함