使用 HTTP/2,HTTP/2 为了提高网络性能,一个主机只建立一个连接,所有的请求都通过该连接进行
底层网络
k8s.io/client-go/rest/transport.go
func TransportFor(config *Config) (http.RoundTripper, error) {
cfg, err := config.TransportConfig()
if err != nil {
return nil, err
}
return transport.New(cfg)
}
k8s.io/client-go/transport/transport.go 构建transport
func New(config *Config) (http.RoundTripper, error) {
// Set transport level security
if config.Transport != nil && (config.HasCA() || config.HasCertAuth() || config.HasCertCallback() || config.TLS.Insecure) {
return nil, fmt.Errorf("using a custom transport with TLS certificate options or the insecure flag is not allowed")
}
var (
rt http.RoundTripper
err error
)
if config.Transport != nil {
rt = config.Transport
} else {
// 获取Transport
rt, err = tlsCache.get(config)
if err != nil {
return nil, err
}
}
return HTTPWrappersForConfig(config, rt)
}
k8s.io/client-go/transport/cache.go 构建transport
func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) {
key, err := tlsConfigKey(config)
if err != nil {
return nil, err
}
// Ensure we only create a single transport for the given TLS options
c.mu.Lock()
defer c.mu.Unlock()
// See if we already have a custom transport for this config
if t, ok := c.transports[key]; ok {
return t, nil
}
// Get the TLS options for this client config
tlsConfig, err := TLSConfigFor(config)
if err != nil {
return nil, err
}
// The options didn't require a custom TLS config
if tlsConfig == nil && config.Dial == nil {
return http.DefaultTransport, nil
}
dial := config.Dial
if dial == nil {
dial = (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext
}
// Cache a single transport for these options
c.transports[key] = utilnet.SetTransportDefaults(&http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: tlsConfig,
MaxIdleConnsPerHost: idleConnsPerHost,
DialContext: dial,
})
return c.transports[key], nil
}
k8s.io/apimachinery/pkg/util/net/http.go
// SetTransportDefaults applies the defaults from http.DefaultTransport
// for the Proxy, Dial, and TLSHandshakeTimeout fields if unset
func SetTransportDefaults(t *http.Transport) *http.Transport {
t = SetOldTransportDefaults(t)
// Allow clients to disable http2 if needed.
if s := os.Getenv("DISABLE_HTTP2"); len(s) > 0 {
klog.Infof("HTTP2 has been explicitly disabled")
} else if allowsHTTP2(t) {
if err := http2.ConfigureTransport(t); err != nil {
klog.Warningf("Transport failed http2 configuration: %v", err)
}
}
return t
}
TLSClientConfig.NextProtos默认是nil,allowsHTTP2返回true
func allowsHTTP2(t *http.Transport) bool {
if t.TLSClientConfig == nil || len(t.TLSClientConfig.NextProtos) == 0 {
// the transport expressed no NextProto preference, allow
return true
}
for _, p := range t.TLSClientConfig.NextProtos {
if p == http2.NextProtoTLS {
// the transport explicitly allowed http/2
return true
}
}
// the transport explicitly set NextProtos and excluded http/2
return false
}