如何限制GCP负载均衡器访问,仅允许GKE应用访问GCS资源?
解决方案
方案1:GKE应用作为代理转发GCS资源(最可靠)
这个方案从根源上隔离GCS的直接访问,所有资源请求必须经过你的GKE应用,确保只有通过GKE应用的用户才能获取资源:
- 将GCS存储桶设为私有:关闭所有公共访问权限,哪怕保留指向GCS的负载均衡,也要确保存储桶没有公开可读的配置。
- 给GKE应用配置Workload Identity:为GKE应用的服务账号绑定GCS的
roles/storage.objectViewer角色,让应用具备读取GCS资源的权限。 - 在GKE应用中添加代理接口:比如创建
/proxy/gcs/{object-path}接口,当用户浏览器的<img>标签指向这个接口时,GKE应用用自身身份去GCS拉取资源,再返回给浏览器。
示例伪代码:@app.route('/proxy/gcs/<path:object_path>') def proxy_gcs(object_path): # 用Workload Identity认证的客户端连接GCS storage_client = storage.Client() bucket = storage_client.bucket('你的存储桶名称') blob = bucket.blob(object_path) # 获取资源内容和类型 content = blob.download_as_bytes() content_type = blob.content_type # 返回给浏览器 return Response(content, mimetype=content_type) - 修改前端
<img>标签:把原来的src="aaa.bbb.com/image-to-read.png"替换为src="你的GKE应用域名/proxy/gcs/image-to-read.png"。
方案2:用签名URL动态访问GCS(适合少改动后端的场景)
如果不想做代理转发,可以让GKE应用为每个资源生成带有效期的签名URL,前端用这个URL访问GCS:
- 设置GCS存储桶为私有:关闭所有公共访问权限。
- 给GKE应用配置Workload Identity:同样绑定
roles/storage.objectViewer权限。 - GKE应用生成签名URL:页面渲染时,为每个
<img>标签的src生成签名URL,只有携带有效签名的请求才能访问GCS资源。
示例伪代码:def generate_signed_url(object_path): storage_client = storage.Client() bucket = storage_client.bucket('你的存储桶名称') blob = bucket.blob(object_path) # 生成有效期1小时的签名URL url = blob.generate_signed_url( version="v4", expiration=datetime.timedelta(hours=1), method="GET" ) return url - 前端渲染签名URL:把
<img src="{{ 生成的签名URL }}">渲染到页面中。
之前方法失效的原因
- CORS设置:CORS是浏览器端的跨域请求限制,无法阻止用户直接在地址栏输入URL访问资源,你遇到的登录要求是因为存储桶配置了Google账号权限,和CORS本身无关。
- Workload Identity:它是服务端应用的身份认证机制,浏览器发起的请求不会携带这个身份凭证,直接用
<img>标签访问GCS自然不生效。 - Cloud Armor:浏览器请求的来源是用户自身的IP,不是GKE应用的IP,所以限制GKE负载均衡IP无法过滤非法请求。
内容的提问来源于stack exchange,提问作者Martavis P.
相关产品推荐
相关产品推荐

