Flask应用Jenkins边缘节点部署,Kerberos认证请求间歇性401故障排查
Flask应用Kerberos认证次日401故障排查与解决
核心原因
nohup启动的Flask进程会继承Jenkins执行kinit时的进程级Kerberos票据缓存,后续通过crontab或手动执行的kinit是在新shell进程中更新票据,不会同步到已经运行的Flask进程环境。当进程内的原始票据过期(通常24小时内),应用无法获取新票据,就会返回401认证失败。
排查步骤
- 核对进程与系统的票据缓存:找到Flask进程ID,执行
cat /proc/<PID>/environ | tr '\0' '\n' | grep KRB5CCNAME,查看进程使用的缓存路径;再执行echo $KRB5CCNAME看当前shell的路径,两者大概率不一致。 - 检查进程内票据状态:用
nsenter -t <PID> -n -i -u -p /bin/bash进入Flask进程的环境,执行klist,会发现票据已过期,而系统级klist显示的是新票据。 - 确认
HTTPKerberosAuth配置:默认情况下,requests_kerberos只会在进程启动时加载一次票据,不会主动刷新。
解决方案
方案1:绑定固定票据缓存文件
修改代码中Kerberos认证的初始化,指定固定缓存路径,确保crontab刷新的是同一个文件:
from requests_kerberos import HTTPKerberosAuth # 指定和crontab一致的缓存路径 auth = HTTPKerberosAuth(ccache='/tmp/krb5cc_flask_app') x = requests.get(url, verify=False, auth=auth)
同时更新crontab的kinit命令:
0 7 * * * kinit user@domain -kt /home/user@domain/access/user.keytab -c /tmp/krb5cc_flask_app
注意给Flask进程分配该文件的读写权限。
方案2:定期重启进程(临时应急)
如果暂时没法改代码,可在crontab中添加票据刷新后重启Flask的命令,比如:
0 7 * * * kinit user@domain -kt /home/user@domain/access/user.keytab && pkill -f "python3 app.py" && nohup python3 app.py > app.log 2>&1 &
这种方式会导致服务短暂中断,适合临时过渡。
方案3:应用内主动刷新票据
用Python的krb5库在每次请求前检查并刷新票据,不依赖外部crontab:
import krb5 from requests_kerberos import HTTPKerberosAuth def get_valid_kerberos_auth(): ctx = krb5.init_context() # 从keytab重新获取凭证 creds = krb5.get_init_creds_keytab(ctx, b'user@domain', b'/home/user@domain/access/user.keytab') # 存入指定缓存文件 ccache = krb5.cc_resolve(ctx, b'/tmp/krb5cc_flask_app') krb5.cc_initialize(ctx, ccache, creds.principal) krb5.cc_store_cred(ctx, ccache, creds) krb5.free_context(ctx) return HTTPKerberosAuth(ccache='/tmp/krb5cc_flask_app') # 每次请求前调用获取有效认证 auth = get_valid_kerberos_auth() x = requests.get(url, verify=False, auth=auth)
内容的提问来源于stack exchange,提问作者Sergio Tallo Torres
相关产品推荐
相关产品推荐

