kafka之ranger插件的一个坑

news2024/11/18 3:30:36

之前文章写过kafka的鉴权,以及集成ranger插件的配置使用。但真正在用起来后,发现里面有个坑,本文就来聊聊这个坑的情况以及排查过程。

【问题现象】

kafka在集成了ranger插件实现鉴权功能后,发现过一段时间后,controller无法正确连接上broker,并有如下报错:

// server.log中的日志
[2022-12-06 15:32:48,068] ERROR [Controller id=0, targetBrokerId=0] Connection to node 0 failed authentication due to: Authentication failed due to invalid credentials with SASL mechanism GSSAPI (org.apache.kafka.clients.NetworkClient)
// controller.log中的日志
[2022-12-06 15:32:48,663] WARN [RequestSendThread controllerId=0] Controller 0's connection to broker kafka-0.bigdata:9090 (id: 0 rack: null) was unsuccessful (kafka.controller.RequestSendThread)

【问题分析】

1. 初步分析

问题咋一看,稍微有点懵,跑得好好的怎么突然就报错了。从日志也不太能看出问题产生的前后逻辑。所以先花了些时间整理相关的逻辑流程、涉及的类以及彼此之间的关系。

1)在kafka的controller管理中,维护了一个broker信息的hashmap,其ID为broker的ID,broker信息则以ControllerBrokerStateInfo实例对象记录。

2)每个ControllerBrokerStateInfo内部都有一个队列,controller需要给broker的发送的请求,均直接发送到该队列中;除了队列,每个ControllerBrokerStateInfo还有一个请求发送线程,循环从队列中取出消息发送给对应的broker。而network则记录与该broker的网络连接相关信息。

fc64aaa981739b4ca2657d3640d23730.jpeg

3) ControllerBrokerStateInfo中的network,往下细分,又包含Selector、KafkaChannel、ChannelBuilder、TransportLayer、Authenticator这么几层。

Selector:充当IO轮询处理的衔接,内部为不同broker,封装为不同的KafkaChannel。

ChannelBuilder:这是一个接口,具体有不同的实现,实际会根据配置中指定的协议类型(SASL、SSL、Plaintext)构造对应的实例类对象。该channelBuilder后续会再根据指定的模式(客户端或服务端)创建对应的传输层(TransportLayer)和鉴权(Authenticator)。

TransportLayer:也是一个接口,会根据实际的协议构造对应的实例类对象,负责完成请求与响应数据的传输

Authenticator:同样是一个接口,根据协议类型构造对应的实例类对象,完成交互过程中可能需要的鉴权,对于SASL又会区分客户端和服务端

KafkaChannel:对应一个broker的连接信息,内部有TransportLayer、Authenticator的实例对象作为类成员,记录连接相关的信息。

61a0c5e5cc523c0178da04f53677d1c6.jpeg

对于开启kafka鉴权时,配置采用了SASL_PLAINTEXT的协议,同时在jaas中指定了keytab文件与对应的principal。

那么controller在与broker交互过程中,会根据协议类型使用SaslChannelBuilder,同时读取jaas配置文件中的principal,并将其传递给SaslClientAuthenticator、SaslServerAuthenticator,在内部分别构造SaslClient、SaslServer时也会透传该principal信息。

2. 锁定问题出现场景

初步梳理了整个流程后,未发现存在问题的地方,也没搞清楚问题出现的时机。于是只能改变思路,模拟制造一些异常场景来分析可能出现问题的时机。

通过制造与zookeeper之间的网络异常、与kerberos之间的网络异常、进程重启、断电等场景来尝试复现问题,但问题就是没有出现。

感觉再次陷入死胡同时,中途插入另外一个紧急的事情,于是将环境搁置了一天,等忙完紧急事情后,发现问题复现了。联想到我们的kerberos票据有效期恰好是1天时间,于是尝试手动缩短kdc的票据时间来加速问题复现,当票据过期后,惊喜地发现问题复现了。

也就是说, 在kerberos票据过期后,尤其是触发controller重新选举,会立即出现该问题。

那么,在这种情形下,前一个版本是否也有同样的问题呢?

回退到前一个版本,再次执行同样的步骤尝试复现,但此时新的controller都能正确的连接到broker。

这也就说明只有当前版本存在这个问题。而当前版本的改动点主要就是引入的ranger插件实现kafka的权限控制。

通过尝试关闭kafka的鉴权、以及使用kafka原生自带的鉴权方式来再次复现问题时,结果都正常。

这样,也就真正锁定了方向,该问题就是使用ranger的kafka插件后,在kerberos票据过期后,必然出现新的controller与所有broker均连接失败的问题。

3. 再次分析

确定问题出现的场景后,终于可以有的放矢进行分析了,重新复现问题后,先通过arthas对错误打印对应代码处进行了跟踪,发现和正常情况下的值有所不同(代码如下所示)

// Jdk中的GssKrb5Server.java
public byte[] evaluateResponse(byte[] responseData) throws SaslException {
    ...
    if (protocolSaved != null &&
        !protocolSaved.equalsIgnoreCase(me.split("[/@]")[0])) {
        throw new SaslException(
            "GSS context targ name protocol error: " + me);
    }
    ...
}

正常情况下"protocolSaved"应该是一个空值,而出现问题时却是"hadoop"。

一开始怀疑是kafka所使用的keytab文件的问题(该文件中包含了两个principal,一个是kafka所使用的principal: kafka/_<HOSTNAME@bigdata.com>,另外一个则是hadoop),手动将keytab中hadoop的principal剔除后,发现出现问题时对应的值依旧是hadoop。

又一次查看整个流程,也没有看到有可能将hadoop赋值进去的地方,分析再一次陷入僵局。

再次转变思路,既然问题是引入ranger插件后引发的,先分析下ranger插件里面都做了些什么事情。

在ranger插件初始化时,会根据kafka中jaas指定的principal构造一个UGI(hadoop中的UserGroupInformation类),后续都会使用该UGI完成审计信息的记录。

但是:在构造UGI的时候,会在原有的subject中添加进程启动的系统用户的principal(对于我们的场景而言,kafka就是以hadoop用户来启动的。hadoop也就是在此时添加进去的)

225e515b06d52874a3726557a3901aa5.jpeg

这样一来,在subject中就同时增加了两个principal。

注意,subject中的首个principal还是jaas中指定的,因为是先依次构造的subject,然后在构造UGI时,才添加了进程对应系统用户的principal。

当kerberos票据过期后,keytab中对应的principal会从subject中移除,系统用户对应的principan会变成subject中的首个principal。

此后,kafka的controller连接broker的交互过程中,broker作为服务端创建saslServer时,由于subject中的首个principal已经变为系统用户,与客户端指定的服务端principal不符,导致出现问题。

【问题解决】

问题出现后,先在社区上逛了一圈,恰好发现有人已经修复了此问题,本质上就是在ranger插件中,修改调用UGI的方法,避免在原有subject中引入进程对应系统用户的principal。我们引入该patch后,问题也就自然而然地解决了。

对应的issue: https://issues.apache.org/jira/browse/RANGER-2810

【总结】

在这个问题排查过程中,有很多东西还可以再深入下,例如controller与broker交互的源码,jaas的原理等等,有兴趣的可以自己去看看。另外就是,遇到问题,先不要慌,偶现问题找规律变成必现问题,这样离解决问题就不远了。最后,开源的问题很多时候可以去社区上找找答案。

好了,这就是本文的全部内容,如果觉得本文对您有帮助,请点赞+转发,也欢迎加我微信交流~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/77893.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Gaussian 计算静电云图确定吸附位点

计算背景&#xff1a; 利用高分子有机物等活性材料对有毒分子、原子、离子在真空、水溶液、有机溶液等环境下吸附&#xff0c;已是当今环境科学、矿物学、土壤化学等学科领域研究的热点。但如何确定最佳吸附位点以计算其吸附能就显得尤为重要。 现阶段多数物质的吸附均依据粒…

Eureka自我保护模式和InstanceID的配置

本节我们主要介绍 Eureka 自我保护模式的开启和关闭和自定义 Eureka 的 InstanceID 的配置。 关闭自我保护 保护模式主要在一组客户端和 Eureka Server 之间存在网络分区场景时使用。一旦进入保护模式&#xff0c;Eureka Server 将会尝试保护其服务的注册表中的信息&#xff…

PMP内容1

PMP目录概述需求&#xff1a;设计思路实现思路分析1.2.确认范围3.控制范围4.进度管理5.规划进度管理成本管理估算成本参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a bette…

Yocto系列讲解[驱动篇]89 - 内核通知事件notifier chain驱动示例

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 内核通知事件知识Yocto中添加recipe第一个驱动模块:notifier chain provider驱动第二个驱动模块:notifier chain customer驱动两个驱…

使用 `laravel-nestedset` 实现动态权限路由

laravel-nestedset 是一款基于嵌套集合模型&#xff08;Nested Set Model&#xff09;的用于实现有序树的 laravel 扩展包。 什么是嵌套集合模型&#xff1f; 嵌套集合或嵌套集合模型是一种在关系数据库表中高效存储分层数据的方法&#xff0c;理论基础为预排序遍历树算法&am…

开源SCRM营销平台-MarketGo产品介绍(一)

1、MarketGo概述 MarketGo中国式营销自动化开源项目标杆。 MarketGo更像是一个 SDK 、引擎&#xff0c;通过提供的标准化功能和基础能力&#xff0c;让开发者能快速搭建一个营销自动化系统&#xff0c;快速完成从0-1的过程&#xff0c;并且能基于开放的能力和源码&#xff0c…

【Unity3D】使用GL绘制线段

1 前言 线段渲染器LineRenderer、拖尾TrailRenderer、绘制物体表面三角形网格从不同角度介绍了绘制线段的方法&#xff0c;本文再介绍一种新的绘制线段的方法&#xff1a;使用 GL 绘制线段。 Graphics Library&#xff08;简称 GL&#xff09;&#xff0c;包含一系列类似 OpenG…

python tk 小案例:制作一个问题搜索器

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 又到了学Python时刻~ 在逛百度搜东西的时候&#xff0c;有一些杂乱的词条容易混入进来‘ 那么&#xff1f;我们能不能自己创建一个类似百度的搜索器呢&#xff1f; 当然是可以的&#xff0c;今天博主就来分享一下如何…

Dell电脑搭配Win10休眠 = 黑屏

应该是Dell的硬件和win10操作系统的适配性不行。 Dell黑屏现象 刚买Dell笔记本的时候&#xff0c;就有“黑屏”问题。刚买的一个周、一个月、一年、两年都有这样的问题&#xff0c;而且一个月至少发生一次&#xff1a; 摁了开机键&#xff0c;也开机成功了&#xff0c;电脑就…

Python——旋转字符串

题目描述 给定两个字符串s和goal&#xff0c;如果在若干次旋转操作后s能够变成goal&#xff0c;那么就返回True s的旋转操作就是把s最左面的字符放到最右面 例如&#xff1a; s ‘abcde’ 旋转一次就是‘bceda’ 而如果goal是bceda&#xff0c;那么goal就是s的旋转字符串 P…

[附源码]JAVA毕业设计心理学网站(系统+LW)

[附源码]JAVA毕业设计心理学网站&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#…

MySQL数据库的索引以及事务详解

课前导读&#xff1a; 本章设计到MySQL数据库的索引和事务操作&#xff0c;索引操作设计的概念内容比较多&#xff0c;但是他涉及到数据库的内部运行效率和使用空间等多方面知识&#xff0c;相比比较重要&#xff0c;也需要进行相关学习。而事务操作更不用多说&#xff0c;是我…

WEB进销存管理系统源码带操作手册和源码安装说明文档

适用于大众化普通商品&#xff0c;包括鞋服、眼镜店等&#xff0c;前端使用js、html、css最基本的技术&#xff0c;后端使用sql、存储过程&#xff0c;前后端才有json交互&#xff0c;不依赖于任何第三方框架&#xff0c;简单易用易学&#xff0c;适合扩展。 源码类型&#…

Java十年功力还是涨不了薪,推荐必看《Java核心技术及面试指南》

很多程序员工作努力&#xff0c;但表现一般&#xff0c;导致面试失败或者涨不了薪资&#xff0c;在我看来&#xff0c;这种情况出现的原因有两个&#xff1a;一个是“盲人摸象&#xff0c;只知其一不知其二”&#xff0c;埋头做技术或者“CV工程师”&#xff0c;再做几年也没成…

JavaScript期末大作业 基于HTML+CSS+JavaScript技术制作web前端开发个人博客(48页)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

MOSFET 和 IGBT 栅极驱动器电路的基本原理学习笔记(四)高侧非隔离栅极驱动

高侧非隔离栅极驱动 1.适用于P沟道的高侧驱动器 2.适用于N沟道的高侧直接驱动器 1.适用于P沟道的高侧驱动器 高侧非隔离栅极驱动可按照所驱动的器件类型或涉及的驱动电路类型来分类。相应地&#xff0c;无论是使用P沟道还是 N沟道器件&#xff0c;是实施直接驱动、电平位移驱…

项目设置统一返回结果对象

一、统一返回数据格式 项目中我们会将响应封装成json返回&#xff0c;一般我们会将所有接口的数据格式统一&#xff0c; 使前端(iOS,Android, Web)对数据的操作更一致、轻松。 一般情况下&#xff0c;统一返回数据格式没有固定的格式&#xff0c;只要能描述清楚返回的数据状态以…

十四、使用 Vue Router 开发单页应用(4)

本周概要 导航守卫 全局守卫路由独享的守卫组件内守卫导航解析流程 14.10 导航守卫 在 14.4 嵌套路由 小节中已经使用过一个组件内的导航守卫&#xff1a;beforeRouteUpdate 。Vue Router 提供的导航守卫主要用于在导航过程中重定向或取消路由&#xff0c;或添加权限验证、…

python基于用户画像和协同过滤实现电影推荐系统

1、概要 传统电影推荐系统大多使用协同过滤算法实现电影推荐&#xff0c;主要实现机理是通过用户评分及用户观影历史数据抽象为多维向量利用欧式距离或其他向量计算公式实现推荐&#xff0c;本文中将采用常用的机器学习算法Kmeans聚类算法协同过滤算法word2vec搜索推荐模型多模…

【猿如意】MySQL的下载、安装、使用,这一文足够了~

大家好&#xff0c;我是笑小枫&#xff0c;本篇文章为大家分享一个好用的工具-【猿如意】 对于这个工具呢&#xff0c;怎么说呢&#xff1f;简单点就是&#xff1a;不经意间回首&#xff0c;放眼望去&#xff0c;满眼是你~ 下面就已Mysql下载安装的过程来和大家一起体验下我们的…