【问题标题】:Google Cloud Functions with VPC Serverless Connector Egress with Cloud NAT not working带有 VPC 无服务器连接器的 Google Cloud Functions 带有 Cloud NAT 的出口无法正常工作
【发布时间】:2021-07-04 20:16:01
【问题描述】:

这与以下问题有关,已过时

目前 GCP 有 VPC Serverless Connector,可让您通过 VPC 连接器路由所有流量并设置 Cloud NAT 以获取静态 IP 地址。

我已按照以下指南 https://cloud.google.com/functions/docs/networking/network-settings#associate-static-ip 使用区域 us-east4,但来自我的云功能的外部请求总是超时。

我不确定这是一个错误还是我遗漏了什么。

编辑: 为确保我已遵循所有步骤,我尽可能使用gcloud 命令完成所有步骤。这些命令是从 GCP 的指南中复制而来的。

  1. 设置项目 ID 以供将来使用
PROJECT_ID=my-test-gcf-vpc-nat
  1. 转到控制台并启用计费

  2. 设置 VPC 和测试 VM 以测试 Cloud NAT

gcloud services enable compute.googleapis.com \
  --project $PROJECT_ID

gcloud compute networks create custom-network1 \
  --subnet-mode custom \
  --project $PROJECT_ID

gcloud compute networks subnets create subnet-us-east-192 \
  --network custom-network1 \
  --region us-east4 \
  --range 192.168.1.0/24 \
  --project $PROJECT_ID

gcloud compute instances create nat-test-1 \
  --image-family debian-9 \
  --image-project debian-cloud \
  --network custom-network1 \
  --subnet subnet-us-east-192 \
  --zone us-east4-c \
  --no-address \
  --project $PROJECT_ID

gcloud compute firewall-rules create allow-ssh \
  --network custom-network1 \
  --source-ranges 35.235.240.0/20 \
  --allow tcp:22 \
  --project $PROJECT_ID
  1. 使用控制台创建 IAP SSH 权限

  2. 测试网络配置,没有 Cloud NAT,VM 应该无法访问互联网

gcloud compute ssh nat-test-1 \
  --zone us-east4-c \
  --command "curl -s ifconfig.io" \
  --tunnel-through-iap \
  --project $PROJECT_ID

命令回复connection timed out

  1. 设置云 NAT
gcloud compute routers create nat-router \
  --network custom-network1 \
  --region us-east4 \
  --project $PROJECT_ID

gcloud compute routers nats create nat-config \
  --router-region us-east4 \
  --router nat-router \
  --nat-all-subnet-ip-ranges \
  --auto-allocate-nat-external-ips \
  --project $PROJECT_ID
  1. 再次测试网络配置,虚拟机应该可以通过 Cloud NAT 访问互联网
gcloud compute ssh nat-test-1 \
  --zone us-east4-c \
  --command "curl -s ifconfig.io" \
  --tunnel-through-iap \
  --project $PROJECT_ID

命令以 IP 地址响应

  1. 已创建 VPC 访问连接器
gcloud services enable vpcaccess.googleapis.com \
  --project $PROJECT_ID

gcloud compute networks vpc-access connectors create custom-network1-us-east4 \
  --network custom-network1 \
  --region us-east4 \
  --range 10.8.0.0/28 \
  --project $PROJECT_ID

gcloud compute networks vpc-access connectors describe custom-network1-us-east4 \
  --region us-east4 \
  --project $PROJECT_ID
  1. 为 Google Cloud Functions 服务帐号添加了权限
gcloud services enable cloudfunctions.googleapis.com \
  --project $PROJECT_ID

PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:service-$PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com \
  --role=roles/viewer

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:service-$PROJECT_NUMBER@gcf-admin-robot.iam.gserviceaccount.com \
  --role=roles/compute.networkUser
  1. 有建议我应该添加额外的防火墙规则和服务帐户权限
# Additional Firewall Rules
gcloud compute firewall-rules create custom-network1-allow-http \
  --network custom-network1 \
  --source-ranges 0.0.0.0/0 \
  --allow tcp:80 \
  --project $PROJECT_ID

gcloud compute firewall-rules create custom-network1-allow-https \
  --network custom-network1 \
  --source-ranges 0.0.0.0/0 \
  --allow tcp:443 \
  --project $PROJECT_ID


# Additional Permission, actually this service account has an Editor role already.
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member=serviceAccount:$PROJECT_ID@appspot.gserviceaccount.com \
  --role=roles/compute.networkUser
  1. 已部署测试 Cloud Functions

index.js

const publicIp = require('public-ip')

exports.testVPC = async (req, res) => {
  const v4 = await publicIp.v4()
  const v6 = await publicIp.v6()
  console.log('ip', [v4, v6])
  return res.end(JSON.stringify([v4, v6]))
}
exports.testNoVPC = exports.testVPC
# Cloud Function with VPC Connector
gcloud functions deploy testVPC \
  --runtime nodejs10 \
  --trigger-http \
  --vpc-connector custom-network1-us-east4 \
  --egress-settings all \
  --region us-east4 \
  --allow-unauthenticated \
  --project $PROJECT_ID

# Cloud Function without VPC Connector
gcloud functions deploy testNoVPC \
  --runtime nodejs10 \
  --trigger-http \
  --region us-east4 \
  --allow-unauthenticated \
  --project $PROJECT_ID

没有 VPC 连接器的 Cloud Function 以 IP 地址响应 https://us-east4-my-test-gcf-vpc-nat.cloudfunctions.net/testNoVPC

具有 VPC 连接器的 Cloud Functions 超时 https://us-east4-my-test-gcf-vpc-nat.cloudfunctions.net/testVPC

【问题讨论】:

  • 您好,您解决了这个问题吗?我已经尝试了 2 天,仍然没有:( stackoverflow.com/questions/64711513/…
  • 是的,我有,请按照我的cmets在下面的答案,问题是包public-ip没有按预期工作,您可以尝试其他方法获取静态IP
  • 不管我用什么,该功能似乎无法连接到互联网(在我的特殊情况下是尝试连接到 ftp 服务器以删除一些文件)

标签: google-cloud-platform google-cloud-functions google-cloud-networking


【解决方案1】:
  1. Configure a sample Cloud NAT setup with Compute Engine。使用 Compute Engine 测试您的 Cloud NAT 设置是否成功。

  2. Configuring Serverless VPC Access。确保在步骤 1 中创建的 custom-network1 上创建 VPC 连接器。

  3. Create a Google Cloud Function

a.在网络下选择您在第 2 步中创建的连接器和Route all traffic through the VPC connector


import requests
import json

from flask import escape

def hello_http(request):

    response = requests.get('https://stackoverflow.com')

    print(response.headers)    
    return 'Accessing stackoverflow from cloud function:  {}!'.format(response.headers)

Cloud Nat、Vpc 连接器和 Cloud Function 的区域是us-central1

4.测试功能是否可以上网:

Accessing stackoverflow from cloud function:  {'Cache-Control': 'private', 'Content-Type': 'text/html; charset=utf-8', 'Content-Encoding': 'gzip', 'X-Frame-Options': 'SAMEORIGIN', 'X-Request-Guid': 'edf3d1f8-7466-4161-8170-ae4d6e615d5c', 'Strict-Transport-Security': 'max-age=15552000', 'Feature-Policy': "microphone 'none'; speaker 'none'", 'Content-Security-Policy': "upgrade-insecure-requests; frame-ancestors 'self' https://stackexchange.com", 'Content-Length': '26391', 'Accept-Ranges': 'bytes', 'Date': 'Sat, 28 Mar 2020 19:03:17 GMT', 'Via': '1.1 varnish', 'Connection': 'keep-alive', 'X-Served-By': 'cache-mdw17354-MDW', 'X-Cache': 'MISS', 'X-Cache-Hits': '0', 'X-Timer': 'S1585422197.002185,VS0,VE37', 'Vary': 'Accept-Encoding,Fastly-SSL', 'X-DNS-Prefetch-Control': 'off', 'Set-Cookie': 'prov=78ecd1a5-54ea-ab1d-6d19-2cf5dc44a86b; domain=.stackoverflow.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly'}!

成功了,现在可以specify a static IP address for NAT

【讨论】:

  • 这真的很奇怪,我创建了一个新项目并按照您建议的步骤 1-4,我启用了所需的 API,配置了所需的权限,但我得到了相同的结果。我可以确认步骤 1 中的测试。工作正常,Cloud NAT 设置正确。我设置的与指南不同的只是名称和区域asia-east2 而不是us-central1,但我还将云功能配置为部署到asia-east2。要么我遗漏了什么,要么文档遗漏了什么。
  • 您是否授予作为云功能运行的服务帐户(在我的情况下为默认 App Engine 服务帐户)compute network user 角色?
  • 另外,不知道有没有区别,这些是我在natrules:allow-ssh Ingress Apply to all IP ranges: 35.235.240.0/20 tcp:22 Allow 1000 custom-network1-allow-http Ingress http-server IP ranges: 0.0.0.0/0 tcp:80 Allow 1000 custom-network1-allow-https Ingress https-server IP ranges: 0.0.0.0/0 tcp:443 Allow 1000 Equivalent REST上的防火墙,也是你的连接器在同一个区域吗?
  • 嗨,我知道这听起来很疯狂,但是使用 python 代码我可以访问互联网,使用 node.js 我没有。我不知道我做错了什么,但我用你的代码测试过,我超时了。
  • 这很有帮助。这是因为包public-ip,当我尝试request.get('https://ifconfig.co/ip') 时,它可以正常工作。谢谢!!
【解决方案2】:

检查 cloud nat 路由器是否在无服务器 VPC 访问使用的同一 VPC 中创建。

还要检查 Cloud Function 是否部署在 Cloud Nat 使用的 Cloud Routers 的同一区域。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-15
    • 2020-03-22
    • 2018-05-12
    • 2021-06-18
    • 2020-09-25
    • 2018-11-18
    • 2013-06-03
    • 2021-02-02
    相关资源
    最近更新 更多