Implement kubernetes & kubernetes-ro services

This commit is contained in:
Daniel Smith
2014-10-27 17:56:33 -07:00
parent 3045311398
commit 7146ec9d49
5 changed files with 232 additions and 6 deletions

View File

@@ -19,7 +19,9 @@ package master
import (
"net"
"net/http"
"strconv"
"strings"
"sync"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
@@ -34,6 +36,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
cloudcontroller "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller"
"github.com/GoogleCloudPlatform/kubernetes/pkg/election"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/binding"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/controller"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/endpoint"
@@ -70,6 +73,16 @@ type Config struct {
APIPrefix string
CorsAllowedOriginList util.StringList
TokenAuthFile string
// The port on PublicAddress where a read-only server will be installed.
// Defaults to 7080 if not set.
ReadOnlyPort int
// The port on PublicAddress where a read-write server will be installed.
// Defaults to 443 if not set.
ReadWritePort int
// If empty, the first result from net.InterfaceAddrs will be used.
PublicAddress string
}
// Master contains state for a Kubernetes cluster master/api server.
@@ -91,8 +104,18 @@ type Master struct {
apiPrefix string
corsAllowedOriginList util.StringList
tokenAuthFile string
// "Outputs"
Handler http.Handler
elector election.MasterElector
readOnlyServer string
readWriteServer string
electedMasterServices *util.Runner
// lock must be held when accessing the below read-write members.
lock sync.RWMutex
electedMaster election.Master
}
// NewEtcdHelper returns an EtcdHelper for the provided arguments or an error if the version
@@ -108,8 +131,44 @@ func NewEtcdHelper(client tools.EtcdGetSet, version string) (helper tools.EtcdHe
return tools.EtcdHelper{client, versionInterfaces.Codec, tools.RuntimeVersionAdapter{versionInterfaces.MetadataAccessor}}, nil
}
// setDefaults fills in any fields not set that are required to have valid data.
func setDefaults(c *Config) {
if c.ReadOnlyPort == 0 {
c.ReadOnlyPort = 7080
}
if c.ReadWritePort == 0 {
c.ReadWritePort = 443
}
if c.PublicAddress == "" {
addrs, err := net.InterfaceAddrs()
if err != nil {
glog.Fatalf("Unable to get network interfaces: error='%v'", err)
}
found := false
for i := range addrs {
ip, _, err := net.ParseCIDR(addrs[i].String())
if err != nil {
glog.Errorf("Error parsing '%v': %v", addrs[i], err)
continue
}
if ip.IsLoopback() {
glog.Infof("'%v' (%v) is a loopback address, ignoring.", ip, addrs[i])
continue
}
found = true
c.PublicAddress = ip.String()
glog.Infof("Will report %v as public IP address.", ip)
break
}
if !found {
glog.Fatalf("Unable to find suitible network address in list: %v", addrs)
}
}
}
// New returns a new instance of Master connected to the given etcd server.
func New(c *Config) *Master {
setDefaults(c)
minionRegistry := makeMinionRegistry(c)
serviceRegistry := etcd.NewRegistry(c.EtcdHelper, nil)
boundPodFactory := &pod.BasicBoundPodFactory{
@@ -131,7 +190,11 @@ func New(c *Config) *Master {
apiPrefix: c.APIPrefix,
corsAllowedOriginList: c.CorsAllowedOriginList,
tokenAuthFile: c.TokenAuthFile,
elector: election.NewEtcdMasterElector(c.EtcdHelper.Client),
readOnlyServer: net.JoinHostPort(c.PublicAddress, strconv.Itoa(int(c.ReadOnlyPort))),
readWriteServer: net.JoinHostPort(c.PublicAddress, strconv.Itoa(int(c.ReadWritePort))),
}
m.electedMasterServices = util.NewRunner(m.serviceWriterLoop, m.electionAnnounce)
m.init(c)
return m
}
@@ -188,6 +251,7 @@ func (m *Master) init(c *Config) {
// TODO: should appear only in scheduler API group.
"bindings": binding.NewREST(m.bindingRegistry),
}
apiserver.NewAPIGroup(m.API_v1beta1()).InstallREST(m.mux, c.APIPrefix+"/v1beta1")
apiserver.NewAPIGroup(m.API_v1beta2()).InstallREST(m.mux, c.APIPrefix+"/v1beta2")
versionHandler := apiserver.APIVersionHandler("v1beta1", "v1beta2")
@@ -216,6 +280,19 @@ func (m *Master) init(c *Config) {
m.mux.HandleFunc("/_whoami", handleWhoAmI(authenticator))
m.Handler = handler
if m.readWriteServer != "" {
glog.Infof("Starting election services as %v", m.readWriteServer)
go election.Notify(m.elector, "/registry/elections/k8smaster", m.readWriteServer, m.electedMasterServices)
}
// TODO: start a goroutine to report ourselves to the elected master.
}
func (m *Master) electionAnnounce(stop chan struct{}) {
glog.Infof("Elected as master")
<-stop
glog.Info("Lost election for master")
}
// API_v1beta1 returns the resources and codec for API version v1beta1.