Kubernetes client-go Informer运行15分钟后出现未授权错误求助
解决方案
问题出在你直接将静态Token赋值给rest.Config.BearerToken,client-go无法自动刷新这个静态值。要实现Token自动刷新,需要用BearerTokenSource替代直接设置BearerToken,让client-go在需要时主动获取最新Token。
核心修改思路
- 实现一个自定义的
TokenSource,封装AWS IAM Authenticator的Token生成逻辑,支持按需刷新 - 将这个
TokenSource配置到rest.Config中,client-go会自动在Token过期前/请求失败时尝试获取新Token
修改后的代码示例
import ( "context" "fmt" "time" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic/dynamicinformer" "k8s.io/client-go/rest" "k8s.io/client-go/tools/cache" "sigs.k8s.io/aws-iam-authenticator/pkg/token" "github.com/aws/aws-sdk-go/aws" ) // 自定义TokenSource,封装AWS Token生成逻辑 type awsTokenSource struct { generator *token.Generator opts *token.GetTokenOptions } func (s *awsTokenSource) Token() (*corev1.Secret, error) { tok, err := s.generator.GetWithOptions(s.opts) if err != nil { return nil, err } return &corev1.Secret{ Data: map[string][]byte{ corev1.ServiceAccountTokenKey: []byte(tok.Token), }, }, nil } func main() { // 省略awsSession、cluster、ca等初始化代码... ctx := context.Background() gen, err := token.NewGenerator(false, false) if err != nil { panic(err) } opts := &token.GetTokenOptions{ Region: cluster.Region, ClusterID: aws.StringValue(&cluster.Name), AssumeRoleARN: cluster.AssumeRoleConfig.RoleArn, AssumeRoleExternalID: cluster.AssumeRoleConfig.ExternalId, SessionName: "testsession", Session: awsSession, } // 初始化自定义TokenSource tokenSource := &awsTokenSource{ generator: gen, opts: opts, } clientConfig := &rest.Config{ Host: cluster.Endpoint, TLSClientConfig: rest.TLSClientConfig{CAData: ca}, // 配置BearerTokenSource,替代静态BearerToken BearerTokenSource: tokenSource, } dynamicClient, err := dynamic.NewForConfig(clientConfig) if err != nil { panic(err) } factory := dynamicinformer.NewFilteredDynamicSharedInformerFactory(dynamicClient, 60*time.Minute, "", nil) // 修正原代码中Version字段的多余空格 gvr := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"} informer := factory.ForResource(gvr).Informer() informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { fmt.Println(obj) }, UpdateFunc: func(old, new interface{}) { fmt.Println(old) fmt.Println(new) }, }) factory.Start(ctx.Done()) // 等待缓存同步完成(可选但推荐) for _, ok := range factory.WaitForCacheSync(ctx.Done()) { if !ok { panic("informer cache sync failed") } } <-ctx.Done() }
关键说明
BearerTokenSource是client-go的扩展点,客户端发起请求时会自动调用其Token()方法获取最新Token,无需手动干预刷新逻辑- 原代码中
Version: "v1 "的多余空格会导致API路由匹配失败,已修正 - 若需要减少AWS API调用频率,可以在
awsTokenSource中加入缓存逻辑:记录Token的过期时间,下次获取时判断是否需要重新生成
额外注意事项
你当前客户端版本v0.25与服务端v1.22的版本差超过了Kubernetes官方支持的±1小版本偏差,可能引发未知兼容性问题,建议将客户端版本降级到v0.22或v0.23,保持版本兼容。
内容的提问来源于stack exchange,提问作者jeevanragula
相关产品推荐
相关产品推荐

