2014-10-27 17:04:39 +00:00
/ *
2015-05-01 16:19:44 +00:00
Copyright 2014 The Kubernetes Authors All rights reserved .
2014-10-27 17:04:39 +00:00
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 .
* /
// A binary that is capable of running a complete, standalone kubernetes cluster.
// Expects an etcd server is available, or on the path somewhere.
// Does *not* currently setup the Kubernetes network model, that must be done ahead of time.
// TODO: Setup the k8s network bridge as part of setup.
2015-02-19 18:30:31 +00:00
// TODO: combine this with the hypercube thingy.
2014-10-27 17:04:39 +00:00
package main
import (
"fmt"
2015-01-20 03:25:06 +00:00
"net"
2015-02-02 18:32:31 +00:00
"net/http"
2015-02-19 18:30:31 +00:00
"runtime"
2015-02-02 18:32:31 +00:00
"time"
2014-10-27 17:04:39 +00:00
2015-02-07 21:30:53 +00:00
kubeletapp "github.com/GoogleCloudPlatform/kubernetes/cmd/kubelet/app"
2015-01-08 15:25:14 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
2015-02-02 18:32:31 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
2014-10-27 17:04:39 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
2015-02-02 18:32:31 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
2014-10-27 17:04:39 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
2015-03-23 22:59:38 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/nodecontroller"
2015-03-24 17:32:43 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/servicecontroller"
2015-02-02 18:32:31 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/controller"
2015-03-10 05:39:00 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/cadvisor"
2015-04-27 20:03:55 +00:00
kubecontainer "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/container"
2015-02-05 00:58:26 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools"
2015-02-02 18:32:31 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/service"
2014-10-27 17:04:39 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
2015-02-02 18:32:31 +00:00
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler"
_ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/algorithmprovider"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory"
2014-10-27 17:04:39 +00:00
"github.com/golang/glog"
2015-01-13 19:22:02 +00:00
flag "github.com/spf13/pflag"
2014-10-27 17:04:39 +00:00
)
var (
addr = flag . String ( "addr" , "127.0.0.1" , "The address to use for the apiserver." )
port = flag . Int ( "port" , 8080 , "The port for the apiserver to use." )
2015-04-24 06:10:33 +00:00
dockerEndpoint = flag . String ( "docker-endpoint" , "" , "If non-empty, use this for the docker endpoint to communicate with" )
etcdServer = flag . String ( "etcd-server" , "http://localhost:4001" , "If non-empty, path to the set of etcd server to use" )
2014-10-27 17:04:39 +00:00
// TODO: Discover these by pinging the host machines, and rip out these flags.
2015-04-24 06:10:33 +00:00
nodeMilliCPU = flag . Int64 ( "node-milli-cpu" , 1000 , "The amount of MilliCPU provisioned on each node" )
nodeMemory = flag . Int64 ( "node-memory" , 3 * 1024 * 1024 * 1024 , "The amount of memory (in bytes) provisioned on each node" )
masterServiceNamespace = flag . String ( "master-service-namespace" , api . NamespaceDefault , "The namespace from which the kubernetes master services should be injected into pods" )
2015-03-13 15:44:11 +00:00
enableProfiling = flag . Bool ( "profiling" , false , "Enable profiling via web interface host:port/debug/pprof/" )
2015-04-24 06:10:33 +00:00
deletingPodsQps = flag . Float32 ( "deleting-pods-qps" , 0.1 , "" )
deletingPodsBurst = flag . Int ( "deleting-pods-burst" , 10 , "" )
2014-10-27 17:04:39 +00:00
)
2015-02-02 18:32:31 +00:00
type delegateHandler struct {
delegate http . Handler
}
func ( h * delegateHandler ) ServeHTTP ( w http . ResponseWriter , req * http . Request ) {
if h . delegate != nil {
h . delegate . ServeHTTP ( w , req )
return
}
w . WriteHeader ( http . StatusNotFound )
}
// RunApiServer starts an API server in a go routine.
2015-03-18 08:21:10 +00:00
func runApiServer ( etcdClient tools . EtcdClient , addr net . IP , port int , masterServiceNamespace string ) {
2015-02-02 18:32:31 +00:00
handler := delegateHandler { }
2015-03-11 17:10:09 +00:00
helper , err := master . NewEtcdHelper ( etcdClient , "" , master . DefaultEtcdPathPrefix )
2015-02-02 18:32:31 +00:00
if err != nil {
glog . Fatalf ( "Unable to get etcd helper: %v" , err )
}
// Create a master and install handlers into mux.
m := master . New ( & master . Config {
EtcdHelper : helper ,
KubeletClient : & client . HTTPKubeletClient {
Client : http . DefaultClient ,
Port : 10250 ,
} ,
2015-05-03 22:44:05 +00:00
EnableCoreControllers : true ,
EnableLogsSupport : false ,
EnableSwaggerSupport : true ,
EnableProfiling : * enableProfiling ,
APIPrefix : "/api" ,
Authorizer : apiserver . NewAlwaysAllowAuthorizer ( ) ,
2015-02-02 18:32:31 +00:00
ReadWritePort : port ,
ReadOnlyPort : port ,
PublicAddress : addr ,
MasterServiceNamespace : masterServiceNamespace ,
} )
handler . delegate = m . InsecureHandler
go http . ListenAndServe ( fmt . Sprintf ( "%s:%d" , addr , port ) , & handler )
}
// RunScheduler starts up a scheduler in it's own goroutine
func runScheduler ( cl * client . Client ) {
// Scheduler
schedulerConfigFactory := factory . NewConfigFactory ( cl )
schedulerConfig , err := schedulerConfigFactory . Create ( )
if err != nil {
glog . Fatalf ( "Couldn't create scheduler config: %v" , err )
}
scheduler . New ( schedulerConfig ) . Run ( )
}
// RunControllerManager starts a controller
2015-05-20 20:47:51 +00:00
func runControllerManager ( machineList [ ] string , cl * client . Client , nodeMilliCPU , nodeMemory int64 ) {
2015-02-02 18:32:31 +00:00
nodeResources := & api . NodeResources {
Capacity : api . ResourceList {
api . ResourceCPU : * resource . NewMilliQuantity ( nodeMilliCPU , resource . DecimalSI ) ,
api . ResourceMemory : * resource . NewQuantity ( nodeMemory , resource . BinarySI ) ,
} ,
}
2015-02-07 19:53:42 +00:00
2015-04-22 20:54:44 +00:00
const nodeSyncPeriod = 10 * time . Second
2015-03-23 22:59:38 +00:00
nodeController := nodecontroller . NewNodeController (
2015-05-20 20:47:51 +00:00
nil , "" , machineList , nodeResources , cl , 10 , 5 * time . Minute , util . NewTokenBucketRateLimiter ( * deletingPodsQps , * deletingPodsBurst ) ,
2015-05-14 08:17:04 +00:00
40 * time . Second , 60 * time . Second , 5 * time . Second , nil , false )
2015-04-22 20:54:44 +00:00
nodeController . Run ( nodeSyncPeriod , true )
2015-02-02 18:32:31 +00:00
2015-03-24 17:32:43 +00:00
serviceController := servicecontroller . New ( nil , cl , "kubernetes" )
2015-04-22 20:54:44 +00:00
if err := serviceController . Run ( nodeSyncPeriod ) ; err != nil {
2015-03-24 17:32:43 +00:00
glog . Warningf ( "Running without a service controller: %v" , err )
}
2015-02-02 18:32:31 +00:00
endpoints := service . NewEndpointController ( cl )
2015-04-16 23:18:02 +00:00
go endpoints . Run ( 5 , util . NeverStop )
2015-02-02 18:32:31 +00:00
2015-05-06 21:39:14 +00:00
controllerManager := controller . NewReplicationManager ( cl , controller . BurstReplicas )
2015-04-21 20:40:35 +00:00
go controllerManager . Run ( 5 , util . NeverStop )
2015-02-02 18:32:31 +00:00
}
2015-01-20 03:25:06 +00:00
func startComponents ( etcdClient tools . EtcdClient , cl * client . Client , addr net . IP , port int ) {
2015-05-20 20:47:51 +00:00
machineList := [ ] string { "localhost" }
2015-03-18 08:21:10 +00:00
runApiServer ( etcdClient , addr , port , * masterServiceNamespace )
2015-02-02 18:32:31 +00:00
runScheduler ( cl )
2015-05-20 20:47:51 +00:00
runControllerManager ( machineList , cl , * nodeMilliCPU , * nodeMemory )
2014-11-27 21:28:56 +00:00
2015-02-05 00:58:26 +00:00
dockerClient := dockertools . ConnectToDockerOrDie ( * dockerEndpoint )
2015-03-10 05:39:00 +00:00
cadvisorInterface , err := cadvisor . New ( 0 )
if err != nil {
glog . Fatalf ( "Failed to create cAdvisor: %v" , err )
}
2015-05-20 20:47:51 +00:00
kcfg := kubeletapp . SimpleKubelet ( cl , dockerClient , machineList [ 0 ] , "/tmp/kubernetes" , "" , "127.0.0.1" , 10250 , * masterServiceNamespace , kubeletapp . ProbeVolumePlugins ( ) , nil , cadvisorInterface , "" , nil , kubecontainer . RealOS { } )
2015-03-26 12:31:54 +00:00
kubeletapp . RunKubelet ( kcfg , nil )
2015-03-23 22:31:13 +00:00
2014-10-27 17:04:39 +00:00
}
2015-01-20 03:25:06 +00:00
func newApiClient ( addr net . IP , port int ) * client . Client {
2014-10-27 17:04:39 +00:00
apiServerURL := fmt . Sprintf ( "http://%s:%d" , addr , port )
cl := client . NewOrDie ( & client . Config { Host : apiServerURL , Version : testapi . Version ( ) } )
return cl
}
func main ( ) {
2015-02-19 18:30:31 +00:00
runtime . GOMAXPROCS ( runtime . NumCPU ( ) )
2015-01-14 22:59:55 +00:00
util . InitFlags ( )
2014-10-27 17:04:39 +00:00
util . InitLogs ( )
defer util . FlushLogs ( )
glog . Infof ( "Creating etcd client pointing to %v" , * etcdServer )
etcdClient , err := tools . NewEtcdClientStartServerIfNecessary ( * etcdServer )
if err != nil {
glog . Fatalf ( "Failed to connect to etcd: %v" , err )
}
2015-01-20 03:25:06 +00:00
address := net . ParseIP ( * addr )
startComponents ( etcdClient , newApiClient ( address , * port ) , address , * port )
2014-10-27 17:04:39 +00:00
glog . Infof ( "Kubernetes API Server is up and running on http://%s:%d" , * addr , * port )
select { }
}