Accessing the Cruise Control REST API

Learn how you set up access to the Cruise Control REST API.

The Cruise Control REST API supports a number of GET requests, which can be used for read-only operations. These operations do not perform any Kafka changes and do not change the state or configuration of Cruise Control. Having access to these endpoints enables you to carry out operations such as the following.

  • Query detailed Cruise Control specific statistics and data in a secure way. For example you can get access to information surrounding cluster and partition load as well as user tasks.
  • Monitor Kafka cluster with the Cruise Control user interface.
  • Debug Cruise Control securely.

You configure access control to the Cruise Control REST API endpoints using a single Kubernetes Secret. The Secret contains the list of all users who are granted access to the endpoints and their role.

Strimzi uses roles to grant users or third-party applications different levels of access to the Cruise Control REST API. Each user is configured with a static password for basic HTTP authentication.

By default Cruise Control defines the following three roles.

  • VIEWER – has access to the most lightweight kafka_cluster_state, user_tasks and review_board endpoints.
  • USER – has access to all GET endpoints except bootstrap and train.
  • ADMIN – has access to all endpoints.

Strimzi supports the USER and VIEWER roles only. This restriction is in place so that REST API calls made by users and third-party applications do not interfere with the calls, for example, the write operations, made by the Strimzi Cluster Operator and potentially cause damage to the Kafka cluster managed by Strimzi.

Configuring Cruise Control users

Learn how to configure REST API users for Cruise Control. Users you configure are granted access to the Cruise Control REST API.

You specify the users you want to grant access to the Cruise Control REST API in a Secret. The Secret must be referenced in spec.cruiseControl.apiusers of the Kafka resource.

  1. Create API users in Jetty’s HashLoginService file format (cruise-control-auth.txt).
    Add your users, their passwords, as well as the roles.
    [***USER 1***]: [***PASSWORD 1***], VIEWER
    [***USER 2***]: [***PASSWORD 2***], USER
  2. Create a Secret using the file you created in the previous step.
    kubectl create secret generic cruise-control-api-users-secret \
      --from-file=cruise-control-auth.txt=cruise-control-auth.txt
  3. Reference the Secret in spec.cruiseControl.apiUsers of the Kafka resource.
    #...
    kind: Kafka
    spec:
      cruiseControl:
        config:
          webserver.security.enable: true
          webserver.ssl.enable: true
        apiUsers:
          type: hashLoginService
          valueFrom:
            secretKeyRef:
              name: cruise-control-api-users-secret
              key: cruise-control-auth.txt
    • webserver.security.enable – Enables HTTP Basic authentication for the Cruise Control REST API and enforces the policies defined in spec.cruiseControl.apiUsers.

    • webserver.ssl.enable – Enables TLS encryption for the Cruise Control REST API.

    • apiUsers – Configures the Cruise Control REST API users by referencing a Secret.

Configuring external access

Learn how to enable external access for the Cruise Control REST API. Configuring external access makes it possible for Cruise Control users to access the REST API from outside the Kubernetes cluster.

The Cruise Control REST API can be secured with authentication, authorization and encryption. As a result, it is considered safe to allow access from outside the Kubernetes cluster as well. Cloudera recommends that access control is always used when enabling external access to Cruise Control.

By default, the Strimzi Cluster Operator generates a strict network policy that blocks external connections to Cruise Control. Additionally, the TLS certificates for Cruise Control are automatically generated and cannot be modified. As a result, to set up external access to Cruise Control you require the following.

  • Have or create a resource, like an NGINX-based Ingress, to route and manage traffic coming from outside the cluster. Any type of resource can be used that can route outside traffic.

  • Create a new network policy that enables access to Cruise Control.

  • Use the Cruise Control certificates internally.

    When TLS is enabled for Cruise Control the service certificates are generated by Strimzi and cannot be modified. This is because most of the ssl. configurations are restricted and managed by the Strimzi Cluster Operator. Because of this, the resource (for example, an Ingress) providing access to the Kubernetes cluster must use the generated TLS credentials to communicate with Cruise Control. External connections can be configured with user generated and managed certificates.

The following steps demonstrate how you can configure NGINX-based Ingress to access Cruise Control. This is just a specific example and any other type of Ingress can be used.

  1. Create a NetworkPolicy that allows the connection from the Ingress pod.
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: [***NEW CRUISE CONTROL NETWORK POLICY NAME***]
      namespace: [***CRUISE CONTROL NAMESPACE***]
    spec:
      podSelector:
        matchLabels:
          strimzi.io/cluster: [***KAFKA CLUSTER NAME***]
          strimzi.io/kind: Kafka
          strimzi.io/name: [***KAFKA CLUSTER NAME***]-cruise-control
      policyTypes:
      - Ingress
      ingress:
      - from:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              app.kubernetes.io/instance: ingress-nginx
        ports:
        - protocol: TCP
          port: 9090
  2. Get the generated Cruise Control certificate and key.
    kubectl get secret [***KAFKA CLUSTER NAME***]-cruise-control-certs \
      --namespace [***KAFKA NAMESPACE***] \
      --output "jsonpath={.data.cruise-control\.crt}" \
    | base64 -d > cert.crt
    kubectl get secret [***KAFKA CLUSTER NAME***]-cruise-control-certs \
      --namespace [***KAFKA NAMESPACE***] \
      --output "jsonpath={.data.cruise-control\.key}" \
    | base64 -d > cert.key
  3. Create a Secret with the specific format of your Ingress using the files created in the previous step.
    These needed to be updated manually if the Cruise Control Secret was regenerated.
    kubectl create secret tls [***CRUISE CONTROL INGRESS SECRET NAME***] \
      --key ./cert.key \
      --cert ./cert.crt \
      --namespace [***KAFKA NAMESPACE***]
  4. Create the Ingress rule.
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: cruise-control-ingress-service
      namespace: [***KAFKA NAMESPACE***]
      annotations:
        nginx.ingress.kubernetes.io/use-regex: 'true'
        nginx.ingress.kubernetes.io/backend-protocol: 'HTTPS'
        nginx.ingress.kubernetes.io/proxy-ssl-secret: '[***KAFKA NAMESPACE***]
    /[***CRUISE CONTROL INGRESS SECRET NAME***]'
    spec:
      ingressClassName: nginx
      tls:
      - hosts:
          - [***HOST NAME***]
        secretName: [***INGRESS SECRET NAME***]
      rules:
      - host: [***HOST NAME***]
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: [***KAFKA CLUSTER NAME***]-cruise-control
                port: 
                  number: 9090
    
    • nginx.ingress.kubernetes.io/backend-protocol– Instructs the Ingress to use encrypted communication between the Ingress and the Cruise Control pod.

    • nginx.ingress.kubernetes.io/proxy-ssl-secret – Specifies the Secret which contains the Cruise Control certificate in the required format of the Ingress solution.

    • spec.tls – Enables secure connection between the clients and the Ingress itself. This property must define the same host as the rule. the Secret should point to the Secret where the credentials for the secure client communication are stored.