ASM支持通过出口网关访问外部LLM服务,主要适用于请求发起方位于集群内的场景。本文介绍当请求方位于集群内且注入了sidecar时,如何通过出口网关访问集群外服务。
前提条件
已添加集群到ASM实例,且ASM实例版本为1.22及以上。
已创建入口网关。
已部署sleep示例应用。具体操作,请参见创建测试应用sleep。
已经开通百炼,并且获取了可用的API_KEY。具体操作,请参见获取API Key
功能概述
未引入出口网关时,客户端请求被Sidecar拦截,由Sidecar代理向LLM提供商发起请求。Sidecar和客户端部署在同一个Pod中,这种使用方式存在诸多安全风险,可能出现API_KEY泄漏、未授权访问等问题,如果您比较对这方面风险比较敏感的话,请务必使用出口网关路由模型。
在请求链路中引入ASM出口网关之后,由于出口网关的独立于客户端部署,您可以通过ACK集群提供的RBAC机制方便的限制可以操作出口网关的用户,进而提升出口网关的安全水位。此时,API_KEY动态添加、认证鉴权策略全部在出口网关上执行,您可以使用全量的ASM网关安全能力。
本文演示的请求链路如下所示:
步骤一:创建出口网关和网关规则
创建出口网关,配置开放80端口并开启支持双向TLS认证。具体操作,请参见创建出口网关。
使用以下内容,创建egress-gw.yaml。
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: egress-gw namespace: istio-system spec: selector: istio: egressgateway servers: - hosts: - '*' port: name: http number: 80 protocol: HTTPS tls: mode: ISTIO_MUTUAL
使用ASM实例的kubeconfig,执行以下命令,创建网关规则。
kubectl apply -f egress-gw.yaml
步骤二:创建仅在出口网关生效的LLMProvider
仅在出口网关生效的LLMProvider可以确保API KEY只会存在于出口网关的内存中,不会轻易被客户端获取。
使用以下内容,创建dashscope-qwen.yaml。
apiVersion: istio.alibabacloud.com/v1beta1 kind: LLMProvider metadata: name: dashscope-qwen namespace: istio-system spec: workloadSelector: labels: istio: egressgateway host: dashscope.aliyuncs.com path: /compatible-mode/v1/chat/completions configs: defaultConfig: openAIConfig: model: qwen-1.8b-chat # 千问开源系列大模型 stream: false apiKey: ${API_KEY}
执行以下命令,创建LLMProvider。
kubectl apply -f dashscope-qwen.yaml
步骤三:创建LLMRoute
使用以下内容创建dashscope-route.yaml,将流量指向出口网关。
apiVersion: istio.alibabacloud.com/v1beta1 kind: LLMRoute metadata: name: dashscope-route spec: host: dashscope.aliyuncs.com gateways: - mesh - istio-system/egress-gw rules: - name: mesh-route # sidecar收到dashscope.aliyuncs.com的请求之后,转发给出口网关 matches: - gateways: - mesh backendRefs: - providerHost: istio-egressgateway.istio-system.svc.cluster.local - name: egress-gw-route # 出口网关收到dashscope.aliyuncs.com的请求之后,转发给真正的provider matches: - gateways: - istio-system/egress-gw backendRefs: - providerHost: dashscope.aliyuncs.com
执行以下命令,创建LLMRoute。
kubectl apply -f dashscope-route.yaml
步骤四:执行测试
使用ACK集群kubeconfig,执行以下命令发起测试。
kubectl exec deployment/sleep -it -- curl --location 'http://dashscope.aliyuncs.com' \
--header 'Content-Type: application/json' \
--data '{
"messages": [
{"role": "user", "content": "请介绍你自己"}
]
}'
预期输出:
{"choices":[{"message":{"role":"assistant","content":"我是来自阿里云的大规模语言模型,我叫通义千问。我的主要功能是回答用户的问题、提供信息和进行对话交流。我可以理解用户的提问,并基于自然语言生成相应的答案或建议。我也可以学习新的知识,并将其应用于各种场景中。如果您有任何问题或需要帮助,请随时告诉我,我会尽力为您提供支持。"},"finish_reason":"stop","index":0,"logprobs":null}],"object":"chat.completion","usage":{"prompt_tokens":3,"completion_tokens":72,"total_tokens":75},"created":1720680044,"system_fingerprint":null,"model":"qwen-1.8b-chat","id":"chatcmpl-1c33b950-3220-9bfe-9066-xxxxxxxxxxxx"}
步骤五:配置授权策略
使用以下内容,创建authpolicy.yaml。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: test namespace: istio-system spec: action: DENY rules: - from: - source: principals: - cluster.local/ns/default/sa/sleep to: - operation: hosts: - dashscope.aliyuncs.com selector: matchLabels: istio: egressgateway
使用ASM kubeconfig,执行以下命令配置授权策略。
kubectl apply -f authpolicy.yaml
再次执行步骤四中的命令发起测试。
预期输出:
RBAC: access denied
可以看到请求被拒绝。
ASM网关针对普通HTTP请求所具备的安全能力同样适用于LLM请求,包括完整的授权策略、JWT认证和自定义授权服务等。通过在出口网关上应用这些策略,可以更有效地保障您的应用安全。