Strimzi is one of the best and easiest way to deploy Kafka cluster on Kubernetes. It provides a simple way of managing users, topics, security, etc.
Confluent Schema Registry provides a serving layer for your metadata. It provides a RESTful interface for storing and retrieving your Avro®, JSON Schema, and Protobuf schemas.
It is an application that resides outside your Kafka cluster and handles the distribution of schemas to producers and consumers by storing a copy of the schema in its storage.
Confluent Schema Registry well integrated with Confluent Platform and Confluent Cloud. But not with Strimzi.
One of the instruments that integrates Confluent Schema Registry with a Strimzi Kafka cluster is strimzi-registry-operator. However, unfortunately, it is no longer maintained (the last commit was on Dec 21, 2022) and has several issues, like broken Kubernetes RBAC and only HTTP access to the Schema Registry REST API endpoint. Therefore I decided to rewrite it, focusing on using the Operator SDK in Golang and add some missing functionality.
StrimziSchemaRegistry resource, the operator creates a Kubernetes deployment of the Confluent Schema Registry, along with an associated Kubernetes service and secret.A Helm chart is available for strimzi-registry-operator on GitHub at randsw/schema-registry-operator-strimzi
helm repo add ssr-operator https://randsw.github.io/schema-registry-operator-strimzi/
helm repo update
helm install ssr ssr-operator/ssr-operator --namespace <desired_namespace> --create-namespace
:warning: Don't forget specify namespace
:warning: Pay attention to the label strimzi.io/cluster. It should match the Kafka cluster name (the name of the Kafka CR).
Deploy a KafkaTopic that the Schema Registry will use as its primary storage.
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaTopic
metadata:
name: registry-schemas
labels:
strimzi.io/cluster: kafka-cluster
spec:
partitions: 1
replicas: 3
config:
# http://kafka.apache.org/documentation/#topicconfigs
cleanup.policy: compact
Note The name
registry-schemasis currently required. The default name,_schemasisn't used because it isn't convenient to create withKafkaTopicresources.
Deploy a KafkaUser for the Schema Registry that gives the Schema Registry sufficient permissions:
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaUser
metadata:
name: confluent-schema-registry
labels:
strimzi.io/cluster: kafka-cluster
spec:
authentication:
type: tls
authorization:
# Official docs on authorizations required for the Schema Registry:
# https://docs.confluent.io/current/schema-registry/security/index.html#authorizing-access-to-the-schemas-topic
type: simple
acls:
# Allow all operations on the registry-schemas topic
# Read, Write, and DescribeConfigs are known to be required
- resource:
type: topic
name: registry-schemas
patternType: literal
operation: All
type: allow
# Allow all operations on the schema-registry* group
- resource:
type: group
name: schema-registry
patternType: prefix
operation: All
type: allow
# Allow Describe on the __consumer_offsets topic
- resource:
type: topic
name: __consumer_offsets
patternType: literal
operation: Describe
type: allow
Now that there is a topic and a user, you can deploy the Schema Registry itself.
The strimzi-schema-registry operator deploys the Schema Registry given a StrimziSchemaRegistry resource:
apiVersion: strimziregistryoperator.randsw.code/v1alpha1
kind: StrimziSchemaRegistry
metadata:
name: confluent-schema-registry
labels:
strimzi.io/cluster: kafka-cluster
spec:
strimziversion: "v1beta2"
securehttp: true
listener: "tls"
compatibilitylevel: "forward"
securityprotocol: "SSL"
template:
spec:
containers:
- name: confluent-sr
image: confluentinc/cp-schema-registry:7.6.5
imagePullPolicy: IfNotPresent
restartPolicy: Always
Schema Registry can be accessed using service in namespace where StrimziSchemaRegistry deployed. The name of the service matches the name of the CR.
These configurations can be set as fields of the StrimziSchemaRegistry's spec field:
apiVersion: strimziregistryoperator.randsw.code/v1alpha1
kind: StrimziSchemaRegistry
metadata:
name: confluent-schema-registry
labels:
strimzi.io/cluster: kafka-cluster
spec:
securehttp: true
listener: "tls"
compatibilitylevel: "forward"
securityprotocol: "SSL"
tlssecretName: ""
template:
spec:
containers:
- name: confluent-sr
image: confluentinc/cp-schema-registry:7.6.5
imagePullPolicy: IfNotPresent
restartPolicy: Always
listener is the name of the Kafka listener that the Schema Registry should use.
You should set this value based on your Kafka resource.
The "In-detail: listener configuration" section, below, explains this in more detail.
See also: Schema Registry listeners docs.
securityProtocol is the security protocol for the Schema Registry to communicate with Kafka. Default is SSL. Can be:
SSLPLAINTEXTSASL_PLAINTEXTSASL_SSLSee also: Schema Registry kafkastore.security.protocol docs.
compatibilityLevel is the default schema compatibility level. Possible values:
nonebackwardbackward_transitiveforwardforward_transitivefullfull_transitiveSee also: Schema Registry schema.compatibility.level docs.
securehttp enable TLS on Schema Registry REST API endpoint.
If securehttp is disabled the associated service points to 8081 port in Schema Registry pod. If enabled - to 8085 port.
tlssecretName is name of secret that contain TLS certificate and private key pair in JKS format. Must be in same
namespace with StrimziSchemaRegistry CR
If this field is omitted or an empty string, the SSR operator automatically creates a TLS certificate and private key pair in JKS format, signs them with the Strimzi Kafka cluster CA(stored in the <kafka-clustername>-cluster-ca and <kafka-clustername>-cluster-ca-cert secrets)
and mounts the secret to the Schema Registry pod.
Secret data format:
| Key | Value |
|---|---|
| tls-keystore.jks | Keystore |
| keystore_password | Keystore password |
| key_password | Key password |
See also: Schema Registry Configuring the REST API for HTTP or HTTPS
template is a standart Kubernetes template for pod. you can configure it as you want according to the pod specification
The spec.listener field in the StrimziSchemaRegistry resource specifies the Kafka broker listener that the Schema Registry uses.
These listeners are configured in the Kafka resource you created with Strimzi.
Consider a Kafka resource:
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: my-cluster
spec:
kafka:
#...
listeners:
- name: plain
port: 9092
type: internal
tls: false
- name: tls
port: 9093
type: internal
tls: true
authentication:
type: tls
- name: external1
port: 9094
type: route
tls: true
- name: external2
port: 9095
type: ingress
tls: true
authentication:
type: tls
configuration:
bootstrap:
host: bootstrap.myingress.com
brokers:
- broker: 0
host: broker-0.myingress.com
- broker: 1
host: broker-1.myingress.com
- broker: 2
host: broker-2.myingress.com
#...
To use the encrypted internal listener, the spec.listener field in your StrimziSchemaRegistry resource should be tls:
apiVersion: strimziregistryoperator.randsw.code/v1alpha1
kind: StrimziSchemaRegistry
metadata:
name: confluent-schema-registry
spec:
listener: tls
To use the unencrypted internal listener instead, the spec.listener field in your StrimziSchemaRegistry resource should be plain instead:
apiVersion: strimziregistryoperator.randsw.code/v1alpha1
kind: StrimziSchemaRegistry
metadata:
name: confluent-schema-registry
spec:
listener: plain
You can find example of using the schema registry in my repo - https://github.com/Randsw/strimzi-kafka-cluster
I want to thank all the people who worked on lsst-sqre/strimzi-registry-operator You create a great instrument!
There are many Schema Registry functionalities that not implemented in this operator because i don't need them. If you need some of that functionality create an issue and i see what i can do