mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-30 21:30:16 +00:00 
			
		
		
		
	Covert the kubelet binary to hyperkube.
This leaves `pkg/kubelet/server/server.go` looking a little ugly as there is an extra layer of "config" structs that isn't needed. This is left as a TODO for now.
This commit is contained in:
		| @@ -23,6 +23,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/controllermanager" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/controllermanager" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/hyperkube" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/hyperkube" | ||||||
|  | 	kubelet "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/server" | ||||||
| 	apiserver "github.com/GoogleCloudPlatform/kubernetes/pkg/master/server" | 	apiserver "github.com/GoogleCloudPlatform/kubernetes/pkg/master/server" | ||||||
| 	sched "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/server" | 	sched "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/server" | ||||||
| ) | ) | ||||||
| @@ -36,6 +37,7 @@ func main() { | |||||||
| 	hk.AddServer(apiserver.NewHyperkubeServer()) | 	hk.AddServer(apiserver.NewHyperkubeServer()) | ||||||
| 	hk.AddServer(controllermanager.NewHyperkubeServer()) | 	hk.AddServer(controllermanager.NewHyperkubeServer()) | ||||||
| 	hk.AddServer(sched.NewHyperkubeServer()) | 	hk.AddServer(sched.NewHyperkubeServer()) | ||||||
|  | 	hk.AddServer(kubelet.NewHyperkubeServer()) | ||||||
|  |  | ||||||
| 	hk.RunToExit(os.Args) | 	hk.RunToExit(os.Args) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -21,145 +21,22 @@ limitations under the License. | |||||||
| package main | package main | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"math/rand" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/server" | ||||||
| 	"net" |  | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/cmd/kubelet/app" |  | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/api" |  | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider" |  | ||||||
| 	_ "github.com/GoogleCloudPlatform/kubernetes/pkg/healthz" |  | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet" |  | ||||||
| 	kubeletServer "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/server" |  | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports" |  | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/version/verflag" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/version/verflag" | ||||||
|  |  | ||||||
| 	"github.com/golang/glog" | 	"github.com/spf13/pflag" | ||||||
| 	flag "github.com/spf13/pflag" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const defaultRootDir = "/var/lib/kubelet" |  | ||||||
|  |  | ||||||
| var ( |  | ||||||
| 	config                  = flag.String("config", "", "Path to the config file or directory of files") |  | ||||||
| 	syncFrequency           = flag.Duration("sync_frequency", 10*time.Second, "Max period between synchronizing running containers and config") |  | ||||||
| 	fileCheckFrequency      = flag.Duration("file_check_frequency", 20*time.Second, "Duration between checking config files for new data") |  | ||||||
| 	httpCheckFrequency      = flag.Duration("http_check_frequency", 20*time.Second, "Duration between checking http for new data") |  | ||||||
| 	manifestURL             = flag.String("manifest_url", "", "URL for accessing the container manifest") |  | ||||||
| 	enableServer            = flag.Bool("enable_server", true, "Enable the info server") |  | ||||||
| 	address                 = util.IP(net.ParseIP("127.0.0.1")) |  | ||||||
| 	port                    = flag.Uint("port", ports.KubeletPort, "The port for the info server to serve on") |  | ||||||
| 	hostnameOverride        = flag.String("hostname_override", "", "If non-empty, will use this string as identification instead of the actual hostname.") |  | ||||||
| 	podInfraContainerImage  = flag.String("pod_infra_container_image", kubelet.PodInfraContainerImage, "The image whose network/ipc namespaces containers in each pod will use.") |  | ||||||
| 	dockerEndpoint          = flag.String("docker_endpoint", "", "If non-empty, use this for the docker endpoint to communicate with") |  | ||||||
| 	etcdServerList          util.StringList |  | ||||||
| 	etcdConfigFile          = flag.String("etcd_config", "", "The config file for the etcd client. Mutually exclusive with -etcd_servers") |  | ||||||
| 	rootDirectory           = flag.String("root_dir", defaultRootDir, "Directory path for managing kubelet files (volume mounts,etc).") |  | ||||||
| 	allowPrivileged         = flag.Bool("allow_privileged", false, "If true, allow containers to request privileged mode. [default=false]") |  | ||||||
| 	registryPullQPS         = flag.Float64("registry_qps", 0.0, "If > 0, limit registry pull QPS to this value.  If 0, unlimited. [default=0.0]") |  | ||||||
| 	registryBurst           = flag.Int("registry_burst", 10, "Maximum size of a bursty pulls, temporarily allows pulls to burst to this number, while still not exceeding registry_qps.  Only used if --registry_qps > 0") |  | ||||||
| 	runonce                 = flag.Bool("runonce", false, "If true, exit after spawning pods from local manifests or remote urls. Exclusive with --etcd_servers, --api_servers, and --enable-server") |  | ||||||
| 	enableDebuggingHandlers = flag.Bool("enable_debugging_handlers", true, "Enables server endpoints for log collection and local running of containers and commands") |  | ||||||
| 	minimumGCAge            = flag.Duration("minimum_container_ttl_duration", 1*time.Minute, "Minimum age for a finished container before it is garbage collected.  Examples: '300ms', '10s' or '2h45m'") |  | ||||||
| 	maxContainerCount       = flag.Int("maximum_dead_containers_per_container", 5, "Maximum number of old instances of a container to retain per container.  Each container takes up some disk space.  Default: 5.") |  | ||||||
| 	authPath                = flag.String("auth_path", "", "Path to .kubernetes_auth file, specifying how to authenticate to API server.") |  | ||||||
| 	cAdvisorPort            = flag.Uint("cadvisor_port", 4194, "The port of the localhost cAdvisor endpoint") |  | ||||||
| 	oomScoreAdj             = flag.Int("oom_score_adj", -900, "The oom_score_adj value for kubelet process. Values must be within the range [-1000, 1000]") |  | ||||||
| 	apiServerList           util.StringList |  | ||||||
| 	clusterDomain           = flag.String("cluster_domain", "", "Domain for this cluster.  If set, kubelet will configure all containers to search this domain in addition to the host's search domains") |  | ||||||
| 	masterServiceNamespace  = flag.String("master_service_namespace", api.NamespaceDefault, "The namespace from which the kubernetes master services should be injected into pods") |  | ||||||
| 	clusterDNS              = util.IP(nil) |  | ||||||
| 	reallyCrashForTesting   = flag.Bool("really_crash_for_testing", false, "If true, crash with panics more often.") |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func init() { |  | ||||||
| 	flag.Var(&etcdServerList, "etcd_servers", "List of etcd servers to watch (http://ip:port), comma separated. Mutually exclusive with -etcd_config") |  | ||||||
| 	flag.Var(&address, "address", "The IP address for the info server to serve on (set to 0.0.0.0 for all interfaces)") |  | ||||||
| 	flag.Var(&apiServerList, "api_servers", "List of Kubernetes API servers for publishing events, and reading pods and services. (ip:port), comma separated.") |  | ||||||
| 	flag.Var(&clusterDNS, "cluster_dns", "IP address for a cluster DNS server.  If set, kubelet will configure all containers to use this for DNS resolution in addition to the host's DNS servers") |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func setupRunOnce() { |  | ||||||
| 	if *runonce { |  | ||||||
| 		// Don't use remote (etcd or apiserver) sources |  | ||||||
| 		if len(etcdServerList) > 0 { |  | ||||||
| 			glog.Fatalf("invalid option: --runonce and --etcd_servers are mutually exclusive") |  | ||||||
| 		} |  | ||||||
| 		if len(apiServerList) > 0 { |  | ||||||
| 			glog.Fatalf("invalid option: --runonce and --api_servers are mutually exclusive") |  | ||||||
| 		} |  | ||||||
| 		if *enableServer { |  | ||||||
| 			glog.Infof("--runonce is set, disabling server") |  | ||||||
| 			*enableServer = false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func main() { | func main() { | ||||||
|  | 	s := server.NewKubeletServer() | ||||||
|  | 	s.AddFlags(pflag.CommandLine) | ||||||
|  |  | ||||||
| 	util.InitFlags() | 	util.InitFlags() | ||||||
| 	util.InitLogs() | 	util.InitLogs() | ||||||
| 	util.ReallyCrash = *reallyCrashForTesting |  | ||||||
| 	defer util.FlushLogs() | 	defer util.FlushLogs() | ||||||
| 	rand.Seed(time.Now().UTC().UnixNano()) |  | ||||||
|  |  | ||||||
| 	verflag.PrintAndExitIfRequested() | 	verflag.PrintAndExitIfRequested() | ||||||
|  |  | ||||||
| 	// Cluster creation scripts support both kubernetes versions that 1) support kublet watching | 	s.Run(pflag.CommandLine.Args()) | ||||||
| 	// apiserver for pods, and 2) ones that don't. So they ca set both --etcd_servers and |  | ||||||
| 	// --api_servers.  The current code will ignore the --etcd_servers flag, while older kubelet |  | ||||||
| 	// code will use the --etd_servers flag for pods, and use --api_servers for event publising. |  | ||||||
| 	// |  | ||||||
| 	// TODO(erictune): convert all cloud provider scripts and Google Container Engine to |  | ||||||
| 	// use only --api_servers, then delete --etcd_servers flag and the resulting dead code. |  | ||||||
| 	if len(etcdServerList) > 0 && len(apiServerList) > 0 { |  | ||||||
| 		glog.Infof("Both --etcd_servers and --api_servers are set.  Not using etcd source.") |  | ||||||
| 		etcdServerList = util.StringList{} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	setupRunOnce() |  | ||||||
|  |  | ||||||
| 	if err := util.ApplyOomScoreAdj(*oomScoreAdj); err != nil { |  | ||||||
| 		glog.Info(err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	client, err := kubeletServer.GetAPIServerClient(*authPath, apiServerList) |  | ||||||
| 	if err != nil && len(apiServerList) > 0 { |  | ||||||
| 		glog.Warningf("No API client: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	credentialprovider.SetPreferredDockercfgPath(*rootDirectory) |  | ||||||
|  |  | ||||||
| 	kcfg := kubeletServer.KubeletConfig{ |  | ||||||
| 		Address:                 address, |  | ||||||
| 		AllowPrivileged:         *allowPrivileged, |  | ||||||
| 		HostnameOverride:        *hostnameOverride, |  | ||||||
| 		RootDirectory:           *rootDirectory, |  | ||||||
| 		ConfigFile:              *config, |  | ||||||
| 		ManifestURL:             *manifestURL, |  | ||||||
| 		FileCheckFrequency:      *fileCheckFrequency, |  | ||||||
| 		HttpCheckFrequency:      *httpCheckFrequency, |  | ||||||
| 		PodInfraContainerImage:  *podInfraContainerImage, |  | ||||||
| 		SyncFrequency:           *syncFrequency, |  | ||||||
| 		RegistryPullQPS:         *registryPullQPS, |  | ||||||
| 		RegistryBurst:           *registryBurst, |  | ||||||
| 		MinimumGCAge:            *minimumGCAge, |  | ||||||
| 		MaxContainerCount:       *maxContainerCount, |  | ||||||
| 		ClusterDomain:           *clusterDomain, |  | ||||||
| 		ClusterDNS:              clusterDNS, |  | ||||||
| 		Runonce:                 *runonce, |  | ||||||
| 		Port:                    *port, |  | ||||||
| 		CAdvisorPort:            *cAdvisorPort, |  | ||||||
| 		EnableServer:            *enableServer, |  | ||||||
| 		EnableDebuggingHandlers: *enableDebuggingHandlers, |  | ||||||
| 		DockerClient:            util.ConnectToDockerOrDie(*dockerEndpoint), |  | ||||||
| 		KubeClient:              client, |  | ||||||
| 		EtcdClient:              kubelet.EtcdClientOrDie(etcdServerList, *etcdConfigFile), |  | ||||||
| 		MasterServiceNamespace:  *masterServiceNamespace, |  | ||||||
| 		VolumePlugins:           app.ProbeVolumePlugins(), |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	kubeletServer.RunKubelet(&kcfg) |  | ||||||
| 	// runs forever |  | ||||||
| 	select {} |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -26,7 +26,6 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	kubeletapp "github.com/GoogleCloudPlatform/kubernetes/cmd/kubelet/app" |  | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/api" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/api" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" | ||||||
| @@ -141,7 +140,7 @@ func startComponents(etcdClient tools.EtcdClient, cl *client.Client, addr net.IP | |||||||
| 	runControllerManager(machineList, cl, *nodeMilliCPU, *nodeMemory) | 	runControllerManager(machineList, cl, *nodeMilliCPU, *nodeMemory) | ||||||
|  |  | ||||||
| 	dockerClient := util.ConnectToDockerOrDie(*dockerEndpoint) | 	dockerClient := util.ConnectToDockerOrDie(*dockerEndpoint) | ||||||
| 	kubeletServer.SimpleRunKubelet(cl, nil, dockerClient, machineList[0], "/tmp/kubernetes", "", "127.0.0.1", 10250, *masterServiceNamespace, kubeletapp.ProbeVolumePlugins()) | 	kubeletServer.SimpleRunKubelet(cl, nil, dockerClient, machineList[0], "/tmp/kubernetes", "", "127.0.0.1", 10250, *masterServiceNamespace, kubeletServer.ProbeVolumePlugins()) | ||||||
| } | } | ||||||
|  |  | ||||||
| func newApiClient(addr net.IP, port int) *client.Client { | func newApiClient(addr net.IP, port int) *client.Client { | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and | |||||||
| limitations under the License. | limitations under the License. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| package app | package server | ||||||
| 
 | 
 | ||||||
| // This file exists to force the desired plugin implementations to be linked. | // This file exists to force the desired plugin implementations to be linked. | ||||||
| import ( | import ( | ||||||
| @@ -28,6 +28,7 @@ import ( | |||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/host_path" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/host_path" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // ProbeVolumePlugins collects all volume plugins into an easy to use list. | ||||||
| func ProbeVolumePlugins() []volume.Plugin { | func ProbeVolumePlugins() []volume.Plugin { | ||||||
| 	allPlugins := []volume.Plugin{} | 	allPlugins := []volume.Plugin{} | ||||||
| 
 | 
 | ||||||
| @@ -14,30 +14,228 @@ See the License for the specific language governing permissions and | |||||||
| limitations under the License. | limitations under the License. | ||||||
| */ | */ | ||||||
|  |  | ||||||
| // package server makes it easy to create a kubelet server for various contexts. | // Package server makes it easy to create a kubelet server for various contexts. | ||||||
| package server | package server | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"math/rand" | ||||||
| 	"net" | 	"net" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/api" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/client" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/client" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider" | ||||||
|  | 	_ "github.com/GoogleCloudPlatform/kubernetes/pkg/healthz" | ||||||
|  | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/hyperkube" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume" | ||||||
|  | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" | ||||||
| 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util" | 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util" | ||||||
|  |  | ||||||
| 	"github.com/golang/glog" | 	"github.com/golang/glog" | ||||||
|  | 	"github.com/spf13/pflag" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | const defaultRootDir = "/var/lib/kubelet" | ||||||
|  |  | ||||||
|  | // KubeletServer encapsulates all of the parameters necessary for starting up | ||||||
|  | // a kubelet. These can either be set via command line or directly. | ||||||
|  | type KubeletServer struct { | ||||||
|  | 	Config                  string | ||||||
|  | 	SyncFrequency           time.Duration | ||||||
|  | 	FileCheckFrequency      time.Duration | ||||||
|  | 	HTTPCheckFrequency      time.Duration | ||||||
|  | 	ManifestURL             string | ||||||
|  | 	EnableServer            bool | ||||||
|  | 	Address                 util.IP | ||||||
|  | 	Port                    uint | ||||||
|  | 	HostnameOverride        string | ||||||
|  | 	PodInfraContainerImage  string | ||||||
|  | 	DockerEndpoint          string | ||||||
|  | 	EtcdServerList          util.StringList | ||||||
|  | 	EtcdConfigFile          string | ||||||
|  | 	RootDirectory           string | ||||||
|  | 	AllowPrivileged         bool | ||||||
|  | 	RegistryPullQPS         float64 | ||||||
|  | 	RegistryBurst           int | ||||||
|  | 	RunOnce                 bool | ||||||
|  | 	EnableDebuggingHandlers bool | ||||||
|  | 	MinimumGCAge            time.Duration | ||||||
|  | 	MaxContainerCount       int | ||||||
|  | 	AuthPath                string | ||||||
|  | 	CAdvisorPort            uint | ||||||
|  | 	OOMScoreAdj             int | ||||||
|  | 	APIServerList           util.StringList | ||||||
|  | 	ClusterDomain           string | ||||||
|  | 	MasterServiceNamespace  string | ||||||
|  | 	ClusterDNS              util.IP | ||||||
|  | 	ReallyCrashForTesting   bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewKubeletServer will create a new KubeletServer with default values. | ||||||
|  | func NewKubeletServer() *KubeletServer { | ||||||
|  | 	return &KubeletServer{ | ||||||
|  | 		SyncFrequency:      10 * time.Second, | ||||||
|  | 		FileCheckFrequency: 20 * time.Second, | ||||||
|  | 		HTTPCheckFrequency: 20 * time.Second, | ||||||
|  | 		EnableServer:       true, | ||||||
|  | 		Address:            util.IP(net.ParseIP("127.0.0.1")), | ||||||
|  | 		Port:               ports.KubeletPort, | ||||||
|  | 		PodInfraContainerImage:  kubelet.PodInfraContainerImage, | ||||||
|  | 		RootDirectory:           defaultRootDir, | ||||||
|  | 		RegistryBurst:           10, | ||||||
|  | 		EnableDebuggingHandlers: true, | ||||||
|  | 		MinimumGCAge:            1 * time.Minute, | ||||||
|  | 		MaxContainerCount:       5, | ||||||
|  | 		CAdvisorPort:            4194, | ||||||
|  | 		OOMScoreAdj:             -900, | ||||||
|  | 		MasterServiceNamespace:  api.NamespaceDefault, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewHyperkubeServer creates a new hyperkube Server object that includes the | ||||||
|  | // description and flags. | ||||||
|  | func NewHyperkubeServer() *hyperkube.Server { | ||||||
|  | 	s := NewKubeletServer() | ||||||
|  | 	hks := hyperkube.Server{ | ||||||
|  | 		SimpleUsage: "kubelet", | ||||||
|  | 		Long: `The kubelet binary is responsible for maintaining a set of containers on a | ||||||
|  | particular node. It syncs data from a variety of sources including a | ||||||
|  | Kubernetes API server, an etcd cluster, HTTP endpoint or local file. It then | ||||||
|  | queries Docker to see what is currently running.  It synchronizes the | ||||||
|  | configuration data, with the running set of containers by starting or stopping | ||||||
|  | Docker containers.`, | ||||||
|  | 		Run: func(_ *hyperkube.Server, args []string) error { | ||||||
|  | 			return s.Run(args) | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	s.AddFlags(hks.Flags()) | ||||||
|  | 	return &hks | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // AddFlags adds flags for a specific KubeletServer to the specified FlagSet | ||||||
|  | func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) { | ||||||
|  | 	fs.StringVar(&s.Config, "config", s.Config, "Path to the config file or directory of files") | ||||||
|  | 	fs.DurationVar(&s.SyncFrequency, "sync_frequency", s.SyncFrequency, "Max period between synchronizing running containers and config") | ||||||
|  | 	fs.DurationVar(&s.FileCheckFrequency, "file_check_frequency", s.FileCheckFrequency, "Duration between checking config files for new data") | ||||||
|  | 	fs.DurationVar(&s.HTTPCheckFrequency, "http_check_frequency", s.HTTPCheckFrequency, "Duration between checking http for new data") | ||||||
|  | 	fs.StringVar(&s.ManifestURL, "manifest_url", s.ManifestURL, "URL for accessing the container manifest") | ||||||
|  | 	fs.BoolVar(&s.EnableServer, "enable_server", s.EnableServer, "Enable the info server") | ||||||
|  | 	fs.Var(&s.Address, "address", "The IP address for the info server to serve on (set to 0.0.0.0 for all interfaces)") | ||||||
|  | 	fs.UintVar(&s.Port, "port", s.Port, "The port for the info server to serve on") | ||||||
|  | 	fs.StringVar(&s.HostnameOverride, "hostname_override", s.HostnameOverride, "If non-empty, will use this string as identification instead of the actual hostname.") | ||||||
|  | 	fs.StringVar(&s.PodInfraContainerImage, "pod_infra_container_image", s.PodInfraContainerImage, "The image whose network/ipc namespaces containers in each pod will use.") | ||||||
|  | 	fs.StringVar(&s.DockerEndpoint, "docker_endpoint", s.DockerEndpoint, "If non-empty, use this for the docker endpoint to communicate with") | ||||||
|  | 	fs.Var(&s.EtcdServerList, "etcd_servers", "List of etcd servers to watch (http://ip:port), comma separated. Mutually exclusive with -etcd_config") | ||||||
|  | 	fs.StringVar(&s.EtcdConfigFile, "etcd_config", s.EtcdConfigFile, "The config file for the etcd client. Mutually exclusive with -etcd_servers") | ||||||
|  | 	fs.StringVar(&s.RootDirectory, "root_dir", s.RootDirectory, "Directory path for managing kubelet files (volume mounts,etc).") | ||||||
|  | 	fs.BoolVar(&s.AllowPrivileged, "allow_privileged", s.AllowPrivileged, "If true, allow containers to request privileged mode. [default=false]") | ||||||
|  | 	fs.Float64Var(&s.RegistryPullQPS, "registry_qps", s.RegistryPullQPS, "If > 0, limit registry pull QPS to this value.  If 0, unlimited. [default=0.0]") | ||||||
|  | 	fs.IntVar(&s.RegistryBurst, "registry_burst", s.RegistryBurst, "Maximum size of a bursty pulls, temporarily allows pulls to burst to this number, while still not exceeding registry_qps.  Only used if --registry_qps > 0") | ||||||
|  | 	fs.BoolVar(&s.RunOnce, "runonce", s.RunOnce, "If true, exit after spawning pods from local manifests or remote urls. Exclusive with --etcd_servers, --api_servers, and --enable-server") | ||||||
|  | 	fs.BoolVar(&s.EnableDebuggingHandlers, "enable_debugging_handlers", s.EnableDebuggingHandlers, "Enables server endpoints for log collection and local running of containers and commands") | ||||||
|  | 	fs.DurationVar(&s.MinimumGCAge, "minimum_container_ttl_duration", s.MinimumGCAge, "Minimum age for a finished container before it is garbage collected.  Examples: '300ms', '10s' or '2h45m'") | ||||||
|  | 	fs.IntVar(&s.MaxContainerCount, "maximum_dead_containers_per_container", s.MaxContainerCount, "Maximum number of old instances of a container to retain per container.  Each container takes up some disk space.  Default: 5.") | ||||||
|  | 	fs.StringVar(&s.AuthPath, "auth_path", s.AuthPath, "Path to .kubernetes_auth file, specifying how to authenticate to API server.") | ||||||
|  | 	fs.UintVar(&s.CAdvisorPort, "cadvisor_port", s.CAdvisorPort, "The port of the localhost cAdvisor endpoint") | ||||||
|  | 	fs.IntVar(&s.OOMScoreAdj, "oom_score_adj", s.OOMScoreAdj, "The oom_score_adj value for kubelet process. Values must be within the range [-1000, 1000]") | ||||||
|  | 	fs.Var(&s.APIServerList, "api_servers", "List of Kubernetes API servers for publishing events, and reading pods and services. (ip:port), comma separated.") | ||||||
|  | 	fs.StringVar(&s.ClusterDomain, "cluster_domain", s.ClusterDomain, "Domain for this cluster.  If set, kubelet will configure all containers to search this domain in addition to the host's search domains") | ||||||
|  | 	fs.StringVar(&s.MasterServiceNamespace, "master_service_namespace", s.MasterServiceNamespace, "The namespace from which the kubernetes master services should be injected into pods") | ||||||
|  | 	fs.Var(&s.ClusterDNS, "cluster_dns", "IP address for a cluster DNS server.  If set, kubelet will configure all containers to use this for DNS resolution in addition to the host's DNS servers") | ||||||
|  | 	fs.BoolVar(&s.ReallyCrashForTesting, "really_crash_for_testing", s.ReallyCrashForTesting, "If true, crash with panics more often.") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Run runs the specified KubeletServer.  This should never exit. | ||||||
|  | func (s *KubeletServer) Run(_ []string) error { | ||||||
|  | 	util.ReallyCrash = s.ReallyCrashForTesting | ||||||
|  | 	rand.Seed(time.Now().UTC().UnixNano()) | ||||||
|  |  | ||||||
|  | 	// Cluster creation scripts support both kubernetes versions that 1) | ||||||
|  | 	// support kublet watching apiserver for pods, and 2) ones that don't. So | ||||||
|  | 	// they can set both --etcd_servers and --api_servers.  The current code | ||||||
|  | 	// will ignore the --etcd_servers flag, while older kubelet code will use | ||||||
|  | 	// the --etcd_servers flag for pods, and use --api_servers for event | ||||||
|  | 	// publising. | ||||||
|  | 	// | ||||||
|  | 	// TODO(erictune): convert all cloud provider scripts and Google Container Engine to | ||||||
|  | 	// use only --api_servers, then delete --etcd_servers flag and the resulting dead code. | ||||||
|  | 	if len(s.EtcdServerList) > 0 && len(s.APIServerList) > 0 { | ||||||
|  | 		glog.Infof("Both --etcd_servers and --api_servers are set.  Not using etcd source.") | ||||||
|  | 		s.EtcdServerList = util.StringList{} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err := util.ApplyOomScoreAdj(s.OOMScoreAdj); err != nil { | ||||||
|  | 		glog.Info(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	client, err := s.createAPIServerClient() | ||||||
|  | 	if err != nil && len(s.APIServerList) > 0 { | ||||||
|  | 		glog.Warningf("No API client: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	credentialprovider.SetPreferredDockercfgPath(s.RootDirectory) | ||||||
|  |  | ||||||
|  | 	kcfg := KubeletConfig{ | ||||||
|  | 		Address:                 s.Address, | ||||||
|  | 		AllowPrivileged:         s.AllowPrivileged, | ||||||
|  | 		HostnameOverride:        s.HostnameOverride, | ||||||
|  | 		RootDirectory:           s.RootDirectory, | ||||||
|  | 		ConfigFile:              s.Config, | ||||||
|  | 		ManifestURL:             s.ManifestURL, | ||||||
|  | 		FileCheckFrequency:      s.FileCheckFrequency, | ||||||
|  | 		HTTPCheckFrequency:      s.HTTPCheckFrequency, | ||||||
|  | 		PodInfraContainerImage:  s.PodInfraContainerImage, | ||||||
|  | 		SyncFrequency:           s.SyncFrequency, | ||||||
|  | 		RegistryPullQPS:         s.RegistryPullQPS, | ||||||
|  | 		RegistryBurst:           s.RegistryBurst, | ||||||
|  | 		MinimumGCAge:            s.MinimumGCAge, | ||||||
|  | 		MaxContainerCount:       s.MaxContainerCount, | ||||||
|  | 		ClusterDomain:           s.ClusterDomain, | ||||||
|  | 		ClusterDNS:              s.ClusterDNS, | ||||||
|  | 		Runonce:                 s.RunOnce, | ||||||
|  | 		Port:                    s.Port, | ||||||
|  | 		CAdvisorPort:            s.CAdvisorPort, | ||||||
|  | 		EnableServer:            s.EnableServer, | ||||||
|  | 		EnableDebuggingHandlers: s.EnableDebuggingHandlers, | ||||||
|  | 		DockerClient:            util.ConnectToDockerOrDie(s.DockerEndpoint), | ||||||
|  | 		KubeClient:              client, | ||||||
|  | 		EtcdClient:              kubelet.EtcdClientOrDie(s.EtcdServerList, s.EtcdConfigFile), | ||||||
|  | 		MasterServiceNamespace:  s.MasterServiceNamespace, | ||||||
|  | 		VolumePlugins:           ProbeVolumePlugins(), | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	RunKubelet(&kcfg) | ||||||
|  |  | ||||||
|  | 	// runs forever | ||||||
|  | 	select {} | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *KubeletServer) setupRunOnce() { | ||||||
|  | 	if s.RunOnce { | ||||||
|  | 		// Don't use remote (etcd or apiserver) sources | ||||||
|  | 		if len(s.EtcdServerList) > 0 { | ||||||
|  | 			glog.Fatalf("invalid option: --runonce and --etcd_servers are mutually exclusive") | ||||||
|  | 		} | ||||||
|  | 		if len(s.APIServerList) > 0 { | ||||||
|  | 			glog.Fatalf("invalid option: --runonce and --api_servers are mutually exclusive") | ||||||
|  | 		} | ||||||
|  | 		if s.EnableServer { | ||||||
|  | 			glog.Infof("--runonce is set, disabling server") | ||||||
|  | 			s.EnableServer = false | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| // TODO: replace this with clientcmd | // TODO: replace this with clientcmd | ||||||
| func GetAPIServerClient(authPath string, apiServerList util.StringList) (*client.Client, error) { | func (s *KubeletServer) createAPIServerClient() (*client.Client, error) { | ||||||
| 	authInfo, err := clientauth.LoadFromFile(authPath) | 	authInfo, err := clientauth.LoadFromFile(s.AuthPath) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		glog.Warningf("Could not load kubernetes auth path: %v. Continuing with defaults.", err) | 		glog.Warningf("Could not load kubernetes auth path: %v. Continuing with defaults.", err) | ||||||
| 	} | 	} | ||||||
| @@ -49,14 +247,14 @@ func GetAPIServerClient(authPath string, apiServerList util.StringList) (*client | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	if len(apiServerList) < 1 { | 	if len(s.APIServerList) < 1 { | ||||||
| 		return nil, fmt.Errorf("no api servers specified.") | 		return nil, fmt.Errorf("no api servers specified") | ||||||
| 	} | 	} | ||||||
| 	// TODO: adapt Kube client to support LB over several servers | 	// TODO: adapt Kube client to support LB over several servers | ||||||
| 	if len(apiServerList) > 1 { | 	if len(s.APIServerList) > 1 { | ||||||
| 		glog.Infof("Multiple api servers specified.  Picking first one") | 		glog.Infof("Multiple api servers specified.  Picking first one") | ||||||
| 	} | 	} | ||||||
| 	clientConfig.Host = apiServerList[0] | 	clientConfig.Host = s.APIServerList[0] | ||||||
| 	c, err := client.New(&clientConfig) | 	c, err := client.New(&clientConfig) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @@ -111,25 +309,25 @@ func RunKubelet(kcfg *KubeletConfig) { | |||||||
|  |  | ||||||
| 	credentialprovider.SetPreferredDockercfgPath(kcfg.RootDirectory) | 	credentialprovider.SetPreferredDockercfgPath(kcfg.RootDirectory) | ||||||
|  |  | ||||||
| 	cfg := makePodSourceConfig(kcfg) | 	podCfg := makePodSourceConfig(kcfg) | ||||||
| 	k, err := createAndInitKubelet(kcfg, cfg) | 	k, err := createAndInitKubelet(kcfg, podCfg) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		glog.Errorf("Failed to create kubelet: %s", err) | 		glog.Errorf("Failed to create kubelet: %s", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	// process pods and exit. | 	// process pods and exit. | ||||||
| 	if kcfg.Runonce { | 	if kcfg.Runonce { | ||||||
| 		if _, err := k.RunOnce(cfg.Updates()); err != nil { | 		if _, err := k.RunOnce(podCfg.Updates()); err != nil { | ||||||
| 			glog.Errorf("--runonce failed: %v", err) | 			glog.Errorf("--runonce failed: %v", err) | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		startKubelet(k, cfg, kcfg) | 		startKubelet(k, podCfg, kcfg) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func startKubelet(k *kubelet.Kubelet, cfg *config.PodConfig, kc *KubeletConfig) { | func startKubelet(k *kubelet.Kubelet, podCfg *config.PodConfig, kc *KubeletConfig) { | ||||||
| 	// start the kubelet | 	// start the kubelet | ||||||
| 	go util.Forever(func() { k.Run(cfg.Updates()) }, 0) | 	go util.Forever(func() { k.Run(podCfg.Updates()) }, 0) | ||||||
|  |  | ||||||
| 	// start the kubelet server | 	// start the kubelet server | ||||||
| 	if kc.EnableServer { | 	if kc.EnableServer { | ||||||
| @@ -152,7 +350,7 @@ func makePodSourceConfig(kc *KubeletConfig) *config.PodConfig { | |||||||
| 	// define url config source | 	// define url config source | ||||||
| 	if kc.ManifestURL != "" { | 	if kc.ManifestURL != "" { | ||||||
| 		glog.Infof("Adding manifest url: %v", kc.ManifestURL) | 		glog.Infof("Adding manifest url: %v", kc.ManifestURL) | ||||||
| 		config.NewSourceURL(kc.ManifestURL, kc.HttpCheckFrequency, cfg.Channel(kubelet.HTTPSource)) | 		config.NewSourceURL(kc.ManifestURL, kc.HTTPCheckFrequency, cfg.Channel(kubelet.HTTPSource)) | ||||||
| 	} | 	} | ||||||
| 	if kc.EtcdClient != nil { | 	if kc.EtcdClient != nil { | ||||||
| 		glog.Infof("Watching for etcd configs at %v", kc.EtcdClient.GetCluster()) | 		glog.Infof("Watching for etcd configs at %v", kc.EtcdClient.GetCluster()) | ||||||
| @@ -165,6 +363,8 @@ func makePodSourceConfig(kc *KubeletConfig) *config.PodConfig { | |||||||
| 	return cfg | 	return cfg | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // KubeletConfig is all of the parameters necessary for running a kubelet. | ||||||
|  | // TODO: This should probably be merged with KubeletServer.  The extra object is a consequence of refactoring. | ||||||
| type KubeletConfig struct { | type KubeletConfig struct { | ||||||
| 	EtcdClient              tools.EtcdClient | 	EtcdClient              tools.EtcdClient | ||||||
| 	KubeClient              *client.Client | 	KubeClient              *client.Client | ||||||
| @@ -177,7 +377,7 @@ type KubeletConfig struct { | |||||||
| 	ConfigFile              string | 	ConfigFile              string | ||||||
| 	ManifestURL             string | 	ManifestURL             string | ||||||
| 	FileCheckFrequency      time.Duration | 	FileCheckFrequency      time.Duration | ||||||
| 	HttpCheckFrequency      time.Duration | 	HTTPCheckFrequency      time.Duration | ||||||
| 	Hostname                string | 	Hostname                string | ||||||
| 	PodInfraContainerImage  string | 	PodInfraContainerImage  string | ||||||
| 	SyncFrequency           time.Duration | 	SyncFrequency           time.Duration | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user