使用 HTTP/2,HTTP/2 为了提高网络性能,一个主机只建立一个连接,所有的请求都通过该连接进行

    底层网络
    k8s.io/client-go/rest/transport.go

    1. func TransportFor(config *Config) (http.RoundTripper, error) {
    2. cfg, err := config.TransportConfig()
    3. if err != nil {
    4. return nil, err
    5. }
    6. return transport.New(cfg)
    7. }

    k8s.io/client-go/transport/transport.go 构建transport

    1. func New(config *Config) (http.RoundTripper, error) {
    2. // Set transport level security
    3. if config.Transport != nil && (config.HasCA() || config.HasCertAuth() || config.HasCertCallback() || config.TLS.Insecure) {
    4. return nil, fmt.Errorf("using a custom transport with TLS certificate options or the insecure flag is not allowed")
    5. }
    6. var (
    7. rt http.RoundTripper
    8. err error
    9. )
    10. if config.Transport != nil {
    11. rt = config.Transport
    12. } else {
    13. // 获取Transport
    14. rt, err = tlsCache.get(config)
    15. if err != nil {
    16. return nil, err
    17. }
    18. }
    19. return HTTPWrappersForConfig(config, rt)
    20. }

    k8s.io/client-go/transport/cache.go 构建transport

    1. func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) {
    2. key, err := tlsConfigKey(config)
    3. if err != nil {
    4. return nil, err
    5. }
    6. // Ensure we only create a single transport for the given TLS options
    7. c.mu.Lock()
    8. defer c.mu.Unlock()
    9. // See if we already have a custom transport for this config
    10. if t, ok := c.transports[key]; ok {
    11. return t, nil
    12. }
    13. // Get the TLS options for this client config
    14. tlsConfig, err := TLSConfigFor(config)
    15. if err != nil {
    16. return nil, err
    17. }
    18. // The options didn't require a custom TLS config
    19. if tlsConfig == nil && config.Dial == nil {
    20. return http.DefaultTransport, nil
    21. }
    22. dial := config.Dial
    23. if dial == nil {
    24. dial = (&net.Dialer{
    25. Timeout: 30 * time.Second,
    26. KeepAlive: 30 * time.Second,
    27. }).DialContext
    28. }
    29. // Cache a single transport for these options
    30. c.transports[key] = utilnet.SetTransportDefaults(&http.Transport{
    31. Proxy: http.ProxyFromEnvironment,
    32. TLSHandshakeTimeout: 10 * time.Second,
    33. TLSClientConfig: tlsConfig,
    34. MaxIdleConnsPerHost: idleConnsPerHost,
    35. DialContext: dial,
    36. })
    37. return c.transports[key], nil
    38. }

    k8s.io/apimachinery/pkg/util/net/http.go

    1. // SetTransportDefaults applies the defaults from http.DefaultTransport
    2. // for the Proxy, Dial, and TLSHandshakeTimeout fields if unset
    3. func SetTransportDefaults(t *http.Transport) *http.Transport {
    4. t = SetOldTransportDefaults(t)
    5. // Allow clients to disable http2 if needed.
    6. if s := os.Getenv("DISABLE_HTTP2"); len(s) > 0 {
    7. klog.Infof("HTTP2 has been explicitly disabled")
    8. } else if allowsHTTP2(t) {
    9. if err := http2.ConfigureTransport(t); err != nil {
    10. klog.Warningf("Transport failed http2 configuration: %v", err)
    11. }
    12. }
    13. return t
    14. }

    TLSClientConfig.NextProtos默认是nil,allowsHTTP2返回true

    1. func allowsHTTP2(t *http.Transport) bool {
    2. if t.TLSClientConfig == nil || len(t.TLSClientConfig.NextProtos) == 0 {
    3. // the transport expressed no NextProto preference, allow
    4. return true
    5. }
    6. for _, p := range t.TLSClientConfig.NextProtos {
    7. if p == http2.NextProtoTLS {
    8. // the transport explicitly allowed http/2
    9. return true
    10. }
    11. }
    12. // the transport explicitly set NextProtos and excluded http/2
    13. return false
    14. }