mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Merge pull request #35449 from MrHohn/kubedns-readysignal
Automatic merge from submit-queue kubedns: use initial resource listing as ready signal Fix #35140. Set up the ready signal after the first resource listing finished for both endpoints and services instead of listen on kubernetes service. @bprashanth @bowei @thockin **Release note**: ``` ```
This commit is contained in:
commit
8820922997
@ -23,6 +23,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@ -31,9 +32,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type KubeDNSConfig struct {
|
type KubeDNSConfig struct {
|
||||||
ClusterDomain string
|
ClusterDomain string
|
||||||
KubeConfigFile string
|
KubeConfigFile string
|
||||||
KubeMasterURL string
|
KubeMasterURL string
|
||||||
|
InitialSyncTimeout time.Duration
|
||||||
|
|
||||||
HealthzPort int
|
HealthzPort int
|
||||||
DNSBindAddress string
|
DNSBindAddress string
|
||||||
@ -47,10 +49,11 @@ type KubeDNSConfig struct {
|
|||||||
|
|
||||||
func NewKubeDNSConfig() *KubeDNSConfig {
|
func NewKubeDNSConfig() *KubeDNSConfig {
|
||||||
return &KubeDNSConfig{
|
return &KubeDNSConfig{
|
||||||
ClusterDomain: "cluster.local.",
|
ClusterDomain: "cluster.local.",
|
||||||
HealthzPort: 8081,
|
HealthzPort: 8081,
|
||||||
DNSBindAddress: "0.0.0.0",
|
DNSBindAddress: "0.0.0.0",
|
||||||
DNSPort: 53,
|
DNSPort: 53,
|
||||||
|
InitialSyncTimeout: 60 * time.Second,
|
||||||
|
|
||||||
Federations: make(map[string]string),
|
Federations: make(map[string]string),
|
||||||
|
|
||||||
@ -160,4 +163,6 @@ func (s *KubeDNSConfig) AddFlags(fs *pflag.FlagSet) {
|
|||||||
"config-map name. If empty, then the config-map will not used. Cannot be "+
|
"config-map name. If empty, then the config-map will not used. Cannot be "+
|
||||||
" used in conjunction with federations flag. config-map contains "+
|
" used in conjunction with federations flag. config-map contains "+
|
||||||
"dynamically adjustable configuration.")
|
"dynamically adjustable configuration.")
|
||||||
|
fs.DurationVar(&s.InitialSyncTimeout, "initial-sync-timeout", s.InitialSyncTimeout,
|
||||||
|
"Timeout for initial resource sync.")
|
||||||
}
|
}
|
||||||
|
@ -47,17 +47,11 @@ type KubeDNSServer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewKubeDNSServerDefault(config *options.KubeDNSConfig) *KubeDNSServer {
|
func NewKubeDNSServerDefault(config *options.KubeDNSConfig) *KubeDNSServer {
|
||||||
ks := KubeDNSServer{domain: config.ClusterDomain}
|
|
||||||
|
|
||||||
kubeClient, err := newKubeClient(config)
|
kubeClient, err := newKubeClient(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("Failed to create a kubernetes client: %v", err)
|
glog.Fatalf("Failed to create a kubernetes client: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ks.healthzPort = config.HealthzPort
|
|
||||||
ks.dnsBindAddress = config.DNSBindAddress
|
|
||||||
ks.dnsPort = config.DNSPort
|
|
||||||
|
|
||||||
var configSync dnsconfig.Sync
|
var configSync dnsconfig.Sync
|
||||||
if config.ConfigMap == "" {
|
if config.ConfigMap == "" {
|
||||||
glog.V(0).Infof("ConfigMap not configured, using values from command line flags")
|
glog.V(0).Infof("ConfigMap not configured, using values from command line flags")
|
||||||
@ -70,9 +64,13 @@ func NewKubeDNSServerDefault(config *options.KubeDNSConfig) *KubeDNSServer {
|
|||||||
kubeClient, config.ConfigMapNs, config.ConfigMap)
|
kubeClient, config.ConfigMapNs, config.ConfigMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
ks.kd = kdns.NewKubeDNS(kubeClient, config.ClusterDomain, configSync)
|
return &KubeDNSServer{
|
||||||
|
domain: config.ClusterDomain,
|
||||||
return &ks
|
healthzPort: config.HealthzPort,
|
||||||
|
dnsBindAddress: config.DNSBindAddress,
|
||||||
|
dnsPort: config.DNSPort,
|
||||||
|
kd: kdns.NewKubeDNS(kubeClient, config.ClusterDomain, config.InitialSyncTimeout, configSync),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: evaluate using pkg/client/clientcmd
|
// TODO: evaluate using pkg/client/clientcmd
|
||||||
|
@ -276,6 +276,7 @@ image-service-endpoint
|
|||||||
include-extended-apis
|
include-extended-apis
|
||||||
include-extended-apis
|
include-extended-apis
|
||||||
included-types-overrides
|
included-types-overrides
|
||||||
|
initial-sync-timeout
|
||||||
input-base
|
input-base
|
||||||
input-dirs
|
input-dirs
|
||||||
insecure-allow-any-token
|
insecure-allow-any-token
|
||||||
|
@ -24,9 +24,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
etcd "github.com/coreos/etcd/client"
|
|
||||||
"github.com/miekg/dns"
|
|
||||||
skymsg "github.com/skynetservices/skydns/msg"
|
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/api/v1/endpoints"
|
"k8s.io/kubernetes/pkg/api/v1/endpoints"
|
||||||
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
|
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
|
||||||
@ -40,7 +37,10 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/util/wait"
|
"k8s.io/kubernetes/pkg/util/wait"
|
||||||
"k8s.io/kubernetes/pkg/watch"
|
"k8s.io/kubernetes/pkg/watch"
|
||||||
|
|
||||||
|
etcd "github.com/coreos/etcd/client"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/miekg/dns"
|
||||||
|
skymsg "github.com/skynetservices/skydns/msg"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -117,9 +117,12 @@ type KubeDNS struct {
|
|||||||
configLock sync.RWMutex
|
configLock sync.RWMutex
|
||||||
// configSync manages synchronization of the config map
|
// configSync manages synchronization of the config map
|
||||||
configSync config.Sync
|
configSync config.Sync
|
||||||
|
|
||||||
|
// Initial timeout for endpoints and services to be synced from APIServer
|
||||||
|
initialSyncTimeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewKubeDNS(client clientset.Interface, clusterDomain string, configSync config.Sync) *KubeDNS {
|
func NewKubeDNS(client clientset.Interface, clusterDomain string, timeout time.Duration, configSync config.Sync) *KubeDNS {
|
||||||
kd := &KubeDNS{
|
kd := &KubeDNS{
|
||||||
kubeClient: client,
|
kubeClient: client,
|
||||||
domain: clusterDomain,
|
domain: clusterDomain,
|
||||||
@ -129,6 +132,7 @@ func NewKubeDNS(client clientset.Interface, clusterDomain string, configSync con
|
|||||||
reverseRecordMap: make(map[string]*skymsg.Service),
|
reverseRecordMap: make(map[string]*skymsg.Service),
|
||||||
clusterIPServiceMap: make(map[string]*v1.Service),
|
clusterIPServiceMap: make(map[string]*v1.Service),
|
||||||
domainPath: util.ReverseArray(strings.Split(strings.TrimRight(clusterDomain, "."), ".")),
|
domainPath: util.ReverseArray(strings.Split(strings.TrimRight(clusterDomain, "."), ".")),
|
||||||
|
initialSyncTimeout: timeout,
|
||||||
|
|
||||||
configLock: sync.RWMutex{},
|
configLock: sync.RWMutex{},
|
||||||
configSync: configSync,
|
configSync: configSync,
|
||||||
@ -149,38 +153,28 @@ func (kd *KubeDNS) Start() {
|
|||||||
|
|
||||||
kd.startConfigMapSync()
|
kd.startConfigMapSync()
|
||||||
|
|
||||||
// Wait synchronously for the Kubernetes service. This ensures that
|
// Wait synchronously for the initial list operations to be
|
||||||
// the Start function returns only after having received Service
|
// complete of endpoints and services from APIServer.
|
||||||
// objects from APIServer.
|
kd.waitForResourceSyncedOrDie()
|
||||||
//
|
|
||||||
// TODO: we might not have to wait for kubernetes service
|
|
||||||
// specifically. We should just wait for a list operation to be
|
|
||||||
// complete from APIServer.
|
|
||||||
kd.waitForKubernetesService()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kd *KubeDNS) waitForKubernetesService() {
|
func (kd *KubeDNS) waitForResourceSyncedOrDie() {
|
||||||
glog.V(2).Infof("Waiting for Kubernetes service")
|
// Wait for both controllers have completed an initial resource listing
|
||||||
|
timeout := time.After(kd.initialSyncTimeout)
|
||||||
const kubernetesSvcName = "kubernetes"
|
ticker := time.NewTicker(500 * time.Millisecond)
|
||||||
const servicePollInterval = 1 * time.Second
|
defer ticker.Stop()
|
||||||
|
|
||||||
name := fmt.Sprintf("%v/%v", v1.NamespaceDefault, kubernetesSvcName)
|
|
||||||
glog.V(2).Infof("Waiting for service: %v", name)
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
svc, err := kd.kubeClient.Core().Services(v1.NamespaceDefault).Get(kubernetesSvcName)
|
select {
|
||||||
if err != nil || svc == nil {
|
case <-timeout:
|
||||||
glog.V(3).Infof(
|
glog.Fatalf("Timeout waiting for initialization")
|
||||||
"Ignoring error while waiting for service %v: %v. Sleeping %v before retrying.",
|
case <-ticker.C:
|
||||||
name, err, servicePollInterval)
|
if kd.endpointsController.HasSynced() && kd.serviceController.HasSynced() {
|
||||||
time.Sleep(servicePollInterval)
|
glog.V(0).Infof("Initialized services and endpoints from apiserver")
|
||||||
continue
|
return
|
||||||
|
}
|
||||||
|
glog.V(0).Infof("DNS server not ready, retry in 500 milliseconds")
|
||||||
}
|
}
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kd *KubeDNS) startConfigMapSync() {
|
func (kd *KubeDNS) startConfigMapSync() {
|
||||||
|
Loading…
Reference in New Issue
Block a user