带你读《云原生应用开发 Operator原理与实践》第二章 Operator 原理2.2Client-go 原理(十四)

简介: 带你读《云原生应用开发 Operator原理与实践》第二章 Operator 原理2.2Client-go 原理

2.2.7         Transport说明

本节简要介绍 Client-go源码中 Transport包的实现和底层原理。

 

1. Transport功能说明

 

Transport提 供 认 证 授 权 安 全 的 传 输 控 制 协 议(TCP,TransmissionControlProtocol)连接,基于 SPDY协议支持 HTTP(Stream)传输机制。Transport包是通过自定义 Transporthttp.Client的定制化封装实现的,在 Client-go源码中作为工具包RESTClient封装 HTTP 客户端请求。在实际开发过程中,一般只需要调用 Client-go中提供的 RESTClient、DiscoveryClient、ClientSet、DynamicClient即可。

 

2. Transport的内部实现

 

Transport包主要是对 http.RoundTripper 的封装实现,为了更好地理解本节内容,首先介绍 http.RoundTripper的概念和实现,然后介绍 Transport是怎样封装http.RoundTripper的。最后简要介绍Client-go包中底层的 RESTClient是如何使用 Transport的。

(1)      http.RoundTripper

http.RoundTripper能够执行单个 HTTP事务,获取给定请求的响应。实现http.RoundTripper接口的代码通常需要在多个   Goroutine   中并发执行,因此,必须确保实现代码的线程安全性。

http.RoundTripper是在 Go语言 HTTP包中定义的接口,接口定义见代码清单 2-49

typeRoundTripperinterface{RoundTrip(*Request)(*Response,error)

}

 

从上述代码中可以看出,http.RoundTripper接口很简单,只定义了一个名为 RoundTrip的方法。RoundTrip() 方法用于执行一个独立的 HTTP事务,接收传入的 *Request 请求值作为参数并返回对应的 *Response响应值,以及一个 error值。任何实现了 RoundTrip() 法的类型都实现了http.RoundTripper接口。

代码清单 2-50简单展示了 http.RoundTripper接口的实现。

typetestTransportstruct{agentstring

originalTransporthttp.RoundTripper

}

 

func(c*testTransport)RoundTrip(r*http.Request)(*http.Response,error){iflen(r.Header.Get("User-Agent"))!=0{

returnc.originalTransport.RoundTrip(r)

}

r=utilnet.CloneRequest(r)r.Header.Set("User-Agent",c.agent)

resp,err:=c.originalTransport.RoundTrip(r)


 

iferr!=nil{

returnnil,err

}

returnresp,nil


}

上述代码定义了一个 testTransport结构体类型,通过实现该类型的RoundTrip法实现了该类型的 http.RoundTripper接口。该接口的功能是在 HTTP的请求头中添User-Agent参数。通过以上 http.RoundTripper接口的简单实现,我们了解了 http.RoundTripper接口是如何封装 HTTP请求的。Transport包中以同样的方式实现了多种封装类型。下面具体介绍 Transport包中 http.RoundTripper的封装。

(2)      Transport包中对 http.RoundTripper的封装

Transport包中定义了 New函数,该函数通过传入的 Config参数创建 http.Round-Tripper,具体见代码清单 2-51。

funcNew(config*Config)(http.RoundTripper,error){

//设置Transport的安全级别

ifconfig.Transport!=nil&&(config.HasCA()||config.HasCertAuth()||config.HasCertCallback()||config.TLS.Insecure){

returnnil,fmt.Errorf("usingacustomtransportwithTLScertificateoptionsortheinsecureflagisnotallowed")

}

 

var(

rthttp.RoundTrippererrerror

)

 

ifconfig.Transport!=nil{rt=config.Transport

}else{

rt,err=tlsCache.get(config)

iferr!=nil{returnnil,err

}

}

 

returnHTTPWrappersForConfig(config,rt)


}

 

New函数中,首先通过 config 对象的方法获取认证信息,如果认证信息是非安全设置的,则返回 nil;如果配置中满足安全设置,则 New函数会读取配置中的 Transport息;如果 Transport为空,New 函数就从缓存中读取缓存的 Transport,如果缓存中没有Transport,那么需要初始化一个默认的 Transport。最后调用 HTTPWrappersForConfig函数,该函数将Config作为参数对 Transport进行进一步的封装。

HTTPWrappersForConfig函数见代码清单 2-52。

funcHTTPWrappersForConfig(config*Config,rthttp.RoundTripper)(http.RoundTripper,

error){

ifconfig.WrapTransport!=nil{rt=config.WrapTransport(rt)

}

 

rt=DebugWrappers(rt)

 

//Setauthenticationwrappersswitch{

caseconfig.HasBasicAuth()&&config.HasTokenAuth():

returnnil,fmt.Errorf("username/passwordorbearertokenmaybeset,butnot

both")

caseconfig.HasTokenAuth():

varerrerror

rt,err=NewBearerAuthWithRefreshRoundTripper(config.BearerToken,config.

BearerTokenFile,rt)

iferr!=nil{returnnil,err

}

caseconfig.HasBasicAuth():

rt=NewBasicAuthRoundTripper(config.Username,config.Password,rt)

}

iflen(config.UserAgent)>0{

rt=NewUserAgentRoundTripper(config.UserAgent,rt)

}

iflen(config.Impersonate.UserName)>0||len(config.Impersonate.Groups)>0||len(config.Impersonate.Extra)>0{

rt=NewImpersonatingRoundTripper(config.Impersonate,rt)

}

returnrt,nil

}


 

HTTPWrappersForConfig函数可以根据不同配置的认证信息创建不同的 http.Round‐Tripper。由以上代码可知该函数共创建了4种不同类型的 http.RoundTripper。

NewBearerAuthWithRefreshRoundTripper创建了 BearerAuthWithRefres-hRoundTripper类型对象, 实现了 http.RoundTripper接口, 并将提供的Bearer牌添加到请求中,如果 tokenFile是非空的,则定期读取 tokenFile,最后一次成功读取的内容作为 Bearer令牌;如果 tokenFile是非空的,而 Bearer是空的,tokenFile会被立即读取,以填充初始的 Bearer 令牌。

NewBasicAuthRoundTripper创建了 basicAuthRoundTripper类型对象,它将基auth 授权应用到请求中,通过用户名和密码授权实现 http.RoundTripper接口。

NewUserAgentRoundTripper创建了userAgentRoundTripper类型对象,它向请求添加 User-Agent请求头,实现了 http.RoundTripper接口。

NewImpersonatingRoundTripper创建了 ImpersonatingRoundTripper类型对象,向请求添加一个 Act-As请求头,实现了 http.RoundTripper接口。

以上4种不同类型的http.RoundTripper实现方式与2.2.6 节的案例实现是同一种方式,这里不再赘述。除了以上4种不同类型的 http.RoundTripperhttp.RoundTripper接口的实现,Transport中还包括 authProxyRoundTripper、debuggingRoundTripper等其他类型,具体可在/client-go/transport/round_trippers.go文件中查看。

相关文章
|
2月前
|
运维 监控 Cloud Native
【云故事探索】NO.17:国诚投顾的云原生 Serverless 实践
国诚投顾携手阿里云,依托Serverless架构实现技术全面升级,构建高弹性、智能化技术底座,提升业务稳定性与运行效率。通过云原生API网关、微服务治理与智能监控,实现流量精细化管理与系统可观测性增强,打造安全、敏捷的智能投顾平台,助力行业数字化变革。
【云故事探索】NO.17:国诚投顾的云原生 Serverless 实践
|
4月前
|
Kubernetes Cloud Native 安全
云原生机密计算新范式 PeerPods技术方案在阿里云上的落地和实践
PeerPods 技术价值已在阿里云实际场景中深度落地。
|
4月前
|
Kubernetes Cloud Native 安全
云原生机密计算新范式 PeerPods 技术方案在阿里云上的落地和实践
PeerPods 技术价值已在阿里云实际场景中深度落地。
|
8天前
|
人工智能 Cloud Native 算法
拔俗云原生 AI 临床大数据平台:赋能医学科研的开发者实践
AI临床大数据科研平台依托阿里云、腾讯云,打通医疗数据孤岛,提供从数据治理到模型落地的全链路支持。通过联邦学习、弹性算力与安全合规技术,实现跨机构协作与高效训练,助力开发者提升科研效率,推动医学AI创新落地。(238字)
|
2月前
|
弹性计算 运维 Cloud Native
【云故事探索】NO.17:国诚投顾的云原生Serverless实践
简介: 通过与阿里云深度合作,国诚投顾完成了从传统 ECS 架构向云原生 Serverless 架构的全面转型。新的技术架构不仅解决了原有系统在稳定性、弹性、运维效率等方面的痛点,还在成本控制、API 治理、可观测性、DevOps 自动化等方面实现了全方位升级。
|
1月前
|
存储 弹性计算 Cloud Native
云原生数据库的演进与应用实践
随着企业业务扩展,传统数据库难以应对高并发与弹性需求。云原生数据库应运而生,具备计算存储分离、弹性伸缩、高可用等核心特性,广泛应用于电商、金融、物联网等场景。阿里云PolarDB、Lindorm等产品已形成完善生态,助力企业高效处理数据。未来,AI驱动、Serverless与多云兼容将推动其进一步发展。
114 8
|
2月前
|
运维 监控 Cloud Native
【云故事探索】NO.17:国诚投顾的云原生 Serverless 实践
通过与阿里云深度合作,国诚投顾完成了从传统 ECS 架构向云原生 Serverless 架构的全面转型。新的技术架构不仅解决了原有系统在稳定性、弹性、运维效率等方面的痛点,还在成本控制、API 治理、可观测性、DevOps 自动化等方面实现了全方位升级。
|
3月前
|
Cloud Native 中间件 调度
云原生信息提取系统:容器化流程与CI/CD集成实践
本文介绍如何通过工程化手段解决数据提取任务中的稳定性与部署难题。结合 Scrapy、Docker、代理中间件与 CI/CD 工具,构建可自动运行、持续迭代的云原生信息提取系统,实现结构化数据采集与标准化交付。
119 1
云原生信息提取系统:容器化流程与CI/CD集成实践
|
3月前
|
人工智能 安全 Java
Go与Java泛型原理简介
本文介绍了Go与Java泛型的实现原理。Go通过单态化为不同类型生成函数副本,提升运行效率;而Java则采用类型擦除,将泛型转为Object类型处理,保持兼容性但牺牲部分类型安全。两种机制各有优劣,适用于不同场景。
104 24
|
3月前
|
存储 人工智能 安全
深入理解 go sync.Map - 基本原理
本文介绍了 Go 语言中 `map` 在并发使用时的常见问题及其解决方案,重点对比了 `sync.Mutex`、`sync.RWMutex` 和 `sync.Map` 的性能差异及适用场景。文章指出,普通 `map` 不支持并发读写,容易引发错误;而 `sync.Map` 通过原子操作和优化设计,在某些场景下能显著提升性能。同时详细讲解了 `sync.Map` 的基本用法及其适合的应用环境,如读多写少或不同 goroutine 操作不同键的场景。
156 1

热门文章

最新文章