mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 02:03:20 -04:00 
			
		
		
		
	Deprecate multiple endpoints for out-of-cluster k8s api (#2454)
This fix deprecates endpoints for out-of-cluster k8s api, The Corefile still takes multiple endpoints though only the first one is used. A warning is shown if there are multiple endpoints. Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
		| @@ -32,7 +32,7 @@ all the zones the plugin should be authoritative for. | |||||||
| ``` | ``` | ||||||
| kubernetes [ZONES...] { | kubernetes [ZONES...] { | ||||||
|     resyncperiod DURATION |     resyncperiod DURATION | ||||||
|     endpoint URL [URL...] |     endpoint URL | ||||||
|     tls CERT KEY CACERT |     tls CERT KEY CACERT | ||||||
|     kubeconfig KUBECONFIG CONTEXT |     kubeconfig KUBECONFIG CONTEXT | ||||||
|     namespaces NAMESPACE... |     namespaces NAMESPACE... | ||||||
| @@ -51,10 +51,6 @@ kubernetes [ZONES...] { | |||||||
| * `resyncperiod` specifies the Kubernetes data API **DURATION** period. | * `resyncperiod` specifies the Kubernetes data API **DURATION** period. | ||||||
| * `endpoint` specifies the **URL** for a remote k8s API endpoint. | * `endpoint` specifies the **URL** for a remote k8s API endpoint. | ||||||
|    If omitted, it will connect to k8s in-cluster using the cluster service account. |    If omitted, it will connect to k8s in-cluster using the cluster service account. | ||||||
|    Multiple k8s API endpoints could be specified: |  | ||||||
|    `endpoint http://k8s-endpoint1:8080 http://k8s-endpoint2:8080`. |  | ||||||
|    CoreDNS will automatically perform a healthcheck and proxy to the healthy k8s API endpoint. |  | ||||||
|    Note that only http is supported when more than one k8s API endpoints are specified at the moment. |  | ||||||
| * `tls` **CERT** **KEY** **CACERT** are the TLS cert, key and the CA cert file names for remote k8s connection. | * `tls` **CERT** **KEY** **CACERT** are the TLS cert, key and the CA cert file names for remote k8s connection. | ||||||
|    This option is ignored if connecting in-cluster (i.e. endpoint is not specified). |    This option is ignored if connecting in-cluster (i.e. endpoint is not specified). | ||||||
| * `kubeconfig` **KUBECONFIG** **CONTEXT** authenticates the connection to a remote k8s cluster using a kubeconfig file. It supports TLS, username and password, or token-based authentication. This option is ignored if connecting in-cluster (i.e., the endpoint is not specified). | * `kubeconfig` **KUBECONFIG** **CONTEXT** authenticates the connection to a remote k8s cluster using a kubeconfig file. It supports TLS, username and password, or token-based authentication. This option is ignored if connecting in-cluster (i.e., the endpoint is not specified). | ||||||
|   | |||||||
| @@ -6,15 +6,12 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net" | 	"net" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"sync/atomic" |  | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"github.com/coredns/coredns/plugin" | 	"github.com/coredns/coredns/plugin" | ||||||
| 	"github.com/coredns/coredns/plugin/etcd/msg" | 	"github.com/coredns/coredns/plugin/etcd/msg" | ||||||
| 	"github.com/coredns/coredns/plugin/kubernetes/object" | 	"github.com/coredns/coredns/plugin/kubernetes/object" | ||||||
| 	"github.com/coredns/coredns/plugin/pkg/dnsutil" | 	"github.com/coredns/coredns/plugin/pkg/dnsutil" | ||||||
| 	"github.com/coredns/coredns/plugin/pkg/fall" | 	"github.com/coredns/coredns/plugin/pkg/fall" | ||||||
| 	"github.com/coredns/coredns/plugin/pkg/healthcheck" |  | ||||||
| 	"github.com/coredns/coredns/plugin/pkg/upstream" | 	"github.com/coredns/coredns/plugin/pkg/upstream" | ||||||
| 	"github.com/coredns/coredns/request" | 	"github.com/coredns/coredns/request" | ||||||
|  |  | ||||||
| @@ -174,50 +171,8 @@ func (k *Kubernetes) getClientConfig() (*rest.Config, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Connect to API from out of cluster | 	// Connect to API from out of cluster | ||||||
| 	endpoint := k.APIServerList[0] | 	// Only the first one is used. We will deprecated multiple endpoints later. | ||||||
| 	if len(k.APIServerList) > 1 { | 	clusterinfo.Server = k.APIServerList[0] | ||||||
| 		// Use a random port for api proxy, will get the value later through listener.Addr() |  | ||||||
| 		listener, err := net.Listen("tcp", "127.0.0.1:0") |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, fmt.Errorf("failed to create kubernetes api proxy: %v", err) |  | ||||||
| 		} |  | ||||||
| 		k.APIProxy = &apiProxy{ |  | ||||||
| 			listener: listener, |  | ||||||
| 			handler: proxyHandler{ |  | ||||||
| 				HealthCheck: healthcheck.HealthCheck{ |  | ||||||
| 					FailTimeout: 3 * time.Second, |  | ||||||
| 					MaxFails:    1, |  | ||||||
| 					Path:        "/", |  | ||||||
| 					Interval:    5 * time.Second, |  | ||||||
| 				}, |  | ||||||
| 			}, |  | ||||||
| 		} |  | ||||||
| 		k.APIProxy.handler.Hosts = make([]*healthcheck.UpstreamHost, len(k.APIServerList)) |  | ||||||
| 		for i, entry := range k.APIServerList { |  | ||||||
|  |  | ||||||
| 			uh := &healthcheck.UpstreamHost{ |  | ||||||
| 				Name: strings.TrimPrefix(entry, "http://"), |  | ||||||
|  |  | ||||||
| 				CheckDown: func(upstream *proxyHandler) healthcheck.UpstreamHostDownFunc { |  | ||||||
| 					return func(uh *healthcheck.UpstreamHost) bool { |  | ||||||
|  |  | ||||||
| 						fails := atomic.LoadInt32(&uh.Fails) |  | ||||||
| 						if fails >= upstream.MaxFails && upstream.MaxFails != 0 { |  | ||||||
| 							return true |  | ||||||
| 						} |  | ||||||
| 						return false |  | ||||||
| 					} |  | ||||||
| 				}(&k.APIProxy.handler), |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			k.APIProxy.handler.Hosts[i] = uh |  | ||||||
| 		} |  | ||||||
| 		k.APIProxy.Handler = &k.APIProxy.handler |  | ||||||
|  |  | ||||||
| 		// Find the random port used for api proxy |  | ||||||
| 		endpoint = fmt.Sprintf("http://%s", listener.Addr()) |  | ||||||
| 	} |  | ||||||
| 	clusterinfo.Server = endpoint |  | ||||||
|  |  | ||||||
| 	if len(k.APICertAuth) > 0 { | 	if len(k.APICertAuth) > 0 { | ||||||
| 		clusterinfo.CertificateAuthority = k.APICertAuth | 		clusterinfo.CertificateAuthority = k.APICertAuth | ||||||
|   | |||||||
| @@ -195,15 +195,11 @@ func ParseStanza(c *caddy.Controller) (*Kubernetes, error) { | |||||||
| 		case "endpoint": | 		case "endpoint": | ||||||
| 			args := c.RemainingArgs() | 			args := c.RemainingArgs() | ||||||
| 			if len(args) > 0 { | 			if len(args) > 0 { | ||||||
|  | 				// Multiple endoints are deprecated but still could be specified, | ||||||
|  | 				// only the first one be used, though | ||||||
| 				k8s.APIServerList = args | 				k8s.APIServerList = args | ||||||
| 				if len(args) > 1 { | 				if len(args) > 1 { | ||||||
| 					// If multiple endoints specified, then only http allowed | 					log.Warningf("Multiple endpoints have been deprecated, only the first specified endpoint '%s' is used", args[0]) | ||||||
| 					for i := range args { |  | ||||||
| 						parts := strings.SplitN(args[i], "://", 2) |  | ||||||
| 						if len(parts) == 2 && parts[0] != "http" { |  | ||||||
| 							return nil, fmt.Errorf("multiple endpoints can only accept http, found: %v", args[i]) |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -394,19 +394,6 @@ kubernetes cluster.local`, | |||||||
| 			podModeDisabled, | 			podModeDisabled, | ||||||
| 			fall.Zero, | 			fall.Zero, | ||||||
| 		}, | 		}, | ||||||
| 		{ |  | ||||||
| 			`kubernetes coredns.local { |  | ||||||
|     endpoint http://localhost:9090 https://localhost:9091 |  | ||||||
| }`, |  | ||||||
| 			true, |  | ||||||
| 			"multiple endpoints can only accept http", |  | ||||||
| 			-1, |  | ||||||
| 			-1, |  | ||||||
| 			defaultResyncPeriod, |  | ||||||
| 			"", |  | ||||||
| 			podModeDisabled, |  | ||||||
| 			fall.Zero, |  | ||||||
| 		}, |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for i, test := range tests { | 	for i, test := range tests { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user