Apache Kafka作为业界广泛采用的消息队列系统,以其高吞吐量、低延迟和分布式特性,在大数据处理、实时流处理等领域扮演着至关重要的角色。然而,在企业级应用中,特别是在需要处理内外网通信的情况下,如何高效、安全地实现Kafka集群的内外网分流成为了一项重要挑战。本文将深入探讨Kafka内外网分流的策略、技术细节、常见问题及其解决方法,并通过实际案例和代码示例,为读者提供一套可操作的实践指南。
现代企业的IT架构往往需要同时服务于内部系统和外部客户,而Kafka作为数据交换的核心组件,其访问控制和流量管理变得尤为关键。一方面,内部系统间的通信需要高效且低延迟;另一方面,对外提供的服务需要安全可控,避免对内部网络造成不必要的压力或安全隐患。因此,实现Kafka集群的内外网分流,既能保障内部服务的稳定高效,又能确保外部接入的安全隔离。
最直观的内外网分流方式是在Kafka节点上配置双网卡,分别绑定内网IP和外网IP。这种配置下,Kafka可以通过不同的监听端口或不同的Broker地址来区分内外网流量。
另一种常见的做法是引入代理服务,如Nginx、HAProxy或者专门的Kafka代理软件,这些代理可以作为内外网通信的桥梁,实现流量的路由和安全控制。
在云原生环境下,利用容器技术(如Docker)、Kubernetes网络策略或虚拟私有云(VPC),可以创建逻辑隔离的网络环境,为内外网流量提供不同的入口点。
假设我们有三台Kafka Broker节点,每台都配置了内网IP(例如10.0.0.x)和外网IP(例如192.168.0.x)。为了实现内外网分流,我们可以在server.properties
文件中分别配置两个监听器:
Properties1# 对内监听器
2listeners=INTERNAL://10.0.0.x:9092,EXTERNAL://192.168.0.x:9093
3
4# 对应的广告地址
5advertised.listeners=INTERNAL://kafka-node-internal.example.com:9092,EXTERNAL://kafka-node-external.example.com:9093
其中,INTERNAL
和EXTERNAL
是自定义的监听器名称,advertised.listeners
用于告诉客户端应该连接哪个地址。
若采用Nginx作为代理,可以配置如下Nginx配置文件片段,实现内外网的负载均衡与转发:
Nginx1stream {
2 upstream kafka_internal {
3 server kafka-node-internal.example.com:9092;
4 }
5
6 upstream kafka_external {
7 server kafka-node-external.example.com:9093;
8 }
9
10 server {
11 listen 9092;
12 proxy_pass kafka_internal;
13 }
14
15 server {
16 listen 9093;
17 proxy_pass kafka_external;
18 # 可以在此处添加SSL/TLS加密配置,增强安全性
19 }
20}
在云原生或高度虚拟化的环境中,利用容器技术和Kubernetes等平台,可以灵活地部署和管理Kafka集群,同时通过细致的网络策略来实现内外网的隔离与分流。下面详细介绍如何在Kubernetes上实现Kafka的内外网分流。
在Kubernetes中,每个Kafka Broker节点可以作为一个Pod运行,而Service则负责定义这些Pod的访问方式。为了实现内外网的分离,我们可以为每个Kafka Broker创建两个Service:一个用于内部通信,另一个用于外部访问。
Yaml1apiVersion: v1
2kind: Service
3metadata:
4 name: kafka-broker-internal
5spec:
6 selector:
7 app: kafka-broker
8 ports:
9 - name: kafka-port
10 port: 9092
11 targetPort: 9092
12 type: ClusterIP
Yaml1apiVersion: v1
2kind: Service
3metadata:
4 name: kafka-broker-external
5spec:
6 selector:
7 app: kafka-broker
8 ports:
9 - name: kafka-port
10 port: 9092
11 targetPort: 9092
12 type: NodePort
这里,kafka-broker-internal
使用ClusterIP类型,仅在集群内部可访问;而kafka-broker-external
使用NodePort类型,允许通过节点的IP和开放端口从外部访问。
为了进一步加强内外网的隔离,可以利用Kubernetes的NetworkPolicy资源来精细控制Pod之间的网络访问。以下是一个示例,它允许来自内部网络的Pod访问Kafka,同时限制外部访问:
Yaml1apiVersion: networking.k8s.io/v1
2kind: NetworkPolicy
3metadata:
4 name: kafka-policy
5spec:
6 podSelector:
7 matchLabels:
8 app: kafka-broker
9 policyTypes:
10 - Ingress
11 ingress:
12 - from:
13 - podSelector:
14 matchLabels:
15 app: my-internal-app
16 ports:
17 - protocol: TCP
18 port: 9092
这个NetworkPolicy只允许标签为my-internal-app
的Pod访问Kafka Broker,从而实现了严格的内外网访问控制。
在云服务提供商的虚拟私有云(VPC)中,可以创建不同的子网来实现物理层面的隔离。例如,将Kafka Broker部署在一个仅允许内网访问的子网中,而对外服务的Kafka Proxy或者负载均衡器部署在面向公网的子网中。通过安全组规则进一步细化网络访问权限,确保内外网流量的隔离与安全。
无论采用何种网络策略,确保数据在传输过程中的安全性至关重要。在Kubernetes上,可以为Kafka Broker配置TLS加密,并结合客户端认证机制,为内外网通信提供额外的安全保障。
Yaml1# 示例:Kafka Broker的TLS配置
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: kafka-broker
6spec:
7 template:
8 metadata:
9 labels:
10 app: kafka-broker
11 spec:
12 containers:
13 - name: kafka
14 image: confluentinc/cp-kafka
15 ports:
16 - containerPort: 9092
17 env:
18 - name: KAFKA_ZOOKEEPER_CONNECT
19 value: zookeeper-service:2181
20 - name: KAFKA_LISTENERS
21 value: INTERNAL://0.0.0.0:9092,EXTERNAL://0.0.0.0:9093
22 - name: KAFKA_ADVERTISED_LISTENERS
23 value: INTERNAL://kafka-broker-internal:9092,EXTERNAL://kafka-broker-external:9093
24 - name: KAFKA_SSL_KEYSTORE_LOCATION
25 value: /var/private/keystore.jks
26 - name: KAFKA_SSL_KEYSTORE_PASSWORD
27 valueFrom:
28 secretKeyRef:
29 name: kafka-ssl-secret
30 key: keystore-password
31 # 其他SSL相关的环境变量配置...
listener配置是用来绑定BrokerIP+端口地址
的,也就是只有通过绑定的地址才能够访问到该Broker。除了绑定地址之外,还可以配置该监听地址的认证协议,也就是使用该地址连接Broker时需要指定使用何种协议方式进行连接。
如下配置:
listeners: INTERNAL://172.17.0.10:9092,EXTERNAL://172.17.0.10:9094
kafka_listener_security_protocol_map: "INTERNAL:SASL_PLAINTEXT,EXTERNAL:SASL_PLAINTEXT"
连接该Broker的客户端只能通过172.17.0.10:9092
和172.17.0.10:9094
这两个地址访问kafka,并给前一个地址设置listener名称为INTERNAL
,后一个为EXTERNAL
在kafka_listener_security_protocol_map
配置中设置listener所使用的通信协议,INTERNAL设置的是SASL_PLAINTEXT
,这也是常见的用户名和密码认证协议,EXTERNAL
设置也是该协议。
最终,kafka 客户端连接该kafka broker,需要通过172.17.0.10:9092
或172.17.0.10:9094
地址进行连接,并且都需要使用用户名和密码进行认证。
该配置指定Kafka Broker对外公开的网络IP和端口,用于告知客户端如何连接到Kafka Broker。公开的方式是通过存储在zookeeper中进行共享数据的。
如下配置:
listeners: INTERNAL://172.17.0.10:9092,EXTERNAL://172.17.0.10:9094
advertised_listeners: INTERNAL://172.17.0.10:9092,EXTERNAL://公网IP:端口
kafka_listener_security_protocol_map: "INTERNAL:SASL_PLAINTEXT,EXTERNAL:SASL_PLAINTEXT"
listeners
和kafka_listener_security_protocol_map
的配置和上面讲的一样,而advertised_listeners
的配置和listeners
配置含义基本一致,但是它会保存在zookeeper中/brokers/ids/0
的endpoints里。
...
"endpoints":["INTERNAL://172.17.0.10:9092","EXTERNAL://172.17.0.10:9094"]
...
kafka客户端连接kafka broker时,会先获取所有brokers的元数据信息,获取到endpoints的信息,然后再通过其中的endpint进行对broker进行连接操作。
在需要代理才能连接kafka broker时,在这种场景时,需要将advertised.listeners
设置为代理的地址。
在公有云场景下部署kafka集群,公网IP不是在本节点网卡上的,所以无法通过listener进行绑定,所以只能通过0.0.0.0进行绑定。但是在集群外部时,kafka客户端进行连接,它是需要有能力访问kafka的每一个broker节点的,所以需要在advertised.listeners中配置公网IP,并存储在zookeeper中,这样kafka客户端就能拿到所有broker节点的公网IP并进行访问。
总结一句话:
修改kafka的配置文件
vi config/server.properties
listener.security.protocol.map=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
listeners=INTERNAL://192.168.88.12:9092,EXTERNAL://192.168.100.104:19092
advertised.listeners=INTERNAL://192.168.88.12:9092,EXTERNAL://192.168.100.104:19092
inter.broker.listener.name=INTERNAL
重启kafka服务
sh kafka.sh restart
内外网验证
上面用到的Kafka的两个配置参数,一个是listeners,用于指定当前节点监听本机的哪个IP地址,另一个是advertised.listeners,用于指定客户端可以通过哪个IP访问到当前节点。假设机器没有外网网卡(即上服务器是没有eth1网卡的),外网通信地址基于转发或映射出来的IP,那么,我们的Kafka配置就应该改成这样配置。
listener.security.protocol.map=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
listeners=INTERNAL://192.168.88.12:9092,EXTERNAL://192.168.88.12:19092
advertised.listeners=INTERNAL://192.168.88.12:9092,EXTERNAL://192.168.100.104:19092
inter.broker.listener.name=INTERNAL
Kafka集群内外网分流的实施是一项综合性的工程,涉及到网络规划、配置管理、安全策略等多个层面。通过上述策略和技术的合理应用,可以有效提升系统的安全性与性能。未来,随着云原生技术的发展,更加灵活和自动化的网络管理方案将成为趋势,比如Kafka本身也可能内置更多针对复杂网络环境的支持。总之,内外网分流不仅是技术上的挑战,更是对企业IT治理能力的一次检验,而正确的实践和持续的优化将为企业的数字化转型之路奠定坚实的基础。
最后,感谢腾讯云开发者社区小伙伴的陪伴,如果你喜欢我的博客内容,认可我的观点和经验分享,请点赞、收藏和评论,这将是对我最大的鼓励和支持。同时,也欢迎大家提出宝贵的意见和建议,让我能够更好地改进和完善我的博客。谢谢!我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!
参考链接:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。