Skip to content
This repository was archived by the owner on Aug 19, 2020. It is now read-only.
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions pkg/apis/keepalive/v1beta1/register.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package v1beta1

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)

// VirtualIP is a keepalived CRD specificiation for virtual IP addresses
type VirtualIP struct {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the intent with this CRD that every IP + interface -> Service:port mapping would have a separate definition? That would require quite a bit duplication by the user if they had multiple services on one IP. What about a way to select which services apply by labels?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the intent with this CRD that every IP + interface -> Service:port mapping would have a separate definition?

I changed the definition to a list of serviceReferences

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about instead of binding the virtual IP to services in a centralized spot in the CRD, we decentralize it to be an annotation on the service? The annotation would be reference back the CRD's metadata.name. For example:

apiVersion: v1
kind: Service
metadata:
  name: myservice
  annotations:
    keepalived/vip: myvipname
spec:
  externalIPs:
  - 10.0.22.170

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be even nicer if it could populate the externalIPs on the service object. MetalLB does something similar to what I'm suggesting using annotations and modifying service IP:

https://metallb.universe.tf/usage/

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am aware of the externalIPs field but using that also makes validation harder (I am thinking to add a webhook to avoid invalid configuration/duplicated IPs). Also using the service could lead to someone ask for externalTrafficPolicy support

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think people should be aware that externalTrafficPolicy does not apply to externalIPs. We can document it in the README if need be or point to kubernetes docs.

If populating externalIPs is difficult/error prone, what do you think about just the annotation idea to do service binding?

metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`

Spec VirtualIPSpec `json:"spec"`
Status Status `json:"status"`
}

// VirtualIPSpec defines the spec of the CRD in a vrrp_instance section
type VirtualIPSpec struct {
// Name defines the name of the vrrp_instance
Name string `json:"name"`

// IP virtual IP to use
IP string `json:"ip"`

// Interface interface where the virtual IP should be configured
// The default value is eth0
Interface *string `json:"interface,omitempty"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be better to detect by CIDR on machine with keepalived controller?

And then may be webhook, to check if interface exists?


// ServiceReferences defines a reference to the service to expose
ServiceReferences []ServiceReference `json:"serviceReferences"`

// VirtualRouterID arbitrary unique number from 0 to 255.
// Used to differentiate multiple instances of vrrpd running on the same NIC (and hence same socket)
VirtualRouterID int `json:"virtualRouterID"`
// Priority for electing MASTER, highest priority wins
// To be MASTER, make this 50 more than on other machines.
Priority int `json:"priority,omitempty"`
// DelayLoop delay timer for checker polling
// Default: 5
DelayLoop *int `json:"delayLoop,omitempty"`
// LVSScheduler LVS scheduler (rr|wrr|lc|wlc|lblc|sh|mh|dh|fo|ovf|lblcr|sed|nq)
// Default: rr
LVSScheduler *LVSScheduler `json:"lvsScheduler,omitempty"`
// LVSMethod default LVS forwarding method (NAT|DR)
// Default: NAT
LVSMethod *string `json:"lvsMethod,omitempty"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one also should be an enum.


// UseUnicast defines if unicast should be used instead of multicast (default) to publish vrrp packets
UseUnicast bool `json:"useUnicast,omitempty"`

// Notify defines a script for ANY state transition.
Notify *string `json:"notify,omitempty"`

// AdditionalConfiguration defines additional keepalived configuration valid inside the virtual_server section
AdditionalConfiguration *string `json:"additionalConfiguration,omitempty"`
}

// Status reports the current state of the VirtualIP
type Status struct {
CurrentStatus string `json:"currentStatus"`
Description string `json:"description"`
}

// ServiceReference holds a reference to Service.legacy.k8s.io
type ServiceReference struct {
// Namespace is the namespace of the service
Namespace string `json:"namespace,omitempty"`

// Name is the name of the service
Name string `json:"name,omitempty"`

// Port of the service
Port intstr.IntOrString `json:"port,omitempty"`

//Protocol defines the protocol of the service. Valid values are TCP and UDP
Protocol corev1.Protocol `json:"protocol"`

// ProxyProtocol indicates if proxy-protocol is enabled in the service being exposed
// Valid only for TCP protocol
ProxyProtocol bool `json:"proxyProtocol"`
}

// LVSScheduler LVS scheduler (rr|wrr|lc|wlc|lblc|sh|mh|dh|fo|ovf|lblcr|sed|nq)
type LVSScheduler string

const (
Copy link
Copy Markdown
Contributor

@panpan0000 panpan0000 Apr 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems keepalived supports moer than 4
https://www.keepalived.org/doc/configuration_synopsis.html#virtual-server-definitions-synopsis
it says lb_algo can be rr|wrr|lc|wlc|sh|dh|lblc ?

RRScheduler LVSScheduler = "rr"
WRRScheduler LVSScheduler = "wrr"
LCScheduler LVSScheduler = "lc"
WLCScheduler LVSScheduler = "wlc"
)