mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
fa03a0df3c
The containerd flag was accidentally added to kubelet and is deprecated, but needed for cadvisor to properly connect with the k3s containerd socket, so adding for now.
207 lines
5.8 KiB
Go
207 lines
5.8 KiB
Go
package agent
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"math/rand"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/opencontainers/runc/libcontainer/system"
|
|
"github.com/rancher/k3s/pkg/daemons/config"
|
|
"github.com/sirupsen/logrus"
|
|
"k8s.io/apimachinery/pkg/util/net"
|
|
"k8s.io/component-base/logs"
|
|
proxy "k8s.io/kubernetes/cmd/kube-proxy/app"
|
|
kubelet "k8s.io/kubernetes/cmd/kubelet/app"
|
|
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
|
|
|
_ "k8s.io/component-base/metrics/prometheus/restclient" // for client metric registration
|
|
_ "k8s.io/component-base/metrics/prometheus/version" // for version metric registration
|
|
)
|
|
|
|
func Agent(config *config.Agent) error {
|
|
rand.Seed(time.Now().UTC().UnixNano())
|
|
|
|
logs.InitLogs()
|
|
defer logs.FlushLogs()
|
|
|
|
startKubelet(config)
|
|
startKubeProxy(config)
|
|
|
|
return nil
|
|
}
|
|
|
|
func startKubeProxy(cfg *config.Agent) {
|
|
argsMap := map[string]string{
|
|
"proxy-mode": "iptables",
|
|
"healthz-bind-address": "127.0.0.1",
|
|
"kubeconfig": cfg.KubeConfigKubeProxy,
|
|
"cluster-cidr": cfg.ClusterCIDR.String(),
|
|
}
|
|
if cfg.NodeName != "" {
|
|
argsMap["hostname-override"] = cfg.NodeName
|
|
}
|
|
|
|
args := config.GetArgsList(argsMap, cfg.ExtraKubeProxyArgs)
|
|
command := proxy.NewProxyCommand()
|
|
command.SetArgs(args)
|
|
|
|
go func() {
|
|
logrus.Infof("Running kube-proxy %s", config.ArgString(args))
|
|
logrus.Fatalf("kube-proxy exited: %v", command.Execute())
|
|
}()
|
|
}
|
|
|
|
func startKubelet(cfg *config.Agent) {
|
|
argsMap := map[string]string{
|
|
"healthz-bind-address": "127.0.0.1",
|
|
"read-only-port": "0",
|
|
"cluster-domain": cfg.ClusterDomain,
|
|
"kubeconfig": cfg.KubeConfigKubelet,
|
|
"eviction-hard": "imagefs.available<5%,nodefs.available<5%",
|
|
"eviction-minimum-reclaim": "imagefs.available=10%,nodefs.available=10%",
|
|
"fail-swap-on": "false",
|
|
//"cgroup-root": "/k3s",
|
|
"cgroup-driver": "cgroupfs",
|
|
"authentication-token-webhook": "true",
|
|
"anonymous-auth": "false",
|
|
"authorization-mode": modes.ModeWebhook,
|
|
}
|
|
if cfg.RootDir != "" {
|
|
argsMap["root-dir"] = cfg.RootDir
|
|
argsMap["cert-dir"] = filepath.Join(cfg.RootDir, "pki")
|
|
argsMap["seccomp-profile-root"] = filepath.Join(cfg.RootDir, "seccomp")
|
|
}
|
|
if cfg.CNIConfDir != "" {
|
|
argsMap["cni-conf-dir"] = cfg.CNIConfDir
|
|
}
|
|
if cfg.CNIBinDir != "" {
|
|
argsMap["cni-bin-dir"] = cfg.CNIBinDir
|
|
}
|
|
if cfg.CNIPlugin {
|
|
argsMap["network-plugin"] = "cni"
|
|
}
|
|
if len(cfg.ClusterDNS) > 0 {
|
|
argsMap["cluster-dns"] = cfg.ClusterDNS.String()
|
|
}
|
|
if cfg.ResolvConf != "" {
|
|
argsMap["resolv-conf"] = cfg.ResolvConf
|
|
}
|
|
if cfg.RuntimeSocket != "" {
|
|
argsMap["container-runtime"] = "remote"
|
|
argsMap["container-runtime-endpoint"] = cfg.RuntimeSocket
|
|
argsMap["containerd"] = cfg.RuntimeSocket
|
|
argsMap["serialize-image-pulls"] = "false"
|
|
} else if cfg.PauseImage != "" {
|
|
argsMap["pod-infra-container-image"] = cfg.PauseImage
|
|
}
|
|
if cfg.ListenAddress != "" {
|
|
argsMap["address"] = cfg.ListenAddress
|
|
}
|
|
if cfg.ClientCA != "" {
|
|
argsMap["anonymous-auth"] = "false"
|
|
argsMap["client-ca-file"] = cfg.ClientCA
|
|
}
|
|
if cfg.ServingKubeletCert != "" && cfg.ServingKubeletKey != "" {
|
|
argsMap["tls-cert-file"] = cfg.ServingKubeletCert
|
|
argsMap["tls-private-key-file"] = cfg.ServingKubeletKey
|
|
}
|
|
if cfg.NodeName != "" {
|
|
argsMap["hostname-override"] = cfg.NodeName
|
|
}
|
|
defaultIP, err := net.ChooseHostInterface()
|
|
if err != nil || defaultIP.String() != cfg.NodeIP {
|
|
argsMap["node-ip"] = cfg.NodeIP
|
|
}
|
|
root, hasCFS, hasPIDs := checkCgroups()
|
|
if !hasCFS {
|
|
logrus.Warn("Disabling CPU quotas due to missing cpu.cfs_period_us")
|
|
argsMap["cpu-cfs-quota"] = "false"
|
|
}
|
|
if !hasPIDs {
|
|
logrus.Warn("Disabling pod PIDs limit feature due to missing cgroup pids support")
|
|
argsMap["cgroups-per-qos"] = "false"
|
|
argsMap["enforce-node-allocatable"] = ""
|
|
argsMap["feature-gates"] = addFeatureGate(argsMap["feature-gates"], "SupportPodPidsLimit=false")
|
|
}
|
|
if root != "" {
|
|
argsMap["runtime-cgroups"] = root
|
|
argsMap["kubelet-cgroups"] = root
|
|
}
|
|
if system.RunningInUserNS() {
|
|
argsMap["feature-gates"] = addFeatureGate(argsMap["feature-gates"], "DevicePlugins=false")
|
|
}
|
|
|
|
argsMap["node-labels"] = strings.Join(cfg.NodeLabels, ",")
|
|
if len(cfg.NodeTaints) > 0 {
|
|
argsMap["register-with-taints"] = strings.Join(cfg.NodeTaints, ",")
|
|
}
|
|
if !cfg.DisableCCM {
|
|
argsMap["cloud-provider"] = "external"
|
|
}
|
|
|
|
if cfg.Rootless {
|
|
// flags are from https://github.com/rootless-containers/usernetes/blob/v20190826.0/boot/kubelet.sh
|
|
argsMap["cgroup-driver"] = "none"
|
|
argsMap["feature-gates=SupportNoneCgroupDriver"] = "true"
|
|
argsMap["cgroups-per-qos"] = "false"
|
|
argsMap["enforce-node-allocatable"] = ""
|
|
}
|
|
|
|
args := config.GetArgsList(argsMap, cfg.ExtraKubeletArgs)
|
|
command := kubelet.NewKubeletCommand(context.Background().Done())
|
|
command.SetArgs(args)
|
|
|
|
go func() {
|
|
logrus.Infof("Running kubelet %s", config.ArgString(args))
|
|
logrus.Fatalf("kubelet exited: %v", command.Execute())
|
|
}()
|
|
}
|
|
|
|
func addFeatureGate(current, new string) string {
|
|
if current == "" {
|
|
return new
|
|
}
|
|
return current + "," + new
|
|
}
|
|
|
|
func checkCgroups() (root string, hasCFS bool, hasPIDs bool) {
|
|
f, err := os.Open("/proc/self/cgroup")
|
|
if err != nil {
|
|
return "", false, false
|
|
}
|
|
defer f.Close()
|
|
|
|
scan := bufio.NewScanner(f)
|
|
for scan.Scan() {
|
|
parts := strings.Split(scan.Text(), ":")
|
|
if len(parts) < 3 {
|
|
continue
|
|
}
|
|
systems := strings.Split(parts[1], ",")
|
|
for _, system := range systems {
|
|
if system == "pids" {
|
|
hasPIDs = true
|
|
} else if system == "cpu" {
|
|
p := filepath.Join("/sys/fs/cgroup", parts[1], parts[2], "cpu.cfs_period_us")
|
|
if _, err := os.Stat(p); err == nil {
|
|
hasCFS = true
|
|
}
|
|
} else if system == "name=systemd" {
|
|
last := parts[len(parts)-1]
|
|
i := strings.LastIndex(last, ".slice")
|
|
if i > 0 {
|
|
root = "/systemd" + last[:i+len(".slice")]
|
|
} else {
|
|
root = "/systemd"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return root, hasCFS, hasPIDs
|
|
}
|