mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/kube-vip/kube-vip.git
synced 2026-09-20 08:03:47 +08:00
160 lines
5.4 KiB
Go
160 lines
5.4 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
log "log/slog"
|
|
|
|
"github.com/kube-vip/kube-vip/pkg/kubevip"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// kubeadm adds two subcommands for managing a vip during a kubeadm init/join
|
|
// It is designed to operate "light" and take minimal input to start
|
|
|
|
func init() {
|
|
kubeKubeadmJoin.Flags().StringVar(&kubeConfigPath, "config", "/etc/kubernetes/admin.conf", "The path of a Kubernetes configuration file")
|
|
|
|
kubeKubeadm.AddCommand(kubeKubeadmInit)
|
|
kubeKubeadm.AddCommand(kubeKubeadmJoin)
|
|
}
|
|
|
|
var kubeKubeadm = &cobra.Command{
|
|
Use: "kubeadm",
|
|
Short: "Kubeadm functions",
|
|
Long: `This command group provides utilities for generating static Pod manifests specifically tailored for the kubeadm bootstrapping process.
|
|
It contains two subcommands:
|
|
- init: Generates a manifest to be used during 'kubeadm init' on the first control-plane node.
|
|
- join: Generates a manifest to be used during 'kubeadm join' for additional control-plane nodes.
|
|
|
|
The generated YAML manifest should be saved to the kubeadm static Pod directory (typically /etc/kubernetes/manifests/) so that kubeadm launches the kube-vip static Pod automatically.`,
|
|
Run: func(cmd *cobra.Command, _ []string) {
|
|
_ = cmd.Help()
|
|
},
|
|
}
|
|
|
|
var kubeKubeadmInit = &cobra.Command{
|
|
Use: "init",
|
|
Short: "kube-vip init",
|
|
Long: `The 'init' subcommand generates a Kubernetes Pod manifest that kubeadm will start as a static Pod during the cluster initialisation phase.
|
|
|
|
This manifest runs kube-vip on the first control-plane node to advertise the Virtual IP (VIP) for the API server. The VIP is typically configured using ARP (Layer 2) or BGP (dynamic routing).
|
|
|
|
Required flags for this command:
|
|
--interface : The network interface to bind the VIP to (e.g., eth0).
|
|
--vip or --address : The Virtual IP address or DNS name to use.
|
|
|
|
Example:
|
|
kube-vip kubeadm init --interface eth0 --vip 192.168.1.100 --controlplane
|
|
|
|
The output YAML should be written to the kubeadm manifests directory, e.g.:
|
|
kube-vip kubeadm init ... > /etc/kubernetes/manifests/kube-vip.yaml`,
|
|
Run: func(cmd *cobra.Command, _ []string) {
|
|
|
|
initConfig.LoadBalancers = append(initConfig.LoadBalancers, initLoadBalancer)
|
|
err := kubevip.ParseEnvironment(&initConfig)
|
|
if err != nil {
|
|
log.Error("parsing environment", "err", err)
|
|
return
|
|
}
|
|
if err := initConfig.Validate(); err != nil {
|
|
log.Error("validating configuration", "err", err)
|
|
return
|
|
}
|
|
|
|
// TODO - check for certain things VIP/interfaces
|
|
if initConfig.Interface == "" {
|
|
_ = cmd.Help()
|
|
log.Error("No interface is specified for kube-vip to bind to")
|
|
return
|
|
}
|
|
|
|
if initConfig.VIP == "" && initConfig.Address == "" {
|
|
_ = cmd.Help()
|
|
log.Error("No address is specified for kube-vip to expose services on")
|
|
return
|
|
}
|
|
|
|
// Ensure there is an address to generate the CIDR from
|
|
if initConfig.VIPSubnet == "" && initConfig.Address != "" {
|
|
initConfig.VIPSubnet, err = GenerateCidrRange(initConfig.Address, initConfig.DNSMode)
|
|
if err != nil {
|
|
log.Error("generating VIPSubnet", "err", err)
|
|
return
|
|
}
|
|
}
|
|
|
|
cfg, err := kubevip.GeneratePodManifestFromConfig(&initConfig, image, Release.Version, inCluster)
|
|
if err != nil {
|
|
log.Error("unable to create manifest", "err", err)
|
|
return
|
|
}
|
|
fmt.Println(cfg) // output manifest to stdout
|
|
},
|
|
}
|
|
|
|
var kubeKubeadmJoin = &cobra.Command{
|
|
Use: "join",
|
|
Short: "kube-vip join",
|
|
Long: `The 'join' subcommand generates a Kubernetes Pod manifest for additional control-plane nodes joining an existing cluster via 'kubeadm join'.
|
|
|
|
It functions identically to the 'init' subcommand, but is intended for secondary control-plane nodes. It validates that the kubeconfig file (specified by --config, defaulting to /etc/kubernetes/admin.conf) exists on the node to ensure the node can authenticate with the cluster.
|
|
|
|
Required flags for this command:
|
|
--interface : The network interface to bind the VIP to.
|
|
--vip or --address : The Virtual IP address or DNS name (must match the VIP used during 'init').
|
|
|
|
Example:
|
|
kube-vip kubeadm join --interface eth0 --vip 192.168.1.100
|
|
|
|
The output YAML should be saved to the kubeadm manifests directory on the joining node.`,
|
|
Run: func(cmd *cobra.Command, _ []string) {
|
|
|
|
initConfig.LoadBalancers = append(initConfig.LoadBalancers, initLoadBalancer)
|
|
err := kubevip.ParseEnvironment(&initConfig)
|
|
if err != nil {
|
|
log.Error("parsing environment", "err", err)
|
|
return
|
|
}
|
|
if err := initConfig.Validate(); err != nil {
|
|
log.Error("validating configuration", "err", err)
|
|
return
|
|
}
|
|
|
|
// TODO - check for certain things VIP/interfaces
|
|
if initConfig.Interface == "" {
|
|
_ = cmd.Help()
|
|
log.Error("No interface is specified for kube-vip to bind to")
|
|
return
|
|
}
|
|
|
|
if initConfig.VIP == "" && initConfig.Address == "" {
|
|
_ = cmd.Help()
|
|
log.Error("No address is specified for kube-vip to expose services on")
|
|
return
|
|
}
|
|
|
|
if _, err := os.Stat(kubeConfigPath); os.IsNotExist(err) {
|
|
log.Error("kubeConfig not found", "Path", kubeConfigPath)
|
|
return
|
|
}
|
|
|
|
// Ensure there is an address to generate the CIDR from
|
|
if initConfig.VIPSubnet == "" && initConfig.Address != "" {
|
|
initConfig.VIPSubnet, err = GenerateCidrRange(initConfig.Address, initConfig.DNSMode)
|
|
if err != nil {
|
|
log.Error("generating VIPSubnet", "err", err)
|
|
return
|
|
}
|
|
}
|
|
|
|
cfg, err := kubevip.GeneratePodManifestFromConfig(&initConfig, image, Release.Version, inCluster)
|
|
if err != nil {
|
|
log.Error("unable to create manifest", "err", err)
|
|
return
|
|
}
|
|
fmt.Println(cfg) // output manifest to stdout
|
|
},
|
|
}
|