发布于 2026-01-06 4 阅读
0

具有静态 IP 地址的 GCP 云函数

具有静态 IP 地址的 GCP 云函数

我总是建议先查阅文档。然而,有时有些概念对某些人来说并不那么容易理解。例如,这里提到的面向开发人员的网络概念。

当我们听到“无服务器”这个词时,我们几乎忘记了 DevOps、网络、内存等等所有相关的东西,只关心代码,这样也无妨。

但现在我们有一个要求:客户端 API 只接受来自白名单 IP 的请求。

这是“传统”架构的示意图:

传统的

云函数可以解决大部分架构问题,但正如你所看到的,要实现我们的目标,仍然需要一些“传统”架构中的资源,而这正是我想要提供帮助的地方。

无服务器


创建一个简单的 HTTP 函数

main.py

# This function will return the IP address for egress
import requests
import json

def test_ip(request):
    result = requests.get("https://api.ipify.org?format=json")
    return json.dumps(result.json())
Enter fullscreen mode Exit fullscreen mode

部署

gcloud functions deploy testIP \
    --runtime python37 \
    --entry-point test_ip \
    --trigger-http \
    --allow-unauthenticated
Enter fullscreen mode Exit fullscreen mode

测试

curl https://us-central1-your-project.cloudfunctions.net/testIP
# {"ip": "35.203.245.150"} (ephemeral: changes any time)
Enter fullscreen mode Exit fullscreen mode

联网

所以,这部分会让一些开发人员感到困惑,我们将使用VPC(虚拟私有云)为我们的云服务(在本例中是我们的云函数)提供网络功能。

VPC网络本身不关联任何IP地址范围。IP地址范围是为子网定义的。

# Create VPC
gcloud services enable compute.googleapis.com

gcloud compute networks create my-vpc \
    --subnet-mode=custom \
    --bgp-routing-mode=regional
Enter fullscreen mode Exit fullscreen mode

然后我们需要创建一个无服务器 VPC 访问连接器,允许云函数(和其他无服务器资源)连接到 VPC。

# Create a Serverless VPC Access connectors 
gcloud services enable vpcaccess.googleapis.com

gcloud compute networks vpc-access connectors create functions-connector \
    --network my-vpc \
    --region us-central1 \
    --range 10.8.0.0/28
Enter fullscreen mode Exit fullscreen mode

在使用我们的函数连接器之前,我们必须向云函数服务帐户授予相应的权限,以便云函数能够连接到我们的函数连接器

# Grant Permissions 
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
export PROJECT_NUMBER=$(gcloud projects list --filter="$PROJECT_ID" --format="value(PROJECT_NUMBER)")

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
Enter fullscreen mode Exit fullscreen mode

好了,我们已经有了连接器和权限,接下来让我们配置云函数来使用该连接器。

# Configurate the connector
gcloud functions deploy testIP \
    --runtime python37 \
    --entry-point test_ip \
    --trigger-http \
    --allow-unauthenticated \
    --vpc-connector functions-connector \
    --egress-settings all
Enter fullscreen mode Exit fullscreen mode

如果您向我们的云函数发出请求,您将看到以下消息:“错误:无法处理请求”,这是因为我们的VPC没有通往互联网的出口。

为了与外界接轨,我们必须:

  • 预留一个静态IP地址

  • 配置云路由器以路由我们的网络流量。

  • 创建云NAT,允许没有外部IP的实例向互联网发送出站数据包,并接收任何相应的已建立的入站响应数据包(即通过静态IP)。

# Reserve static IP
gcloud compute addresses create functions-static-ip \
    --region=us-central1

gcloud compute addresses list
# NAME                 ADDRESS/RANGE  TYPE      PURPOSE  NETWORK  REGION       SUBNET  STATUS
# functions-static-ip  34.72.171.164  EXTERNAL                    us-central1          RESERVED
Enter fullscreen mode Exit fullscreen mode

我们已获得静态IP地址!34.72.171.164

# Creating the Cloud Router
gcloud compute routers create my-router \
    --network my-vpc \
    --region us-central1

# Creating Cloud Nat
gcloud compute routers nats create my-cloud-nat-config \
    --router=my-router \
    --nat-external-ip-pool=functions-static-ip \
    --nat-all-subnet-ip-ranges \
    --enable-logging
Enter fullscreen mode Exit fullscreen mode

太棒了!现在让我们用一个新的请求来测试一下我们的云函数。

curl https://us-central1-your-project.cloudfunctions.net/testIP
# {"ip": "34.72.171.164"} (our static IP!)
Enter fullscreen mode Exit fullscreen mode

太好了!一切正常 :) 简单回顾一下:

  1. 我们部署了一个简单的云函数(HTTP)

  2. 创建了一个VPC,为我们的云函数提供网络功能。

  3. 创建了一个无服务器 VPC 访问连接器,允许我们的云函数使用 VPC 功能(例如使用 IP 地址)。

  4. 已授予云函数服务帐户使用网络资源的权限。

  5. 已配置云函数以使用无服务器 VPC 访问连接器,并将所有出站请求重定向到VPC。

  6. 已预留静态IP地址

  7. 创建了一个云路由器来路由我们的网络流量。

  8. 最后创建一个云NAT,用于与外部世界通信。

希望这篇文章对你有帮助,如果你有任何问题或建议,请告诉我。

源代码:https://github.com/AlvarDev/functions-static-ip

文章来源:https://dev.to/alvardev/gcp-cloud-functions-with-a-static-ip-3fe9