Google-Cloud-Platform

無法訪問 Google Cloud Run 實例的靜態外部 IP - 遵循指南(路由器、子網、NAT、VPC 等)

  • February 25, 2021

我正在嘗試為我們的 Cloud Run 實例分配一個外部靜態 IP 地址,以便我可以將它與 websockets 一起使用(我讀過它需要一個靜態 IP 才能工作,而不是自指定/負載平衡的 GCloud應用程序域名)。可以訪問正常 URL,但靜態 IP 只是掛起。

我主要嘗試遵循本指南: https ://cloud.google.com/run/docs/configuring/static-outbound-ip

我不完全確定外部 IP 是如何路由到 Cloud Run 實例的,因為它是一個自我管理的實例(即上面沒有私有 IP 地址),但假設其他部分正在解決這個問題。 .

我做了什麼:

  • 創建了一個雲路由器:

gcloud compute routers create cloud-run-router --network=default --region=us-central1

路由器

  • 創建外部靜態 IP:

gcloud compute addresses create cloud-run --region=us-central1

外部IP

  • 我還在網路上創建了一個子網:

gcloud compute networks subnets create cloud-run-subnet --range=10.20.0.0/28 --network=default --region=us-central1

子網

  • 然後我用這個子網創建了一個無伺服器 VPC 訪問連接器:

gcloud beta compute networks vpc-access connectors create cloud-run-sub-conn --subnet-project=project-name --subnet=cloud-run-subnet --region=us-central1

vpc 連接器

  • 然後我用這個路由器和子網創建了一個新的 Cloud NAT 網關:

gcloud compute routers nats create cloud-run-nat --router=cloud-run-router --region=us-central1 --nat-custom-subnet-ip-ranges=cloud-run-subnet --nat-external-ip-pool=cloud-run

網關

  • 我還設置了一些防火牆規則,以嘗試允許一切: 防火牆
  • 然後,我部署了引用 VPC 出口和連接器的 Cloud Run 實例:

gcloud beta run deploy api-node --image gcr.io/project-name/api-node:latest --platform managed --allow-unauthenticated --set-env-vars REDISHOST='10.0.0.4',REDISPORT=6379,GOOGLE_APPLICATION_CREDENTIALS=credentials.json --set-cloudsql-instances=project-name:us-central1:mysql-db --vpc-egress=all --vpc-connector=cloud-run-sub-conn

Service [api-node] revision [api-node-00035-waw] has been deployed and is serving 100 percent of traffic.
Service URL: https://api-node-ojzumfbnoq-uc.a.run.app

出於某種原因,Cloud Run 實例仍可通過自指定 url 訪問: https ://api-node-ojzumfbnoq-uc.a.run.app/

…但外部 IP 不起作用: http: //104.197.97.194/ https://104.197.97.194/ http://104.197.97.194:8080/ https://104.197.97.194:80/

Cloud Run 服務 yaml 文件如下所示:

gcloud run services describe api-node --format export > service.yaml

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
 annotations:
   client.knative.dev/user-image: gcr.io/project-name/api-node
   run.googleapis.com/ingress: all
   run.googleapis.com/ingress-status: all
   run.googleapis.com/launch-stage: BETA
 labels:
   cloud.googleapis.com/location: us-central1
 name: api-node
 namespace: '938045200399'
spec:
 template:
   metadata:
     annotations:
       autoscaling.knative.dev/maxScale: '1000'
       autoscaling.knative.dev/minScale: '4'
       client.knative.dev/user-image: gcr.io/project-name/api-node
       run.googleapis.com/client-name: gcloud
       run.googleapis.com/client-version: 329.0.0
       run.googleapis.com/cloudsql-instances: project-name:us-central1:mysql-db
       run.googleapis.com/sandbox: gvisor
       run.googleapis.com/vpc-access-connector: cloud-run-sub-conn
       run.googleapis.com/vpc-access-egress: all
     name: api-node-00034-xah
   spec:
     containerConcurrency: 250
     containers:
     - env:
       - name: REDISHOST
         value: 10.0.0.4
       - name: REDISPORT
         value: '6379'
       - name: GOOGLE_APPLICATION_CREDENTIALS
         value: credentials.json
       image: gcr.io/project-name/api-node
       ports:
       - containerPort: 8080
       resources:
         limits:
           cpu: '4'
           memory: 2Gi
     serviceAccountName: cloud-functions@project-name.iam.gserviceaccount.com
     timeoutSeconds: 20
 traffic:
 - latestRevision: true
   percent: 100

這是我的 Dockerfile,如果有幫助的話:

# Use the official lightweight Node.js 12 image.
# https://hub.docker.com/_/node
FROM node:12-slim

# Create and change to the app directory.
WORKDIR /usr/src/app

ENV REDISHOST='10.0.0.4'
ENV REDISPORT=6379
ENV GOOGLE_APPLICATION_CREDENTIALS=credentials.json
ENV PORT=80

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY package*.json ./

# Install production dependencies.
# If you add a package-lock.json, speed your build by switching to 'npm ci'.
# RUN npm ci --only=production
RUN npm install --only=production

# Copy local code to the container image.
COPY . ./

EXPOSE 80/tcp
EXPOSE 8080/tcp
EXPOSE 9001/tcp

# Run the web service on container startup.
CMD [ "node", "build/index.js" ]

有沒有人看到上述步驟有什麼問題?將不勝感激任何幫助!搞了幾天。

好吧,您的方法的主要問題是您實際上錯過了該文件最重要的部分,即標題,即:

靜態出站 IP 地址

而這個標題背後的原因是 Cloud NAT不允許入站流量,即您不能使用 NAT 的靜態 IP 作為 Endpoint 向 Cloud Run Service 發出請求,這就是它“掛起”的原因。

因此,您可以遵循的最佳方法是為無伺服器應用程序創建負載均衡器,如此所述。您可以試一試並檢查它是否適用於websockets.

引用自:https://serverfault.com/questions/1054922