Skip to content

Commit cb2e8e1

Browse files
authored
Merge pull request #11632 from ilya-zuyev/ilyaz/fix_vm_ctrd_timeout
Restore "containerd: upgrade io.containerd.runtime.v1.linux to io.containerd.runc.v2 (suppot cgroup v2)" #2
2 parents 16d2f2a + f04da67 commit cb2e8e1

File tree

15 files changed

+133
-34
lines changed

15 files changed

+133
-34
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ KUBERNETES_VERSION ?= $(shell egrep "DefaultKubernetesVersion =" pkg/minikube/co
2323
KIC_VERSION ?= $(shell egrep "Version =" pkg/drivers/kic/types.go | cut -d \" -f2)
2424

2525
# Default to .0 for higher cache hit rates, as build increments typically don't require new ISO versions
26-
ISO_VERSION ?= v1.21.0
26+
ISO_VERSION ?= v1.21.0-1623378770-11632
2727
# Dashes are valid in semver, but not Linux packaging. Use ~ to delimit alpha/beta
2828
DEB_VERSION ?= $(subst -,~,$(RAW_VERSION))
2929
DEB_REVISION ?= 0

deploy/iso/minikube-iso/package/containerd-bin/containerd.service

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ ExecStart=/usr/bin/containerd \
1616
--root ${PERSISTENT_DIR}/var/lib/containerd
1717
TasksMax=8192
1818
Delegate=yes
19-
KillMode=process
19+
KillMode=mixed
2020
LimitNOFILE=1048576
2121
# Having non-zero Limit*s causes performance problems due to accounting overhead
2222
# in the kernel. We recommend using cgroups to do container-local accounting.

pkg/minikube/bootstrapper/bsutil/kverify/api_server.go

+17-1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,22 @@ func APIServerVersionMatch(client *kubernetes.Clientset, expected string) error
143143
return nil
144144
}
145145

146+
// WaitForAPIServerStatus waits for 'to' duration to get apiserver pod running or stopped
147+
// this functions is intended to use in situations where apiserver process can be recreated
148+
// by container runtime restart for example and there is a gap before it comes back
149+
func WaitForAPIServerStatus(cr command.Runner, to time.Duration, hostname string, port int) (state.State, error) {
150+
var st state.State
151+
err := wait.PollImmediate(200*time.Millisecond, to, func() (bool, error) {
152+
var err error
153+
st, err = APIServerStatus(cr, hostname, port)
154+
if st == state.Stopped {
155+
return false, nil
156+
}
157+
return true, err
158+
})
159+
return st, err
160+
}
161+
146162
// APIServerStatus returns apiserver status in libmachine style state.State
147163
func APIServerStatus(cr command.Runner, hostname string, port int) (state.State, error) {
148164
klog.Infof("Checking apiserver status ...")
@@ -207,7 +223,7 @@ func apiServerHealthz(hostname string, port int) (state.State, error) {
207223
return nil
208224
}
209225

210-
err = retry.Local(check, 5*time.Second)
226+
err = retry.Local(check, 15*time.Second)
211227

212228
// Don't propagate 'Stopped' upwards as an error message, as clients may interpret the err
213229
// as an inability to get status. We need it for retry.Local, however.

pkg/minikube/bootstrapper/kubeadm/kubeadm.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -568,13 +568,13 @@ func (k *Bootstrapper) needsReconfigure(conf string, hostname string, port int,
568568
klog.Infof("needs reconfigure: configs differ:\n%s", rr.Output())
569569
return true
570570
}
571-
572-
st, err := kverify.APIServerStatus(k.c, hostname, port)
571+
// cruntime.Enable() may restart kube-apiserver but does not wait for it to return back
572+
apiStatusTimeout := 3000 * time.Millisecond
573+
st, err := kverify.WaitForAPIServerStatus(k.c, apiStatusTimeout, hostname, port)
573574
if err != nil {
574575
klog.Infof("needs reconfigure: apiserver error: %v", err)
575576
return true
576577
}
577-
578578
if st != state.Running {
579579
klog.Infof("needs reconfigure: apiserver in state %s", st)
580580
return true

pkg/minikube/cluster/pause.go

+3-5
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,10 @@ func pause(cr cruntime.Manager, r command.Runner, namespaces []string) ([]string
4747

4848
// Disable the kubelet so it does not attempt to restart paused pods
4949
sm := sysinit.New(r)
50-
if err := sm.Disable("kubelet"); err != nil {
51-
return ids, errors.Wrap(err, "kubelet disable")
52-
}
50+
klog.Info("kubelet running: ", sm.Active("kubelet"))
5351

54-
if err := sm.Stop("kubelet"); err != nil {
55-
return ids, errors.Wrap(err, "kubelet stop")
52+
if err := sm.DisableNow("kubelet"); err != nil {
53+
return ids, errors.Wrap(err, "kubelet disable --now")
5654
}
5755

5856
ids, err := cr.ListContainers(cruntime.ListContainersOptions{State: cruntime.Running, Namespaces: namespaces})

pkg/minikube/cruntime/containerd.go

+10-12
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ const (
4949
containerdConfigTemplate = `root = "/var/lib/containerd"
5050
state = "/run/containerd"
5151
oom_score = 0
52-
5352
[grpc]
5453
address = "/run/containerd/containerd.sock"
5554
uid = 0
@@ -79,16 +78,21 @@ oom_score = 0
7978
enable_selinux = false
8079
sandbox_image = "{{ .PodInfraContainerImage }}"
8180
stats_collect_period = 10
82-
systemd_cgroup = {{ .SystemdCgroup }}
8381
enable_tls_streaming = false
8482
max_container_log_line_size = 16384
83+
84+
[plugins."io.containerd.grpc.v1.cri"]
85+
[plugins."io.containerd.grpc.v1.cri".containerd]
86+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
87+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
88+
runtime_type = "io.containerd.runc.v2"
89+
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
90+
SystemdCgroup = {{ .SystemdCgroup }}
91+
8592
[plugins.cri.containerd]
8693
snapshotter = "overlayfs"
87-
no_pivot = true
8894
[plugins.cri.containerd.default_runtime]
89-
runtime_type = "io.containerd.runtime.v1.linux"
90-
runtime_engine = ""
91-
runtime_root = ""
95+
runtime_type = "io.containerd.runc.v2"
9296
[plugins.cri.containerd.untrusted_workload_runtime]
9397
runtime_type = ""
9498
runtime_engine = ""
@@ -107,12 +111,6 @@ oom_score = 0
107111
{{ end -}}
108112
[plugins.diff-service]
109113
default = ["walking"]
110-
[plugins.linux]
111-
shim = "containerd-shim"
112-
runtime = "runc"
113-
runtime_root = ""
114-
no_shim = false
115-
shim_debug = false
116114
[plugins.scheduler]
117115
pause_threshold = 0.02
118116
deletion_threshold = 0

pkg/minikube/cruntime/cruntime.go

+50
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,30 @@ type ListImagesOptions struct {
163163
// ErrContainerRuntimeNotRunning is thrown when container runtime is not running
164164
var ErrContainerRuntimeNotRunning = errors.New("container runtime is not running")
165165

166+
// ErrServiceVersion is the error returned when disk image has incompatible version of service
167+
type ErrServiceVersion struct {
168+
// Service is the name of the incompatible service
169+
Service string
170+
// Installed is the installed version of Service
171+
Installed string
172+
// Required is the minimum required version of Service
173+
Required string
174+
}
175+
176+
// NewErrServiceVersion creates a new ErrServiceVersion
177+
func NewErrServiceVersion(svc, required, installed string) *ErrServiceVersion {
178+
return &ErrServiceVersion{
179+
Service: svc,
180+
Installed: installed,
181+
Required: required,
182+
}
183+
}
184+
185+
func (e ErrServiceVersion) Error() string {
186+
return fmt.Sprintf("service %q version is %v. Required: %v",
187+
e.Service, e.Installed, e.Required)
188+
}
189+
166190
// New returns an appropriately configured runtime
167191
func New(c Config) (Manager, error) {
168192
sm := sysinit.New(c.Runner)
@@ -243,3 +267,29 @@ func disableOthers(me Manager, cr CommandRunner) error {
243267
}
244268
return nil
245269
}
270+
271+
var requiredContainerdVersion = semver.MustParse("1.4.0")
272+
273+
// compatibleWithVersion checks if current version of "runtime" is compatible with version "v"
274+
func compatibleWithVersion(runtime, v string) error {
275+
if runtime == "containerd" {
276+
vv, err := semver.Make(v)
277+
if err != nil {
278+
return err
279+
}
280+
if requiredContainerdVersion.GT(vv) {
281+
return NewErrServiceVersion(runtime, requiredContainerdVersion.String(), vv.String())
282+
}
283+
}
284+
return nil
285+
}
286+
287+
// CheckCompatibility checks if the container runtime managed by "cr" is compatible with current minikube code
288+
// returns: NewErrServiceVersion if not
289+
func CheckCompatibility(cr Manager) error {
290+
v, err := cr.Version()
291+
if err != nil {
292+
return errors.Wrap(err, "Failed to check container runtime version")
293+
}
294+
return compatibleWithVersion(cr.Name(), v)
295+
}

pkg/minikube/download/iso.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const fileScheme = "file"
4040
// DefaultISOURLs returns a list of ISO URL's to consult by default, in priority order
4141
func DefaultISOURLs() []string {
4242
v := version.GetISOVersion()
43-
isoBucket := "minikube/iso"
43+
isoBucket := "minikube-builds/iso/11632"
4444
return []string{
4545
fmt.Sprintf("https://storage.googleapis.com/%s/minikube-%s.iso", isoBucket, v),
4646
fmt.Sprintf("https://github.com/kubernetes/minikube/releases/download/%s/minikube-%s.iso", v, v),

pkg/minikube/node/advice.go

+12
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ limitations under the License.
1717
package node
1818

1919
import (
20+
"fmt"
2021
"runtime"
2122

2223
"github.com/pkg/errors"
2324
"k8s.io/minikube/pkg/drivers/kic/oci"
2425
"k8s.io/minikube/pkg/minikube/bootstrapper/kubeadm"
26+
"k8s.io/minikube/pkg/minikube/cruntime"
2527
"k8s.io/minikube/pkg/minikube/exit"
2628
"k8s.io/minikube/pkg/minikube/reason"
2729
"k8s.io/minikube/pkg/minikube/style"
@@ -62,4 +64,14 @@ func ExitIfFatal(err error) {
6264
Advice: "Ensure that your Docker mountpoints do not have the 'noexec' flag set",
6365
}, "The kubeadm binary within the Docker container is not executable")
6466
}
67+
68+
if rtErr, ok := err.(*cruntime.ErrServiceVersion); ok {
69+
exit.Message(reason.Kind{
70+
ID: "PROVIDER_INVALID_VERSION",
71+
ExitCode: reason.ExGuestConfig,
72+
Style: style.Unsupported,
73+
Advice: "Try to start minikube with '--delete-on-failure=true' option",
74+
}, fmt.Sprintf("Your existing minikube instance has version %s of service %v which is too old. "+
75+
"Please try to start minikube with --delete-on-failure=true option", rtErr.Installed, rtErr.Service))
76+
}
6577
}

pkg/minikube/node/start.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ func Start(starter Starter, apiServer bool) (*kubeconfig.Settings, error) {
9797

9898
// configure the runtime (docker, containerd, crio)
9999
cr := configureRuntimes(starter.Runner, *starter.Cfg, sv)
100+
101+
// check if installed runtime is compatible with current minikube code
102+
if err = cruntime.CheckCompatibility(cr); err != nil {
103+
return nil, err
104+
}
105+
100106
showVersionInfo(starter.Node.KubernetesVersion, cr)
101107

102108
// Add "host.minikube.internal" DNS alias (intentionally non-fatal)
@@ -353,7 +359,6 @@ func configureRuntimes(runner cruntime.CommandRunner, cc config.ClusterConfig, k
353359
if err != nil {
354360
exit.Error(reason.RuntimeEnable, "Failed to start container runtime", err)
355361
}
356-
357362
return cr
358363
}
359364

pkg/minikube/sysinit/openrc.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,11 @@ func (s *OpenRC) Disable(svc string) error {
117117
return nil
118118
}
119119

120-
// DisableNow not implemented for openRC
120+
// DisableNow does Disable + Stop
121121
func (s *OpenRC) DisableNow(svc string) error {
122-
return fmt.Errorf("disable now is not implemented for OpenRC! PRs to fix are welcomed")
122+
// supposed to do disable + stop
123+
// disable does nothing for OpenRC, so just Stop here
124+
return s.Stop(svc)
123125
}
124126

125127
// Mask does nothing
@@ -132,9 +134,11 @@ func (s *OpenRC) Enable(svc string) error {
132134
return nil
133135
}
134136

135-
// EnableNow not implemented for openRC
137+
// EnableNow does Enable + Start
136138
func (s *OpenRC) EnableNow(svc string) error {
137-
return fmt.Errorf("enable now is not implemented for OpenRC! PRs to fix are welcomed")
139+
// supposed to do enable + start
140+
// enable does nothing for OpenRC, so just Start here
141+
return s.Start(svc)
138142
}
139143

140144
// Unmask does nothing

pkg/minikube/sysinit/systemd.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ func (s *Systemd) Active(svc string) bool {
5050

5151
// Disable disables a service
5252
func (s *Systemd) Disable(svc string) error {
53-
_, err := s.r.RunCmd(exec.Command("sudo", "systemctl", "disable", svc))
53+
cmd := exec.Command("sudo", "systemctl", "disable", svc)
54+
// See https://github.com/kubernetes/minikube/issues/11615#issuecomment-861794258
55+
cmd.Env = append(cmd.Env, "SYSTEMCTL_SKIP_SYSV=1")
56+
_, err := s.r.RunCmd(cmd)
5457
return err
5558
}
5659

site/content/en/docs/commands/start.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ minikube start [flags]
6464
--insecure-registry strings Insecure Docker registries to pass to the Docker daemon. The default service CIDR range will automatically be added.
6565
--install-addons If set, install addons. Defaults to true. (default true)
6666
--interactive Allow user prompts for more information (default true)
67-
--iso-url strings Locations to fetch the minikube ISO from. (default [https://storage.googleapis.com/minikube/iso/minikube-v1.21.0.iso,https://github.com/kubernetes/minikube/releases/download/v1.21.0/minikube-v1.21.0.iso,https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.21.0.iso])
67+
--iso-url strings Locations to fetch the minikube ISO from. (default [https://storage.googleapis.com/minikube-builds/iso/11632/minikube-v1.21.0-1623378770-11632.iso,https://github.com/kubernetes/minikube/releases/download/v1.21.0-1623378770-11632/minikube-v1.21.0-1623378770-11632.iso,https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.21.0-1623378770-11632.iso])
6868
--keep-context This will keep the existing kubectl context and will create a minikube context.
6969
--kubernetes-version string The Kubernetes version that the minikube VM will use (ex: v1.2.3, 'stable' for v1.20.7, 'latest' for v1.22.0-alpha.2). Defaults to 'stable'.
7070
--kvm-gpu Enable experimental NVIDIA GPU support in minikube

test/integration/docker_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func validateContainerdSystemd(ctx context.Context, t *testing.T, profile string
114114
if err != nil {
115115
t.Errorf("failed to get docker cgroup driver. args %q: %v", rr.Command(), err)
116116
}
117-
if !strings.Contains(rr.Output(), "systemd_cgroup = true") {
117+
if !strings.Contains(rr.Output(), "SystemdCgroup = true") {
118118
t.Fatalf("expected systemd cgroup driver, got: %v", rr.Output())
119119
}
120120
}

test/integration/version_upgrade_test.go

+15-2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ func TestRunningBinaryUpgrade(t *testing.T) {
8787
legacyVersion = "v1.9.0"
8888
}
8989
}
90+
// the version containerd in ISO was upgraded to 1.4.2
91+
// we need it to use runc.v2 plugin
92+
if ContainerRuntime() == "containerd" {
93+
legacyVersion = "v1.16.0"
94+
}
9095

9196
tf, err := installRelease(legacyVersion)
9297
if err != nil {
@@ -98,7 +103,7 @@ func TestRunningBinaryUpgrade(t *testing.T) {
98103
rr := &RunResult{}
99104
r := func() error {
100105
c := exec.CommandContext(ctx, tf.Name(), args...)
101-
legacyEnv := []string{}
106+
var legacyEnv []string
102107
// replace the global KUBECONFIG with a fresh kubeconfig
103108
// because for minikube<1.17.0 it can not read the new kubeconfigs that have extra "Extenions" block
104109
// see: https://github.com/kubernetes/minikube/issues/10210
@@ -155,8 +160,16 @@ func TestStoppedBinaryUpgrade(t *testing.T) {
155160
if arm64Platform() {
156161
// first release with non-experimental arm64 KIC
157162
legacyVersion = "v1.17.0"
163+
} else {
164+
// v1.8.0 would be selected, but: https://github.com/kubernetes/minikube/issues/8740
165+
legacyVersion = "v1.9.0"
158166
}
159167
}
168+
if ContainerRuntime() == "containerd" {
169+
// the version containerd in ISO was upgraded to 1.4.2
170+
// we need it to use runc.v2 plugin
171+
legacyVersion = "v1.16.0"
172+
}
160173

161174
tf, err := installRelease(legacyVersion)
162175
if err != nil {
@@ -168,7 +181,7 @@ func TestStoppedBinaryUpgrade(t *testing.T) {
168181
rr := &RunResult{}
169182
r := func() error {
170183
c := exec.CommandContext(ctx, tf.Name(), args...)
171-
legacyEnv := []string{}
184+
var legacyEnv []string
172185
// replace the global KUBECONFIG with a fresh kubeconfig
173186
// because for minikube<1.17.0 it can not read the new kubeconfigs that have extra "Extenions" block
174187
// see: https://github.com/kubernetes/minikube/issues/10210

0 commit comments

Comments
 (0)