mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/kube-vip/kube-vip.git
synced 2026-09-20 08:03:47 +08:00
This fixes numerous issues
- Adds the CIDR to the VIP, needed for BGP - Seperates the EIP association to a seperate function making leader Election code clearer - Fixes to environment variable names - Clean un-needed `fatalf` errors - Added additional comments
This commit is contained in:
@@ -33,11 +33,15 @@ func init() {
|
||||
//initConfig.Peers = append(initConfig.Peers, *localpeer)
|
||||
kubeKubeadm.PersistentFlags().StringVar(&initConfig.Interface, "interface", "", "Name of the interface to bind to")
|
||||
kubeKubeadm.PersistentFlags().StringVar(&initConfig.VIP, "vip", "", "The Virtual IP address")
|
||||
kubeKubeadm.PersistentFlags().BoolVar(&initConfig.StartAsLeader, "startAsLeader", false, "Start this instance as the cluster leader")
|
||||
|
||||
kubeKubeadm.PersistentFlags().BoolVar(&initConfig.AddPeersAsBackends, "addPeersToLB", true, "The Virtual IP address")
|
||||
kubeKubeadm.PersistentFlags().StringVar(&initConfig.VIPCIDR, "cidr", "", "The CIDR range for the virtual IP address")
|
||||
kubeKubeadm.PersistentFlags().BoolVar(&initConfig.GratuitousARP, "arp", true, "Enable Arp for Vip changes")
|
||||
|
||||
// Clustering type (leaderElection/raft)
|
||||
kubeKubeadm.PersistentFlags().BoolVar(&initConfig.EnableLeaderElection, "leaderElection", false, "Use the Kubernetes leader election mechanism for clustering")
|
||||
kubeKubeadm.PersistentFlags().BoolVar(&initConfig.StartAsLeader, "startAsLeader", false, "Start this instance as the cluster leader")
|
||||
kubeKubeadm.PersistentFlags().BoolVar(&initConfig.AddPeersAsBackends, "addPeersToLB", true, "Add raft peers to the load-balancer")
|
||||
|
||||
// Packet flags
|
||||
kubeKubeadm.PersistentFlags().BoolVar(&initConfig.EnablePacket, "packet", false, "This will use the Packet API (requires the token ENV) to update the EIP <-> VIP")
|
||||
kubeKubeadm.PersistentFlags().StringVar(&initConfig.PacketAPIKey, "packetKey", "", "The API token for authenticating with the Packet API")
|
||||
kubeKubeadm.PersistentFlags().StringVar(&initConfig.PacketProject, "packetProject", "", "The name of project already created within Packet")
|
||||
@@ -52,7 +56,6 @@ func init() {
|
||||
|
||||
// BGP flags
|
||||
kubeKubeadm.PersistentFlags().BoolVar(&initConfig.EnableBGP, "bgp", false, "This will enable BGP support within kube-vip")
|
||||
|
||||
kubeKubeadm.PersistentFlags().StringVar(&initConfig.BGPConfig.RouterID, "bgpRouterID", "", "The routerID for the bgp server")
|
||||
kubeKubeadm.PersistentFlags().Uint32Var(&initConfig.BGPConfig.AS, "localAS", 65000, "The local AS number for the bgp server")
|
||||
kubeKubeadm.PersistentFlags().StringVar(&initConfig.BGPPeerConfig.Address, "peerAddress", "", "The address of a BGP peer")
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@@ -88,6 +87,7 @@ func (cluster *Cluster) StartLeaderCluster(c *kubevip.Config, sm *Manager) error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("Beginning cluster membership, namespace [%s], lock name [%s], id [%s]", namespace, plunderLock, id)
|
||||
|
||||
// we use the Lease lock type since edits to Leases are less common
|
||||
@@ -202,58 +202,27 @@ func (cluster *Cluster) StartLeaderCluster(c *kubevip.Config, sm *Manager) error
|
||||
log.Error(err)
|
||||
}
|
||||
} else {
|
||||
|
||||
projects, _, err := packetClient.Projects.List(nil)
|
||||
// If not attempt to attach the EIP in the standard manner
|
||||
log.Debugf("Attaching the Packet EIP through the API to this host")
|
||||
err = packet.AttachEIP(packetClient, c, id)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
for _, p := range projects {
|
||||
log.Println(p.ID, p.Name)
|
||||
|
||||
// Find our project
|
||||
if p.Name == c.PacketProject {
|
||||
ips, _, _ := packetClient.ProjectIPs.List(p.ID)
|
||||
for _, ip := range ips {
|
||||
|
||||
// Find the device id for our EIP
|
||||
if ip.Address == c.VIP {
|
||||
log.Infof("Found EIP ->%s ID -> %s\n", ip.Address, ip.ID)
|
||||
|
||||
if len(ip.Assignments) != 0 {
|
||||
hrefID := strings.Replace(ip.Assignments[0].Href, "/ips/", "", -1)
|
||||
packetClient.DeviceIPs.Unassign(hrefID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Go through devices
|
||||
dev, _, _ := packetClient.Devices.List(p.ID, &packngo.ListOptions{})
|
||||
for _, d := range dev {
|
||||
|
||||
if d.Hostname == id {
|
||||
log.Infof("Assigning EIP to -> %s\n", d.Hostname)
|
||||
_, _, err := packetClient.DeviceIPs.Assign(d.ID, &packngo.AddressStruct{
|
||||
Address: c.VIP,
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if c.EnableBGP {
|
||||
// Lets start BGP
|
||||
log.Debugf("Starting the BGP server to adverise VIP routes to VGP peers")
|
||||
bgpServer, err = bgp.NewBGPServer(&c.BGPConfig)
|
||||
|
||||
// Lets advertise the EIP over BGP
|
||||
err = bgpServer.AddHost(c.VIP)
|
||||
// Lets advertise the EIP over BGP, the host needs to be passed using CIDR notation
|
||||
cidrVip := fmt.Sprintf("%s/%s", c.VIP, c.VIPCIDR)
|
||||
log.Debugf("Attempting to advertise the address [%s] over BGP", cidrVip)
|
||||
|
||||
err = bgpServer.AddHost(cidrVip)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,6 +309,7 @@ func (cluster *Cluster) StartLeaderCluster(c *kubevip.Config, sm *Manager) error
|
||||
|
||||
//<-signalChan
|
||||
log.Infof("Shutting down Kube-Vip Leader Election cluster")
|
||||
|
||||
// Force a removal of the VIP (ignore the error if we don't have it)
|
||||
cluster.network.DeleteIP()
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@ const (
|
||||
//vipAddress - defines the address that the vip will expose
|
||||
vipAddress = "vip_address"
|
||||
|
||||
//vipCidr - defines the cidr that the vip will use
|
||||
vipCidr = "vip_cidr"
|
||||
|
||||
//vipSingleNode - defines the vip start as a single node cluster
|
||||
vipSingleNode = "vip_singlenode"
|
||||
|
||||
@@ -56,7 +59,7 @@ const (
|
||||
//bgpEnable defines if BGP should be enabled
|
||||
bgpEnable = "bgp_enable"
|
||||
//bgpRouterID defines the routerID for the BGP server
|
||||
bgpRouterID = "bgp_routerID"
|
||||
bgpRouterID = "bgp_routerid"
|
||||
//bgpRouterAS defines the AS for the BGP server
|
||||
bgpRouterAS = "bgp_as"
|
||||
//bgpPeerAddress defines the address for a BGP peer
|
||||
@@ -115,6 +118,13 @@ func ParseEnvironment(c *Config) error {
|
||||
c.VIP = env
|
||||
}
|
||||
|
||||
// Find vip address cidr range
|
||||
env = os.Getenv(c.VIPCIDR)
|
||||
if env != "" {
|
||||
// TODO - parse address net.Host()
|
||||
c.VIPCIDR = env
|
||||
}
|
||||
|
||||
// Find Single Node
|
||||
env = os.Getenv(vipSingleNode)
|
||||
if env != "" {
|
||||
@@ -360,6 +370,20 @@ func GenerateManifestFromConfig(c *Config, imageVersion string) string {
|
||||
},
|
||||
}
|
||||
|
||||
// If a CIDR is used add it to the manifest
|
||||
if c.VIPCIDR != "" {
|
||||
// build environment variables
|
||||
cidr := []appv1.EnvVar{
|
||||
{
|
||||
Name: vipCidr,
|
||||
Value: c.VIPCIDR,
|
||||
},
|
||||
}
|
||||
newEnvironment = append(newEnvironment, cidr...)
|
||||
|
||||
}
|
||||
|
||||
// If Leader election is enabled then add the configuration to the manifest
|
||||
if !c.EnableLeaderElection {
|
||||
raft := []appv1.EnvVar{
|
||||
{
|
||||
@@ -378,6 +402,8 @@ func GenerateManifestFromConfig(c *Config, imageVersion string) string {
|
||||
newEnvironment = append(newEnvironment, raft...)
|
||||
|
||||
}
|
||||
|
||||
// If Packet is enabled then add it to the manifest
|
||||
if c.EnablePacket {
|
||||
packet := []appv1.EnvVar{
|
||||
{
|
||||
@@ -397,6 +423,7 @@ func GenerateManifestFromConfig(c *Config, imageVersion string) string {
|
||||
|
||||
}
|
||||
|
||||
// If BGP is enabled then add it to the manifest
|
||||
if c.EnableBGP {
|
||||
bgp := []appv1.EnvVar{
|
||||
{
|
||||
@@ -424,6 +451,7 @@ func GenerateManifestFromConfig(c *Config, imageVersion string) string {
|
||||
|
||||
}
|
||||
|
||||
// If the load-balancer is enabled then add the configuration to the manifest
|
||||
if c.EnableLoadBalancer {
|
||||
lb := []appv1.EnvVar{
|
||||
{
|
||||
|
||||
@@ -24,6 +24,9 @@ type Config struct {
|
||||
// VIP is the Virtual IP address exposed for the cluster
|
||||
VIP string `yaml:"vip"`
|
||||
|
||||
// VIPCIDR is cidr range for the VIP (primarily needed for BGP)
|
||||
VIPCIDR string `yaml:"vipCidr"`
|
||||
|
||||
// GratuitousARP will broadcast an ARP update when the VIP changes host
|
||||
GratuitousARP bool `yaml:"gratuitousARP"`
|
||||
|
||||
|
||||
@@ -17,18 +17,24 @@ func BGPLookup(c *packngo.Client, k *kubevip.Config) error {
|
||||
}
|
||||
thisDevice := findSelf(c, proj.ID)
|
||||
if thisDevice == nil {
|
||||
return fmt.Errorf("Unable to find correct device")
|
||||
return fmt.Errorf("Unable to find local/this device in packet API")
|
||||
}
|
||||
|
||||
fmt.Printf("Querying BGP settings for [%s]", thisDevice.Hostname)
|
||||
neighbours, _, _ := c.Devices.ListBGPNeighbors(thisDevice.ID, &packngo.ListOptions{})
|
||||
if len(neighbours) > 1 {
|
||||
return fmt.Errorf("There are [%s] neighbours, only designed to manage one", len(neighbours))
|
||||
return fmt.Errorf("There are [%d] neighbours, only designed to manage one", len(neighbours))
|
||||
}
|
||||
k.BGPConfig.RouterID = neighbours[0].CustomerIP
|
||||
k.BGPConfig.AS = uint32(neighbours[0].CustomerAs)
|
||||
|
||||
// Add the peer
|
||||
k.BGPConfig.Peers = []bgp.Peer{bgp.Peer{Address: neighbours[0].PeerIps[0], AS: uint32(neighbours[0].PeerAs)}}
|
||||
k.BGPConfig.Peers = []bgp.Peer{
|
||||
{
|
||||
Address: neighbours[0].PeerIps[0],
|
||||
AS: uint32(neighbours[0].PeerAs),
|
||||
},
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1 +1,51 @@
|
||||
package packet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/packethost/packngo"
|
||||
"github.com/plunder-app/kube-vip/pkg/kubevip"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// AttachEIP will use the packet APIs to move an EIP and attach to a host
|
||||
func AttachEIP(c *packngo.Client, k *kubevip.Config, hostname string) error {
|
||||
|
||||
// Find our project
|
||||
proj := findProject(k.PacketProject, c)
|
||||
if proj == nil {
|
||||
return fmt.Errorf("Unable to find Project [%s]", k.PacketProject)
|
||||
}
|
||||
|
||||
ips, _, _ := c.ProjectIPs.List(proj.ID)
|
||||
for _, ip := range ips {
|
||||
|
||||
// Find the device id for our EIP
|
||||
if ip.Address == k.VIP {
|
||||
log.Infof("Found EIP ->%s ID -> %s\n", ip.Address, ip.ID)
|
||||
// If attachements already exist then remove them
|
||||
if len(ip.Assignments) != 0 {
|
||||
hrefID := strings.Replace(ip.Assignments[0].Href, "/ips/", "", -1)
|
||||
c.DeviceIPs.Unassign(hrefID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lookup this server through the packet API
|
||||
thisDevice := findSelf(c, proj.ID)
|
||||
if thisDevice == nil {
|
||||
return fmt.Errorf("Unable to find local/this device in packet API")
|
||||
}
|
||||
|
||||
// Assign the EIP to this device
|
||||
log.Infof("Assigning EIP to -> %s\n", thisDevice.Hostname)
|
||||
_, _, err := c.DeviceIPs.Assign(thisDevice.ID, &packngo.AddressStruct{
|
||||
Address: k.VIP,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user