Build backend config using the K8S endpoint resource.
* Potentialy saves a network hop * Ability to configure LB algothim (given some work to expose an anotation etc...) * K8s config Watch is triggered far less often
This commit is contained in:
parent
b79535f369
commit
e948a013cd
4 changed files with 210 additions and 42 deletions
|
@ -22,6 +22,7 @@ const (
|
|||
type Client interface {
|
||||
GetIngresses(predicate func(Ingress) bool) ([]Ingress, error)
|
||||
GetServices(predicate func(Service) bool) ([]Service, error)
|
||||
GetEndpoints(name, namespace string) (Endpoints, error)
|
||||
WatchAll(stopCh <-chan bool) (chan interface{}, chan error, error)
|
||||
}
|
||||
|
||||
|
@ -104,21 +105,26 @@ func (c *clientImpl) WatchServices(stopCh <-chan bool) (chan interface{}, chan e
|
|||
return c.watch(getURL, stopCh)
|
||||
}
|
||||
|
||||
// WatchEvents returns events in the cluster
|
||||
func (c *clientImpl) WatchEvents(stopCh <-chan bool) (chan interface{}, chan error, error) {
|
||||
getURL := c.endpointURL + APIEndpoint + "/events"
|
||||
return c.watch(getURL, stopCh)
|
||||
// GetEndpoints returns the named Endpoints
|
||||
// Endpoints have the same name as the coresponding service
|
||||
func (c *clientImpl) GetEndpoints(name, namespace string) (Endpoints, error) {
|
||||
getURL := c.endpointURL + APIEndpoint + "/namespaces/" + namespace + "/endpoints/" + name
|
||||
|
||||
body, err := c.do(c.request(getURL))
|
||||
if err != nil {
|
||||
return Endpoints{}, fmt.Errorf("failed to create endpoints request: GET %q : %v", getURL, err)
|
||||
}
|
||||
|
||||
var endpoints Endpoints
|
||||
if err := json.Unmarshal(body, &endpoints); err != nil {
|
||||
return Endpoints{}, fmt.Errorf("failed to decode endpoints resources: %v", err)
|
||||
}
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
// WatchPods returns pods in the cluster
|
||||
func (c *clientImpl) WatchPods(stopCh <-chan bool) (chan interface{}, chan error, error) {
|
||||
getURL := c.endpointURL + APIEndpoint + "/pods"
|
||||
return c.watch(getURL, stopCh)
|
||||
}
|
||||
|
||||
// WatchReplicationControllers returns ReplicationControllers in the cluster
|
||||
func (c *clientImpl) WatchReplicationControllers(stopCh <-chan bool) (chan interface{}, chan error, error) {
|
||||
getURL := c.endpointURL + APIEndpoint + "/replicationcontrollers"
|
||||
// WatchEndpoints returns endpoints in the cluster
|
||||
func (c *clientImpl) WatchEndpoints(stopCh <-chan bool) (chan interface{}, chan error, error) {
|
||||
getURL := c.endpointURL + APIEndpoint + "/endpoints"
|
||||
return c.watch(getURL, stopCh)
|
||||
}
|
||||
|
||||
|
@ -137,13 +143,8 @@ func (c *clientImpl) WatchAll(stopCh <-chan bool) (chan interface{}, chan error,
|
|||
if err != nil {
|
||||
return watchCh, errCh, fmt.Errorf("failed to create watch: %v", err)
|
||||
}
|
||||
stopPods := make(chan bool)
|
||||
chanPods, chanPodsErr, err := c.WatchPods(stopPods)
|
||||
if err != nil {
|
||||
return watchCh, errCh, fmt.Errorf("failed to create watch: %v", err)
|
||||
}
|
||||
stopReplicationControllers := make(chan bool)
|
||||
chanReplicationControllers, chanReplicationControllersErr, err := c.WatchReplicationControllers(stopReplicationControllers)
|
||||
stopEndpoints := make(chan bool)
|
||||
chanEndpoints, chanEndpointsErr, err := c.WatchEndpoints(stopEndpoints)
|
||||
if err != nil {
|
||||
return watchCh, errCh, fmt.Errorf("failed to create watch: %v", err)
|
||||
}
|
||||
|
@ -152,32 +153,26 @@ func (c *clientImpl) WatchAll(stopCh <-chan bool) (chan interface{}, chan error,
|
|||
defer close(errCh)
|
||||
defer close(stopIngresses)
|
||||
defer close(stopServices)
|
||||
defer close(stopPods)
|
||||
defer close(stopReplicationControllers)
|
||||
defer close(stopEndpoints)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-stopCh:
|
||||
stopIngresses <- true
|
||||
stopServices <- true
|
||||
stopPods <- true
|
||||
stopReplicationControllers <- true
|
||||
stopEndpoints <- true
|
||||
return
|
||||
case err := <-chanIngressesErr:
|
||||
errCh <- err
|
||||
case err := <-chanServicesErr:
|
||||
errCh <- err
|
||||
case err := <-chanPodsErr:
|
||||
errCh <- err
|
||||
case err := <-chanReplicationControllersErr:
|
||||
case err := <-chanEndpointsErr:
|
||||
errCh <- err
|
||||
case event := <-chanIngresses:
|
||||
watchCh <- event
|
||||
case event := <-chanServices:
|
||||
watchCh <- event
|
||||
case event := <-chanPods:
|
||||
watchCh <- event
|
||||
case event := <-chanReplicationControllers:
|
||||
case event := <-chanEndpoints:
|
||||
watchCh <- event
|
||||
}
|
||||
}
|
||||
|
|
84
provider/k8s/endpoints.go
Normal file
84
provider/k8s/endpoints.go
Normal file
|
@ -0,0 +1,84 @@
|
|||
package k8s
|
||||
|
||||
// Endpoints is a collection of endpoints that implement the actual service. Example:
|
||||
// Name: "mysvc",
|
||||
// Subsets: [
|
||||
// {
|
||||
// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}],
|
||||
// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}]
|
||||
// },
|
||||
// {
|
||||
// Addresses: [{"ip": "10.10.3.3"}],
|
||||
// Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}]
|
||||
// },
|
||||
// ]
|
||||
type Endpoints struct {
|
||||
TypeMeta `json:",inline"`
|
||||
ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// The set of all endpoints is the union of all subsets.
|
||||
Subsets []EndpointSubset
|
||||
}
|
||||
|
||||
// EndpointSubset is a group of addresses with a common set of ports. The
|
||||
// expanded set of endpoints is the Cartesian product of Addresses x Ports.
|
||||
// For example, given:
|
||||
// {
|
||||
// Addresses: [{"ip": "10.10.1.1"}, {"ip": "10.10.2.2"}],
|
||||
// Ports: [{"name": "a", "port": 8675}, {"name": "b", "port": 309}]
|
||||
// }
|
||||
// The resulting set of endpoints can be viewed as:
|
||||
// a: [ 10.10.1.1:8675, 10.10.2.2:8675 ],
|
||||
// b: [ 10.10.1.1:309, 10.10.2.2:309 ]
|
||||
type EndpointSubset struct {
|
||||
Addresses []EndpointAddress
|
||||
NotReadyAddresses []EndpointAddress
|
||||
Ports []EndpointPort
|
||||
}
|
||||
|
||||
// EndpointAddress is a tuple that describes single IP address.
|
||||
type EndpointAddress struct {
|
||||
// The IP of this endpoint.
|
||||
// IPv6 is also accepted but not fully supported on all platforms. Also, certain
|
||||
// kubernetes components, like kube-proxy, are not IPv6 ready.
|
||||
// TODO: This should allow hostname or IP, see #4447.
|
||||
IP string
|
||||
// Optional: Hostname of this endpoint
|
||||
// Meant to be used by DNS servers etc.
|
||||
Hostname string `json:"hostname,omitempty"`
|
||||
// Optional: The kubernetes object related to the entry point.
|
||||
TargetRef *ObjectReference
|
||||
}
|
||||
|
||||
// EndpointPort is a tuple that describes a single port.
|
||||
type EndpointPort struct {
|
||||
// The name of this port (corresponds to ServicePort.Name). Optional
|
||||
// if only one port is defined. Must be a DNS_LABEL.
|
||||
Name string
|
||||
|
||||
// The port number.
|
||||
Port int32
|
||||
|
||||
// The IP protocol for this port.
|
||||
Protocol Protocol
|
||||
}
|
||||
|
||||
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||
type ObjectReference struct {
|
||||
Kind string `json:"kind,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
UID UID `json:"uid,omitempty"`
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
ResourceVersion string `json:"resourceVersion,omitempty"`
|
||||
|
||||
// Optional. If referring to a piece of an object instead of an entire object, this string
|
||||
// should contain information to identify the sub-object. For example, if the object
|
||||
// reference is to a container within a pod, this would take on a value like:
|
||||
// "spec.containers{name}" (where "name" refers to the name of the container that triggered
|
||||
// the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
// index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
// referencing a part of an object.
|
||||
// TODO: this design is not final and this field is subject to change in the future.
|
||||
FieldPath string `json:"fieldPath,omitempty"`
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue