1. 소개
개요
많은 조직에서 서비스와 애플리케이션의 네트워크 트래픽을 보호하기 위해 경계 제어가 포함된 Google Cloud에서 데이터 무단 반출을 방지하는 Virtual Private Cloud (VPC) 네트워크를 사용합니다. VPC 네트워크는 Google의 프로덕션 네트워크 내에서 구현되는 물리적 네트워크의 가상 버전입니다. VPC 네트워크는 Compute Engine 가상 머신 (VM) 인스턴스에 연결을 제공하고, 내부 애플리케이션 부하 분산기를 위한 기본 내부 패스 스루 네트워크 부하 분산기 및 프록시 시스템을 제공하며, Cloud VPN 터널 및 Cloud Interconnect용 VLAN 연결을 사용하여 온프레미스 네트워크에 연결하고, Google Cloud 외부 부하 분산기에서 백엔드로 트래픽을 분산합니다.
VM과 달리 Cloud Run 서비스는 기본적으로 특정 VPC 네트워크와 연결되지 않습니다. 이 Codelab에서는 VPC에서 들어오는 트래픽만 Cloud Run 서비스 (예: 백엔드 서비스)에 액세스할 수 있도록 인그레스 (인바운드 연결) 설정을 변경하는 방법을 보여줍니다. 또한 이 Codelab은 두 번째 서비스 (예: 프런트엔드 서비스)가 VPC를 통해 백엔드 Cloud Run 서비스에 액세스하도록 하는 방법을 보여줍니다.
이 예시에서는 백엔드 Cloud Run 서비스가 Hello World를 반환합니다. 프런트엔드 Cloud Run 서비스는 URL을 수집할 수 있는 입력 필드를 UI에 제공합니다. 그러면 프런트엔드 서비스가 해당 URL(예: 백엔드 서비스)에 GET 요청을 하므로 브라우저에서 서비스 간 요청이 아닌 서비스 간 요청이 됩니다. 프런트엔드 서비스가 백엔드에 성공적으로 연결되면 브라우저에 hello world 메시지가 표시됩니다.
학습할 내용
- VPC에서 Cloud Run 서비스로의 트래픽만 허용하는 방법
- 내부 인그레스 전용 Cloud Run 서비스와 통신하도록 Cloud Run 서비스에서 이그레스를 구성하는 방법
2. 설정 및 요구사항
기본 요건
- Cloud 콘솔에 로그인했습니다.
- 이전에 Cloud Run 서비스를 배포했습니다. 예를 들어 소스 코드에서 웹 서비스 배포 빠른 시작의 안내에 따라 시작할 수 있습니다.
Cloud Shell 활성화
- Cloud Console에서 Cloud Shell 활성화
를 클릭합니다.
Cloud Shell을 처음 시작하는 경우에는 무엇이 있는지 설명하는 중간 화면이 표시됩니다. 중간 화면이 표시되면 계속을 클릭합니다.
Cloud Shell을 프로비저닝하고 연결하는 데 몇 분 정도만 걸립니다.
가상 머신에는 필요한 개발 도구가 모두 들어 있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab에서 대부분의 작업은 브라우저를 사용하여 수행할 수 있습니다.
Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 자신의 프로젝트 ID로 설정된 것을 확인할 수 있습니다.
- Cloud Shell에서 다음 명령어를 실행하여 인증되었는지 확인합니다.
gcloud auth list
명령어 결과
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- Cloud Shell에서 다음 명령어를 실행하여 gcloud 명령어가 프로젝트를 알고 있는지 확인합니다.
gcloud config list project
명령어 결과
[core] project = <PROJECT_ID>
또는 다음 명령어로 설정할 수 있습니다.
gcloud config set project <PROJECT_ID>
명령어 결과
Updated property [core/project].
3. Cloud Run 서비스 만들기
환경 변수 설정
이 Codelab 전체에서 사용할 환경 변수를 설정할 수 있습니다.
REGION=<YOUR_REGION, e.g. us-central1> FRONTEND=frontend BACKEND=backend
백엔드 Cloud Run 서비스 만들기
먼저 소스 코드용 디렉터리를 만들고 해당 디렉터리로 cd하세요.
mkdir -p internal-codelab/frontend internal-codelab/backend && cd internal-codelab/backend
그런 다음, 다음 콘텐츠로 package.json
파일을 만듭니다.
{ "name": "backend-service", "version": "1.0.0", "description": "", "scripts": { "start": "node index.js" }, "dependencies": { "express": "^4.18.1" } }
다음으로, 아래 콘텐츠로 index.js
소스 파일을 만듭니다. 이 파일에는 서비스의 진입점과 앱의 기본 로직이 포함되어 있습니다.
const express = require('express'); const app = express(); app.use(express.urlencoded({ extended: true })); app.get('/', function (req, res) { res.send("hello world"); }); const port = parseInt(process.env.PORT) || 8080; app.listen(port, () => { console.log(`helloworld: listening on port ${port}`); });
마지막으로 다음 명령어를 실행하여 Cloud Run 서비스를 배포합니다.
gcloud run deploy $BACKEND --source . --allow-unauthenticated --region $REGION
프런트엔드 Cloud Run 서비스 만들기
프런트엔드 디렉터리로 이동합니다.
cd ../frontend
그런 다음, 다음 콘텐츠로 package.json
파일을 만듭니다.
{ "name": "frontend", "version": "1.0.0", "description": "", "scripts": { "start": "node index.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "axios": "^1.6.6", "express": "^4.18.2" } }
다음으로, 아래 콘텐츠로 index.js
소스 파일을 만듭니다. 이 파일에는 서비스의 진입점과 앱의 기본 로직이 포함되어 있습니다.
const express = require("express"); const app = express(); const port = 8080; const path = require('path'); const axios = require('axios'); // serve static content (index.html) using // built-in middleware function in Express app.use(express.static('public')); app.use(express.urlencoded({ extended: true })); // this endpoint receives a URL in the post body // and then makes a get request to that URL // results are sent back to the caller app.post('/callService', async (req, res) => { const url = req.body.url; let message = ""; try { console.log("url: ", url); const response = await axios.get(url); message = response.data; } catch (error) { message = error.message; console.error(error.message); } res.send(` ${message} <p> </p> `); }); app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
index.html 파일을 위한 공개 디렉터리 만들기
mkdir public touch public/index.html
그리고 다음을 포함하도록 index.html을 업데이트합니다.
<html> <script src="https://unpkg.com/htmx.org@1.9.10" integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC" crossorigin="anonymous" ></script> <body> <div style="margin-top: 100px; margin-left: 100px"> <h1>I'm the Frontend service on the Internet</h1> <form hx-trigger="submit" hx-post="/callService" hx-target="#message"> <label for="url"> URL:</label> <input style="width: 308px" type="text" id="url" name="url" placeholder="The backend service URL" required /> <button hx-indicator="#loading" type="submit">Submit</button> <p></p> <span class="htmx-indicator" id="loading"> Loading... </span> <div id="message" style="white-space: pre-wrap"></div> <p></p> </form> </div> </body> </html>
마지막으로 다음 명령어를 실행하여 Cloud Run 서비스를 배포합니다.
gcloud run deploy $FRONTEND --source . --allow-unauthenticated --region $REGION
백엔드 서비스 호출
Cloud Run 서비스 두 개를 배포했는지 확인합니다.
웹브라우저에서 프런트엔드 서비스의 URL을 엽니다.
텍스트 상자에 백엔드 서비스의 URL을 입력합니다. 이 요청은 브라우저에서 라우팅되는 대신 프런트엔드 Cloud Run 인스턴스에서 백엔드 Cloud Run 서비스로 라우팅됩니다.
'hello world'가 표시됩니다.
4. 내부 인그레스 전용 백엔드 서비스 설정
다음 gcloud 명령어를 실행하여 VPC 네트워크 내의 트래픽만 백엔드 서비스에 액세스하도록 허용합니다.
gcloud run services update $BACKEND --ingress internal --region $REGION
백엔드 서비스가 VPC의 트래픽만 수신할 수 있는지 확인하려면 프런트엔드 서비스에서 백엔드 서비스를 다시 호출해 보세요.
이번에는 '요청 실패, 상태 코드 404'가 표시됩니다.
이 오류는 프런트엔드 Cloud Run 서비스 아웃바운드 요청 (즉, 이그레스)이 먼저 인터넷에 연결되므로 Google Cloud에서 요청의 출처를 알 수 없기 때문에 표시되었습니다.
다음 섹션에서는 Google Cloud가 요청이 내부 소스로 인식되는 VPC에서 전송되었음을 인식할 수 있도록 VPC에 액세스하도록 프런트엔드 서비스를 구성합니다.
5. VPC에 액세스하도록 프런트엔드 서비스 구성
이 섹션에서는 VPC를 통해 백엔드 서비스와 통신하도록 프런트엔드 Cloud Run 서비스를 구성합니다.
이렇게 하려면 프런트엔드 Cloud Run 인스턴스에 직접 VPC 이그레스를 추가하여 VPC 내에서 사용할 내부 IP를 서비스에 제공해야 합니다. 그런 다음 프런트엔드 서비스의 모든 아웃바운드 연결이 VPC로 이동하도록 이그레스를 구성합니다.
먼저 다음 명령어를 실행하여 직접 VPC 이그레스를 사용 설정합니다.
gcloud beta run services update $FRONTEND \ --network=default \ --subnet=default \ --vpc-egress=all-traffic \ --region=$REGION
이제 프런트엔드 서비스에 VPC 액세스 권한이 있는지 확인할 수 있습니다.
gcloud beta run services describe $FRONTEND \ --region=$REGION
다음과 비슷한 출력이 표시됩니다.
VPC access: Network: default Subnet: default Egress: all-traffic
이제 프런트엔드 서비스에서 백엔드 서비스를 다시 호출해 보세요.
이번에는 'hello world'가 표시됩니다.
참고: 모든 이그레스가 VPC로 라우팅되었으므로 프런트엔드 서비스에서 인터넷에 액세스할 수 없습니다. 예를 들어 프런트엔드 서비스가 https://curlmyip.org/에 액세스하려고 하면 시간이 초과됩니다.
6. 축하합니다.
축하합니다. Codelab을 완료했습니다.
Cloud Run 문서 및 Cloud Run 서비스의 비공개 네트워킹 구성 방법을 검토하는 것이 좋습니다.
학습한 내용
- VPC에서 Cloud Run 서비스로의 트래픽만 허용하는 방법
- 내부 인그레스 전용 Cloud Run 서비스와 통신하도록 Cloud Run 서비스에서 이그레스를 구성하는 방법
7. 삭제
Cloud Run 서비스가 무료 등급의 월별 Cloud Run 호출 할당보다 실수로 더 많이 호출되는 경우 실수로 인한 요금이 청구되지 않도록 하려면 Cloud Run을 삭제하거나 2단계에서 만든 프로젝트를 삭제하면 됩니다.
Cloud Run 서비스를 삭제하려면 Cloud Run Cloud 콘솔(https://console.cloud.google.com/run)으로 이동하여 $FRONTEND 및 $BACKEND 서비스를 삭제합니다.
전체 프로젝트를 삭제하려면 https://console.cloud.google.com/cloud-resource-manager로 이동하여 2단계에서 만든 프로젝트를 선택한 후 삭제를 선택하면 됩니다. 프로젝트를 삭제하면 Cloud SDK에서 프로젝트를 변경해야 합니다. gcloud projects list
를 실행하면 사용 가능한 모든 프로젝트의 목록을 볼 수 있습니다.