diff --git a/cilium/cmd/preflight_identity_crd_migrate.go b/cilium/cmd/preflight_identity_crd_migrate.go index 2a5ba787b263..e925e593279b 100644 --- a/cilium/cmd/preflight_identity_crd_migrate.go +++ b/cilium/cmd/preflight_identity_crd_migrate.go @@ -1,4 +1,4 @@ -// Copyright 2019 Authors of Cilium +// Copyright 2019-2020 Authors of Cilium // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package cmd import ( "context" "errors" + "os" "path" "time" @@ -199,6 +200,10 @@ func initK8s(ctx context.Context) (crdBackend allocator.Backend, crdAllocator *a log.WithError(err).Fatal("Unable to connect to Kubernetes apiserver") } + if err := k8s.GetNodeSpec(os.Getenv(k8s.EnvNodeNameSpec)); err != nil { + log.WithError(err).Fatal("Unable to connect to get node spec from apiserver") + } + // Update CRDs to ensure ciliumIdentity is present k8s.RegisterCRDs() diff --git a/daemon/cmd/daemon.go b/daemon/cmd/daemon.go index 56c28c289a8a..d032abd1150b 100644 --- a/daemon/cmd/daemon.go +++ b/daemon/cmd/daemon.go @@ -411,6 +411,10 @@ func NewDaemon(ctx context.Context, dp datapath.Datapath) (*Daemon, *endpointRes log.WithError(err).Fatal("Unable to register CRDs") } + if err := k8s.GetNodeSpec(os.Getenv(k8s.EnvNodeNameSpec)); err != nil { + log.WithError(err).Fatal("Unable to connect to get node spec from apiserver") + } + // Kubernetes demands that the localhost can always reach local // pods. Therefore unless the AllowLocalhost policy is set to a // specific mode, always allow localhost to reach local diff --git a/pkg/k8s/init.go b/pkg/k8s/init.go index f6547fc3406d..95586db44f0d 100644 --- a/pkg/k8s/init.go +++ b/pkg/k8s/init.go @@ -18,7 +18,6 @@ package k8s import ( "context" "fmt" - "os" "time" "github.com/cilium/cilium/pkg/backoff" @@ -162,52 +161,60 @@ func Init(conf k8sconfig.Configuration) error { k8sversion.Version(), k8sversion.MinimalVersionConstraint) } - if nodeName := os.Getenv(EnvNodeNameSpec); nodeName != "" { - // Use of the environment variable overwrites the node-name - // automatically derived - nodeTypes.SetName(nodeName) - - if n := waitForNodeInformation(context.TODO(), nodeName); n != nil { - nodeIP4 := n.GetNodeIP(false) - nodeIP6 := n.GetNodeIP(true) - - log.WithFields(logrus.Fields{ - logfields.NodeName: n.Name, - logfields.IPAddr + ".ipv4": nodeIP4, - logfields.IPAddr + ".ipv6": nodeIP6, - logfields.V4Prefix: n.IPv4AllocCIDR, - logfields.V6Prefix: n.IPv6AllocCIDR, - }).Info("Received own node information from API server") - - useNodeCIDR(n) - - // Note: Node IPs are derived regardless of - // option.Config.EnableIPv4 and - // option.Config.EnableIPv6. This is done to enable - // underlay addressing to be different from overlay - // addressing, e.g. an IPv6 only PodCIDR running over - // IPv4 encapsulation. - if nodeIP4 != nil { - node.SetExternalIPv4(nodeIP4) - } - - if nodeIP6 != nil { - node.SetIPv6(nodeIP6) - } - } else { - // if node resource could not be received, fail if - // PodCIDR requirement has been requested - if option.Config.K8sRequireIPv4PodCIDR || option.Config.K8sRequireIPv6PodCIDR { - log.Fatal("Unable to derive PodCIDR from Kubernetes node resource, giving up") - } + return nil +} + +// GetNodeSpec retrieves this node spec from kubernetes. This node information +// can either be derived from a CiliumNode or a Kubernetes node. +func GetNodeSpec(nodeName string) error { + if nodeName == "" { + if option.Config.K8sRequireIPv4PodCIDR || option.Config.K8sRequireIPv6PodCIDR { + return fmt.Errorf("node name must be specified via environment variable '%s' to retrieve Kubernetes PodCIDR range", EnvNodeNameSpec) } + return nil + } - // Annotate addresses will occur later since the user might - // want to specify them manually - } else if option.Config.K8sRequireIPv4PodCIDR || option.Config.K8sRequireIPv6PodCIDR { - return fmt.Errorf("node name must be specified via environment variable '%s' to retrieve Kubernetes PodCIDR range", EnvNodeNameSpec) + // Use of the environment variable overwrites the node-name + // automatically derived + nodeTypes.SetName(nodeName) + + if n := waitForNodeInformation(context.TODO(), nodeName); n != nil { + nodeIP4 := n.GetNodeIP(false) + nodeIP6 := n.GetNodeIP(true) + + log.WithFields(logrus.Fields{ + logfields.NodeName: n.Name, + logfields.IPAddr + ".ipv4": nodeIP4, + logfields.IPAddr + ".ipv6": nodeIP6, + logfields.V4Prefix: n.IPv4AllocCIDR, + logfields.V6Prefix: n.IPv6AllocCIDR, + }).Info("Received own node information from API server") + + useNodeCIDR(n) + + // Note: Node IPs are derived regardless of + // option.Config.EnableIPv4 and + // option.Config.EnableIPv6. This is done to enable + // underlay addressing to be different from overlay + // addressing, e.g. an IPv6 only PodCIDR running over + // IPv4 encapsulation. + if nodeIP4 != nil { + node.SetExternalIPv4(nodeIP4) + } + + if nodeIP6 != nil { + node.SetIPv6(nodeIP6) + } + } else { + // if node resource could not be received, fail if + // PodCIDR requirement has been requested + if option.Config.K8sRequireIPv4PodCIDR || option.Config.K8sRequireIPv6PodCIDR { + log.Fatal("Unable to derive PodCIDR from Kubernetes node resource, giving up") + } } + // Annotate addresses will occur later since the user might + // want to specify them manually return nil }