2019-01-01 08:23:01 +00:00
|
|
|
package agent
|
|
|
|
|
|
|
|
import (
|
2019-01-22 21:14:58 +00:00
|
|
|
"bufio"
|
2019-01-01 08:23:01 +00:00
|
|
|
"context"
|
|
|
|
"math/rand"
|
2019-01-22 21:14:58 +00:00
|
|
|
"os"
|
2019-01-09 16:54:15 +00:00
|
|
|
"path/filepath"
|
2019-01-22 21:14:58 +00:00
|
|
|
"strings"
|
2019-01-01 08:23:01 +00:00
|
|
|
"time"
|
|
|
|
|
2019-01-09 16:54:15 +00:00
|
|
|
"github.com/rancher/k3s/pkg/daemons/config"
|
2019-01-01 08:23:01 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
2019-01-22 21:14:58 +00:00
|
|
|
"k8s.io/apimachinery/pkg/util/net"
|
2019-01-01 08:23:01 +00:00
|
|
|
"k8s.io/apiserver/pkg/util/logs"
|
|
|
|
app2 "k8s.io/kubernetes/cmd/kube-proxy/app"
|
|
|
|
"k8s.io/kubernetes/cmd/kubelet/app"
|
|
|
|
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
|
|
|
_ "k8s.io/kubernetes/pkg/version/prometheus" // for version metric registration
|
|
|
|
)
|
|
|
|
|
|
|
|
func Agent(config *config.Agent) error {
|
|
|
|
rand.Seed(time.Now().UTC().UnixNano())
|
|
|
|
|
|
|
|
kubelet(config)
|
|
|
|
kubeProxy(config)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func kubeProxy(config *config.Agent) {
|
|
|
|
args := []string{
|
|
|
|
"--proxy-mode", "iptables",
|
|
|
|
"--healthz-bind-address", "127.0.0.1",
|
|
|
|
"--kubeconfig", config.KubeConfig,
|
|
|
|
"--cluster-cidr", config.ClusterCIDR.String(),
|
|
|
|
}
|
|
|
|
args = append(args, config.ExtraKubeletArgs...)
|
|
|
|
|
|
|
|
command := app2.NewProxyCommand()
|
|
|
|
command.SetArgs(args)
|
|
|
|
go func() {
|
|
|
|
err := command.Execute()
|
|
|
|
logrus.Fatalf("kube-proxy exited: %v", err)
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
2019-01-09 16:54:15 +00:00
|
|
|
func kubelet(cfg *config.Agent) {
|
2019-01-01 08:23:01 +00:00
|
|
|
command := app.NewKubeletCommand(context.Background().Done())
|
|
|
|
logs.InitLogs()
|
|
|
|
defer logs.FlushLogs()
|
|
|
|
|
|
|
|
args := []string{
|
|
|
|
"--healthz-bind-address", "127.0.0.1",
|
|
|
|
"--read-only-port", "0",
|
|
|
|
"--allow-privileged=true",
|
|
|
|
"--cluster-domain", "cluster.local",
|
2019-01-09 16:54:15 +00:00
|
|
|
"--kubeconfig", cfg.KubeConfig,
|
2019-01-01 08:23:01 +00:00
|
|
|
"--eviction-hard", "imagefs.available<5%,nodefs.available<5%",
|
|
|
|
"--eviction-minimum-reclaim", "imagefs.available=10%,nodefs.available=10%",
|
|
|
|
"--fail-swap-on=false",
|
2019-01-09 16:54:15 +00:00
|
|
|
//"--cgroup-root", "/k3s",
|
2019-01-01 08:23:01 +00:00
|
|
|
"--cgroup-driver", "cgroupfs",
|
|
|
|
}
|
2019-01-09 16:54:15 +00:00
|
|
|
if cfg.RootDir != "" {
|
|
|
|
args = append(args, "--root-dir", cfg.RootDir)
|
|
|
|
args = append(args, "--cert-dir", filepath.Join(cfg.RootDir, "pki"))
|
|
|
|
args = append(args, "--seccomp-profile-root", filepath.Join(cfg.RootDir, "seccomp"))
|
2019-01-01 08:23:01 +00:00
|
|
|
}
|
2019-01-09 16:54:15 +00:00
|
|
|
if cfg.CNIConfDir != "" {
|
|
|
|
args = append(args, "--cni-conf-dir", cfg.CNIConfDir)
|
2019-01-01 08:23:01 +00:00
|
|
|
}
|
2019-01-09 16:54:15 +00:00
|
|
|
if cfg.CNIBinDir != "" {
|
|
|
|
args = append(args, "--cni-bin-dir", cfg.CNIBinDir)
|
2019-01-01 08:23:01 +00:00
|
|
|
}
|
2019-01-09 16:54:15 +00:00
|
|
|
if len(cfg.ClusterDNS) > 0 {
|
|
|
|
args = append(args, "--cluster-dns", cfg.ClusterDNS.String())
|
2019-01-01 08:23:01 +00:00
|
|
|
}
|
2019-01-09 16:54:15 +00:00
|
|
|
if cfg.RuntimeSocket != "" {
|
|
|
|
args = append(args, "--container-runtime", "remote")
|
|
|
|
args = append(args, "--container-runtime-endpoint", cfg.RuntimeSocket)
|
2019-01-01 08:23:01 +00:00
|
|
|
}
|
2019-01-09 16:54:15 +00:00
|
|
|
if cfg.ListenAddress != "" {
|
|
|
|
args = append(args, "--address", cfg.ListenAddress)
|
|
|
|
}
|
|
|
|
if cfg.CACertPath != "" {
|
|
|
|
args = append(args, "--anonymous-auth=false", "--client-ca-file", cfg.CACertPath)
|
|
|
|
}
|
|
|
|
if cfg.NodeName != "" {
|
|
|
|
args = append(args, "--hostname-override", cfg.NodeName)
|
|
|
|
}
|
|
|
|
defaultIP, err := net.ChooseHostInterface()
|
|
|
|
if err != nil || defaultIP.String() != cfg.NodeIP {
|
|
|
|
args = append(args, "--node-ip", cfg.NodeIP)
|
|
|
|
}
|
2019-01-22 21:14:58 +00:00
|
|
|
if !hasCFS() {
|
|
|
|
logrus.Warn("Disabling CPU quotas due to missing cpu.cfs_period_us")
|
|
|
|
args = append(args, "--cpu-cfs-quota=false")
|
|
|
|
}
|
2019-01-09 16:54:15 +00:00
|
|
|
args = append(args, cfg.ExtraKubeletArgs...)
|
2019-01-01 08:23:01 +00:00
|
|
|
|
|
|
|
command.SetArgs(args)
|
|
|
|
|
|
|
|
go func() {
|
2019-01-09 16:54:15 +00:00
|
|
|
logrus.Infof("Running kubelet %s", config.ArgString(args))
|
2019-01-01 08:23:01 +00:00
|
|
|
logrus.Fatalf("kubelet exited: %v", command.Execute())
|
|
|
|
}()
|
|
|
|
}
|
2019-01-22 21:14:58 +00:00
|
|
|
|
|
|
|
func hasCFS() bool {
|
|
|
|
f, err := os.Open("/proc/self/cgroup")
|
|
|
|
if err != nil {
|
|
|
|
return 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 == "cpu" {
|
|
|
|
p := filepath.Join("/sys/fs/cgroup", parts[1], parts[2], "cpu.cfs_period_us")
|
|
|
|
if _, err := os.Stat(p); err == nil {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|