本教程介绍了如何在专用 Google Kubernetes Engine (GKE) 集群中创建专用 HTTP 端点,以使用 Eventarc 接收 Pub/Sub 消息事件。如需详细了解此事件目标位置,请参阅将事件路由到 VPC 网络中的内部 HTTP 端点。
专用 GKE 集群是一种 Virtual Private Cloud (VPC) 原生集群,其中的节点仅具有内部 IP 地址,这意味着节点和 Pod 默认与互联网隔离。您可以选择对控制平面没有客户端访问权限、具有受限访问权限或不受限访问权限。您不能将现有非专用集群转换为专用集群。如需了解详情,请参阅专用集群简介。
您可以在终端或 Cloud Shell 中使用 Google Cloud CLI 运行以下命令。
目标
在此教程中,您将学习以下操作:
- 在默认 VPC 网络中创建一个代理专用子网,并创建一个 VPC 防火墙规则。
- 创建对公共端点没有客户端访问权限的专用 GKE Autopilot 集群。
- 在 VPC 网络的指定子网中创建 Compute Engine 虚拟机 (VM) 实例。
- 建立与虚拟机实例的 SSH 连接,并在虚拟机实例上部署事件接收器服务。
- 在集群中部署网关和
HTTPRoute
清单,以对 Kubernetes 中的流量到应用后端的路由进行配置。 - 创建网络连接,以允许提供方 VPC 网络发起与使用方 VPC 网络的连接。
- 创建 Eventarc 触发器,以将 Pub/Sub 事件路由到虚拟机实例上的事件接收器。
- 向 Pub/Sub 主题发布消息以生成事件,并在应用 Pod 日志中查看事件正文。
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
您可使用价格计算器根据您的预计使用情况来估算费用。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
准备工作
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud Resource Manager, Compute Engine, Eventarc, GKE, and Pub/Sub APIs:
gcloud services enable compute.googleapis.com
container.googleapis.com cloudresourcemanager.googleapis.com eventarc.googleapis.com pubsub.googleapis.com - Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud Resource Manager, Compute Engine, Eventarc, GKE, and Pub/Sub APIs:
gcloud services enable compute.googleapis.com
container.googleapis.com cloudresourcemanager.googleapis.com eventarc.googleapis.com pubsub.googleapis.com - 更新 Google Cloud CLI 组件:
gcloud components update
- 使用您的账号登录:
gcloud auth login
-
如果您是项目创建者,则会被授予基本 Owner 角色 (
roles/owner
)。默认情况下,此 Identity and Access Management (IAM) 角色可提供完全访问大多数 Google Cloud 资源所需的权限,您可以跳过此步骤。如果您不是项目创建者,则必须向主账号授予项目的必需权限。例如,主账号可以是 Google 账号(针对最终用户)或服务账号(针对应用和计算工作负载)。如需了解详情,请参阅事件目标位置的角色和权限页面。
所需权限
如需获得完成本快速入门所需的权限,请让您的管理员为您授予项目的以下 IAM 角色:
-
Compute Network Admin (
roles/compute.networkAdmin
) -
Compute Security Admin (
roles/compute.securityAdmin
) -
Eventarc Admin (
roles/eventarc.admin
) -
Kubernetes Engine Admin (
roles/container.admin
) -
Logs View Accessor (
roles/logging.viewAccessor
) -
Project IAM Admin (
roles/resourcemanager.projectIamAdmin
) -
Pub/Sub Publisher (
roles/pubsub.publisher
) -
Service Account Admin (
roles/iam.serviceAccountAdmin
) -
Service Account User (
roles/iam.serviceAccountUser
) -
Service Usage Admin (
roles/serviceusage.serviceUsageAdmin
)
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
-
Compute Network Admin (
记下 Compute Engine 默认服务账号,因为您将把它附加到 Eventarc 触发器以代表触发器的身份信息进行测试。启用或使用包含 Compute Engine 的 Google Cloud 服务后,系统会自动创建此服务账号,其电子邮件地址格式如下:
PROJECT_NUMBER-compute@developer.gserviceaccount.com
将
PROJECT_NUMBER
替换为您的 Google Cloud 项目编号。您可以在 Google Cloud 控制台的欢迎页面上或者通过运行以下命令找到项目编号:gcloud projects describe PROJECT_ID --format='value(projectNumber)'
对于生产环境,我们强烈建议创建新的服务账号,并为其授予一个或多个 IAM 角色,这些角色包含所需的最小权限并遵循最小权限原则。
- 如果您在 2021 年 4 月 8 日或之前启用了 Cloud Pub/Sub 服务代理,以支持经过身份验证的 Pub/Sub 推送请求,请向该服务代理授予 Service Account Token Creator 角色 (
roles/iam.serviceAccountTokenCreator
)。否则,系统会默认授予此角色:gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \ --role=roles/iam.serviceAccountTokenCreator
创建代理专用子网
除非您创建组织政策来禁止 VPC 网络,否则新项目会首先创建一个默认网络(自动模式 VPC 网络),此网络在每个区域内都包含一个子网。每个 VPC 网络均由一个或多个 IP 地址范围(即“子网”)组成。子网属于区域级资源,并且具有与之关联的 IP 地址范围。
使用
gcloud compute networks subnets create
命令在默认网络中创建代理专用子网。gcloud compute networks subnets create proxy-only-subnet \ --purpose=REGIONAL_MANAGED_PROXY \ --role=ACTIVE \ --region=us-central1 \ --network=default \ --range=10.10.10.0/24
请注意,
purpose=REGIONAL_MANAGED_PROXY
的子网已为基于 Envoy 的负载均衡器预留,并且range
必须提供 64 个或更多 IP 地址。创建一条防火墙规则,以与代理专用子网的范围匹配并允许 TCP 端口 8080 上的流量。
gcloud compute firewall-rules create allow-proxy-connection \ --allow tcp:8080 \ --source-ranges 10.10.10.0/24 \ --network=default
创建专用 GKE 集群
使用 gcloud container clusters create-auto
命令在 Autopilot 模式中创建具有专用节点且对公共端点没有客户端访问权限的专用 GKE 集群。
以下示例创建了一个名为 private-cluster
的专用 GKE 集群,同时还创建了一个名为 my-subnet
的子网:
gcloud container clusters create-auto private-cluster \
--create-subnetwork name=my-subnet \
--enable-master-authorized-networks \
--enable-private-nodes \
--enable-private-endpoint \
--region=us-central1
请注意以下几点:
--enable-master-authorized-networks
用于指定仅限您授权的 IP 地址范围访问公共端点。--enable-private-nodes
表示集群的节点没有外部 IP 地址。--enable-private-endpoint
表示使用控制平面 API 端点的内部 IP 地址管理集群。
集群创建可能需要几分钟才能完成。创建集群后,输出应指示集群的状态为 RUNNING
。
在指定子网中创建虚拟机实例
Compute Engine 虚拟机实例是托管在 Google 基础架构上的虚拟机。术语 Compute Engine 实例、虚拟机实例和虚拟机是同义词,可互换使用。虚拟机实例包括 GKE 集群、App Engine 柔性环境实例,以及 Compute Engine 虚拟机上构建的其他 Google Cloud 产品。
使用 gcloud compute instances create
命令在您之前创建的子网中创建 Compute Engine 虚拟机实例。关联服务账号,并将虚拟机的访问权限范围设置为 cloud-platform
。
gcloud compute instances create my-vm \
--service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--zone=us-central1-a \
--subnet=my-subnet
如需了解详情,请参阅创建并启动虚拟机实例。
在虚拟机上部署事件接收器
使用预构建的映像 us-docker.pkg.dev/cloudrun/container/hello
在虚拟机上部署一项服务,以监听端口 80 并接收和记录事件。
通过运行以下命令,与虚拟机实例建立 SSH 连接:
gcloud compute ssh my-vm --project=PROJECT_ID --zone=us-central1-a
建立与 SSH 服务器的连接后,请在虚拟机实例上运行其余命令。
如有必要,安装
kubectl
和所有必需的插件。在虚拟机实例中,使用
get-credentials
命令启用kubectl
以处理您创建的集群。gcloud container clusters get-credentials private-cluster \ --region=us-central1 \ --internal-ip
使用 Kubernetes 命令
kubectl create deployment
将应用部署到该集群。kubectl create deployment hello-app \ --image=us-docker.pkg.dev/cloudrun/container/hello
这会创建一个名为
hello-app
的 Deployment。此 Deployment 的 Pod 运行hello
容器映像。部署应用后,您可以通过创建 Kubernetes 服务向流量公开应用。运行以下
kubectl expose
命令:kubectl expose deployment hello-app \ --type ClusterIP \ --port 80 \ --target-port 8080
您应该会在输出中看到
service/hello-app exposed
。您可以忽略类似于以下内容的任何消息:
E0418 14:15:33.970933 1129 memcache.go:287] couldn't get resource list for metrics.k8s.io/v1beta1: the server is currently unable to handle the request
配置 Kubernetes 流量路由
网关资源表示在 Kubernetes 中路由流量的数据层面。网关可表示许多不同类型的负载均衡和路由,具体取决于派生网关的 GatewayClass。如需了解详情,请参阅部署网关。系统会部署一个 HTTPRoute
清单以创建路由并将流量发送到应用后端。
在集群中部署网关。
kubectl apply -f - <<EOF kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: internal-http spec: gatewayClassName: gke-l7-rilb listeners: - name: http protocol: HTTP port: 80 EOF
请注意以下几点:
gatewayClassName: gke-l7-rilb
指定派生此网关的 GatewayClass。gke-l7-rilb
对应于内部应用负载均衡器。port: 80
指定网关仅公开端口 80 来侦听 HTTP 流量。
验证网关是否已正确部署。部署其所有资源可能需要几分钟时间。
kubectl describe gateways.gateway.networking.k8s.io internal-http
输出类似于以下内容:
Name: internal-http Namespace: default ... API Version: gateway.networking.k8s.io/v1beta1 Kind: Gateway ... Spec: Gateway Class Name: gke-l7-rilb Listeners: Allowed Routes: Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 10.36.172.5 ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 80s sc-gateway-controller default/internal-http Normal UPDATE 20s (x3 over 80s) sc-gateway-controller default/internal-http Normal SYNC 20s sc-gateway-controller SYNC on default/internal-http was a success
部署
HTTPRoute
清单以将 HTTP 流量路由到端口 80 上的hello-app
服务。kubectl apply -f - <<EOF kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: hello-app-route spec: parentRefs: - kind: Gateway name: internal-http rules: - backendRefs: - name: hello-app port: 80 EOF
创建网络连接
网络连接是一种资源,允许提供方 VPC 网络通过 Private Service Connect 接口启动与使用方 VPC 网络的连接。
为了发布事件,Eventarc 使用网络连接与 VPC 网络中托管的内部 HTTP 端点建立连接。
您可以创建一个网络连接,以自动接受与该网络连接关联的任何 Private Service Connect 接口发出的连接。在包含 HTTP 目标服务的同一网络和区域中创建网络连接。
gcloud compute network-attachments create my-network-attachment \ --region=us-central1 \ --subnets=my-subnet\ --connection-preference=ACCEPT_AUTOMATIC
如需了解详情,请参阅关于网络连接。
创建 Eventarc 触发器
创建一个 Eventarc 触发器,用于创建新的 Pub/Sub 主题,并在消息发布到 Pub/Sub 主题时将事件路由到虚拟机上部署的事件接收器。
检索网关地址。
GATEWAY_ADDRESS=$(kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}")
创建触发器。
gcloud eventarc triggers create my-trigger \ --location=us-central1 \ --destination-http-endpoint-uri="http://$GATEWAY_ADDRESS:80/" \ --network-attachment="projects/PROJECT_ID/regions/us-central1/networkAttachments/my-network-attachment" \ --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \ --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com
将
PROJECT_NUMBER
替换为您的 Google Cloud 项目编号。您可以在 Google Cloud 控制台的欢迎页面上或者通过运行以下命令找到项目编号:gcloud projects describe PROJECT_ID --format='value(projectNumber)'
如需详细了解如何配置触发器,请参阅将事件路由到 VPC 网络中的内部 HTTP 端点。
生成并查看 Pub/Sub 主题事件
您可以通过向 Pub/Sub 主题发布消息来生成事件。
查找 Pub/Sub 主题并将其设置为环境变量。
export MY_TOPIC=$(gcloud eventarc triggers describe my-trigger \ --location=us-central1 \ --format='value(transport.pubsub.topic)')
向 Pub/Sub 主题发布消息以生成事件。
gcloud pubsub topics publish $MY_TOPIC --message "Hello World"
Eventarc 触发器会将事件路由到专用 GKE 集群中的内部 HTTP 端点。
检查应用 Pod 日志并验证事件传送情况。
POD_NAME=$(kubectl get pod --selector app=hello-app --output=name) kubectl logs $POD_NAME
事件正文应类似于以下内容:
2024/04/18 20:31:43 Hello from Cloud Run! The container started successfully and is listening for HTTP requests on $PORT {"severity":"INFO","eventType":"google.cloud.pubsub.topic.v1.messagePublished","message":"Received event of type google.cloud.pubsub.topic.v1.messagePublished. Event data: Hello World","event":{"specversion":"1.0","id":"10935738681111260","source":"//pubsub.googleapis.com/projects/my-project/topics/eventarc-us-central1-my-trigger-224","type":"google.cloud.pubsub.topic.v1.messagePublished","datacontenttype":"application/json","time":"2024-04-18T20:40:03Z","data": {"message":{"data":"SGVsbG8gV29ybGQ=","messageId":"10935738681111260","publishTime":"2024-04-18T20:40:03Z"}}}}
您已成功将事件接收器服务部署到专用 GKE 集群中的内部 HTTP 端点,创建 Eventarc 触发器,从 Pub/Sub 生成事件,并确认事件已由触发器按预期路由到目标端点。
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除项目
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
删除各个资源
- 删除 Eventarc 触发器:
gcloud eventarc triggers delete my-trigger --location=us-central1
- 退出虚拟机,然后删除虚拟机实例:
gcloud compute instances delete my-vm --zone=us-central1-a
- 删除网络连接:
gcloud compute network-attachments delete my-network-attachment --region=us-central1
- 删除防火墙规则:
gcloud compute firewall-rules delete allow-proxy-connection
- 删除集群:
gcloud container clusters delete private-cluster --region=us-central1
- Delete the subnet:
gcloud compute networks subnets delete proxy-only-subnet --region=us-central1