cmd/kg: only delete iface if requested

This commit modifies the default behavior of Kilo so that the WireGuard
interface is only deleted on shutdown if explicitly requested.

Fixes: https://github.com/squat/kilo/issues/17#issuecomment-534658157
This commit is contained in:
Lucas Servén Marín 2019-09-25 13:45:28 +02:00
parent e83db17d88
commit 3facc9f34f
No known key found for this signature in database
GPG Key ID: 586FEAF680DA74AD
2 changed files with 51 additions and 50 deletions

View File

@ -79,16 +79,17 @@ var (
// Main is the principal function for the binary, wrapped only by `main` for convenience. // Main is the principal function for the binary, wrapped only by `main` for convenience.
func Main() error { func Main() error {
backend := flag.String("backend", k8s.Backend, fmt.Sprintf("The backend for the mesh. Possible values: %s", availableBackends)) backend := flag.String("backend", k8s.Backend, fmt.Sprintf("The backend for the mesh. Possible values: %s", availableBackends))
cni := flag.Bool("cni", true, "Should Kilo manage the node's CNI configuration.") cleanUpIface := flag.Bool("clean-up-interface", false, "Should Kilo delete its interface when it shuts down?")
cni := flag.Bool("cni", true, "Should Kilo manage the node's CNI configuration?")
cniPath := flag.String("cni-path", mesh.DefaultCNIPath, "Path to CNI config.") cniPath := flag.String("cni-path", mesh.DefaultCNIPath, "Path to CNI config.")
compatibility := flag.String("compatibility", "", fmt.Sprintf("Should Kilo run in compatibility mode? Possible values: %s", availableCompatibilities)) compatibility := flag.String("compatibility", "", fmt.Sprintf("Should Kilo run in compatibility mode? Possible values: %s", availableCompatibilities))
encapsulate := flag.String("encapsulate", string(encapsulation.Always), fmt.Sprintf("When should Kilo encapsulate packets within a location. Possible values: %s", availableEncapsulations)) encapsulate := flag.String("encapsulate", string(encapsulation.Always), fmt.Sprintf("When should Kilo encapsulate packets within a location? Possible values: %s", availableEncapsulations))
granularity := flag.String("mesh-granularity", string(mesh.LogicalGranularity), fmt.Sprintf("The granularity of the network mesh to create. Possible values: %s", availableGranularities)) granularity := flag.String("mesh-granularity", string(mesh.LogicalGranularity), fmt.Sprintf("The granularity of the network mesh to create. Possible values: %s", availableGranularities))
kubeconfig := flag.String("kubeconfig", "", "Path to kubeconfig.") kubeconfig := flag.String("kubeconfig", "", "Path to kubeconfig.")
hostname := flag.String("hostname", "", "Hostname of the node on which this process is running.") hostname := flag.String("hostname", "", "Hostname of the node on which this process is running.")
iface := flag.String("interface", mesh.DefaultKiloInterface, "Name of the Kilo interface to use; if it does not exist, it will be created.") iface := flag.String("interface", mesh.DefaultKiloInterface, "Name of the Kilo interface to use; if it does not exist, it will be created.")
listen := flag.String("listen", ":1107", "The address at which to listen for health and metrics.") listen := flag.String("listen", ":1107", "The address at which to listen for health and metrics.")
local := flag.Bool("local", true, "Should Kilo manage routes within a location.") local := flag.Bool("local", true, "Should Kilo manage routes within a location?")
logLevel := flag.String("log-level", logLevelInfo, fmt.Sprintf("Log level to use. Possible values: %s", availableLogLevels)) logLevel := flag.String("log-level", logLevelInfo, fmt.Sprintf("Log level to use. Possible values: %s", availableLogLevels))
master := flag.String("master", "", "The address of the Kubernetes API server (overrides any value in kubeconfig).") master := flag.String("master", "", "The address of the Kubernetes API server (overrides any value in kubeconfig).")
var port uint var port uint
@ -175,7 +176,7 @@ func Main() error {
return fmt.Errorf("backend %v unknown; possible values are: %s", *backend, availableBackends) return fmt.Errorf("backend %v unknown; possible values are: %s", *backend, availableBackends)
} }
m, err := mesh.New(b, enc, gr, *hostname, uint32(port), s, *local, *cni, *cniPath, *iface, log.With(logger, "component", "kilo")) m, err := mesh.New(b, enc, gr, *hostname, uint32(port), s, *local, *cni, *cniPath, *iface, *cleanUpIface, log.With(logger, "component", "kilo"))
if err != nil { if err != nil {
return fmt.Errorf("failed to create Kilo mesh: %v", err) return fmt.Errorf("failed to create Kilo mesh: %v", err)
} }

View File

@ -169,27 +169,27 @@ type PeerBackend interface {
// Mesh is able to create Kilo network meshes. // Mesh is able to create Kilo network meshes.
type Mesh struct { type Mesh struct {
Backend Backend
cni bool cleanUpIface bool
cniPath string cni bool
deleteIface bool cniPath string
enc encapsulation.Encapsulator enc encapsulation.Encapsulator
externalIP *net.IPNet externalIP *net.IPNet
granularity Granularity granularity Granularity
hostname string hostname string
internalIP *net.IPNet internalIP *net.IPNet
ipTables *iptables.Controller ipTables *iptables.Controller
kiloIface int kiloIface int
key []byte key []byte
local bool local bool
port uint32 port uint32
priv []byte priv []byte
privIface int privIface int
pub []byte pub []byte
pubIface int pubIface int
stop chan struct{} stop chan struct{}
subnet *net.IPNet subnet *net.IPNet
table *route.Table table *route.Table
wireGuardIP *net.IPNet wireGuardIP *net.IPNet
// nodes and peers are mutable fields in the struct // nodes and peers are mutable fields in the struct
// and needs to be guarded. // and needs to be guarded.
@ -205,7 +205,7 @@ type Mesh struct {
} }
// New returns a new Mesh instance. // New returns a new Mesh instance.
func New(backend Backend, enc encapsulation.Encapsulator, granularity Granularity, hostname string, port uint32, subnet *net.IPNet, local, cni bool, cniPath, iface string, logger log.Logger) (*Mesh, error) { func New(backend Backend, enc encapsulation.Encapsulator, granularity Granularity, hostname string, port uint32, subnet *net.IPNet, local, cni bool, cniPath, iface string, cleanUpIface bool, logger log.Logger) (*Mesh, error) {
if err := os.MkdirAll(KiloPath, 0700); err != nil { if err := os.MkdirAll(KiloPath, 0700); err != nil {
return nil, fmt.Errorf("failed to create directory to store configuration: %v", err) return nil, fmt.Errorf("failed to create directory to store configuration: %v", err)
} }
@ -242,7 +242,7 @@ func New(backend Backend, enc encapsulation.Encapsulator, granularity Granularit
return nil, fmt.Errorf("failed to find interface for public IP: %v", err) return nil, fmt.Errorf("failed to find interface for public IP: %v", err)
} }
pubIface := ifaces[0].Index pubIface := ifaces[0].Index
kiloIface, created, err := wireguard.New(iface) kiloIface, _, err := wireguard.New(iface)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create WireGuard interface: %v", err) return nil, fmt.Errorf("failed to create WireGuard interface: %v", err)
} }
@ -258,28 +258,28 @@ func New(backend Backend, enc encapsulation.Encapsulator, granularity Granularit
return nil, fmt.Errorf("failed to IP tables controller: %v", err) return nil, fmt.Errorf("failed to IP tables controller: %v", err)
} }
return &Mesh{ return &Mesh{
Backend: backend, Backend: backend,
cni: cni, cleanUpIface: cleanUpIface,
cniPath: cniPath, cni: cni,
deleteIface: created, cniPath: cniPath,
enc: enc, enc: enc,
externalIP: publicIP, externalIP: publicIP,
granularity: granularity, granularity: granularity,
hostname: hostname, hostname: hostname,
internalIP: privateIP, internalIP: privateIP,
ipTables: ipTables, ipTables: ipTables,
kiloIface: kiloIface, kiloIface: kiloIface,
nodes: make(map[string]*Node), nodes: make(map[string]*Node),
peers: make(map[string]*Peer), peers: make(map[string]*Peer),
port: port, port: port,
priv: private, priv: private,
privIface: privIface, privIface: privIface,
pub: public, pub: public,
pubIface: pubIface, pubIface: pubIface,
local: local, local: local,
stop: make(chan struct{}), stop: make(chan struct{}),
subnet: subnet, subnet: subnet,
table: route.NewTable(), table: route.NewTable(),
errorCounter: prometheus.NewCounterVec(prometheus.CounterOpts{ errorCounter: prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "kilo_errors_total", Name: "kilo_errors_total",
Help: "Number of errors that occurred while administering the mesh.", Help: "Number of errors that occurred while administering the mesh.",
@ -717,7 +717,7 @@ func (m *Mesh) cleanUp() {
level.Error(m.logger).Log("error", fmt.Sprintf("failed to delete configuration file: %v", err)) level.Error(m.logger).Log("error", fmt.Sprintf("failed to delete configuration file: %v", err))
m.errorCounter.WithLabelValues("cleanUp").Inc() m.errorCounter.WithLabelValues("cleanUp").Inc()
} }
if m.deleteIface { if m.cleanUpIface {
if err := iproute.RemoveInterface(m.kiloIface); err != nil { if err := iproute.RemoveInterface(m.kiloIface); err != nil {
level.Error(m.logger).Log("error", fmt.Sprintf("failed to remove WireGuard interface: %v", err)) level.Error(m.logger).Log("error", fmt.Sprintf("failed to remove WireGuard interface: %v", err))
m.errorCounter.WithLabelValues("cleanUp").Inc() m.errorCounter.WithLabelValues("cleanUp").Inc()