Rename 'portal IP' to 'cluster IP' most everywhere

This covers obvious transforms, but not --portal_net, $PORTAL_NET and
similar.
This commit is contained in:
Tim Hockin
2015-05-23 13:41:11 -07:00
parent 46686616d4
commit 4318ca5a8b
43 changed files with 389 additions and 326 deletions

View File

@@ -27,17 +27,17 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
// Repair is a controller loop that periodically examines all service PortalIP allocations
// Repair is a controller loop that periodically examines all service ClusterIP allocations
// and logs any errors, and then sets the compacted and accurate list of all allocated IPs.
//
// Handles:
// * Duplicate PortalIP assignments caused by operator action or undetected race conditions
// * PortalIPs that do not match the current portal network
// * Duplicate ClusterIP assignments caused by operator action or undetected race conditions
// * ClusterIPs that do not match the currently configured range
// * Allocations to services that were not actually created due to a crash or powerloss
// * Migrates old versions of Kubernetes services into the atomic ipallocator model automatically
//
// Can be run at infrequent intervals, and is best performed on startup of the master.
// Is level driven and idempotent - all valid PortalIPs will be updated into the ipallocator
// Is level driven and idempotent - all valid ClusterIPs will be updated into the ipallocator
// map at the end of a single execution loop if no race is encountered.
//
// TODO: allocate new IPs if necessary
@@ -49,7 +49,7 @@ type Repair struct {
alloc service.RangeRegistry
}
// NewRepair creates a controller that periodically ensures that all portalIPs are uniquely allocated across the cluster
// NewRepair creates a controller that periodically ensures that all clusterIPs are uniquely allocated across the cluster
// and generates informational warnings for a cluster that is not in sync.
func NewRepair(interval time.Duration, registry service.Registry, network *net.IPNet, alloc service.RangeRegistry) *Repair {
return &Repair{
@@ -69,7 +69,7 @@ func (c *Repair) RunUntil(ch chan struct{}) {
}, c.interval, ch)
}
// RunOnce verifies the state of the portal IP allocations and returns an error if an unrecoverable problem occurs.
// RunOnce verifies the state of the cluster IP allocations and returns an error if an unrecoverable problem occurs.
func (c *Repair) RunOnce() error {
// TODO: (per smarterclayton) if Get() or ListServices() is a weak consistency read,
// or if they are executed against different leaders,
@@ -94,27 +94,27 @@ func (c *Repair) RunOnce() error {
if !api.IsServiceIPSet(&svc) {
continue
}
ip := net.ParseIP(svc.Spec.PortalIP)
ip := net.ParseIP(svc.Spec.ClusterIP)
if ip == nil {
// portal IP is broken, reallocate
util.HandleError(fmt.Errorf("the portal IP %s for service %s/%s is not a valid IP; please recreate", svc.Spec.PortalIP, svc.Name, svc.Namespace))
// cluster IP is broken, reallocate
util.HandleError(fmt.Errorf("the cluster IP %s for service %s/%s is not a valid IP; please recreate", svc.Spec.ClusterIP, svc.Name, svc.Namespace))
continue
}
switch err := r.Allocate(ip); err {
case nil:
case ipallocator.ErrAllocated:
// TODO: send event
// portal IP is broken, reallocate
util.HandleError(fmt.Errorf("the portal IP %s for service %s/%s was assigned to multiple services; please recreate", ip, svc.Name, svc.Namespace))
// cluster IP is broken, reallocate
util.HandleError(fmt.Errorf("the cluster IP %s for service %s/%s was assigned to multiple services; please recreate", ip, svc.Name, svc.Namespace))
case ipallocator.ErrNotInRange:
// TODO: send event
// portal IP is broken, reallocate
util.HandleError(fmt.Errorf("the portal IP %s for service %s/%s is not within the service CIDR %s; please recreate", ip, svc.Name, svc.Namespace, c.network))
// cluster IP is broken, reallocate
util.HandleError(fmt.Errorf("the cluster IP %s for service %s/%s is not within the service CIDR %s; please recreate", ip, svc.Name, svc.Namespace, c.network))
case ipallocator.ErrFull:
// TODO: send event
return fmt.Errorf("the service CIDR %s is full; you must widen the CIDR in order to create new services")
default:
return fmt.Errorf("unable to allocate portal IP %s for service %s/%s due to an unknown error, exiting: %v", ip, svc.Name, svc.Namespace, err)
return fmt.Errorf("unable to allocate cluster IP %s for service %s/%s due to an unknown error, exiting: %v", ip, svc.Name, svc.Namespace, err)
}
}

View File

@@ -121,22 +121,22 @@ func TestRepairWithExisting(t *testing.T) {
registry.List = api.ServiceList{
Items: []api.Service{
{
Spec: api.ServiceSpec{PortalIP: "192.168.1.1"},
Spec: api.ServiceSpec{ClusterIP: "192.168.1.1"},
},
{
Spec: api.ServiceSpec{PortalIP: "192.168.1.100"},
Spec: api.ServiceSpec{ClusterIP: "192.168.1.100"},
},
{ // outside CIDR, will be dropped
Spec: api.ServiceSpec{PortalIP: "192.168.0.1"},
Spec: api.ServiceSpec{ClusterIP: "192.168.0.1"},
},
{ // empty, ignored
Spec: api.ServiceSpec{PortalIP: ""},
Spec: api.ServiceSpec{ClusterIP: ""},
},
{ // duplicate, dropped
Spec: api.ServiceSpec{PortalIP: "192.168.1.1"},
Spec: api.ServiceSpec{ClusterIP: "192.168.1.1"},
},
{ // headless
Spec: api.ServiceSpec{PortalIP: "None"},
Spec: api.ServiceSpec{ClusterIP: "None"},
},
},
}

View File

@@ -46,19 +46,19 @@ type REST struct {
registry Registry
machines minion.Registry
endpoints endpoint.Registry
portals ipallocator.Interface
serviceIPs ipallocator.Interface
serviceNodePorts portallocator.Interface
clusterName string
}
// NewStorage returns a new REST.
func NewStorage(registry Registry, machines minion.Registry, endpoints endpoint.Registry, portals ipallocator.Interface,
func NewStorage(registry Registry, machines minion.Registry, endpoints endpoint.Registry, serviceIPs ipallocator.Interface,
serviceNodePorts portallocator.Interface, clusterName string) *REST {
return &REST{
registry: registry,
machines: machines,
endpoints: endpoints,
portals: portals,
serviceIPs: serviceIPs,
serviceNodePorts: serviceNodePorts,
clusterName: clusterName,
}
@@ -75,7 +75,7 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (runtime.Object, err
defer func() {
if releaseServiceIP {
if api.IsServiceIPSet(service) {
rs.portals.Release(net.ParseIP(service.Spec.PortalIP))
rs.serviceIPs.Release(net.ParseIP(service.Spec.ClusterIP))
}
}
}()
@@ -85,17 +85,17 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (runtime.Object, err
if api.IsServiceIPRequested(service) {
// Allocate next available.
ip, err := rs.portals.AllocateNext()
ip, err := rs.serviceIPs.AllocateNext()
if err != nil {
el := fielderrors.ValidationErrorList{fielderrors.NewFieldInvalid("spec.portalIP", service.Spec.PortalIP, err.Error())}
el := fielderrors.ValidationErrorList{fielderrors.NewFieldInvalid("spec.clusterIP", service.Spec.ClusterIP, err.Error())}
return nil, errors.NewInvalid("Service", service.Name, el)
}
service.Spec.PortalIP = ip.String()
service.Spec.ClusterIP = ip.String()
releaseServiceIP = true
} else if api.IsServiceIPSet(service) {
// Try to respect the requested IP.
if err := rs.portals.Allocate(net.ParseIP(service.Spec.PortalIP)); err != nil {
el := fielderrors.ValidationErrorList{fielderrors.NewFieldInvalid("spec.portalIP", service.Spec.PortalIP, err.Error())}
if err := rs.serviceIPs.Allocate(net.ParseIP(service.Spec.ClusterIP)); err != nil {
el := fielderrors.ValidationErrorList{fielderrors.NewFieldInvalid("spec.clusterIP", service.Spec.ClusterIP, err.Error())}
return nil, errors.NewInvalid("Service", service.Name, el)
}
releaseServiceIP = true
@@ -150,7 +150,7 @@ func (rs *REST) Delete(ctx api.Context, id string) (runtime.Object, error) {
}
if api.IsServiceIPSet(service) {
rs.portals.Release(net.ParseIP(service.Spec.PortalIP))
rs.serviceIPs.Release(net.ParseIP(service.Spec.ClusterIP))
}
for _, nodePort := range CollectServiceNodePorts(service) {

View File

@@ -96,8 +96,8 @@ func TestServiceRegistryCreate(t *testing.T) {
if created_service.CreationTimestamp.IsZero() {
t.Errorf("Expected timestamp to be set, got: %v", created_service.CreationTimestamp)
}
if !makeIPNet(t).Contains(net.ParseIP(created_service.Spec.PortalIP)) {
t.Errorf("Unexpected PortalIP: %s", created_service.Spec.PortalIP)
if !makeIPNet(t).Contains(net.ParseIP(created_service.Spec.ClusterIP)) {
t.Errorf("Unexpected ClusterIP: %s", created_service.Spec.ClusterIP)
}
srv, err := registry.GetService(ctx, svc.Name)
if err != nil {
@@ -517,8 +517,8 @@ func TestServiceRegistryIPAllocation(t *testing.T) {
if created_service_1.Name != "foo" {
t.Errorf("Expected foo, but got %v", created_service_1.Name)
}
if !makeIPNet(t).Contains(net.ParseIP(created_service_1.Spec.PortalIP)) {
t.Errorf("Unexpected PortalIP: %s", created_service_1.Spec.PortalIP)
if !makeIPNet(t).Contains(net.ParseIP(created_service_1.Spec.ClusterIP)) {
t.Errorf("Unexpected ClusterIP: %s", created_service_1.Spec.ClusterIP)
}
svc2 := &api.Service{
@@ -538,14 +538,14 @@ func TestServiceRegistryIPAllocation(t *testing.T) {
if created_service_2.Name != "bar" {
t.Errorf("Expected bar, but got %v", created_service_2.Name)
}
if !makeIPNet(t).Contains(net.ParseIP(created_service_2.Spec.PortalIP)) {
t.Errorf("Unexpected PortalIP: %s", created_service_2.Spec.PortalIP)
if !makeIPNet(t).Contains(net.ParseIP(created_service_2.Spec.ClusterIP)) {
t.Errorf("Unexpected ClusterIP: %s", created_service_2.Spec.ClusterIP)
}
testIPs := []string{"1.2.3.93", "1.2.3.94", "1.2.3.95", "1.2.3.96"}
testIP := ""
for _, ip := range testIPs {
if !rest.portals.(*ipallocator.Range).Has(net.ParseIP(ip)) {
if !rest.serviceIPs.(*ipallocator.Range).Has(net.ParseIP(ip)) {
testIP = ip
}
}
@@ -554,7 +554,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) {
ObjectMeta: api.ObjectMeta{Name: "quux"},
Spec: api.ServiceSpec{
Selector: map[string]string{"bar": "baz"},
PortalIP: testIP,
ClusterIP: testIP,
SessionAffinity: api.ServiceAffinityNone,
Type: api.ServiceTypeClusterIP,
Ports: []api.ServicePort{{
@@ -569,8 +569,8 @@ func TestServiceRegistryIPAllocation(t *testing.T) {
t.Fatal(err)
}
created_service_3 := created_svc3.(*api.Service)
if created_service_3.Spec.PortalIP != testIP { // specific IP
t.Errorf("Unexpected PortalIP: %s", created_service_3.Spec.PortalIP)
if created_service_3.Spec.ClusterIP != testIP { // specific IP
t.Errorf("Unexpected ClusterIP: %s", created_service_3.Spec.ClusterIP)
}
}
@@ -595,8 +595,8 @@ func TestServiceRegistryIPReallocation(t *testing.T) {
if created_service_1.Name != "foo" {
t.Errorf("Expected foo, but got %v", created_service_1.Name)
}
if !makeIPNet(t).Contains(net.ParseIP(created_service_1.Spec.PortalIP)) {
t.Errorf("Unexpected PortalIP: %s", created_service_1.Spec.PortalIP)
if !makeIPNet(t).Contains(net.ParseIP(created_service_1.Spec.ClusterIP)) {
t.Errorf("Unexpected ClusterIP: %s", created_service_1.Spec.ClusterIP)
}
_, err := rest.Delete(ctx, created_service_1.Name)
@@ -622,8 +622,8 @@ func TestServiceRegistryIPReallocation(t *testing.T) {
if created_service_2.Name != "bar" {
t.Errorf("Expected bar, but got %v", created_service_2.Name)
}
if !makeIPNet(t).Contains(net.ParseIP(created_service_2.Spec.PortalIP)) {
t.Errorf("Unexpected PortalIP: %s", created_service_2.Spec.PortalIP)
if !makeIPNet(t).Contains(net.ParseIP(created_service_2.Spec.ClusterIP)) {
t.Errorf("Unexpected ClusterIP: %s", created_service_2.Spec.ClusterIP)
}
}
@@ -648,8 +648,8 @@ func TestServiceRegistryIPUpdate(t *testing.T) {
if created_service.Spec.Ports[0].Port != 6502 {
t.Errorf("Expected port 6502, but got %v", created_service.Spec.Ports[0].Port)
}
if !makeIPNet(t).Contains(net.ParseIP(created_service.Spec.PortalIP)) {
t.Errorf("Unexpected PortalIP: %s", created_service.Spec.PortalIP)
if !makeIPNet(t).Contains(net.ParseIP(created_service.Spec.ClusterIP)) {
t.Errorf("Unexpected ClusterIP: %s", created_service.Spec.ClusterIP)
}
update := deepCloneService(created_service)
@@ -663,7 +663,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) {
update = deepCloneService(created_service)
update.Spec.Ports[0].Port = 6503
update.Spec.PortalIP = "1.2.3.76" // error
update.Spec.ClusterIP = "1.2.3.76" // error
_, _, err := rest.Update(ctx, update)
if err == nil || !errors.IsInvalid(err) {
@@ -692,8 +692,8 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) {
if created_service.Spec.Ports[0].Port != 6502 {
t.Errorf("Expected port 6502, but got %v", created_service.Spec.Ports[0].Port)
}
if !makeIPNet(t).Contains(net.ParseIP(created_service.Spec.PortalIP)) {
t.Errorf("Unexpected PortalIP: %s", created_service.Spec.PortalIP)
if !makeIPNet(t).Contains(net.ParseIP(created_service.Spec.ClusterIP)) {
t.Errorf("Unexpected ClusterIP: %s", created_service.Spec.ClusterIP)
}
update := deepCloneService(created_service)
@@ -750,7 +750,7 @@ func TestCreate(t *testing.T) {
&api.Service{
Spec: api.ServiceSpec{
Selector: map[string]string{"bar": "baz"},
PortalIP: "None",
ClusterIP: "None",
SessionAffinity: "None",
Type: api.ServiceTypeClusterIP,
Ports: []api.ServicePort{{
@@ -767,7 +767,7 @@ func TestCreate(t *testing.T) {
&api.Service{
Spec: api.ServiceSpec{
Selector: map[string]string{"bar": "baz"},
PortalIP: "invalid",
ClusterIP: "invalid",
SessionAffinity: "None",
Type: api.ServiceTypeClusterIP,
Ports: []api.ServicePort{{