配置 RBAC#

注入 Istio#

  1. 标记命名空间以启用 Istio 注入。

    kubectl label namespace <namespace> istio-injection=enabled --overwrite
    

    <namespace> 替换为您的目标命名空间。

  2. 删除现有 pod 以使用 Istio 边车容器重新创建它们。

    kubectl delete pod $(kubectl get pods -n <namespace> | awk '{print $1}') -n <namespace>
    

部署 Manifests#

  1. 以下示例 manifest 部署了网关和入口虚拟服务。

    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: rag-gateway
      namespace: istio-system
    spec:
      selector:
        istio: ingressgateway
      servers:
        - port:
            number: 80
            name: http2
            protocol: HTTP
          hosts:
            - "*"
    
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: sample-vs
      namespace: <namespace>
    spec:
      hosts:
        - "*"
      gateways:
        - istio-system/rag-gateway
      http:
        - match:
            - uri:
                prefix: /admin
            - uri:
                prefix: /resources
            - uri:
                prefix: /welcome
            - uri:
                prefix: /realms
          route:
            - destination:
                host: keycloak.default.svc.cluster.local
                port:
                  number: 8080
        - match:
            - uri:
                prefix: /v1/completions
            - uri:
                prefix: /v1/chat/completions
          route:
            - destination:
                host: inferencing
                port:
                  number: 8080
    
  2. 应用 manifest。

    kubectl apply -f istio-sample-manifest.yaml
    
  3. 确定 Istio 入口网关节点端口。

    kubectl get svc -n istio-system | grep ingress
    

    示例输出

    istio-ingressgateway   LoadBalancer   10.102.8.149     10.28.234.101   15021:32658/TCP,80:30611/TCP,443:31874/TCP,31400:30160/TCP,15443:32430/TCP   22h
    
  4. 列出 worker IP 地址。

    for node in `kubectl get nodes | awk '{print $1}' | grep -v NAME`; do echo $node ' ' | tr -d '\n'; kubectl describe node $node | grep -i 'internalIP:' | awk '{print $2}'; done
    

    示例输出

    nim-test-cluster-03-worker-nbhk9-56b4b888dd-8lpqd  10.120.199.16
    nim-test-cluster-03-worker-nbhk9-56b4b888dd-hnrxr  10.120.199.23
    
  5. 以下 manifest 创建请求身份验证资源。

    • 更新目标命名空间。

    • 使用前面 IP 地址之一和前面的入口 Istio 网关节点端口(映射到端口 80)修改 manifest 中的 issuer。

    ---
    apiVersion: security.istio.io/v1beta1
    kind: RequestAuthentication
    metadata:
      name: nim-request-authentication
      namespace: <namespace>
    spec:
      selector:
        matchLabels:
         app.kubernetes.io/name: inferencing
      jwtRules:
      - issuer: "http://10.176.21.249:30669/realms/nvidia-nim"
        jwksUri: "http://keycloak.default.svc.cluster.local:8080/realms/nvidia-nim/protocol/openid-connect/certs"
        forwardOriginalToken: true
        fromHeaders:
          - name: Authorization
            prefix: "Bearer"
      - issuer: "http://10.176.21.249/realms/nvidia-nim"
        jwksUri: "http://keycloak.default.svc.cluster.local:8080/realms/nvidia-nim/protocol/openid-connect/certs"
        forwardOriginalToken: true
        fromHeaders:
          - name: Authorization
            prefix: "Bearer"
    ---
    apiVersion: security.istio.io/v1beta1
    kind: RequestAuthentication
    metadata:
      name: nim-request-authentication-gw
      namespace: istio-system
    spec:
      selector:
        matchLabels:
         istio: ingressgateway
      jwtRules:
      - issuer: "http://10.176.21.249:30669/realms/nvidia-nim"
        jwksUri: "http://keycloak.default.svc.cluster.local:8080/realms/nvidia-nim/protocol/openid-connect/certs"
        forwardOriginalToken: true
        fromHeaders:
          - name: Authorization
            prefix: "Bearer"
      - issuer: "http://10.176.21.249/realms/nvidia-nim"
        jwksUri: "http://keycloak.default.svc.cluster.local:8080/realms/nvidia-nim/protocol/openid-connect/certs"
        forwardOriginalToken: true
        fromHeaders:
          - name: Authorization
            prefix: "Bearer"
    
  6. 应用 manifest。

    kubectl apply -f requestAuthentication.yaml
    
  7. 以下 manifest 创建授权策略资源。

    • 更新目标命名空间。

    • 更新适用于目标微服务的规则。

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: nim-auth-policy
      namespace: <namespace>
    spec:
      selector:
        matchLabels:
          app.kubernetes.io/name: inferencing
      rules:
      - from:
        - source:
            requestPrincipals: ["*"]
        to:
        - operation:
            methods: ["POST"]
            paths: ["/v1/completions*"]
        when:
        - key: request.auth.claims[realm_access][roles]
          values: ["completions"]
      - from:
        - source:
            requestPrincipals: ["*"]
        to:
        - operation:
            methods: ["POST"]
            paths: ["/v1/chat/completions*"]
        when:
        - key: request.auth.claims[realm_access][roles]
          values: ["chat"]
    
  8. 应用 manifest。

    kubectl apply -f authorizationPolicy.yaml
    
  9. 创建用于 Keycloak 身份验证的令牌。更新节点 IP 地址和入口网关节点端口。

    TOKEN=`curl -X POST -d "client_id=nvidia-nim" -d "username=nim" -d "password=nvidia123" -d "grant_type=password" "http://10.217.19.114:30611/realms/nvidia-nim-llm/protocol/openid-connect/token"| jq .access_token| tr -d '"' `
    
  10. 通过 Istio 网关验证从 Keycloak 对微服务的访问。

    curl -v -X POST http://10.217.19.114:30611/v1/completions -H "Authorization: Bearer $TOKEN" -H 'accept: application/json' -H 'Content-Type: application/json' -d '{ "model": "llama-2-13b-chat","prompt": "What is Kubernetes?","max_tokens": 16,"temperature": 1, "n": 1, "stream": false, "stop": "string", "frequency_penalty": 0.0 }'
    

    更新节点 IP 地址和入口网关端口。如果模型名称不是 llama-2-13b-chat,请更新模型名称。

  11. 生成更多数据,以便可以在下一步在 Kiali 仪表板上可视化。

    for i in $(seq 1 100); do curl -X POST http://10.217.19.114:30611/v1/chat/completions -H 'accept: application/json' -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{"model": "llama-2-13b-chat","messages": [{"role": "system","content": "You are a helpful assistant."},{"role": "user", "content": "Hello!"}]}'  -s -o /dev/null; done
    
  12. 访问 Istio 仪表板,指定您的客户端系统 IP 地址。

    istioctl dashboard kiali --address <system-ip>
    

在浏览器中使用 system-ip 和端口 20001 访问。

结论#

此架构为以安全、可扩展且高效的方式部署 NVIDIA NeMo MicroServices 提供了强大的解决方案。将高级服务网格功能与 OIDC 身份验证集成,为构建复杂的 AI 驱动的应用程序树立了新标准。