Deploy NetScaler® CPX Kubernetes Gateway Controller

The deployment process involves deploying the Gateway Controller, which monitors and manages Gateway CRDs that define traffic routing rules. The Gateway Controller then configures the NetScaler CPX to direct external requests to the sample application.

Deploy NetScaler CPX with Kubernetes Gateway Controller

  1. Deploy a sample application to get started.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: cnn-website
      labels:
        name: cnn-website
        app: cnn-website
    spec:
      selector:
        matchLabels:
          app: cnn-website
      replicas: 2
      template:
        metadata:
          labels:
            name: cnn-website
            app: cnn-website
        spec:
          containers:
          - name: cnn-website
            image: quay.io/sample-apps/cnn-website:v1.0.0
            ports:
            - name: http-80
              containerPort: 80
            - name: https-443
              containerPort: 443
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: cnn-website
      labels:
        app: cnn-website
    spec:
      type: NodePort
      ports:
      - name: http-80
        port: 80
        targetPort: 80
      - name: https-443
        port: 443
        targetPort: 443
      selector:
        name: cnn-website
    <!--NeedCopy-->
    
  2. Install the Gateway API CRDs from the official standard channel if they are not already installed.

  3. Generate values.yaml based on your use case. For information about the mandatory and optional parameters that you can configure during NetScaler Kubernetes Gateway Controller installation, see Configurations.

    gatewayController:
        entityPrefix: gwy
        gatewayControllerName: "citrix.com/nscpxgw-controller"
    license:
        accept: yes
    service:
        annotations: {}
        spec:
            type: NodePort
            ports:
            - port: 80
                targetPort: 80
                protocol: TCP
                name: http
            - port: 443
                targetPort: 443
                protocol: TCP
                name: https
    <!--NeedCopy-->
    

    Note:

    entityPrefix and gatewayControllerName are mandatory and must be unique for every deployment of NetScaler CPX with Kubernetes Gateway Controller.

  4. Deploy the NetScaler CPX with Kubernetes Gateway controller using the Helm charts and the values.yaml generated in preceding step. For more information, see NetScaler CPX with Kubernetes Gateway Controller deployment using Helm Chart.

    helm repo add netscaler https://netscaler.github.io/netscaler-helm-charts/
    
    helm install cpx-gateway-controller netscaler/netscaler-cpx-with-gateway-controller  -f values.yaml
    <!--NeedCopy-->
    

Sample Gateway and HTTPRoute CRD

The following is an example of a GatewayClass, Gateway, and an HTTPRoute definition.

  1. Create a GatewayClass resource to define the controller handling Gateway objects.

    Sample GatewayClass

    apiVersion: gateway.networking.k8s.io/v1
    kind: GatewayClass
    metadata:
      name: example-gateway-class
    spec:
      controllerName: citrix.com/nscpxgw-controller
    <!--NeedCopy-->
    
  2. (Optional) Create a self-signed SSL certificate and a key to be used with the Gateway-Listener for TLS configuration.

    The following command is just a sample command to create a self-signed certificate and assumes that the host name of the application is example.com.

    openssl req -subj '/CN=example.com/O=Citrix Systems Inc/C=IN' -new -newkey rsa:2048 -days 5794 -nodes -x509 -keyout $PWD/app1.key  -out $PWD/app1.crt;openssl rsa -in $PWD/app1.key -out $PWD/app1.key
    
    <!--NeedCopy-->
    

    Note:

    If you already have an SSL certificate, you can create a Kubernetes secret using the same.

  3. Create a Kubernetes Secret to store the SSL certificate and key (TLS pair).

    kubectl create secret tls app1-secret  --cert app1.crt –key app1.key
    
    <!--NeedCopy-->
    
  4. Define a Gateway resource to expose services based on defined listeners.

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
    name: example-gateway
    spec:
    gatewayClassName: example-gateway-class
    listeners:
    - name: http
        protocol: HTTP
        port: 80
    - name: https
        protocol: HTTPS
        port: 443
        tls:
        mode: Terminate
        certificateRefs:
        - kind: Secret
            name: app1-secret
            group: ""
    <!--NeedCopy-->
    

    Notes:

    • Verify that the gatewayClassName defined in the Gateway matches the GatewayClass resource that is created in the preceding step.
  5. Apply HTTPRoute or other route CRDs to route traffic to backend services.

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: example-route
    spec:
      parentRefs:
      - name: example-gateway
      hostnames:
        - "example.com"
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /
        backendRefs:
        - name: cnn-website
          namespace: default
          port: 80
    <!--NeedCopy-->
    

    Notes:

    • Ensure that the gateway name specified in parentRefs matches with the Gateway CRD established in the preceding step.
    • Currently, the HTTPRoute CRD only supports a single parentRef.
  6. Verify the gatewayClass status. If the status shows ACCEPTED: True, then the controller has accepted the resource.

    kubectl get gatewayclass
    NAME                     CONTROLLER                   ACCEPTED   AGE  
    example-gateway-class   citrix.com/nscpxgw-controller   True       2d
    <!--NeedCopy-->
    
    kubectl describe gatewayclass
    ...
    Spec:
    Controller Name:  citrix.com/nscpxgw-controller
    Status:
    Conditions:
        Last Transition Time:  2025-10-16T06:24:51Z
        Message:               Accepted by the controller.
        Reason:                Accepted
        Status:                True
        Type:                  Accepted
    Events:                    <none>
    <!--NeedCopy-->
    

    Verify the Gateway resource status. If the status shows PROGRAMMED : True, then controller has successfully pushed the configuration to NetScaler.

    kubectl get gateway example-gateway
    
    NAME            CLASS                    ADDRESS  PROGRAMMED  AGE
    example-gateway   example-gateway-class   10.244.2.28   True         14m
    <!--NeedCopy-->
    
    kubectl describe gateway example-gateway
    
    Status:
        Addresses:
            Type:   IPAddress
            Value:  10.244.2.28
        Conditions:
            Last Transition Time:  2025-10-16T06:24:53Z
            Message:               Accepted by the controller.
            Reason:                CreatedCRDInstance
            Status:                True
            Type:                  Accepted
            Last Transition Time:  2025-10-16T06:25:01Z
            Message:               Config pushed by the controller.
            Reason:                ConfigPushedToNetscaler
            Status:                True
            Type:                  Programmed
        Events:                    <none>
    <!--NeedCopy-->
    
  7. For traffic, as service of CPX is deployed as nodePort, you can use nodeIP:NodePort to send the traffic.

    kubectl get svc -o wide
        
    NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE   SELECTOR
    cpx-gateway-controller-cpx-service   NodePort       10.104.175.74   <none>        80:31375/TCP,443:31994/TCP   11m   app=cpx-gateway-controller-netscaler-cpx-with-gateway-controller
    
    <!--NeedCopy-->
    
    curl -vik --resolve example.com:<nodePort>:<nodeIP> https://example.com:<nodePort>
    
    curl -vik --resolve example.com:31994:<nodeIP> https://example.com:31994
    <!--NeedCopy-->
    
Deploy NetScaler® CPX Kubernetes Gateway Controller