Lab: Enabling TLS
Task 1: Creating a Certificate
Use the certificate CR to create a new TLS certificate.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cluster-1-tls
spec:
isCA: false
commonName: Cluster 1
secretName: cluster-1-tls-managed
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: root-ca-issuer
kind: ClusterIssuer
group: cert-manager.io
dnsNames:
- cluster-1-kafka-bootstrap
# replace {your namespace}
- cluster-1-kafka-bootstrap.{your namespace}
# replace {your namespace}
- cluster-1-kafka-bootstrap.{your namespace}.svc
# replace {your namespace}
- '*.cluster-1-kafka-brokers.{your namespace}.svc'
usages:
- "digital signature"
- "key encipherment"
keystores:
pkcs12:
create: true
password: changeit
profile: Modern2023
jks:
create: true
alias: client-cert
password: changeit
Warning
Replace {your namespace} with your personal namespace (3 occurrences).
Verifying Certificates
After deploying a certificate in your namespace, you can verify its successful creation by issuing the following command:
$ kubectl get -n {your namespace} certificate
Ready: True in the output table.
Task 2: Adding a TLS Listener
Modify your existing Kafka cluster by adding a internal listener to tls using TLS encryption and the TCP
port 9093.
https://strimzi.io/docs/operators/latest/configuring#type-GenericKafkaListener-reference
Hint 1
By creating a certificate in the previous exercise, CertManager created a new secret containing the TLS certificate
and private key. Use this secret to configure a brokerCertChainAndKey in the listener configuration.
Hint 2
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
# ...
spec:
kafka:
# ...
listeners:
- name: tlsnoauth
port: 9093
type: internal
tls: true
configuration:
brokerCertChainAndKey:
secretName: cluster-1-tls-managed
certificate: tls.crt
key: tls.key
Hint 3
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaNodePool
metadata:
name: controller
labels:
strimzi.io/cluster: cluster-1
spec:
replicas: 3
roles:
- controller
storage:
type: jbod
volumes:
- id: 0
type: persistent-claim
size: 50Gi
kraftMetadata: shared
deleteClaim: false
class: managed-csi
resources:
requests:
memory: 2Gi
cpu: "200m"
limits:
memory: 2Gi
---
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaNodePool
metadata:
name: broker
labels:
strimzi.io/cluster: cluster-1
spec:
replicas: 3
roles:
- broker
storage:
type: jbod
volumes:
- id: 0
type: persistent-claim
size: 100Gi
kraftMetadata: shared
deleteClaim: false
class: managed-csi
resources:
requests:
memory: 4Gi
cpu: "500m"
limits:
memory: 4Gi
---
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: cluster-1
annotations:
strimzi.io/node-pools: enabled
strimzi.io/kraft: enabled
spec:
kafkaExporter:
topicRegex: "^[^_].*$"
groupRegex: "^[^_].*$"
kafka:
version: 4.1.0
listeners:
- name: plain
port: 9092
type: internal
tls: false
- name: tls
port: 9093
type: internal
tls: true
configuration:
brokerCertChainAndKey:
secretName: cluster-1-tls-managed
certificate: tls.crt
key: tls.key
config:
offsets.topic.replication.factor: 3
transaction.state.log.replication.factor: 3
transaction.state.log.min.isr: 2
default.replication.factor: 3
min.insync.replicas: 2
metricsConfig:
type: jmxPrometheusExporter
valueFrom:
configMapKeyRef:
name: kafka-metrics
key: kafka-metrics-config.yml
entityOperator:
topicOperator: {}
userOperator: {}
Task 3: Test the Connection
We would like to test the TLS connection using the Kafka CLI tools within the debug container.
Step 1: Mount the Truststore to the Debug CLI Pod
To allow the JVM to access the CA certificates and use them for validation, we need to mount the truststore into our Debug CLI pod. When creating the server certificate used by the TLS listener, cert-manager also created a truststore containing the correct CA certificate within the same secret used to store the listener certificate. For simplicity, we want to mount the secret in our Debug CLI pod.
Mount the secret cluster-1-tls-managed in your pod using the path /run/secrets/ca.
Hint 1
Copy the definition of your Debug CLI deployment from a previous setup and add the volume.
Hint 2
apiVersion: apps/v1
kind: Deployment
# <...>
spec:
# ...
template:
# ...
spec:
# ...
containers:
- name: kafka-otc
# ...
volumeMounts:
- name: broker-tls
mountPath: /run/secrets/ca/
# ...
volumes:
- name: broker-tls
secret:
secretName: cluster-1-tls-managed
# ...
Hint 3
apiVersion: apps/v1
kind: Deployment
metadata:
name: kafka-debug-cli
labels:
app: debug-cli
spec:
replicas: 1
selector:
matchLabels:
app: debug-cli
template:
metadata:
labels:
app: debug-cli
spec:
initContainers:
- name: debug-cli-chown
image: krassestecontainerreistry.azurecr.io/kafka-oauth-client:latest
securityContext:
privileged: true
runAsUser: 0
runAsGroup: 0
command: [ "chown", "-R", "user:user", "/opt/user_conf" ]
volumeMounts:
- name: user-conf
mountPath: /opt/user_conf
readOnly: false
containers:
- name: debug-cli
image: krassestecontainerreistry.azurecr.io/kafka-oauth-client:latest #TODO: replace ACR name
resources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 200m
memory: 200Mi
volumeMounts:
- name: user-conf
mountPath: /opt/user_conf
readOnly: false
- name: cluster-1-config
mountPath: /config/cluster-1
- name: broker-tls
mountPath: /run/secrets/ca/
volumes:
- name: user-conf
persistentVolumeClaim:
claimName: debug-cli-user-conf
- name: cluster-1-config
configMap:
name: cluster-1-client-cfg
- name: broker-tls
secret:
secretName: cluster-1-tls-managed
Step 2: Adding a Client Config
Change the values within the existing ConfigMap you set up to store the client configuration.
Add those configs:
sasl.mechanism=PLAIN
security.protocol=SSL
ssl.truststore.location=/run/secrets/ca/truststore.jks
ssl.truststore.type=JKS
ssl.truststore.password=changeit
Hint 1
Change the existing config map and also change the bootstrap server.
Hint 2
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-1-client-cfg
data:
client.properties: |
bootstrap.servers=cluster-1-kafka-bootstrap.{your namespace}.svc:9093
sasl.mechanism=PLAIN
security.protocol=SSL
ssl.truststore.location=/run/secrets/ca/truststore.jks
ssl.truststore.type=JKS
ssl.truststore.password=changeit
parse.key=true
key.separator=:
Hint 3
ask the trainer
Step 3: Publishing Messages
Now publish some messages to the topic test-0.
Solution
Use the new properties file and the new port 9093, we can publish some sample messages to the topic test-0.
Remember to replace {your namespace} with your personal namespace.
kafka-console-producer \
--bootstrap-server cluster-1-kafka-bootstrap.{your namespace}:9093 \
--producer.config /config/cluster-1/client.properties \
--topic test-0 < /opt/samples/messages_glados_still_alive.txt