Code Monkey home page Code Monkey logo

kafka_istio_ingress's Introduction

Strimzi/Kafka with Istio based Ingress

How's it work?

  • The Gateway API resources are configured for SNI based routing (Gateway/TLSRoute).
  • The Kafka CR is configured using TLS listeners of type cluster-ip. These provide 1 kubernetes service per broker and 1 for bootstrap.
  • The Strimzi advertisedHost feature is used to get Kafka to adveritize broker addresses that are publicly accessible.
  • Alongside each Kafka CR we create TLSRoute objects (1 per service) that permit traffic to be ingressed to the bootstrap and broker address(es). It is the SNI based routing that ensures the traffic reaches the correct kafka cluster and the correct broker within the cluster.
  • /etc/host file entries are used to create resolvable DNS names for kafka bootstrap and broker(s).
graph TD;
    Host-->MinikubeTunnel;
    MinikubeTunnel-->Istio-Gateway;
    subgraph Kubernetes
    Istio-Gateway-->Kafka_1_Bootstrap;
    Istio-Gateway-->Kafka_1_Broker_1;
    Istio-Gateway-->Kafka_1_Broker_n;
    Istio-Gateway-->Kafka_2_Bootstrap_n;
    Istio-Gateway-->Kafka_....;
    end

Prequistes

  1. Install istio locally (I'm using 1.16.2)
  2. Clone this repo and cd into it

Prepare cluster

  1. Using minikube
  2. Install Istio with the Gateway APIs using the instructions below. These are adapted from these instructions:
kubectl get crd gateways.gateway.networking.k8s.io || \
  { kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.5.1" | kubectl apply -f -; }
kubectl apply -f gatewayapi_alphas.yaml
istioctl install --set profile=minimal -y
  1. Install strimzi
kubectl create namespace kafka
kubectl create -f 'https://strimzi.io/install/latest?namespace=kafka' -n kafka

Create Ingress Gateway

kubectl create namespace istio-ingress
kubectl apply -f gateway.yaml
# Await ready
watch kubectl get gateway gateway -n istio-ingress

In another terminal start:

minikube tunnel

Wire up host side name resolution. This will allow the SNI names to resolve locally later.

INGRESS=$(kubectl get gateways gateway -n istio-ingress -ojsonpath='{.status.addresses[*].value}')
echo $INGRESS # It will probably look like 10.96.33.216

sudo sh -c 'cat >> /etc/hosts' << EOF
# Kafka/Ingress Gateway experiment
${INGRESS} my-cluster1-kafka-bootstrap.kafka my-cluster1-kafka-0.kafka my-cluster2-kafka-bootstrap.kafka my-cluster2-kafka-0.kafka
EOF

Create First Kafka Instance with its TLSRoutes and start producer/consumer

The important part here is the overridden advertised host in the my-cluster1-kafka.yaml.

kubectl apply -f my-cluster1-kafka.yaml
kubectl apply -f my-cluster1-tlsroutes.yaml
kubectl wait kafka/my-cluster1 --for=condition=Ready --timeout=300s -n kafka 
kubectl get secrets -n kafka  my-cluster1-cluster-ca-cert -o json | jq -r '.data."ca.crt" | @base64d '  >> /tmp/my-cluster1.crt

In separate windows, start publisher/consumer:

gtr -dc A-Za-z0-9 </dev/urandom | fold -10 |  kafka-console-producer  -bootstrap-server my-cluster1-kafka-bootstrap.kafka:8090 --topic foo --producer-property security.protocol=SSL --producer-property ssl.truststore.type=PEM --producer-property ssl.truststore.location=/tmp/my-cluster1.crt
kafka-console-consumer  -bootstrap-server my-cluster1-kafka-bootstrap.kafka:8090 --topic foo -consumer-property security.protocol=SSL --consumer-property ssl.truststore.type=PEM --consumer-property ssl.truststore.location=/tmp/my-cluster1.crt

Create Second Kafka Instance with its TLSRoutes

kubectl apply -f my-cluster2-kafka.yaml
kubectl apply -f my-cluster2-tlsroutes.yaml
kubectl wait kafka/my-cluster2 --for=condition=Ready --timeout=300s -n kafka 
kubectl get secrets -n kafka  my-cluster2-cluster-ca-cert -o json | jq -r '.data."ca.crt" | @base64d '  >> /tmp/my-cluster2.crt


# And show it is working by sending/receiving a message
echo "hello" | kafka-console-producer  -bootstrap-server my-cluster2-kafka-bootstrap.kafka:8090 --topic foo --producer-property security.protocol=SSL --producer-property ssl.truststore.type=PEM --producer-property ssl.truststore.location=/tmp/my-cluster2.crt
kafka-console-consumer  -bootstrap-server my-cluster2-kafka-bootstrap.kafka:8090 --topic foo -consumer-property security.protocol=SSL --consumer-property ssl.truststore.type=PEM --consumer-property ssl.truststore.location=/tmp/my-cluster2.crt --from-beginning

Notice that the 1st kafka instance is still happily producing/consumer.

Now delete the 2nd instance

kubectl delete -f my-cluster2-kafka.yaml
kubectl delete -f my-cluster2-tlsroutes.yaml

Again 1st kafka instance still producing/consuming.

Useful commands

Using OpenSSL to verify that the SNI is working

Check that the certificate chain presented belongs to the expected cluster.

/usr/local/opt/openssl@3/bin/openssl s_client -connect  my-cluster1-kafka-bootstrap.kafka:8090 -servername my-cluster1-kafka-bootstrap.kafka -showcerts -CAfile /tmp/my-cluster1.crt

Enabling Gateway Debug

istioctl proxy-config log gateway-5b4469658b-qjgjz.istio-ingress --level debug

Istio control plane logging

istioctl admin log  --level 'validationController:debug'

kafka_istio_ingress's People

Contributors

k-wall avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.