GKE Private Service Connect for Strimzi Kafka
Configure Service Attach
apiVersion: networking.gke.io/v1
kind: ServiceAttachment
metadata:
name: kafka-cluster-psc-broker-0
namespace: kafka
spec:
connectionPreference: ACCEPT_MANUAL
consumerAllowList:
- connectionLimit: 5
## automatically accept connection
project: {project id}
# subnets is only for this Service Attach, can not share with different Service Attach.
natSubnets:
- >-
projects/{project/regions/asia-southeast1/subnetworks/{subset-name}
proxyProtocol: false
resourceRef:
kind: Service
name: {kubernetes service name}consumerAllowList: allows automatic connection with defined projectnatSubnets: cannot share with different Service AttachproxyProtocol: usefalsefor Kafka — whentrue, PSC adds proxy protocol bytes that break the Kafka/SASL stream:
2025-09-23 08:48:53,080 INFO [SocketServer listenerType=ZK_BROKER, nodeId=0] Failed authentication with /10.167.48.23 (channelId=10.167.2.223:9097-10.167.48.23:56462-13) (Failing SASL authentication due to invalid receive size) (org.apache.kafka.common.network.Selector) [data-plane-kafka-network-thread-0-ListenerName(EXTERNALPSC-9097)-SASL_PLAINTEXT-21]Configure Listeners
listeners:
- authentication:
type: scram-sha-512
configuration:
bootstrap:
annotations:
cloud.google.com/load-balancer-type: Internal
networking.gke.io/internal-load-balancer-allow-global-access: "true"
brokers:
- advertisedHost: {Use psc IP}
annotations:
cloud.google.com/load-balancer-type: Internal
networking.gke.io/internal-load-balancer-allow-global-access: "true"
broker: 0
- advertisedHost: {Use psc IP}
annotations:
cloud.google.com/load-balancer-type: Internal
networking.gke.io/internal-load-balancer-allow-global-access: "true"
broker: 1
- advertisedHost: {Use psc IP}
annotations:
cloud.google.com/load-balancer-type: Internal
networking.gke.io/internal-load-balancer-allow-global-access: "true"
broker: 2
name: externalpsc
port: 9097
tls: false
type: loadbalancerRoot cause (proxy protocol vs SASL)
A conflict between the proxy protocol and SASL often appears when a load balancer or proxy prepends the proxy protocol header while the application expects a plain TLS ClientHello or another framing. Proxy protocol bytes at the start of the stream interfere with SASL framing and handshakes, which leads to failures such as invalid receive size during authentication.