mirror of
https://github.com/coredns/coredns.git
synced 2025-10-28 08:44:17 -04:00
add args: startup_timeout for kubernetes plugin (#7068)
Signed-off-by: mangoyhuang <mangoyhuang@tencent.com> Co-authored-by: mangoyhuang <mangoyhuang@tencent.com>
This commit is contained in:
@@ -43,6 +43,7 @@ kubernetes [ZONES...] {
|
|||||||
fallthrough [ZONES...]
|
fallthrough [ZONES...]
|
||||||
ignore empty_service
|
ignore empty_service
|
||||||
multicluster [ZONES...]
|
multicluster [ZONES...]
|
||||||
|
startup_timeout DURATION
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -106,6 +107,8 @@ kubernetes [ZONES...] {
|
|||||||
Services API (MCS-API). Specifying this option is generally paired with the
|
Services API (MCS-API). Specifying this option is generally paired with the
|
||||||
installation of an MCS-API implementation and the ServiceImport and ServiceExport
|
installation of an MCS-API implementation and the ServiceImport and ServiceExport
|
||||||
CRDs. The plugin MUST be authoritative for the zones listed here.
|
CRDs. The plugin MUST be authoritative for the zones listed here.
|
||||||
|
* `startup_timeout` specifies the **DURATION** value that limits the time to wait for informer cache synced
|
||||||
|
when the kubernetes plugin starts. If not specified, the default timeout will be 5s.
|
||||||
|
|
||||||
Enabling zone transfer is done by using the *transfer* plugin.
|
Enabling zone transfer is done by using the *transfer* plugin.
|
||||||
|
|
||||||
@@ -115,7 +118,7 @@ When CoreDNS starts with the *kubernetes* plugin enabled, it will delay serving
|
|||||||
until it can connect to the Kubernetes API and synchronize all object watches. If this cannot happen within
|
until it can connect to the Kubernetes API and synchronize all object watches. If this cannot happen within
|
||||||
5 seconds, then CoreDNS will start serving DNS while the *kubernetes* plugin continues to try to connect
|
5 seconds, then CoreDNS will start serving DNS while the *kubernetes* plugin continues to try to connect
|
||||||
and synchronize all object watches. CoreDNS will answer SERVFAIL to any request made for a Kubernetes record
|
and synchronize all object watches. CoreDNS will answer SERVFAIL to any request made for a Kubernetes record
|
||||||
that has not yet been synchronized.
|
that has not yet been synchronized. You can also determine how long to wait by specifying `startup_timeout`.
|
||||||
|
|
||||||
## Monitoring Kubernetes Endpoints
|
## Monitoring Kubernetes Endpoints
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ type Kubernetes struct {
|
|||||||
primaryZoneIndex int
|
primaryZoneIndex int
|
||||||
localIPs []net.IP
|
localIPs []net.IP
|
||||||
autoPathSearch []string // Local search path from /etc/resolv.conf. Needed for autopath.
|
autoPathSearch []string // Local search path from /etc/resolv.conf. Needed for autopath.
|
||||||
|
startupTimeout time.Duration // startupTimeout set timeout of startup
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upstreamer is used to resolve CNAME or other external targets
|
// Upstreamer is used to resolve CNAME or other external targets
|
||||||
@@ -276,8 +277,7 @@ func (k *Kubernetes) InitKubeCache(ctx context.Context) (onStart func() error, o
|
|||||||
k.APIConn.Run()
|
k.APIConn.Run()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
timeout := 5 * time.Second
|
timeoutTicker := time.NewTicker(k.startupTimeout)
|
||||||
timeoutTicker := time.NewTicker(timeout)
|
|
||||||
defer timeoutTicker.Stop()
|
defer timeoutTicker.Stop()
|
||||||
logDelay := 500 * time.Millisecond
|
logDelay := 500 * time.Millisecond
|
||||||
logTicker := time.NewTicker(logDelay)
|
logTicker := time.NewTicker(logDelay)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/coredns/caddy"
|
"github.com/coredns/caddy"
|
||||||
"github.com/coredns/coredns/core/dnsserver"
|
"github.com/coredns/coredns/core/dnsserver"
|
||||||
@@ -112,6 +113,7 @@ func ParseStanza(c *caddy.Controller) (*Kubernetes, error) {
|
|||||||
|
|
||||||
k8s.Upstream = upstream.New()
|
k8s.Upstream = upstream.New()
|
||||||
|
|
||||||
|
k8s.startupTimeout = time.Second * 5
|
||||||
for c.NextBlock() {
|
for c.NextBlock() {
|
||||||
switch c.Val() {
|
switch c.Val() {
|
||||||
case "endpoint_pod_names":
|
case "endpoint_pod_names":
|
||||||
@@ -231,6 +233,17 @@ func ParseStanza(c *caddy.Controller) (*Kubernetes, error) {
|
|||||||
k8s.ClientConfig = config
|
k8s.ClientConfig = config
|
||||||
case "multicluster":
|
case "multicluster":
|
||||||
k8s.opts.multiclusterZones = plugin.OriginsFromArgsOrServerBlock(c.RemainingArgs(), []string{})
|
k8s.opts.multiclusterZones = plugin.OriginsFromArgsOrServerBlock(c.RemainingArgs(), []string{})
|
||||||
|
case "startup_timeout":
|
||||||
|
args := c.RemainingArgs()
|
||||||
|
if len(args) == 0 {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
k8s.startupTimeout, err = time.ParseDuration(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse startup_timeout: %v, %s", args[0], err)
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return nil, c.Errf("unknown property '%s'", c.Val())
|
return nil, c.Errf("unknown property '%s'", c.Val())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/coredns/caddy"
|
"github.com/coredns/caddy"
|
||||||
"github.com/coredns/coredns/plugin/pkg/fall"
|
"github.com/coredns/coredns/plugin/pkg/fall"
|
||||||
@@ -11,6 +12,8 @@ import (
|
|||||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var defaultStartupTimeout = time.Second * 5
|
||||||
|
|
||||||
func TestKubernetesParse(t *testing.T) {
|
func TestKubernetesParse(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
input string // Corefile data as string
|
input string // Corefile data as string
|
||||||
@@ -22,6 +25,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
expectedNamespaceLabelSelector string // expected namespace label selector value
|
expectedNamespaceLabelSelector string // expected namespace label selector value
|
||||||
expectedPodMode string
|
expectedPodMode string
|
||||||
expectedFallthrough fall.F
|
expectedFallthrough fall.F
|
||||||
|
expectedStartupTimeout time.Duration
|
||||||
}{
|
}{
|
||||||
// positive
|
// positive
|
||||||
{
|
{
|
||||||
@@ -34,6 +38,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local test.local`,
|
`kubernetes coredns.local test.local`,
|
||||||
@@ -45,6 +50,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -57,6 +63,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -70,6 +77,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -83,6 +91,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -96,6 +105,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -109,6 +119,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -122,6 +133,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -135,6 +147,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"istio-injection=enabled",
|
"istio-injection=enabled",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -149,6 +162,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"istio-injection=enabled",
|
"istio-injection=enabled",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local test.local {
|
`kubernetes coredns.local test.local {
|
||||||
@@ -165,6 +179,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Root,
|
fall.Root,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
// negative
|
// negative
|
||||||
{
|
{
|
||||||
@@ -179,6 +194,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -192,6 +208,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -205,6 +222,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -218,6 +236,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
// pods disabled
|
// pods disabled
|
||||||
{
|
{
|
||||||
@@ -232,6 +251,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
// pods insecure
|
// pods insecure
|
||||||
{
|
{
|
||||||
@@ -246,6 +266,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeInsecure,
|
podModeInsecure,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
// pods verified
|
// pods verified
|
||||||
{
|
{
|
||||||
@@ -260,6 +281,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeVerified,
|
podModeVerified,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
// pods invalid
|
// pods invalid
|
||||||
{
|
{
|
||||||
@@ -274,6 +296,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeVerified,
|
podModeVerified,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
// fallthrough with zones
|
// fallthrough with zones
|
||||||
{
|
{
|
||||||
@@ -288,6 +311,7 @@ func TestKubernetesParse(t *testing.T) {
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.F{Zones: []string{"ip6.arpa.", "inaddr.arpa.", "foo.com."}},
|
fall.F{Zones: []string{"ip6.arpa.", "inaddr.arpa.", "foo.com."}},
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
// More than one Kubernetes not allowed
|
// More than one Kubernetes not allowed
|
||||||
{
|
{
|
||||||
@@ -301,6 +325,7 @@ kubernetes cluster.local`,
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -314,6 +339,7 @@ kubernetes cluster.local`,
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -327,6 +353,7 @@ kubernetes cluster.local`,
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -340,6 +367,7 @@ kubernetes cluster.local`,
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`kubernetes coredns.local {
|
`kubernetes coredns.local {
|
||||||
@@ -353,6 +381,22 @@ kubernetes cluster.local`,
|
|||||||
"",
|
"",
|
||||||
podModeDisabled,
|
podModeDisabled,
|
||||||
fall.Zero,
|
fall.Zero,
|
||||||
|
defaultStartupTimeout,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`kubernetes coredns.local {
|
||||||
|
kubeconfig file context
|
||||||
|
startup_timeout 1s
|
||||||
|
}`,
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
podModeDisabled,
|
||||||
|
fall.Zero,
|
||||||
|
time.Second * 1,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,6 +458,11 @@ kubernetes cluster.local`,
|
|||||||
if !k8sController.Fall.Equal(test.expectedFallthrough) {
|
if !k8sController.Fall.Equal(test.expectedFallthrough) {
|
||||||
t.Errorf("Test %d: Expected kubernetes controller to be initialized with fallthrough '%v'. Instead found fallthrough '%v' for input '%s'", i, test.expectedFallthrough, k8sController.Fall, test.input)
|
t.Errorf("Test %d: Expected kubernetes controller to be initialized with fallthrough '%v'. Instead found fallthrough '%v' for input '%s'", i, test.expectedFallthrough, k8sController.Fall, test.input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// startupTimeout
|
||||||
|
if k8sController.startupTimeout.String() != test.expectedStartupTimeout.String() {
|
||||||
|
t.Errorf("Test %d: Expected kubernetes controller to be initialized with startupTimeout '%v'. Instead found startupTimeout '%v' for input '%s'", i, test.expectedStartupTimeout, k8sController.startupTimeout, test.input)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user