Configure Network Encryption with Confluent for Kubernetes

This document describes how to configure network encryption with Confluent for Kubernetes (CFK). For security concepts in Confluent Platform, see Security.

To protect network communications of Confluent components, CFK supports Transport Layer Security (TLS), an industry-standard encryption protocol.

TLS relies on keys and certificates to establish trusted connections. This section describes how to manage keys and certificates in preparation to configure TLS encryption for Confluent Platform.

CFK supports the following mechanisms to enable TLS encryption:

Auto-generated certificates

CFK auto-generates the server certificates, using a given certificate authority.

If all access and communication to Confluent services is within the Kubernetes network, auto-generated certificates are recommended.

User-provided certificates

User provides the private key, public key and certificate authority.

If you need to enable access to Confluent services from an external-to-Kubernetes domain, user-provided certificates are recommended.

Configure auto-generated TLS certificates

Note

Auto-generated certificates are meant to encrypt internal traffic within the Kubernetes network.

Provide a root certificate authority as a Kubernetes Secret named ca-pair-sslcerts. Provide the certificate authority public and private key in the following format:

kubectl create secret tls ca-pair-sslcerts \
  --cert=/path/to/ca.pem \
  --key=/path/to/ca-key.pem

Configure each component to use auto-generated certificates.

spec:
  tls:
    autoGeneratedCerts: true

CFK will create the required server certificates and store them as Kubernetes secrets, for Confluent components to use:

kubectl get secrets
NAME                             TYPE
...
zookeeper-generated-jks          kubernetes.io/tls
kafka-generated-jks              kubernetes.io/tls
...

The generated server certificates expires in 365 days.

For a tutorial scenario on using auto-generated certs, see the quickstart tutorial.

Configure user-provided TLS certificates

When you provide TLS certificates, CFK takes the provided files and configures Confluent components accordingly.

For each component, the following TLS certificate information should be provided:

  • The certificate authorities for the component to trust, including the authorites used to issue server certificates for any Confluent component cluster.

    These are required so that peer-to-peer communication (e.g. between Kafka Brokers) and communication between components (e.g. from Connect workers to Kafka) will work.

  • The component’s server certificate (public key)

  • The component’s server private key

This TLS certificate information can be provided by the user in one of two formats:

Define SAN

The server certificate Subject Alternative Name (SAN) list must be properly defined and cover all hostnames that the Confluent component will be accessed on:

  • If TLS for internal communication network encryption is enabled, include the internal network, <component>.<namespace>.svc.cluster.local, in the SAN list.
  • If enabling external network communication, include the external domain name in the SAN list.

The following are the internal and external SANs of each Confluent component that need to be included in the component certificate SAN. The examples use the default component prefixes.

Kafka
  • Internal bootstrap access SAN: <customResourceName>.<namespace>.svc.cluster.local

    • Example: kafka.confluent.svc.cluster.local
  • Internal access SAN: kafka-<x>.<customResourceName>.<namespace>.svc.cluster.local

    <x> is the ordinal number of brokers, 0 to (number of brokers - 1).

    • Example: kafka-0.kafka.confluent.svc.cluster.local
    • The range can be handled through a wildcard domain, for example, *.kafka.confluent.svc.cluster.local.
  • External bootstrap domain SAN: <bootstrap_prefix>.my-external-domain

    • Example: kafka-bootstrap.acme.com
  • External broker SAN: <broker_prefix><x>.my-external-domain

    • Example: b0.acme.com
    • The range can be handled through a wildcard domain, for example, *.acme.com
MDS
  • Internal access SAN: kafka-<x>.<customResourceName>.<namespace>.svc.cluster.local

    <x> is the ordinal number of brokers, 0 to (number of brokers - 1).

    • Example: kafka-0.kafka.confluent.svc.cluster.local
  • External domain SAN: <mds_prefix>.my-external-domain

    • Example: mds.my-external-domain
ZooKeeper
  • Internal bootstrap access SAN: <customResourceName>.<namespace>.svc.cluster.local

  • Internal access SAN: zookeeper-<x>.<customResourceName>.<namespace>.svc.cluster.local

    <x> is the ordinal number of ZooKeeper servers, 0 to (number of servers - 1).

    • Example: zookeeper-0.zookeeper.confluent.svc.cluster.local
  • No external access domain

Schema Registry
  • Internal bootstrap access SAN: <customResourceName>.<namespace>.svc.cluster.local

  • Internal access SAN: schemaregistry-<x>.<customResourceName>.<namespace>. svc.cluster.local

    <x> is the ordinal number of Schema Registry servers, 0 to (number of servers - 1).

    • Example: schemaregistry-0.schemaregistry.confluent.svc.cluster.local
  • External domain SAN: <schemaregistry_prefix>.my-external-domain

Connect
  • Internal bootstrap access SAN: <customResourceName>.<namespace>.svc.cluster.local

  • Internal SAN: connect-<x>.<customResourceName>.<namespace>.svc.cluster.local

    <x> is the ordinal number of Connect servers, 0 to (number of servers - 1).

    • Example: connect-0.connect.confluent.svc.cluster.local
  • External domain SAN: <connect_prefix>.my-external-domain

ksqlDB
  • Internal bootstrap access SAN: <customResourceName>.<namespace>.svc.cluster.local

  • Internal access SAN: ksqldb-<x>.<customResourceName>.<namespace>.svc.cluster.local

    <x> is the ordinal number of ksqlDB servers, 0 to (number of servers - 1).

    • Example: ksqldb-0.ksqldb.confluent.svc.cluster.local
  • External domain SAN: <ksqldb_prefix>.my-external-domain

Control Center
  • Internal bootstrap access SAN: <customResourceName>.<namespace>.svc.cluster.local
  • Internal access SAN: controlcenter-0.<customResourceName>.<namespace>.svc.cluster.local
    • Example: controlcenter-0.controlcenter.confluent.svc.cluster.local
  • External domanin SAN: <controlcenter_prefix>.my-external-domain

For an example of how to create certificates with appropriate SAN configurations, see the Create your own certificates tutorial.

Provide TLS keys and certificates in PEM format

Prepare the following files:

  • ca.pem: This contains the list of certificate authorities to trust, in PEM-encoded format. List the certificates by simply concatenating them, one below the other, for example:

    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
    
  • server.pem: This contains the full server certificate chain in PEM-encoded format.

  • server-key.pem: This contains the PEM-encoded server certificate private key.

Create a Kubernetes secret with the following keys:

kubectl create secret generic kafka-tls \
--from-file=fullchain.pem=server.pem \
--from-file=cacerts.pem=ca.pem \
--from-file=privkey.pem=server-key.pem

Alternatively, you can create a Kubernetes secret with the following keys:

kubectl create secret generic kafka-tls \
--from-file=tls.crt=server.pem \
--from-file=ca.crt=ca.pem \
--from-file=tls.key=server-key.pem

Note: the tls.crt, ca.crt and tls.key keys are typically present in secrets created by cert-manager, a popular open source tool to manage certificates. For convenience, CFK supports this convention, but the expected contents of the files and how they are used within Confluent Platform are identical whether using the *.pem keys or the *.crt and *.key keys.

Finally, configure the component CR to use the secret:

spec:
  tls:
    secretRef: kafka-tls

Provide TLS keys and certificates in Java Keystore format

Provide the following files:

  • keystore.jks: PKCS12 format keystore, containing component server key.

  • truststore.jks: PKCS12 format truststore, containing the certificates to trust.

  • jksPassword.txt: Password for the JKS.

    Create the jksPassword.txt file with jksPassword=<password_for_jks>:

    echo -n "jksPassword=<password_for_jks>" > jksPassword.txt
    

Create a Kubernetes secret with the following keys:

kubectl create secret generic kafka-tls \
--from-file=keystore.jks=keystore.jks \
--from-file=truststore.jks=truststore.jks \
--from-file=jksPassword.txt=jksPassword.txt

Configure in the component CR:

spec:
  tls:
    secretRef: kafka-tls