写点什么

Rancher 实战案例 | kube-api-auth 日志中出现大量错误信息怎么办?

  • 2020-05-25
  • 本文字数:3792 字

    阅读完需:约 12 分钟

Rancher实战案例 | kube-api-auth日志中出现大量错误信息怎么办?

为了让大家能够在实际应用场景中更顺利地使用 Rancher,我们推出 Rancher 实战案例系列。该系列的文章均为生产环境中遇到的实际问题,Rancher 研发团队将基于此问题的解决过程,写出问题排查思路。本文为该系列的第一篇,分享 Rancher kube-api-auth 组件的一个问题排查记录。

前言

业界应用最广泛的 Kubernetes 管理平台 Rancher 经过多年的发展,无论是在开源社区还是在商业体系中,都拥有了大量用户。但是,正如你所知,没有任何产品是十全十美的,在用户的业务落地实践中,我们的产品也存在一些缺陷。而在我们的技术团队的支持下,许多问题也得到了改善和解决。本文我们精选了实战问题处理案例,一是分享 Rancher 技术团队成熟的经验供大家参考,二是让更多用户参与进来共同探索切磋技艺,我们坚信寻找答案的路途永远没有终点。


本文,我们将分享 Rancher kube-api-auth 组件的一个问题排查记录。

排查记录

问题描述

某客户的托管集群在经历一些操作后(操作记录未能还原),在某托管集群的 system 项目中的 kube-api-auth Pod 中不断有错误日志输出,错误信息如下:



由于操作记录没有还原,我们未能找到精准的重现方式。而且客户的环境只能远程操作,排查问题也非常不方便。

基本原理

Rancher 是支持多集群管理的平台,用户可以通过 rancher-server API 访问到托管集群的 Kubernetes API。在访问过程中,需要 authentication 信息,authentication 方式由 Rancher 提供。但是,在实际使用中要考虑一些特殊场景:


  1. 如果 rancher-server 宕机无法访问,用户能够直接访问托管集群 api

  2. 考虑到地理远近访问,用户有时候希望不通过 rancher-server,而直接访问托管集群 api


解决以上问题,就是 kube-api-auth 存在的价值,Rancher 会在所有的创建 RKE 集群中部署 kube-api-auth。Kuerbnetes 的 authentication 有很多方式,Rancher 在对接自己用户体系时,采用的是 webhook-token 方式,参考:


https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication


官网中也对集群访问方式有详细描述:


https://rancher.com/docs/rancher/v2.x/en/cluster-admin/cluster-access/ace/


另外一张架构图也很好说明了这两种机制:一种是通过 Rancher server 和 agent 的 tunnel 访问托管集群的 API,authentication 在 Rancher server 已经实现;另一种是直接访问托管集群 API,这时 authentication 主要靠托管集群内的 kube-api-auth 实现。



我们通过 kubectl 来更具体了解 kube-api-auth 的作用。Rancher 本身由生成集群 kubeconfig 的功能,你登录一个用户,可以得到的 kubeconfig 大致如下:


apiVersion: v1kind: Configclusters:- name: "c1"  cluster:    server: "https://*****/k8s/clusters/c-cn2rq"    certificate-authority-data: "xxxx"- name: "c1-ip-172-31-24-41"  cluster:    server: "https://172.31.24.41:6443"    certificate-authority-data: "xxx"
users:- name: "c1" user: token: "kubeconfig-user-gc4s9.c-cn2rq:**********"
contexts:- name: "c1" context: user: "c1" cluster: "c1"- name: "c1-ip-172-31-24-41" context: user: "c1" cluster: "c1-ip-172-31-24-41"
current-context: "c1"
复制代码


我们可以看到几个关键信息:


  • User token 的格式,冒号分割的两部分,可以理解为 access key 和 secret

  • Context 包含两个,一个 rancher-server 入口,一个是托管集群 kube-api 入口;默认使用 rancher-server 入口


当我们用“c1”context 访问,使用 kubectl 随意获取一些资源,观察 kube-api-auth 的 logs,会发现没有任何输出。原因很简单,通过 rancher-server 入口访问,authentication 不走 webhook。它会在 rancher-server 中通过 tcp-proxy via websocket 方式访问托管集群 api,这种情况 authentication 没有走 webhook,直接内部证书授权方式。


当我们用“c1-ip-172-31-24-41” context 访问,观察 kube-api-auth 的 logs,会发现类似信息:


time="2020-02-18T05:30:53Z" level=info msg="Starting Rancher Kube-API-Auth service on 127.0.0.1:6440"time="2020-02-18T06:09:56Z" level=info msg="Processing v1Authenticate request..."time="2020-02-18T06:09:56Z" level=info msg="  ...looking up token for kubeconfig-user-gc4s9.c-cn2rq"time="2020-02-18T06:09:57Z" level=info msg="{\"apiVersion\":\"authentication.k8s.io/v1beta1\",\"kind\":\"TokenReview\",\"status\":{\"authenticated\":true,\"user\":{\"username\":\"user-gc4s9\"}}}"
复制代码


这种情况下,kube-api-auth 是起作用的,而且在 logs 我们也能看 user token 信息,它完全能和 kubeconfig 里面的对应上。user token 的校验信息实际上是存在托管集群的某个 CRD 里面,kube-api-auth 的逻辑就是从 reqeust 信息中获取 token,并和本地 CRD 数据对照:


# kubectl get clusterauthtokens -n cattle-systemNAME                            AGEkubeconfig-user-gc4s9.c-cn2rq   13d
# kubectl get clusterauthtokens kubeconfig-user-gc4s9.c-cn2rq -n cattle-system -o yamlapiVersion: cluster.cattle.io/v3enabled: truehash: $1:fad9a80a83333248:15:8:1:***********kind: ClusterAuthTokenmetadata: creationTimestamp: "2020-02-05T03:06:18Z" generation: 1 labels: cattle.io/creator: norman name: kubeconfig-user-gc4s9.c-cn2rq namespace: cattle-system resourceVersion: "1047" selfLink: /apis/cluster.cattle.io/v3/namespaces/cattle-system/clusterauthtokens/kubeconfig-user-gc4s9.c-cn2rq uid: 5ec4fc46-5030-45fb-b715-1117a5825b72userName: user-gc4s9
复制代码


这里我们需要注意 request user token 的格式,一定是冒号分割的两部分。一旦是非法格式,kube-api-auth 就会拒绝校验,并报出之前问题提到的 logs 信息:“found 1 parts of token”。

原因分析

根据上面分析的基本原理,我们可以知道触发 kube-api-auth 产生 error logs 有两个前提:


  • 通过 kube-api-auth 鉴权访问托管集群

  • 访问托管集群时 user-token 不合法


针对第一个前提,我们知道 Kubernetes 可以开启多种 authentication,在 RKE 中就支持了 X509 Client Certs/ServiceAccount/Webhook token 这些类型,多种 authentication 是可以并存的。Kubernetes 官方文档中有描述:


https://kubernetes.io/docs/reference/access-authn-authz/controlling-access/#authentication

Multiple authentication modules can be specified, in which case each one is tried in sequence, until one of them succeeds.


也就说对于某个 kube-api-client,如果 X509 Client Certs/ServiceAccount 的鉴权都失败,那么一定会走到 Webhook token。


X509 Client Certs 一般不会暴露用户使用,ServiceAccount 是常见的使用方式,ServiceAccount 的本质是会生成一个 secret(保存 JWT token),当 Pod 启动时,会放在固定目录下提供 kube-api-client 使用:


root@ip-172-31-24-41:~# ls -ahl /var/run/secrets/kubernetes.io/serviceaccounttotal 4.0Kdrwxrwxrwt 3 root root  140 Feb 18 09:49 .drwxr-xr-x 3 root root 4.0K Feb 18 09:49 ..drwxr-xr-x 2 root root  100 Feb 18 09:49 ..2020_02_18_09_49_08.912945351lrwxrwxrwx 1 root root   31 Feb 18 09:49 ..data -> ..2020_02_18_09_49_08.912945351lrwxrwxrwx 1 root root   13 Feb 18 09:49 ca.crt -> ..data/ca.crtlrwxrwxrwx 1 root root   16 Feb 18 09:49 namespace -> ..data/namespacelrwxrwxrwx 1 root root   12 Feb 18 09:49 token -> ..data/token
复制代码


假设一种场景,如果我们手动删除 ServiceAccount 对应的 secret,但不重建 Pod,这样导致 Pod 内的 secret 失效,然后观察 kube-api-auth 就可以看到大量 error log。这就是因为 secret 失效,导致 ServiceAccount 鉴权失败,进而 Kubernetes 尝试 Webhook token 鉴权,也就是通过 kube-api-auth。这时 kube-api-auth 获取 request token,而这个 token 是 kube-api-client 传过来失效的 secret JWT token,JWT token 和 webhook token 格式完全不同(没有冒号分割),就会看到“found 1 parts of token”。

解决方案

回到客户的问题本身,应该是某些造成了一些 serviceaccount 的 secret 被重建,比如:cattle serviceaccount,这个 serviceaccount 会用于运行 cluster-agent/node-agent/kube-auth-api 等组件。


这时,只要重建关键的 workload 就可以大概率解决。Rancher 托管的 workload 中,cluster-agent/node-agent/kube-auth-api 都关联了 cattle serviceaccount,重建这些 workload,让对应的 Pod 能够走默认的 serviceaccount 鉴权,就会减少报错概率。

总结

如前面所分析,Rancher 在 Kubernetes 中配置了多种鉴权模式,而 Kubernetes 在处理这些鉴权时,并没有严格固定的顺序。所以,只要 kube-auth-api 没有大批量日志错误是可以接受的,因为该请求后续可能被其他鉴权模式认证通过。反之,出现了大量 error log 则说明整个托管集群确实有问题,顺着本文思路排查,重建 cattle serviceaccount 大概率可以解决。另外,用户自己的 workload 如果依赖某个 serviceaccount,如果这个 serviceaccount 被重建,那么 workload 也会出现问题,这也是需要注意的。


2020-05-25 16:411361

评论

发布
暂无评论
发现更多内容

数据结构——顺序队列

若尘

数据结构 队列

2021金三银四Android大厂面试题来袭!附赠复习资料

欢喜学安卓

android 程序员 面试 移动开发

简单使用HTML集成OnlyOffice

一个需求

onlyoffice

Android性能优化之启动优化实战篇!分享面经

欢喜学安卓

android 程序员 面试 移动开发

Linux内核移植

学神来啦

云计算 Linux 运维 运维自动化

Flink 1.13,State Backend 优化及生产实践分享

Apache Flink

flink

店讯APP开发|店讯系统软件开发

已拿阿里P7+意向书!总结480页,超24W字2021最新一线大厂Java高级架构师面试题

Java架构追梦

Java 阿里巴巴 架构 面试

字节跳动异构场景下的高可用建设实践

Java

Flink 1.13,面向流批一体的运行时与 DataStream API 优化

Apache Flink

flink

GitHub上最火的7个spring cloud开源项目,对新手太友好了

北游学Java

Java 微服务 Spring Cloud 项目源码

JAVA九种排序算法详解(上)

加百利

Java 数组 排序 7月日更

党建百年•融云献礼,重磅发布党建全场景通信解决方案

融云 RongCloud

tms大时代APP开发|tms大时代软件系统开发

连夺十冠!百度CVPR 2021再突破,AI实力接受国际“检验”

百度大脑

人工智能

AI技术在银行内部反欺诈中应用的新思路

索信达控股

人工智能 大数据 金融科技 风控 反欺诈 人工智能模型

2021谈一下当下最合适的Android架构,附小技巧

欢喜学安卓

android 程序员 面试 移动开发

从零开始学习3D可视化之事件的常用方法

ThingJS数字孪生引擎

大前端 可视化 3D可视化 数字孪生 事件

maven私服搭建与插件开发

IT视界

maven nexus

Ubuntu 20.04安装/更新升级后进系统黑屏,屏幕亮度无法调节踩坑记

玏佾

ubuntu Ubuntu20.04 无法进入系统 驱动 屏幕亮度

腾讯云,拿什么获得电商行业信赖?

ToB行业头条

#腾讯云

Go学习笔记之Hello World

架构精进之路

语言 Go 语言 7月日更

难得一次技术面,Java程序员开发七年,突破自己终获小米offer

Java 程序员 架构 面试

watt挖矿软件开发|watt挖矿APP系统开发

乐视界APP开发|乐视界软件系统开发

Hi.com嗨币软件系统开发资料

新一代设计编排运维套件分享

鲸品堂

运维 价值

百度搜索稳定性问题分析的故事(上)

百度Geek说

Android性能优化总结,超详细

欢喜学安卓

android 程序员 面试 移动开发

字节跳动这份面试题,你能打几分

Java 面试

Qunar DNS体系建设

Qunar技术沙龙

DNS DNS服务器

Rancher实战案例 | kube-api-auth日志中出现大量错误信息怎么办?_文化 & 方法_Rancher_InfoQ精选文章