本教程介绍了如何在专用 Google Kubernetes Engine (GKE) 集群中创建专用 HTTP 端点,以使用 Eventarc 接收 Pub/Sub 消息事件。如需详细了解此事件目标位置,请参阅将事件路由到 VPC 网络中的内部 HTTP 端点。
专用 GKE 集群是一种 Virtual Private Cloud (VPC) 原生集群,其中的节点仅具有内部 IP 地址,这意味着节点和 Pod 默认与互联网隔离。您可以选择对控制平面没有客户端访问权限、具有受限访问权限或不受限访问权限。您不能将现有非专用集群转换为专用集群。如需了解详情,请参阅专用集群简介。
您可以在终端或 Cloud Shell 中使用 Google Cloud CLI 运行以下命令。
创建代理专用子网
除非您创建组织政策来禁止 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 生成事件,并确认事件已由触发器按预期路由到目标端点。