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:
parent
f655d404d4
commit
7bd6855155
4 changed files with 6 additions and 72 deletions
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue