mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 14:37:00 +00:00
e2e_node: Correctly kill and log systemd kubelet
This commit is contained in:
parent
b004122dfc
commit
34996f1b84
@ -20,6 +20,7 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -37,16 +38,28 @@ var serverStartTimeout = flag.Duration("server-start-timeout", time.Second*120,
|
|||||||
var reportDir = flag.String("report-dir", "", "Path to the directory where the JUnit XML reports should be saved. Default is empty, which doesn't generate these reports.")
|
var reportDir = flag.String("report-dir", "", "Path to the directory where the JUnit XML reports should be saved. Default is empty, which doesn't generate these reports.")
|
||||||
|
|
||||||
type e2eService struct {
|
type e2eService struct {
|
||||||
etcdCmd *exec.Cmd
|
etcdCmd *killCmd
|
||||||
etcdDataDir string
|
etcdDataDir string
|
||||||
apiServerCmd *exec.Cmd
|
apiServerCmd *killCmd
|
||||||
kubeletCmd *exec.Cmd
|
kubeletCmd *killCmd
|
||||||
kubeletStaticPodDir string
|
kubeletStaticPodDir string
|
||||||
nodeName string
|
nodeName string
|
||||||
|
logFiles map[string]logFileData
|
||||||
|
}
|
||||||
|
|
||||||
|
type logFileData struct {
|
||||||
|
files []string
|
||||||
|
journalctlCommand []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newE2eService(nodeName string) *e2eService {
|
func newE2eService(nodeName string) *e2eService {
|
||||||
return &e2eService{nodeName: nodeName}
|
// Special log files that need to be collected for additional debugging.
|
||||||
|
var logFiles = map[string]logFileData{
|
||||||
|
"kern.log": {[]string{"/var/log/kern.log"}, []string{"-k"}},
|
||||||
|
"docker.log": {[]string{"/var/log/docker.log", "/var/log/upstart/docker.log"}, []string{"-u", "docker"}},
|
||||||
|
}
|
||||||
|
|
||||||
|
return &e2eService{nodeName: nodeName, logFiles: logFiles}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *e2eService) start() error {
|
func (es *e2eService) start() error {
|
||||||
@ -81,22 +94,12 @@ func (es *e2eService) start() error {
|
|||||||
// Get logs of interest either via journalctl or by creating sym links.
|
// Get logs of interest either via journalctl or by creating sym links.
|
||||||
// Since we scp files from the remote directory, symlinks will be treated as normal files and file contents will be copied over.
|
// Since we scp files from the remote directory, symlinks will be treated as normal files and file contents will be copied over.
|
||||||
func (es *e2eService) getLogFiles() {
|
func (es *e2eService) getLogFiles() {
|
||||||
// Special log files that need to be collected for additional debugging.
|
|
||||||
type logFileData struct {
|
|
||||||
files []string
|
|
||||||
journalctlCommand []string
|
|
||||||
}
|
|
||||||
var logFiles = map[string]logFileData{
|
|
||||||
"kern.log": {[]string{"/var/log/kern.log"}, []string{"-k"}},
|
|
||||||
"docker.log": {[]string{"/var/log/docker.log", "/var/log/upstart/docker.log"}, []string{"-u", "docker"}},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nothing to do if report dir is not specified.
|
// Nothing to do if report dir is not specified.
|
||||||
if *reportDir == "" {
|
if *reportDir == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
journaldFound := isJournaldAvailable()
|
journaldFound := isJournaldAvailable()
|
||||||
for targetFileName, logFileData := range logFiles {
|
for targetFileName, logFileData := range es.logFiles {
|
||||||
targetLink := path.Join(*reportDir, targetFileName)
|
targetLink := path.Join(*reportDir, targetFileName)
|
||||||
if journaldFound {
|
if journaldFound {
|
||||||
// Skip log files that do not have an equivalent in journald based machines.
|
// Skip log files that do not have an equivalent in journald based machines.
|
||||||
@ -144,7 +147,7 @@ func isJournaldAvailable() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (es *e2eService) stop() {
|
func (es *e2eService) stop() {
|
||||||
if err := es.stopService("kubelet", es.kubeletCmd); err != nil {
|
if err := es.stopService(es.kubeletCmd); err != nil {
|
||||||
glog.Errorf("Failed to stop kubelet: %v", err)
|
glog.Errorf("Failed to stop kubelet: %v", err)
|
||||||
}
|
}
|
||||||
if es.kubeletStaticPodDir != "" {
|
if es.kubeletStaticPodDir != "" {
|
||||||
@ -153,10 +156,10 @@ func (es *e2eService) stop() {
|
|||||||
glog.Errorf("Failed to delete kubelet static pod directory %s.\n%v", es.kubeletStaticPodDir, err)
|
glog.Errorf("Failed to delete kubelet static pod directory %s.\n%v", es.kubeletStaticPodDir, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := es.stopService("kube-apiserver", es.apiServerCmd); err != nil {
|
if err := es.stopService(es.apiServerCmd); err != nil {
|
||||||
glog.Errorf("Failed to stop kube-apiserver: %v", err)
|
glog.Errorf("Failed to stop kube-apiserver: %v", err)
|
||||||
}
|
}
|
||||||
if err := es.stopService("etcd", es.etcdCmd); err != nil {
|
if err := es.stopService(es.etcdCmd); err != nil {
|
||||||
glog.Errorf("Failed to stop etcd: %v", err)
|
glog.Errorf("Failed to stop etcd: %v", err)
|
||||||
}
|
}
|
||||||
if es.etcdDataDir != "" {
|
if es.etcdDataDir != "" {
|
||||||
@ -167,7 +170,7 @@ func (es *e2eService) stop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *e2eService) startEtcd() (*exec.Cmd, error) {
|
func (es *e2eService) startEtcd() (*killCmd, error) {
|
||||||
dataDir, err := ioutil.TempDir("", "node-e2e")
|
dataDir, err := ioutil.TempDir("", "node-e2e")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -181,10 +184,10 @@ func (es *e2eService) startEtcd() (*exec.Cmd, error) {
|
|||||||
"http://127.0.0.1:4001/v2/keys/", // Trailing slash is required,
|
"http://127.0.0.1:4001/v2/keys/", // Trailing slash is required,
|
||||||
cmd,
|
cmd,
|
||||||
"etcd.log")
|
"etcd.log")
|
||||||
return cmd, es.startServer(hcc)
|
return &killCmd{name: "etcd", cmd: cmd}, es.startServer(hcc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *e2eService) startApiServer() (*exec.Cmd, error) {
|
func (es *e2eService) startApiServer() (*killCmd, error) {
|
||||||
cmd := exec.Command("sudo", getApiServerBin(),
|
cmd := exec.Command("sudo", getApiServerBin(),
|
||||||
"--etcd-servers", "http://127.0.0.1:4001",
|
"--etcd-servers", "http://127.0.0.1:4001",
|
||||||
"--insecure-bind-address", "0.0.0.0",
|
"--insecure-bind-address", "0.0.0.0",
|
||||||
@ -197,22 +200,28 @@ func (es *e2eService) startApiServer() (*exec.Cmd, error) {
|
|||||||
"http://127.0.0.1:8080/healthz",
|
"http://127.0.0.1:8080/healthz",
|
||||||
cmd,
|
cmd,
|
||||||
"kube-apiserver.log")
|
"kube-apiserver.log")
|
||||||
return cmd, es.startServer(hcc)
|
return &killCmd{name: "kube-apiserver", cmd: cmd}, es.startServer(hcc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *e2eService) startKubeletServer() (*exec.Cmd, error) {
|
func (es *e2eService) startKubeletServer() (*killCmd, error) {
|
||||||
dataDir, err := ioutil.TempDir("", "node-e2e-pod")
|
dataDir, err := ioutil.TempDir("", "node-e2e-pod")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
es.kubeletStaticPodDir = dataDir
|
es.kubeletStaticPodDir = dataDir
|
||||||
|
var killOverride *exec.Cmd
|
||||||
cmdArgs := []string{}
|
cmdArgs := []string{}
|
||||||
if systemdRun, err := exec.LookPath("systemd-run"); err == nil {
|
if systemdRun, err := exec.LookPath("systemd-run"); err == nil {
|
||||||
// On systemd services, detection of a service / unit works reliably while
|
// On systemd services, detection of a service / unit works reliably while
|
||||||
// detection of a process started from an ssh session does not work.
|
// detection of a process started from an ssh session does not work.
|
||||||
// Since kubelet will typically be run as a service it also makes more
|
// Since kubelet will typically be run as a service it also makes more
|
||||||
// sense to test it that way
|
// sense to test it that way
|
||||||
cmdArgs = append(cmdArgs, systemdRun, getKubeletServerBin())
|
unitName := fmt.Sprintf("kubelet-%d.service", rand.Int31())
|
||||||
|
cmdArgs = append(cmdArgs, systemdRun, "--unit="+unitName, getKubeletServerBin())
|
||||||
|
killOverride = exec.Command("sudo", "systemctl", "kill", unitName)
|
||||||
|
es.logFiles["kubelet.log"] = logFileData{
|
||||||
|
journalctlCommand: []string{"-u", unitName},
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cmdArgs = append(cmdArgs, getKubeletServerBin())
|
cmdArgs = append(cmdArgs, getKubeletServerBin())
|
||||||
}
|
}
|
||||||
@ -233,7 +242,7 @@ func (es *e2eService) startKubeletServer() (*exec.Cmd, error) {
|
|||||||
"http://127.0.0.1:10255/healthz",
|
"http://127.0.0.1:10255/healthz",
|
||||||
cmd,
|
cmd,
|
||||||
"kubelet.log")
|
"kubelet.log")
|
||||||
return cmd, es.startServer(hcc)
|
return &killCmd{name: "kubelet", cmd: cmd, override: killOverride}, es.startServer(hcc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *e2eService) startServer(cmd *healthCheckCommand) error {
|
func (es *e2eService) startServer(cmd *healthCheckCommand) error {
|
||||||
@ -290,7 +299,27 @@ func (es *e2eService) startServer(cmd *healthCheckCommand) error {
|
|||||||
return fmt.Errorf("Timeout waiting for service %s", cmd)
|
return fmt.Errorf("Timeout waiting for service %s", cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *e2eService) stopService(name string, cmd *exec.Cmd) error {
|
func (es *e2eService) stopService(cmd *killCmd) error {
|
||||||
|
return cmd.Kill()
|
||||||
|
}
|
||||||
|
|
||||||
|
// killCmd is a struct to kill a given cmd. The cmd member specifies a command
|
||||||
|
// to find the pid of and attempt to kill.
|
||||||
|
// If the override field is set, that will be used instead to kill the command.
|
||||||
|
// name is only used for logging
|
||||||
|
type killCmd struct {
|
||||||
|
name string
|
||||||
|
cmd *exec.Cmd
|
||||||
|
override *exec.Cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *killCmd) Kill() error {
|
||||||
|
if k.override != nil {
|
||||||
|
return k.override.Run()
|
||||||
|
}
|
||||||
|
name := k.name
|
||||||
|
cmd := k.cmd
|
||||||
|
|
||||||
if cmd == nil || cmd.Process == nil {
|
if cmd == nil || cmd.Process == nil {
|
||||||
glog.V(2).Infof("%s not running", name)
|
glog.V(2).Infof("%s not running", name)
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user