写点什么

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:411118

评论

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

数字人民币 为经济添活力

CECBC

如何基于 Agora Android SDK 在应用中实现视频通话?

声网

人工智能 android 音视频

【网络安全】Agent内存马的自动分析与查杀

H

网络安全 WEB安全

MySQL是怎么保证redo log和binlog是完整的?

华为云开发者联盟

MySQL Binlog Redo Log WAL机制 日志逻辑序列号

全球首个开源车路协同数据集发布,促进学界业界跨界融合

百度开发者中心

产品更新 | 云原生综合运维平台SchedulX V 0.2.0 已发布,支持部署服务至云服务器

星汉未来

Python代码阅读(第76篇):摄氏温度与华氏温度互转

Felix

Python 编程 阅读代码 Python初学者

做中台,我从一名产品经理做成了合伙人

木木杨老师

中台 产品经理 产品设计 数字化 企业数智化

腾讯WeTest开通微信视频号啦

WeTest

频繁项集挖掘算法在告警关联中的应用

云智慧AIOps社区

算法 告警

燃气表场景物联解决方案

😌

IoT 燃气

如何高效交付专有云?百度智能云有妙招

百度开发者中心

面试官:linux零拷贝的原理是什么?

CRMEB

盖世无双之国产数据库风云榜-2022年02月

墨天轮

数据库 GaussDB TiDB 国产数据库

云防火墙:防御企业上云“亿”点网络攻击

青云技术社区

大力发展区块链技术,做好数字经济“新基建”

CECBC

回声嘹亮 之 Go 的 Echo 框架 —— 上手初体验

宇宙之一粟

Go web Go 语言 2月月更

解码北京冬奥沉浸式报道黑科技: 阿里云视频云「互动虚拟演播技术」

阿里云CloudImagine

阿里云 计算机视觉 音视频 视频云 冬奥会

用了区块链技术,破产清算办案更透明了!

CECBC

博文干货|Apache InLong 使用 Apache Pulsar 创建数据入库

Apache Pulsar

开源 架构 云原生 Apache Pulsar apache 社区

保证业务高效运营 专有云虚拟网络是关键

百度开发者中心

【Python】第三章(string)

謓泽

Python 2月月更

OpenHarmony移植:如何适配utils子系统之KV存储部件

华为云开发者联盟

LiteOS OpenHarmony utils KV存储部件

MySQL是怎么保证redo log和binlog是完整的?

华为云开发者联盟

MySQL Binlog Redo Log WAL机制 日志逻辑序列号

资本热衷的垂直SaaS,如何能大有作为?

ToB行业头条

Kaggle冠军解读:风电场短期风况预测任务方案

百度大脑

快上车!第十七届全国大学生智能汽车竞赛百度创意组来啦

百度大脑

唯一一家!腾讯云数据库入选“科创中国”先导技术榜

科技热闻

阿里卖家 Flutter for Web 工程实践

阿里巴巴终端技术

flutter Web 客户端开发 ffw

| 从DevOps到BizDevOps, 研发效能提升的系统方法

阿里云云效

云计算 阿里云 DevOps 云原生 研发

容器化 | 在 KubeSphere 中部署 MySQL 集群

RadonDB

MySQL 数据库 高可用 RadonDB KubeSphere

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