You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes client-go Informer运行15分钟后出现未授权错误求助

解决方案

问题出在你直接将静态Token赋值给rest.Config.BearerToken,client-go无法自动刷新这个静态值。要实现Token自动刷新,需要用BearerTokenSource替代直接设置BearerToken,让client-go在需要时主动获取最新Token。

核心修改思路

  1. 实现一个自定义的TokenSource,封装AWS IAM Authenticator的Token生成逻辑,支持按需刷新
  2. 将这个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 19:10:33