Ingress

You can use Ingress to route HTTP/HTTPS traffic from outside the cluster to services within the cluster.

Ingress has two main components. You have Ingress resources, which define the traffic routing rules to your services and pods. In addition, you have Ingress controllers, which route incoming requests based on the rules defined by Ingress resources.

The Ingress API is a native part of Kubernetes, Ingress controllers are not. This means that while creating Ingress resources is possible by default on any Kubernetes cluster, the Ingress controller must be installed separately, otherwise, Ingress cannot function.

While there are numerous controller implementations available for Kubernetes, CSM Operator only supports Ingress-Nginx controllers running in TLS passthrough mode.

In CSM Operator, you set up external cluster access with Ingress by adding an ingress type listener to your Kafka resource (listener.type:ingress) and specify the hostnames for each broker and a bootstrap using the configuration property. In addition, TLS must be enabled for the listener, and, depending on your environment, specifying the Ingress class might be required.

Once configuration is done, CSM Operator deploys multiple Ingress resources as well as multiple ClusterIP Services. This means that you will have the following:
  • An Ingress and a corresponding ClusterIP that serves as an external bootstrap. This is used by clients for the initial connection and to receive metadata (advertised listeners) from the Kafka cluster.
  • A unique Ingress and a ClusterIP for each Kafka Broker. These are used to access the brokers directly and to distinguish the traffic for different brokers.

Kafka clients connect to the bootstrap Ingress, which routes the request through the corresponding bootstrap service to one of the brokers. Connections to the individual brokers are then established using advertised listeners received from the broker. Traffic is then routed from the client to the broker through the broker-specific Ingresses and services.

Once the listener is configured, you can connect your clients running outside of the Kubernetes network by directing them to the bootstrap Ingress. Kubernetes, Ingress, and Kafka handle everything else and ensure that client requests are routed to the correct brokers.

Configuring ingress listeners

Complete the following steps to set up and configure an ingress listener in CSM Operator. The following steps also include an example on how to connect a Kafka console client to the cluster.

These steps demonstrate basic listener configuration. In addition to the configuration shown here, you can further customize your listener and specify a client authentication mechanism with the authentication property and add various additional configurations using the configuration property. For a comprehensive list of available properties, see GenericKafkaListener schema reference in the Strimzi API reference.

  1. Configure your Kafka resource.

    To set up an ingress type listener, you need to configure multiple properties in your Kafka resource.

    1. Add an external listener that has its type property set to ingress.
    2. Specify Ingress hosts used for the different brokers as well as the bootstrap.
      This is done with the configuration property. Add the hostnames to the bootstrap and broker-[***INDEX***] prefixes that identify the bootstrap and brokers.
    3. Ensure that tls is set to true.
    4. Optional: Specify the Ingress class with the class property.
    Once configuration is done, your Kafka resource should look similar to the following example.
    #...
    kind: Kafka
    spec:
      kafka:
        listeners:
          - name: external
            port: 9094
            type: ingress
            tls: true
            authentication:
              type: tls
            configuration:
              bootstrap:
                host: my-bootstrap.cloudera.com
              brokers:
                - broker: 0
                  host: my-broker-0.cloudera.com
                - broker: 1
                  host: my-broker-1.cloudera.com
                - broker: 2
                  host: my-broker-2.cloudera.com
              class: nginx
    
  2. Verify that both Ingress resources and ClusterIP Services are created and running.
    Use kubectl get ingress to list ingresses.
    kubectl get ingress --namespace [***NAMESPACE***]
    The output will be similar to the following example.
    NAME                         CLASS   HOSTS                      ADDRESS     PORTS  
    #...
    my-cluster-kafka-bootstrap   nginx   my-bootstrap.cloudera.com  10.14.91.1  80, 443
    my-cluster-kafka-0           nginx   my-broker-0.cloudera.com   10.14.91.1  80, 443
    my-cluster-kafka-1           nginx   my-broker-1.cloudera.com   10.14.91.1  80, 443
    my-cluster-kafka-2           nginx   my-broker-2.cloudera.com   10.14.91.1  80, 443
    

    Use kubectl get servicesto list Kubernetes Services.

    kubectl get services --namespace [***NAMESPACE***]
    The output will be similar to the following example.
    NAME                                  TYPE        CLUSTER-IP      EXTERNAL-IP
    #...
    my-cluster-kafka-external-bootstrap   ClusterIP   10.43.16.137    <none>
    my-cluster-kafka-0                    ClusterIP   10.43.67.184    <none>
    my-cluster-kafka-1                    ClusterIP   10.43.189.61    <none>
    my-cluster-kafka-2                    ClusterIP   10.43.177.221   <none>
    
  3. Extract the TLS certificate from your broker and import it into a Java truststore file.
    Extracting the TLS certificate is required because TLS encryption is mandatory when using Ingress. Because of this, you must run your clients with a valid certificate. You can use the kubectl get to extract the certificate and the keytool utility to import the certificate into a Java truststore file. For example:
    kubectl get secret [***CLUSTER NAME***]-cluster-ca-cert \
      --namespace [***NAMESPACE***] \
      --output jsonpath='{.data.ca\.crt}' \
      | base64 -d > ca.crt
    keytool -import -trustcacerts -alias [***ALIAS***] \
      -file ca.crt \
      -keystore truststore.jks \
      -storepass [***PASSWORD***] \
      -noprompt
  4. Ensure that the resulting truststore is available on the machine where you will run your client and that the client has access to the file.
  5. Configure your client.
    The following example shows a Kafka console producer. The port used by Ingress is typically 443.
    kafka-console-producer.sh \
      --bootstrap-server [***BOOTSTRAP INGRESS HOST***]:443 \
      --producer-property security.protocol=SSL \
      --producer-property ssl.truststore.password=[***PASSWORD***] \
      --producer-property ssl.truststore.location=[***TRUSTSTORE LOCATION***] \
      --topic [***TOPIC***]