-
쿠버네티스 (클라우드) 환경에서 Front(React)와 Back(Spring boot) 의 API 통신에 대한 방법 (API 호출 주체 = 사용자의 브라우저)
2026. 6. 8.
쿠버네티스 환경에서 프론트엔드와 백엔드를 어떻게 연결할지 이야기하기 전에, 먼저 짚고 넘어가야 할 게 있다.
"API를 호출하는 게 누구인가?"
이 질문에 제대로 답하지 못하면 클라우드 환경에서 왜 localhost가 안 되는지,CORS가 왜 발생하는지, 도메인 전략을 왜 고민해야 하는지 이해할 수 없다.
React로 프론트엔드를 개발하면 빌드 결과물은 결국 HTML, CSS, JS 파일이다.
이 파일들이 브라우저에 로드되고, JS가 실행되는 곳은 사용자의 브라우저다.
버튼 클릭 시 API를 호출하는 코드를 작성한다고 하자.const fetchUser = async () => { const res = await axios.get('http://localhost:8080/api/users/me'); return res.data; };로컬 개발 환경에서는 잘 동작한다. 개발자의 컴퓨터에서 브라우저가 열리고, 같은 컴퓨터에서 Spring Boot가 실행 중이니 localhost:8080은 유효한 주소다.
문제는 서비스를 클라우드에 배포하면서 시작된다.
사용자가 브라우저로 웹사이트에 접속했다. 버튼을 클릭하면 위의 코드가 실행된다.
localhost:8080으로 요청을 보낸다.
여기서 localhost는 누구의 localhost인가?
바로 사용자의 브라우저(컴퓨터)이다. 당신이 올린 클라우드 서버가 아니다.
사용자의 localhost:8080에는 아무것도 없다. 고로, 요청은 작동하지 않는다.
이것이 핵심이다.
API를 호출하는 주체는 서버가 아니라 사용자의 브라우저다.
React 서버가 API를 호출하는게 아니라, 브라우저에 다운로드된 JS 코드가 사용자의 네트워크에서 API를 호출하는 것이다.
즉, 사용자 브라우저 -> React Server -> Spring Boot 서버
가 아니라,
사용자 브라우저 -> JS실행 -> Spring Boot 서버
로 통신이 진행 된다는 것이다.
그럼 결론은 단순하다.
백엔드 API가 인터넷에 공개되어 있어야 한다.
가령 백엔드 API가 공인IP주소를 가지고 있는 1.1.1.1 이라면, JS에서 1.1.1.1/api/users/me 를 호출하면 되는거 아니겠는가?
실제로 네이버 쇼핑 페이지의 F12로 개발자 도구 -> 네트워크 탭을 열어보면 이런 요청을 볼 수 있다.

https://msearch.shopping.naver.com/remote_frame_storage.js 여기서 URL 요청인 " https://msearch.shopping.naver.com/remote_frame_storage.js" 를 실제 주소창에 입력하면?
정보가 나온다.
즉, 프론트가 백엔드에 요청하는 주소는 인터넷 세상을 통해서 닿을 수 있어야 한다.
그럼 여기서 또 다른 문제가 인터넷에 공개되면 누구나 호출할 수 있다는 것이다.
맞는 말이다.
그래서 통제가 필요하다.
방법은 여러가지가 있는데, 일반적으로 많이 사용하는 인증토큰과 IP화이트리스트 등이 있다.
그 중 브라우저 수준에서 동작하는 메커니즘이 Same-Origin Policy(이하 SOP)와 CORS가 있다.
브라우저는 기본적으로 SOP가 적용 된다.
Origin은 프로토콜+도메인+포트의 조합이다.

브라우저는 위의 표 처럼 같은 Origin이 아닌 곳으로의 요청은 차단한다.
즉, https://example.com에서 로드된 JS가 https://api.example.com을 호출하면? 다른 Origin이므로 브라우저가 차단한다. 이게 CORS 에러다.
CORS는 서버가 위의 제한을 명시적으로 허용하는 장치이다.
요컨데 브라우저는 다른 Origin으로 요청을 보내기 전에 서버에게 먼저 물어본다.
"나 API /api/users/me 호출할건데, 내 오리진은 https://www.example.com이야. 허용해줄래?"
이때 서버가 "내 설정에 Access-Control-Allow-Origin: https://www.example.com 이랑 Access-Control-Allow-Methods: GET, POST 이 있네. 너의 Origin 은 허락된 오리진이니까 허락할게."
하며 통신이 진행된다.실제 동작은 이런식으로 도메인을 구성한다.
프론트엔드: https://www.example.com
백엔드 API: https://api.example.com위 두 주소는 서브도메인이 다르므로, 엄밀히 말하면 다른 Origin이다. 따라서 위처럼 Origin 설정이 필요하다.
다만 같은 도메인(example.com)아래에 있기 때문에 관리가 용이하고, 무엇보다 외부의 전혀 다른 도메인에서 오는 요청은 서버가 허용하지 않으므로, 무분별한 API접근을 막을 수있다.
실제는 아래처럼 코딩 되어있을 것이다.
react(프론트) 접근이 가능한 LB가 있을 것이고,
API 접근이 가능한 LB가 있을 것이다.
이 각각의 LB에 host와 DNS설정을 통해 지정된 주소로만 접속 가능하도록 설정한다.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: react-web ..... tls: - hosts: - example.co.kr .... - host: example.co.kr http: paths: - path: / pathType: Prefix backend: service: name: frontend port: number: 80그리고 스프링 부트의 LB에는 아래처럼 마찬가지로 host가 지정된 ingress파일이 있을 것이다.
apiVersion: networking.k8s.io/v1 kind: Ingress .... - hosts: - api.example.co.kr ....여기서 프론트에서는 api.example.co.kr 을 호출하도록 설정하고,
api.example.co.kr과 연결된 스프링 부트에서는 example.co.kr 에서 온 요청만 받도록 CORS 설정을 하면 된다.
그럼 브라우저는 example.co.kr에서 로드된 JS로 api.example.co.kr을 호출하고,
Spring Boot는 example.co.kr에서 온 요청만 허용한다.
외부의 다른 도메인에서 이 API를 직접 호출하려 하면 CORS에 의해 브라우저 수준에서 차단된다.
앞서 설명한 개념들이 Spring Boot와 쿠버네티스 Ingress 설정 몇 줄로 그대로 구현되는 것이다.'네트워크' 카테고리의 다른 글
가비아 + Cloudflare + Let's Encrypt + Kubernetes 실전 연동. (0) 2026.06.07 도메인과 인증서, 뭐가 다른가? : 가비아 + Cloudflare + Let's Encrypt + Kubernetes 실전 연동. 가비아를 사용하면 발생하는 문제점(?) (0) 2026.06.07 SSH 포트는 살아있지만 로그인이 안될때 (0) 2026.05.29 업링크 Uplink & 다운링크 Downlink (0) 2023.03.16 파이버 채널(Fibre Channel) (0) 2023.03.16 댓글
