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

开发者社区> 人民邮电出版社> 正文

带你读《云原生应用开发 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包是通过自定义 Transport对 http.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.RoundTripper对 http.RoundTripper接口的实现,Transport中还包括 authProxyRoundTripper、debuggingRoundTripper等其他类型,具体可在/client-go/transport/round_trippers.go文件中查看。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Spring Cloud Alibaba系列(六)sentinel的实际应用
上一章中我们通过Dashboard来为Sentinel客户端设置各种各样的规则,但是这些规则默认是存放在内存中,极不稳定,无法用于生成环境,所以需要将其持久化。
610 0
怎么设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程
6319 0
KubeMeet 杭州站报名:「云原生应用管理」开发者专场来啦!
4月17日杭州,云原生基金会CNCF和阿里巴巴联合主办的「KubeMeet 开发者沙龙·云原生应用管理专场」来啦!这里有Kubernetes 生态开发者都在关注的开源项目,以及阿里巴巴、携程、第四范式的一线云原生落地实践。赶紧报名吧!
777 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
7574 0
AliOS Things 3.0应用笔记:http client简单应用
AliOS Things 3.0版本新增加了httpc组件(http 客户端组件),httpc组件支持多种RESTful的API调用,包括GET、POST、PUT、HEAD等,也支持https安全协议。
11515 0
iOS 新特性分列式 之 iOS 8.x - 主要内容:应用扩展、手动对焦、Size Class
iOS 新特性分列式 之 iOS 8.x - 主要内容:应用扩展、手动对焦、Size Class 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循“署名-非商业用途-保持一致”创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。
973 0
2017年8月开发语言TOP10,JAVA老三。
上图是国外一家专业杂志IEEE Spectrum给出的专业的语言流行度的趋势报告。 Python已经爬到第一,比去年第4名上升了三个档次。C#重新进入了前五,去年是R语言。
832 0
Elasticsearch Top5典型应用场景
题记 刚接触Elasticsearch的朋友,或多或少会遇到一个问题,Elasticsearch在实际公司应用中除了搜索到底能做什么? 本文给出了答案。 除了“You Know, for Search”,Elasticsearch的使用会不断增长和变化。ObjectRocket作为一家托管云计算公司,已经在ObjectRocket平台上提供托管Elasticsearch一段时间了,并且能够看到我们客户之间的一些明确趋势以及他们如何使用该产品。以下是我们在平台上看到的Top5场景用例:
7 0
472
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载