Skip to content

Do I have to enable proxy to access the broker from outside the Pulsar cluster? #601

@trynocoding

Description

@trynocoding

Describe the bug
I would like to access Pulsar brokers from outside the Kubernetes cluster without using pulsar-proxy.

Version

4.0.3

To Reproduce
Steps to reproduce the behavior:

  1. Deploy a Pulsar cluster (without proxy) using the Pulsar Operator
  2. Modify broker config to include advertisedListeners for external access
[root@master ~]# for i in `seq 0 2`; do kubectl -n pulsar-operator-system exec -it pulsarcluster-sample-broker-$i -- cat /pulsar/conf/broker.conf |egrep 'advertisedListeners|advertisedAddress|internalListenerName'|grep -v "#";doneDefaulted container "broker" out of: broker, wait-bookkeeper-ready (init)
advertisedAddress=pulsarcluster-sample-broker-0.pulsarcluster-sample-broker.pulsar-operator-system.svc.cluster.local
advertisedListeners=internal:pulsar://10.0.0.100:6650,external:pulsar://192.66.111.120:30650
internalListenerName=internal
Defaulted container "broker" out of: broker, wait-bookkeeper-ready (init)
advertisedAddress=pulsarcluster-sample-broker-1.pulsarcluster-sample-broker.pulsar-operator-system.svc.cluster.local
advertisedListeners=internal:pulsar://10.0.1.132:6650,external:pulsar://192.66.111.148:30650
internalListenerName=internal
Defaulted container "broker" out of: broker, wait-bookkeeper-ready (init)
advertisedAddress=pulsarcluster-sample-broker-2.pulsarcluster-sample-broker.pulsar-operator-system.svc.cluster.local
advertisedListeners=internal:pulsar://10.0.2.209:6650,external:pulsar://192.66.111.166:30650
internalListenerName=internal
[root@master ~]# 
  1. Run a Pulsar Go client on a host outside the cluster with:
pulsar.NewClient(pulsar.ClientOptions{
  URL: "pulsar://<NodeIP>:30650",
  ListenerName: "external",
})
  1. Observe producer behavior
[root@crazy producer]# go run producer.go 
INFO[0000] Connecting to broker                          remote_addr="pulsar://100.100.3.198:30650"
INFO[0000] TCP connection established                    local_addr="192.66.111.72:29170" remote_addr="pulsar://100.100.3.198:30650"
INFO[0000] Connection is ready                           local_addr="192.66.111.72:29170" remote_addr="pulsar://100.100.3.198:30650"
INFO[0000] Connecting to broker                          remote_addr="pulsar://192.66.111.148:30650"
INFO[0000] TCP connection established                    local_addr="192.66.111.72:46658" remote_addr="pulsar://192.66.111.148:30650"
INFO[0000] Connection is ready                           local_addr="192.66.111.72:46658" remote_addr="pulsar://192.66.111.148:30650"
INFO[0000] Connected producer                            cnx="192.66.111.72:46658 -> 192.66.111.148:30650" epoch=0 topic="persistent://public/default/test-topic"
INFO[0000] Created producer                              cnx="192.66.111.72:46658 -> 192.66.111.148:30650" producerID=1 producer_name=pulsarcluster-sample-1-3 topic="persistent://public/default/test-topic"
2025/04/15 16:55:55 Published message:  9:12:0
INFO[0000] Closing producer                              producerID=1 producer_name=pulsarcluster-sample-1-3 topic="persistent://public/default/test-topic"
INFO[0000] Closed producer                               producerID=1 producer_name=pulsarcluster-sample-1-3 topic="persistent://public/default/test-topic"
[root@crazy producer]# go run producer.go 
INFO[0000] Connecting to broker                          remote_addr="pulsar://100.100.3.198:30650"
INFO[0000] TCP connection established                    local_addr="192.66.111.72:29182" remote_addr="pulsar://100.100.3.198:30650"
INFO[0000] Connection is ready                           local_addr="192.66.111.72:29182" remote_addr="pulsar://100.100.3.198:30650"
INFO[0000] Connecting to broker                          remote_addr="pulsar://192.66.111.148:30650"
INFO[0000] TCP connection established                    local_addr="192.66.111.72:46662" remote_addr="pulsar://192.66.111.148:30650"
INFO[0000] Connection is ready                           local_addr="192.66.111.72:46662" remote_addr="pulsar://192.66.111.148:30650"
ERRO[0000] Failed to create producer at send PRODUCER request  error="server error: ServiceNotReady: Namespace bundle for topic (persistent://public/default/test-topic) not served by this instance:pulsarcluster-sample-broker-2.pulsarcluster-sample-broker.pulsar-operator-system.svc.cluster.local:8080. Please redo the lookup. Request is denied: namespace=public/default" topic="persistent://public/default/test-topic"
ERRO[0000] Failed to create producer at newPartitionProducer  error="server error: ServiceNotReady: Namespace bundle for topic (persistent://public/default/test-topic) not served by this instance:pulsarcluster-sample-broker-2.pulsarcluster-sample-broker.pulsar-operator-system.svc.cluster.local:8080. Please redo the lookup. Request is denied: namespace=public/default" topic="persistent://public/default/test-topic"
2025/04/15 16:55:57 server error: ServiceNotReady: Namespace bundle for topic (persistent://public/default/test-topic) not served by this instance:pulsarcluster-sample-broker-2.pulsarcluster-sample-broker.pulsar-operator-system.svc.cluster.local:8080. Please redo the lookup. Request is denied: namespace=public/default
exit status 1

Expected behavior
We expect that by exposing broker pulsar:// port via NodePort and configuring advertisedListeners, Pulsar clients can work without proxy.

Desktop (please complete the following information):

[root@master producer]# kubectl get no -owide
NAME      STATUS   ROLES           AGE   VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE          KERNEL-VERSION          CONTAINER-RUNTIME
master    Ready    control-plane   18d   v1.27.7   192.66.111.120   <none>        CentOS Stream 9   5.14.0-533.el9.x86_64   containerd://1.7.26
worker1   Ready    <none>          18d   v1.27.7   192.66.111.148   <none>        CentOS Stream 9   5.14.0-410.el9.x86_64   containerd://1.7.15
worker2   Ready    <none>          18d   v1.27.7   192.66.111.166   <none>        CentOS Stream 9   5.14.0-410.el9.x86_64   containerd://1.7.15
[root@master producer]# 

Additional context

Broker can be accessed normally from within the cluster

[root@master ~]# kubectl -n pulsar-operator-system get po
NAME                                                  READY   STATUS      RESTARTS   AGE
pulsar-operator-controller-manager-6855dffd4d-9pcgt   1/1     Running     0          14m
pulsarcluster-sample-bookie-0                         1/1     Running     0          12m
pulsarcluster-sample-bookie-1                         1/1     Running     0          11m
pulsarcluster-sample-bookie-2                         1/1     Running     0          11m
pulsarcluster-sample-broker-0                         1/1     Running     0          12m
pulsarcluster-sample-broker-1                         1/1     Running     0          11m
pulsarcluster-sample-broker-2                         1/1     Running     0          10m
pulsarcluster-sample-init-cluster-metadata-94nhk      0/1     Completed   0          12m
pulsarcluster-sample-toolset-0                        1/1     Running     0          12m
pulsarcluster-sample-zookeeper-0                      1/1     Running     0          13m
pulsarcluster-sample-zookeeper-1                      1/1     Running     0          13m
pulsarcluster-sample-zookeeper-2                      1/1     Running     0          13m

[root@master ~]# kubectl -n pulsar-operator-system get svc
NAME                                   TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                         AGE
pulsar-operator-webhook-service        ClusterIP   10.96.2.214   <none>        443/TCP                         20m
pulsarcluster-sample-bookie            ClusterIP   None          <none>        3181/TCP                        18m
pulsarcluster-sample-broker            ClusterIP   None          <none>        8080/TCP,6650/TCP               18m
pulsarcluster-sample-broker-nodeport   NodePort    10.96.3.24    <none>        8080:32105/TCP,6650:30650/TCP   18m
pulsarcluster-sample-zookeeper         ClusterIP   None          <none>        2888/TCP,3888/TCP,2181/TCP      19m

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions