Skip to content

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

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions