Implement kubernetes & kubernetes-ro services
This commit is contained in:
@@ -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.
|
||||
|
Reference in New Issue
Block a user