2

I need to read Kafka messages with .Net from an external server. As the first step, I have installed Kafka on my local machine and then wrote the .Net code. It worked as wanted. Then, I moved to the cloud but the code did not work. Here is the setup that I have.

I have a Kafka Server deployed on a Windows VM (VM1: 10.0.0.4) on Azure. It is up and running. I have created a test topic and produced some messages with cmd. To test that everything is working I have opened a consumer with cmd and received the generated messages.

Then I have deployed another Windows VM (VM2, 10.0.0.5) with Visual Studio. Both of the VMs are deployed on the same virtual network so that I do not have to worry about opening ports or any other network configuration.

then, I have copied my Visual Studio project code and then changed the IP address of the bootstrap-server to point to the Kafka server. It did not work then, I read that I have to change the server configuration of Kafka, so I opened the server.properties and modified the listeners property to listeners=PLAINTEXT://10.0.0.4:9092. It still does not work.

I have searched online and tried many of the tips but it does not work. I think first of all to provide the credential to an external server (vm1), and probably some other configuration. Unfortunately, the official documentation of confluent is very short with very few examples. There is also no example to my case on the official GitHub. I have played with the "Sasl" properties in the Consumer Config class, but also no success.

the error message is:

%3|1622220986.498|FAIL|rdkafka#consumer-1| [thrd:10.0.0.4:9092/bootstrap]: 10.0.0.4:9092/bootstrap: Connect to ipv4#10.0.0.4:9092 failed: Unknown error (after 21038ms in state CONNECT) Error: 10.0.0.4:9092/bootstrap: Connect to ipv4#10.0.0.4:9092 failed: Unknown error (after 21038ms in state CONNECT) Error: 1/1 brokers are down

Here is my .Net core code:

static void Main(string[] args)
    {
        string topic = "AzureTopic";
        var config = new ConsumerConfig
        {
            BootstrapServers = "10.0.0.4:9092",
            GroupId = "test",
            //SecurityProtocol = SecurityProtocol.SaslPlaintext,
            //SaslMechanism = SaslMechanism.Plain,
            //SaslUsername = "[User]",
            //SaslPassword = "[Password]",
            AutoOffsetReset = AutoOffsetReset.Latest,
            //EnableAutoCommit = false
        };

        int x = 0;
        
        using (var consumer = new ConsumerBuilder<Ignore, string>(config)
             .SetErrorHandler((_, e) => Console.WriteLine($"Error: {e.Reason}"))
            .Build())
        {
            consumer.Subscribe(topic);
            var cancelToken = new CancellationTokenSource();

            while (true)
            {
                // some tasks
            }
            consumer.Close();
Ziad Salem
  • 496
  • 13
  • 34

1 Answers1

3

If you set listeners to a hard-coded IP, it'll only start the server binding and accepting traffic to that ip

And your listener isn't defined as SASL, so I'm not sure why you've tried using that in the client. While using credentials is strongly encouraged when sending data to cloud resources, it's not required to fix a network connectivity problem. You definitely shouldn't send credentials over plaintext, however

Start with these settings

listeners=PLAINTEXT://0.0.0.0:9092
advertised.listeners=PLAINTEXT://10.0.0.4:9092

That alone should work within the VM shared network. You can use the console tools included with Kafka to test it.

And if that still doesn't work from your local client, then it's because 10.0.0.0/8 address space is considered a private network and you must advertise the VM's public IP and allow TCP traffic on port 9092 through Azure Firewall. It'd also make sense to expose multiple listeners for internal Azure network and external, forwarded network traffic

Details here discuss AWS and Docker, but the basics still apply

Overall, I think it'd be easier to setup Azure EventHub with Kafka support

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • Thanks for your answer! I have already tried with the advertised.listeners and tried once again, it did work. I tried also over the public and open port 9092 but it did not work as well. There is no Firewall setup. Must I set up one and allow the port? EventHubs is a good alternative but it wants to work for the intended purposes. We want to deploy later the code over a container and stay independent of the cloud provider! – Ziad Salem May 31 '21 at 19:40
  • So it did work? If not, did you read through the linked blog and see debugging steps with kafkacat? Also, your infrastructure setup code is already cloud specific; containers don't count until you start leveraging authentication steps within the deployment that depend on the cloud auth services – OneCricketeer May 31 '21 at 19:41
  • Actually, I did not do the step in the linked article with multiple listeners, I was going to try that next, but I am suspecting that the problem lies in the firewall setting- just wanted to make sure first. I did not use Kafkacat, but checked the connection with PowerShell (command> Text-NetConnection [host] -p 9092). PowerShell tells me Ping succeeded, but TCP-Connection on port 9092 failed. So I was thinking that the problem falls on the network configuration. Anyway, I will run the Kafkacat debugger tomorrow and let you know :). – Ziad Salem May 31 '21 at 19:53
  • Port checking is a good first step, but it's not the whole picture. What you're checking there is that `listeners` has opened the port and the bootstrap request will get answered. There's no powershell tool that'll answer if the returned `advertised.listeners` address is able to be connected to, and that's what `kafkacat -L` data shows (which you can then use the commands you just mentioned to connect with individual brokers in the cluster) – OneCricketeer May 31 '21 at 19:57
  • 1
    Probably, we will move to Confluent Cloud. So hopefully I do not have to go over all these painful configurations. However, I read the article, it is very helpful, I do understand what I have to configure to get data back from the broker to my client. Anyway, thanks a lot, OneCricketeer, for your assist! – Ziad Salem Jun 02 '21 at 13:29