Commit 45d2bc06 authored by wlan0's avatar wlan0 Committed by Sidhartha Mani

cloud initialize node in external cloud controller

parent 069a25f3
...@@ -211,7 +211,8 @@ func StartControllers(s *options.CloudControllerManagerServer, kubeconfig *restc ...@@ -211,7 +211,8 @@ func StartControllers(s *options.CloudControllerManagerServer, kubeconfig *restc
nodeController := nodecontroller.NewCloudNodeController( nodeController := nodecontroller.NewCloudNodeController(
sharedInformers.Core().V1().Nodes(), sharedInformers.Core().V1().Nodes(),
client("cloud-node-controller"), cloud, client("cloud-node-controller"), cloud,
s.NodeMonitorPeriod.Duration) s.NodeMonitorPeriod.Duration,
s.NodeStatusUpdateFrequency.Duration)
nodeController.Run() nodeController.Run()
time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))
......
...@@ -37,6 +37,9 @@ type CloudControllerManagerServer struct { ...@@ -37,6 +37,9 @@ type CloudControllerManagerServer struct {
Master string Master string
Kubeconfig string Kubeconfig string
// NodeStatusUpdateFrequency is the freuency at which the controller updates nodes' status
NodeStatusUpdateFrequency metav1.Duration
} }
// NewCloudControllerManagerServer creates a new ExternalCMServer with a default config. // NewCloudControllerManagerServer creates a new ExternalCMServer with a default config.
...@@ -56,6 +59,7 @@ func NewCloudControllerManagerServer() *CloudControllerManagerServer { ...@@ -56,6 +59,7 @@ func NewCloudControllerManagerServer() *CloudControllerManagerServer {
LeaderElection: leaderelection.DefaultLeaderElectionConfiguration(), LeaderElection: leaderelection.DefaultLeaderElectionConfiguration(),
ControllerStartInterval: metav1.Duration{Duration: 0 * time.Second}, ControllerStartInterval: metav1.Duration{Duration: 0 * time.Second},
}, },
NodeStatusUpdateFrequency: metav1.Duration{Duration: 5 * time.Minute},
} }
s.LeaderElection.LeaderElect = true s.LeaderElection.LeaderElect = true
return &s return &s
...@@ -70,6 +74,7 @@ func (s *CloudControllerManagerServer) AddFlags(fs *pflag.FlagSet) { ...@@ -70,6 +74,7 @@ func (s *CloudControllerManagerServer) AddFlags(fs *pflag.FlagSet) {
fs.DurationVar(&s.MinResyncPeriod.Duration, "min-resync-period", s.MinResyncPeriod.Duration, "The resync period in reflectors will be random between MinResyncPeriod and 2*MinResyncPeriod") fs.DurationVar(&s.MinResyncPeriod.Duration, "min-resync-period", s.MinResyncPeriod.Duration, "The resync period in reflectors will be random between MinResyncPeriod and 2*MinResyncPeriod")
fs.DurationVar(&s.NodeMonitorPeriod.Duration, "node-monitor-period", s.NodeMonitorPeriod.Duration, fs.DurationVar(&s.NodeMonitorPeriod.Duration, "node-monitor-period", s.NodeMonitorPeriod.Duration,
"The period for syncing NodeStatus in NodeController.") "The period for syncing NodeStatus in NodeController.")
fs.DurationVar(&s.NodeStatusUpdateFrequency.Duration, "node-status-update-frequency", s.NodeStatusUpdateFrequency.Duration, "Specifies how often the controller updates nodes' status.")
fs.StringVar(&s.ServiceAccountKeyFile, "service-account-private-key-file", s.ServiceAccountKeyFile, "Filename containing a PEM-encoded private RSA or ECDSA key used to sign service account tokens.") fs.StringVar(&s.ServiceAccountKeyFile, "service-account-private-key-file", s.ServiceAccountKeyFile, "Filename containing a PEM-encoded private RSA or ECDSA key used to sign service account tokens.")
fs.BoolVar(&s.UseServiceAccountCredentials, "use-service-account-credentials", s.UseServiceAccountCredentials, "If true, use individual service account credentials for each controller.") fs.BoolVar(&s.UseServiceAccountCredentials, "use-service-account-credentials", s.UseServiceAccountCredentials, "If true, use individual service account credentials for each controller.")
fs.DurationVar(&s.RouteReconciliationPeriod.Duration, "route-reconciliation-period", s.RouteReconciliationPeriod.Duration, "The period for reconciling routes created for Nodes by cloud provider.") fs.DurationVar(&s.RouteReconciliationPeriod.Duration, "route-reconciliation-period", s.RouteReconciliationPeriod.Duration, "The period for reconciling routes created for Nodes by cloud provider.")
......
...@@ -77,6 +77,10 @@ type KubeletFlags struct { ...@@ -77,6 +77,10 @@ type KubeletFlags struct {
// DockershimRootDirectory is the path to the dockershim root directory. Defaults to // DockershimRootDirectory is the path to the dockershim root directory. Defaults to
// /var/lib/dockershim if unset. Exposed for integration testing (e.g. in OpenShift). // /var/lib/dockershim if unset. Exposed for integration testing (e.g. in OpenShift).
DockershimRootDirectory string DockershimRootDirectory string
// This flag, if set, sets the unique id of the instance that an external provider (i.e. cloudprovider)
// can use to identify a specific node
ProviderID string
} }
// KubeletServer encapsulates all of the parameters necessary for starting up // KubeletServer encapsulates all of the parameters necessary for starting up
...@@ -136,6 +140,7 @@ func (f *KubeletFlags) AddFlags(fs *pflag.FlagSet) { ...@@ -136,6 +140,7 @@ func (f *KubeletFlags) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&f.NodeIP, "node-ip", f.NodeIP, "IP address of the node. If set, kubelet will use this IP address for the node") fs.StringVar(&f.NodeIP, "node-ip", f.NodeIP, "IP address of the node. If set, kubelet will use this IP address for the node")
fs.StringVar(&f.DockershimRootDirectory, "experimental-dockershim-root-directory", f.DockershimRootDirectory, "Path to the dockershim root directory.") fs.StringVar(&f.DockershimRootDirectory, "experimental-dockershim-root-directory", f.DockershimRootDirectory, "Path to the dockershim root directory.")
fs.StringVar(&f.ProviderID, "provider-id", f.ProviderID, "Unique identifier for identifying the node in a machine database, i.e cloudprovider")
fs.MarkHidden("experimental-dockershim-root-directory") fs.MarkHidden("experimental-dockershim-root-directory")
} }
......
...@@ -811,7 +811,7 @@ func RunKubelet(kubeFlags *options.KubeletFlags, kubeCfg *componentconfig.Kubele ...@@ -811,7 +811,7 @@ func RunKubelet(kubeFlags *options.KubeletFlags, kubeCfg *componentconfig.Kubele
if kubeDeps.OSInterface == nil { if kubeDeps.OSInterface == nil {
kubeDeps.OSInterface = kubecontainer.RealOS{} kubeDeps.OSInterface = kubecontainer.RealOS{}
} }
k, err := builder(kubeCfg, kubeDeps, standaloneMode, kubeFlags.HostnameOverride, kubeFlags.NodeIP, kubeFlags.DockershimRootDirectory) k, err := builder(kubeCfg, kubeDeps, standaloneMode, kubeFlags.HostnameOverride, kubeFlags.NodeIP, kubeFlags.DockershimRootDirectory, kubeFlags.ProviderID)
if err != nil { if err != nil {
return fmt.Errorf("failed to create kubelet: %v", err) return fmt.Errorf("failed to create kubelet: %v", err)
} }
...@@ -891,11 +891,11 @@ func startKubelet(k kubelet.KubeletBootstrap, podCfg *config.PodConfig, kubeCfg ...@@ -891,11 +891,11 @@ func startKubelet(k kubelet.KubeletBootstrap, podCfg *config.PodConfig, kubeCfg
} }
} }
func CreateAndInitKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *kubelet.KubeletDeps, standaloneMode bool, hostnameOverride, nodeIP, dockershimRootDir string) (k kubelet.KubeletBootstrap, err error) { func CreateAndInitKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *kubelet.KubeletDeps, standaloneMode bool, hostnameOverride, nodeIP, dockershimRootDir, providerID string) (k kubelet.KubeletBootstrap, err error) {
// TODO: block until all sources have delivered at least one update to the channel, or break the sync loop // TODO: block until all sources have delivered at least one update to the channel, or break the sync loop
// up into "per source" synchronizations // up into "per source" synchronizations
k, err = kubelet.NewMainKubelet(kubeCfg, kubeDeps, standaloneMode, hostnameOverride, nodeIP, dockershimRootDir) k, err = kubelet.NewMainKubelet(kubeCfg, kubeDeps, standaloneMode, hostnameOverride, nodeIP, dockershimRootDir, providerID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -545,6 +545,7 @@ private-mountns ...@@ -545,6 +545,7 @@ private-mountns
prom-push-gateway prom-push-gateway
protect-kernel-defaults protect-kernel-defaults
proto-import proto-import
provider-id
proxy-bindall proxy-bindall
proxy-client-cert-file proxy-client-cert-file
proxy-client-key-file proxy-client-key-file
......
...@@ -28,7 +28,7 @@ import ( ...@@ -28,7 +28,7 @@ import (
"k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider"
) )
const ProviderName = "fake" const defaultProviderName = "fake"
// FakeBalancer is a fake storage of balancer information // FakeBalancer is a fake storage of balancer information
type FakeBalancer struct { type FakeBalancer struct {
...@@ -61,6 +61,8 @@ type FakeCloud struct { ...@@ -61,6 +61,8 @@ type FakeCloud struct {
UpdateCalls []FakeUpdateBalancerCall UpdateCalls []FakeUpdateBalancerCall
RouteMap map[string]*FakeRoute RouteMap map[string]*FakeRoute
Lock sync.Mutex Lock sync.Mutex
Provider string
addCallLock sync.Mutex
cloudprovider.Zone cloudprovider.Zone
} }
...@@ -70,6 +72,8 @@ type FakeRoute struct { ...@@ -70,6 +72,8 @@ type FakeRoute struct {
} }
func (f *FakeCloud) addCall(desc string) { func (f *FakeCloud) addCall(desc string) {
f.addCallLock.Lock()
defer f.addCallLock.Unlock()
f.Calls = append(f.Calls, desc) f.Calls = append(f.Calls, desc)
} }
...@@ -92,7 +96,10 @@ func (f *FakeCloud) Clusters() (cloudprovider.Clusters, bool) { ...@@ -92,7 +96,10 @@ func (f *FakeCloud) Clusters() (cloudprovider.Clusters, bool) {
// ProviderName returns the cloud provider ID. // ProviderName returns the cloud provider ID.
func (f *FakeCloud) ProviderName() string { func (f *FakeCloud) ProviderName() string {
return ProviderName if f.Provider == "" {
return defaultProviderName
}
return f.Provider
} }
// ScrubDNS filters DNS settings for pods. // ScrubDNS filters DNS settings for pods.
......
...@@ -18,7 +18,9 @@ go_library( ...@@ -18,7 +18,9 @@ go_library(
"//pkg/api/v1/node:go_default_library", "//pkg/api/v1/node:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/informers/informers_generated/externalversions/core/v1:go_default_library", "//pkg/client/informers/informers_generated/externalversions/core/v1:go_default_library",
"//pkg/client/retry:go_default_library",
"//pkg/cloudprovider:go_default_library", "//pkg/cloudprovider:go_default_library",
"//pkg/util/node:go_default_library",
"//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
...@@ -26,6 +28,7 @@ go_library( ...@@ -26,6 +28,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library", "//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library", "//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/client-go/tools/record:go_default_library", "//vendor/k8s.io/client-go/tools/record:go_default_library",
], ],
) )
...@@ -46,6 +49,7 @@ go_test( ...@@ -46,6 +49,7 @@ go_test(
"//pkg/controller/node/testutil:go_default_library", "//pkg/controller/node/testutil:go_default_library",
"//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library", "//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
"//vendor/k8s.io/client-go/tools/record:go_default_library", "//vendor/k8s.io/client-go/tools/record:go_default_library",
......
...@@ -90,6 +90,11 @@ func (c *FakeNodeHandler) Core() v1core.CoreV1Interface { ...@@ -90,6 +90,11 @@ func (c *FakeNodeHandler) Core() v1core.CoreV1Interface {
return &FakeLegacyHandler{c.Clientset.Core(), c} return &FakeLegacyHandler{c.Clientset.Core(), c}
} }
// CoreV1 returns fake CoreV1Interface
func (c *FakeNodeHandler) CoreV1() v1core.CoreV1Interface {
return &FakeLegacyHandler{c.Clientset.CoreV1(), c}
}
// Nodes return fake NodeInterfaces. // Nodes return fake NodeInterfaces.
func (m *FakeLegacyHandler) Nodes() v1core.NodeInterface { func (m *FakeLegacyHandler) Nodes() v1core.NodeInterface {
return m.n return m.n
......
...@@ -186,7 +186,7 @@ type KubeletBootstrap interface { ...@@ -186,7 +186,7 @@ type KubeletBootstrap interface {
} }
// create and initialize a Kubelet instance // create and initialize a Kubelet instance
type KubeletBuilder func(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *KubeletDeps, standaloneMode bool, hostnameOverride, nodeIP, dockershimRootDir string) (KubeletBootstrap, error) type KubeletBuilder func(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *KubeletDeps, standaloneMode bool, hostnameOverride, nodeIP, dockershimRootDir, providerID string) (KubeletBootstrap, error)
// KubeletDeps is a bin for things we might consider "injected dependencies" -- objects constructed // KubeletDeps is a bin for things we might consider "injected dependencies" -- objects constructed
// at runtime that are necessary for running the Kubelet. This is a temporary solution for grouping // at runtime that are necessary for running the Kubelet. This is a temporary solution for grouping
...@@ -281,7 +281,7 @@ func getRuntimeAndImageServices(config *componentconfig.KubeletConfiguration) (i ...@@ -281,7 +281,7 @@ func getRuntimeAndImageServices(config *componentconfig.KubeletConfiguration) (i
// NewMainKubelet instantiates a new Kubelet object along with all the required internal modules. // NewMainKubelet instantiates a new Kubelet object along with all the required internal modules.
// No initialization of Kubelet and its modules should happen here. // No initialization of Kubelet and its modules should happen here.
func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *KubeletDeps, standaloneMode bool, hostnameOverride, nodeIP, dockershimRootDir string) (*Kubelet, error) { func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *KubeletDeps, standaloneMode bool, hostnameOverride, nodeIP, dockershimRootDir, providerID string) (*Kubelet, error) {
if kubeCfg.RootDirectory == "" { if kubeCfg.RootDirectory == "" {
return nil, fmt.Errorf("invalid root directory %q", kubeCfg.RootDirectory) return nil, fmt.Errorf("invalid root directory %q", kubeCfg.RootDirectory)
} }
...@@ -433,6 +433,8 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub ...@@ -433,6 +433,8 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub
diskSpaceManager: diskSpaceManager, diskSpaceManager: diskSpaceManager,
cloud: kubeDeps.Cloud, cloud: kubeDeps.Cloud,
autoDetectCloudProvider: (componentconfigv1alpha1.AutoDetectCloudProvider == kubeCfg.CloudProvider), autoDetectCloudProvider: (componentconfigv1alpha1.AutoDetectCloudProvider == kubeCfg.CloudProvider),
externalCloudProvider: cloudprovider.IsExternal(kubeCfg.CloudProvider),
providerID: providerID,
nodeRef: nodeRef, nodeRef: nodeRef,
nodeLabels: kubeCfg.NodeLabels, nodeLabels: kubeCfg.NodeLabels,
nodeStatusUpdateFrequency: kubeCfg.NodeStatusUpdateFrequency.Duration, nodeStatusUpdateFrequency: kubeCfg.NodeStatusUpdateFrequency.Duration,
...@@ -904,7 +906,8 @@ type Kubelet struct { ...@@ -904,7 +906,8 @@ type Kubelet struct {
// Cloud provider interface. // Cloud provider interface.
cloud cloudprovider.Interface cloud cloudprovider.Interface
autoDetectCloudProvider bool autoDetectCloudProvider bool
// Indicates that the node initialization happens in an external cloud controller
externalCloudProvider bool
// Reference to this node. // Reference to this node.
nodeRef *clientv1.ObjectReference nodeRef *clientv1.ObjectReference
...@@ -998,6 +1001,9 @@ type Kubelet struct { ...@@ -998,6 +1001,9 @@ type Kubelet struct {
// If non-nil, use this IP address for the node // If non-nil, use this IP address for the node
nodeIP net.IP nodeIP net.IP
// If non-nil, this is a unique identifier for the node in an external database, eg. cloudprovider
providerID string
// clock is an interface that provides time related functionality in a way that makes it // clock is an interface that provides time related functionality in a way that makes it
// easy to test the code. // easy to test the code.
clock clock.Clock clock clock.Clock
......
...@@ -202,6 +202,7 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) { ...@@ -202,6 +202,7 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) {
Unschedulable: !kl.registerSchedulable, Unschedulable: !kl.registerSchedulable,
}, },
} }
nodeTaints := make([]v1.Taint, 0)
if len(kl.kubeletConfiguration.RegisterWithTaints) > 0 { if len(kl.kubeletConfiguration.RegisterWithTaints) > 0 {
taints := make([]v1.Taint, len(kl.kubeletConfiguration.RegisterWithTaints)) taints := make([]v1.Taint, len(kl.kubeletConfiguration.RegisterWithTaints))
for i := range kl.kubeletConfiguration.RegisterWithTaints { for i := range kl.kubeletConfiguration.RegisterWithTaints {
...@@ -209,7 +210,19 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) { ...@@ -209,7 +210,19 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) {
return nil, err return nil, err
} }
} }
node.Spec.Taints = taints nodeTaints = append(nodeTaints, taints...)
}
if kl.externalCloudProvider {
taint := v1.Taint{
Key: metav1.TaintExternalCloudProvider,
Value: "true",
Effect: v1.TaintEffectNoSchedule,
}
nodeTaints = append(nodeTaints, taint)
}
if len(nodeTaints) > 0 {
node.Spec.Taints = nodeTaints
} }
// Initially, set NodeNetworkUnavailable to true. // Initially, set NodeNetworkUnavailable to true.
if kl.providerRequiresNetworkingConfiguration() { if kl.providerRequiresNetworkingConfiguration() {
...@@ -241,6 +254,10 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) { ...@@ -241,6 +254,10 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) {
node.ObjectMeta.Labels[k] = v node.ObjectMeta.Labels[k] = v
} }
if kl.providerID != "" {
node.Spec.ProviderID = kl.providerID
}
if kl.cloud != nil { if kl.cloud != nil {
instances, ok := kl.cloud.Instances() instances, ok := kl.cloud.Instances()
if !ok { if !ok {
...@@ -259,9 +276,11 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) { ...@@ -259,9 +276,11 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) {
// TODO: We can't assume that the node has credentials to talk to the // TODO: We can't assume that the node has credentials to talk to the
// cloudprovider from arbitrary nodes. At most, we should talk to a // cloudprovider from arbitrary nodes. At most, we should talk to a
// local metadata server here. // local metadata server here.
node.Spec.ProviderID, err = cloudprovider.GetInstanceProviderID(kl.cloud, kl.nodeName) if node.Spec.ProviderID == "" {
if err != nil { node.Spec.ProviderID, err = cloudprovider.GetInstanceProviderID(kl.cloud, kl.nodeName)
return nil, err if err != nil {
return nil, err
}
} }
instanceType, err := instances.InstanceType(kl.nodeName) instanceType, err := instances.InstanceType(kl.nodeName)
...@@ -443,6 +462,7 @@ func (kl *Kubelet) setNodeAddress(node *v1.Node) error { ...@@ -443,6 +462,7 @@ func (kl *Kubelet) setNodeAddress(node *v1.Node) error {
// 4) Try to get the IP from the network interface used as default gateway // 4) Try to get the IP from the network interface used as default gateway
if kl.nodeIP != nil { if kl.nodeIP != nil {
ipAddr = kl.nodeIP ipAddr = kl.nodeIP
node.ObjectMeta.Annotations[metav1.AnnotationProvidedIPAddr] = kl.nodeIP.String()
} else if addr := net.ParseIP(kl.hostname); addr != nil { } else if addr := net.ParseIP(kl.hostname); addr != nil {
ipAddr = addr ipAddr = addr
} else { } else {
......
...@@ -44,6 +44,7 @@ go_library( ...@@ -44,6 +44,7 @@ go_library(
"types.go", "types.go",
"types_swagger_doc_generated.go", "types_swagger_doc_generated.go",
"watch.go", "watch.go",
"well_known_annotations.go",
"well_known_labels.go", "well_known_labels.go",
"zz_generated.deepcopy.go", "zz_generated.deepcopy.go",
"zz_generated.defaults.go", "zz_generated.defaults.go",
......
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
const (
// When kubelet is started with the "external" cloud provider, then
// it sets this annotation on the node to denote an ip address set from the
// cmd line flag. This ip is verified with the cloudprovider as valid by
// the cloud-controller-manager
AnnotationProvidedIPAddr = "alpha.kubernetes.io/provided-node-ip"
)
...@@ -36,6 +36,12 @@ const ( ...@@ -36,6 +36,12 @@ const (
// when node becomes unreachable (corresponding to NodeReady status ConditionUnknown) // when node becomes unreachable (corresponding to NodeReady status ConditionUnknown)
// and removed when node becomes reachable (NodeReady status ConditionTrue). // and removed when node becomes reachable (NodeReady status ConditionTrue).
TaintNodeUnreachable = "node.alpha.kubernetes.io/unreachable" TaintNodeUnreachable = "node.alpha.kubernetes.io/unreachable"
// When kubelet is started with the "external" cloud provider, then
// it sets this taint on a node to mark it as unusable, until a controller
// from the cloud-controller-manager intitializes this node, and then removes
// the taint
TaintExternalCloudProvider = "node.cloudprovider.kubernetes.io/uninitialized"
) )
// Role labels are applied to Nodes to mark their purpose. In particular, we // Role labels are applied to Nodes to mark their purpose. In particular, we
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment