mirror of
https://github.com/k3s-io/k3s.git
synced 2026-05-26 19:46:52 -04:00
Some checks are pending
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run
Allow the executor to modify node config before certs are generated, and use this to add VPN node IPs to kubelet serving cert
136 lines
4.1 KiB
Go
136 lines
4.1 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
|
|
"github.com/k3s-io/k3s/pkg/agent"
|
|
"github.com/k3s-io/k3s/pkg/agent/https"
|
|
"github.com/k3s-io/k3s/pkg/cli/cmds"
|
|
"github.com/k3s-io/k3s/pkg/daemons/config"
|
|
"github.com/k3s-io/k3s/pkg/datadir"
|
|
k3smetrics "github.com/k3s-io/k3s/pkg/metrics"
|
|
"github.com/k3s-io/k3s/pkg/proctitle"
|
|
"github.com/k3s-io/k3s/pkg/profile"
|
|
"github.com/k3s-io/k3s/pkg/signals"
|
|
"github.com/k3s-io/k3s/pkg/spegel"
|
|
"github.com/k3s-io/k3s/pkg/util"
|
|
"github.com/k3s-io/k3s/pkg/util/errors"
|
|
"github.com/k3s-io/k3s/pkg/util/logger"
|
|
"github.com/k3s-io/k3s/pkg/util/mux"
|
|
"github.com/k3s-io/k3s/pkg/util/permissions"
|
|
"github.com/k3s-io/k3s/pkg/version"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/urfave/cli/v2"
|
|
"k8s.io/klog/v2"
|
|
)
|
|
|
|
func Run(clx *cli.Context) (rerr error) {
|
|
// Validate build env
|
|
cmds.MustValidateGolang()
|
|
|
|
// hide process arguments from ps output, since they may contain
|
|
// database credentials or other secrets.
|
|
proctitle.SetProcTitle(os.Args[0] + " agent")
|
|
|
|
// Evacuate cgroup v2 before doing anything else that may fork.
|
|
if err := cmds.EvacuateCgroup2(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Initialize logging, and subprocess reaping if necessary.
|
|
// Log output redirection and subprocess reaping both require forking.
|
|
if err := cmds.InitLogging(); err != nil {
|
|
return err
|
|
}
|
|
|
|
klog.EnableContextualLogging(true)
|
|
ctx := logger.NewContext(signals.SetupSignalContext(), version.Program)
|
|
wg := &sync.WaitGroup{}
|
|
|
|
// If exiting due to an error, ensure that contexts are cancelled so that the
|
|
// WaitGroup exits. Otherwise, wait for something else to initiate shutdown.
|
|
defer func() {
|
|
if rerr != nil {
|
|
// do not need to pass the error in here, it will be reported by the CLI error handler
|
|
signals.RequestShutdown(nil)
|
|
} else {
|
|
<-ctx.Done()
|
|
rerr = ctx.Err()
|
|
}
|
|
wg.Wait()
|
|
}()
|
|
|
|
if !cmds.AgentConfig.Rootless {
|
|
if err := permissions.IsPrivileged(); err != nil {
|
|
return errors.WithMessage(err, "agent requires additional privilege if not run with --rootless")
|
|
}
|
|
}
|
|
|
|
if cmds.AgentConfig.TokenFile != "" {
|
|
token, err := util.ReadFile(ctx, cmds.AgentConfig.TokenFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cmds.AgentConfig.Token = token
|
|
}
|
|
|
|
clientKubeletCert := filepath.Join(cmds.AgentConfig.DataDir, "agent", "client-kubelet.crt")
|
|
clientKubeletKey := filepath.Join(cmds.AgentConfig.DataDir, "agent", "client-kubelet.key")
|
|
_, err := tls.LoadX509KeyPair(clientKubeletCert, clientKubeletKey)
|
|
|
|
if err != nil && cmds.AgentConfig.Token == "" {
|
|
return errors.New("--token is required")
|
|
}
|
|
|
|
if cmds.AgentConfig.ServerURL == "" {
|
|
return errors.New("--server is required")
|
|
}
|
|
|
|
if cmds.AgentConfig.FlannelIface != "" && len(cmds.AgentConfig.NodeIP.Value()) == 0 {
|
|
ip, err := util.GetIPFromInterface(cmds.AgentConfig.FlannelIface)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cmds.AgentConfig.NodeIP.Set(ip)
|
|
}
|
|
|
|
logrus.Info("Starting " + version.Program + " agent " + clx.App.Version)
|
|
|
|
dataDir, err := datadir.LocalHome(cmds.AgentConfig.DataDir, cmds.AgentConfig.Rootless)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
cfg := cmds.AgentConfig
|
|
cfg.Debug = clx.Bool("debug")
|
|
cfg.DataDir = dataDir
|
|
|
|
go cmds.WriteCoverage(ctx)
|
|
|
|
// Until the agent is run and retrieves config from the server, we won't know
|
|
// if the embedded registry is enabled. If it is not enabled, these are not
|
|
// used as the registry is never started.
|
|
registry := spegel.DefaultRegistry
|
|
registry.Bootstrapper = spegel.NewAgentBootstrapper(cfg.ServerURL, cfg.Token, cfg.DataDir)
|
|
registry.Router = func(ctx context.Context, nodeConfig *config.Node) (*mux.Router, error) {
|
|
return https.Start(ctx, nodeConfig, nil)
|
|
}
|
|
|
|
// same deal for metrics - these are not used if the extra metrics listener is not enabled.
|
|
metrics := k3smetrics.DefaultMetrics
|
|
metrics.Router = func(ctx context.Context, nodeConfig *config.Node) (*mux.Router, error) {
|
|
return https.Start(ctx, nodeConfig, nil)
|
|
}
|
|
|
|
// and for pprof as well
|
|
pprof := profile.DefaultProfiler
|
|
pprof.Router = func(ctx context.Context, nodeConfig *config.Node) (*mux.Router, error) {
|
|
return https.Start(ctx, nodeConfig, nil)
|
|
}
|
|
|
|
return agent.Run(ctx, wg, cfg)
|
|
}
|