Skip to content

Commit a4d35d5

Browse files
authoredFeb 25, 2021
Merge pull request #10427 from medyagh/auto-pause
auto-pause addon: automatically pause Kubernetes when not in use
2 parents ad640eb + c6668b9 commit a4d35d5

File tree

20 files changed

+434
-11
lines changed

20 files changed

+434
-11
lines changed
 

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ _testmain.go
2626
*.test
2727
*.prof
2828

29+
/deploy/kicbase/auto-pause
2930
/out
3031
/_gopath
3132

‎Makefile

+5-1
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ KICBASE_ARCH = linux/arm64,linux/amd64
648648
KICBASE_IMAGE_REGISTRIES ?= $(REGISTRY)/kicbase:$(KIC_VERSION) kicbase/stable:$(KIC_VERSION)
649649

650650
.PHONY: push-kic-base-image
651-
push-kic-base-image: docker-multi-arch-builder ## Push multi-arch local/kicbase:latest to all remote registries
651+
push-kic-base-image: deploy/kicbase/auto-pause docker-multi-arch-builder ## Push multi-arch local/kicbase:latest to all remote registries
652652
ifdef AUTOPUSH
653653
docker login gcr.io/k8s-minikube
654654
docker login docker.pkg.github.com
@@ -812,6 +812,10 @@ site: site/themes/docsy/assets/vendor/bootstrap/package.js out/hugo/hugo ## Serv
812812
out/mkcmp:
813813
GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $@ cmd/performance/mkcmp/main.go
814814

815+
.PHONY: deploy/kicbase/auto-pause # auto pause binary to be used for kic image work arround for not passing the whole repo as docker context
816+
deploy/kicbase/auto-pause: $(SOURCE_GENERATED) $(SOURCE_FILES)
817+
GOOS=linux GOARCH=$(GOARCH) go build -o $@ cmd/auto-pause/auto-pause.go
818+
815819
.PHONY: out/performance-bot
816820
out/performance-bot:
817821
GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $@ cmd/performance/pr-bot/bot.go

‎cmd/auto-pause/auto-pause.go

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
Copyright 2021 The Kubernetes Authors All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"fmt"
21+
"log"
22+
"net/http"
23+
"sync"
24+
"time"
25+
26+
"k8s.io/minikube/pkg/minikube/cluster"
27+
"k8s.io/minikube/pkg/minikube/command"
28+
"k8s.io/minikube/pkg/minikube/cruntime"
29+
"k8s.io/minikube/pkg/minikube/exit"
30+
"k8s.io/minikube/pkg/minikube/out"
31+
"k8s.io/minikube/pkg/minikube/reason"
32+
"k8s.io/minikube/pkg/minikube/style"
33+
)
34+
35+
var unpauseRequests = make(chan struct{})
36+
var done = make(chan struct{})
37+
var mu sync.Mutex
38+
39+
// TODO: initialize with current state (handle the case that user enables auto-pause after it is already paused)
40+
var runtimePaused = false
41+
var version = "0.0.1"
42+
43+
// TODO: #10597 make this configurable to support containerd/cri-o
44+
var runtime = "docker"
45+
46+
func main() {
47+
// TODO: #10595 make this configurable
48+
const interval = time.Minute * 1
49+
// channel for incoming messages
50+
go func() {
51+
for {
52+
// On each iteration new timer is created
53+
select {
54+
// TODO: #10596 make it memory-leak proof
55+
case <-time.After(interval):
56+
runPause()
57+
case <-unpauseRequests:
58+
fmt.Printf("Got request\n")
59+
if runtimePaused {
60+
runUnpause()
61+
}
62+
63+
done <- struct{}{}
64+
}
65+
}
66+
}()
67+
68+
http.HandleFunc("/", handler) // each request calls handler
69+
fmt.Printf("Starting auto-pause server %s at port 8080 \n", version)
70+
log.Fatal(http.ListenAndServe("0.0.0.0:8080", nil))
71+
}
72+
73+
// handler echoes the Path component of the requested URL.
74+
func handler(w http.ResponseWriter, r *http.Request) {
75+
unpauseRequests <- struct{}{}
76+
<-done
77+
fmt.Fprintf(w, "allow")
78+
}
79+
80+
func runPause() {
81+
mu.Lock()
82+
defer mu.Unlock()
83+
if runtimePaused {
84+
return
85+
}
86+
87+
r := command.NewExecRunner(true)
88+
89+
cr, err := cruntime.New(cruntime.Config{Type: runtime, Runner: r})
90+
if err != nil {
91+
exit.Error(reason.InternalNewRuntime, "Failed runtime", err)
92+
}
93+
94+
uids, err := cluster.Pause(cr, r, []string{"kube-system"})
95+
if err != nil {
96+
exit.Error(reason.GuestPause, "Pause", err)
97+
}
98+
99+
runtimePaused = true
100+
101+
out.Step(style.Unpause, "Paused {{.count}} containers", out.V{"count": len(uids)})
102+
}
103+
104+
func runUnpause() {
105+
fmt.Println("unpausing...")
106+
mu.Lock()
107+
defer mu.Unlock()
108+
109+
r := command.NewExecRunner(true)
110+
111+
cr, err := cruntime.New(cruntime.Config{Type: runtime, Runner: r})
112+
if err != nil {
113+
exit.Error(reason.InternalNewRuntime, "Failed runtime", err)
114+
}
115+
116+
uids, err := cluster.Unpause(cr, r, nil)
117+
if err != nil {
118+
exit.Error(reason.GuestUnpause, "Unpause", err)
119+
}
120+
runtimePaused = false
121+
122+
out.Step(style.Unpause, "Unpaused {{.count}} containers", out.V{"count": len(uids)})
123+
}

‎cmd/minikube/cmd/status.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,14 @@ func nodeStatus(api libmachine.API, cc config.ClusterConfig, n config.Node) (*St
379379
return st, nil
380380
}
381381

382-
hostname, _, port, err := driver.ControlPlaneEndpoint(&cc, &n, host.DriverName)
382+
var hostname string
383+
var port int
384+
if cc.Addons["auto-pause"] {
385+
hostname, _, port, err = driver.AutoPauseProxyEndpoint(&cc, &n, host.DriverName)
386+
} else {
387+
hostname, _, port, err = driver.ControlPlaneEndpoint(&cc, &n, host.DriverName)
388+
}
389+
383390
if err != nil {
384391
klog.Errorf("forwarded endpoint: %v", err)
385392
st.Kubeconfig = Misconfigured
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[Unit]
2+
Description=Auto Pause Service
3+
4+
[Service]
5+
Type=simple
6+
ExecStart=/usr/local/bin/auto-pause
7+
Restart=always
8+
9+
[Install]
10+
WantedBy=multi-user.target
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
apiVersion: v1
3+
kind: Namespace
4+
metadata:
5+
name: auto-pause
6+
---
7+
apiVersion: apps/v1
8+
kind: Deployment
9+
metadata:
10+
name: auto-pause-proxy
11+
namespace: auto-pause
12+
labels:
13+
app: auto-pause-proxy
14+
spec:
15+
replicas: 1
16+
selector:
17+
matchLabels:
18+
app: auto-pause-proxy
19+
template:
20+
metadata:
21+
creationTimestamp: null
22+
labels:
23+
app: auto-pause-proxy
24+
spec:
25+
volumes:
26+
- name: ha-cfg
27+
hostPath:
28+
path: /var/lib/minikube/haproxy.cfg
29+
type: File
30+
- name: lua-script
31+
hostPath:
32+
path: /var/lib/minikube/unpause.lua
33+
type: File
34+
containers:
35+
- name: auto-pause
36+
image: "haproxy:2.3.5-alpine"
37+
ports:
38+
- name: https
39+
containerPort: 6443
40+
hostPort: 32443
41+
protocol: TCP
42+
volumeMounts:
43+
- name: ha-cfg
44+
mountPath: /usr/local/etc/haproxy/haproxy.cfg
45+
readOnly: true
46+
- name: lua-script
47+
mountPath: /etc/haproxy/unpause.lua

‎deploy/addons/auto-pause/haproxy.cfg

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#---------------------------------------------------------------------
2+
# Configure HAProxy for Kubernetes API Server
3+
#---------------------------------------------------------------------
4+
listen stats
5+
bind *:9000
6+
mode http
7+
stats enable
8+
stats hide-version
9+
stats uri /
10+
stats refresh 30s
11+
option httplog
12+
13+
# change haproxy.cfg file with the following
14+
global
15+
lua-load /etc/haproxy/unpause.lua
16+
17+
############## Configure HAProxy Secure Frontend #############
18+
frontend k8s-api-https-proxy
19+
bind *:6443
20+
mode tcp
21+
tcp-request inspect-delay 5s
22+
tcp-request content accept if { req.ssl_hello_type 1 }
23+
default_backend k8s-api-https
24+
############## Configure HAProxy SecureBackend #############
25+
backend k8s-api-https
26+
balance roundrobin
27+
mode tcp
28+
#tcp-request inspect-delay 10s
29+
#tcp-request content lua.foo_action
30+
tcp-request inspect-delay 10s
31+
tcp-request content lua.unpause 192.168.49.2 8080
32+
tcp-request content reject if { var(req.blocked) -m bool }
33+
option tcplog
34+
option tcp-check
35+
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
36+
server k8s-api-1 192.168.49.2:8443 check
37+

‎deploy/addons/auto-pause/unpause.lua

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
local function unpause(txn, addr, port)
2+
if not addr then addr = '127.0.0.1' end
3+
if not port then port = 5000 end
4+
5+
-- Set up a request to the service
6+
local hdrs = {
7+
[1] = string.format('host: %s:%s', addr, port),
8+
[2] = 'accept: */*',
9+
[3] = 'connection: close'
10+
}
11+
12+
local req = {
13+
[1] = string.format('GET /%s HTTP/1.1', tostring(txn.f:src())),
14+
[2] = table.concat(hdrs, '\r\n'),
15+
[3] = '\r\n'
16+
}
17+
18+
req = table.concat(req, '\r\n')
19+
20+
-- Use core.tcp to get an instance of the Socket class
21+
local socket = core.tcp()
22+
socket:settimeout(5)
23+
24+
-- Connect to the service and send the request
25+
if socket:connect(addr, port) then
26+
if socket:send(req) then
27+
-- Skip response headers
28+
while true do
29+
local line, _ = socket:receive('*l')
30+
31+
if not line then break end
32+
if line == '' then break end
33+
end
34+
35+
-- Get response body, if any
36+
local content = socket:receive('*a')
37+
38+
-- Check if this request should be allowed
39+
if content and content == 'allow' then
40+
txn:set_var('req.blocked', false)
41+
return
42+
end
43+
else
44+
core.Alert('Could not connect to IP Checker server (send)')
45+
end
46+
47+
socket:close()
48+
else
49+
core.Alert('Could not connect to IP Checker server (connect)')
50+
end
51+
52+
-- The request should be blocked
53+
txn:set_var('req.blocked', true)
54+
end
55+
56+
core.register_action('unpause', {'tcp-req'}, unpause, 2)
57+

‎deploy/kicbase/Dockerfile

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ COPY 10-network-security.conf /etc/sysctl.d/10-network-security.conf
2828
COPY 11-tcp-mtu-probing.conf /etc/sysctl.d/11-tcp-mtu-probing.conf
2929
COPY clean-install /usr/local/bin/clean-install
3030
COPY entrypoint /usr/local/bin/entrypoint
31+
# must first run make out/auto-pause
32+
COPY auto-pause /usr/local/bin/auto-pause
3133

3234
# Install dependencies, first from apt, then from release tarballs.
3335
# NOTE: we use one RUN to minimize layers.

‎pkg/addons/addons.go

+59-6
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,15 @@ import (
3838
"k8s.io/minikube/pkg/minikube/constants"
3939
"k8s.io/minikube/pkg/minikube/driver"
4040
"k8s.io/minikube/pkg/minikube/exit"
41+
"k8s.io/minikube/pkg/minikube/kubeconfig"
4142
"k8s.io/minikube/pkg/minikube/machine"
43+
"k8s.io/minikube/pkg/minikube/mustload"
4244
"k8s.io/minikube/pkg/minikube/out"
4345
"k8s.io/minikube/pkg/minikube/out/register"
4446
"k8s.io/minikube/pkg/minikube/reason"
4547
"k8s.io/minikube/pkg/minikube/storageclass"
4648
"k8s.io/minikube/pkg/minikube/style"
49+
"k8s.io/minikube/pkg/minikube/sysinit"
4750
"k8s.io/minikube/pkg/util/retry"
4851
)
4952

@@ -201,13 +204,19 @@ https://github.com/kubernetes/minikube/issues/7332`, out.V{"driver_name": cc.Dri
201204
}
202205
}
203206

204-
cmd, err := machine.CommandRunner(host)
207+
runner, err := machine.CommandRunner(host)
205208
if err != nil {
206209
return errors.Wrap(err, "command runner")
207210
}
208211

212+
if name == "auto-pause" && !enable { // needs to be disabled before deleting the service file in the internal disable
213+
if err := sysinit.New(runner).DisableNow("auto-pause"); err != nil {
214+
klog.ErrorS(err, "failed to disable", "service", "auto-pause")
215+
}
216+
}
217+
209218
data := assets.GenerateTemplateData(addon, cc.KubernetesConfig)
210-
return enableOrDisableAddonInternal(cc, addon, cmd, data, enable)
219+
return enableOrDisableAddonInternal(cc, addon, runner, data, enable)
211220
}
212221

213222
func isAddonAlreadySet(cc *config.ClusterConfig, addon *assets.Addon, enable bool) bool {
@@ -223,7 +232,7 @@ func isAddonAlreadySet(cc *config.ClusterConfig, addon *assets.Addon, enable boo
223232
return false
224233
}
225234

226-
func enableOrDisableAddonInternal(cc *config.ClusterConfig, addon *assets.Addon, cmd command.Runner, data interface{}, enable bool) error {
235+
func enableOrDisableAddonInternal(cc *config.ClusterConfig, addon *assets.Addon, runner command.Runner, data interface{}, enable bool) error {
227236
deployFiles := []string{}
228237

229238
for _, addon := range addon.Assets {
@@ -242,13 +251,13 @@ func enableOrDisableAddonInternal(cc *config.ClusterConfig, addon *assets.Addon,
242251

243252
if enable {
244253
klog.Infof("installing %s", fPath)
245-
if err := cmd.Copy(f); err != nil {
254+
if err := runner.Copy(f); err != nil {
246255
return err
247256
}
248257
} else {
249258
klog.Infof("Removing %+v", fPath)
250259
defer func() {
251-
if err := cmd.Remove(f); err != nil {
260+
if err := runner.Remove(f); err != nil {
252261
klog.Warningf("error removing %s; addon should still be disabled as expected", fPath)
253262
}
254263
}()
@@ -260,7 +269,7 @@ func enableOrDisableAddonInternal(cc *config.ClusterConfig, addon *assets.Addon,
260269

261270
// Retry, because sometimes we race against an apiserver restart
262271
apply := func() error {
263-
_, err := cmd.RunCmd(kubectlCommand(cc, deployFiles, enable))
272+
_, err := runner.RunCmd(kubectlCommand(cc, deployFiles, enable))
264273
if err != nil {
265274
klog.Warningf("apply failed, will retry: %v", err)
266275
}
@@ -435,3 +444,47 @@ func Start(wg *sync.WaitGroup, cc *config.ClusterConfig, toEnable map[string]boo
435444
}
436445
}
437446
}
447+
448+
// enableOrDisableAutoPause enables the service after the config was copied by generic enble
449+
func enableOrDisableAutoPause(cc *config.ClusterConfig, name string, val string) error {
450+
enable, err := strconv.ParseBool(val)
451+
if err != nil {
452+
return errors.Wrapf(err, "parsing bool: %s", name)
453+
}
454+
out.Infof("auto-pause addon is an alpha feature and still in early development. Please file issues to help us make it better.")
455+
out.Infof("https://github.com/kubernetes/minikube/labels/co%2Fauto-pause")
456+
457+
if !driver.IsKIC(cc.Driver) || runtime.GOARCH != "amd64" {
458+
exit.Message(reason.Usage, `auto-pause currently is only supported on docker driver/docker runtime/amd64. Track progress of others here: https://github.com/kubernetes/minikube/issues/10601`)
459+
}
460+
co := mustload.Running(cc.Name)
461+
if enable {
462+
if err := sysinit.New(co.CP.Runner).EnableNow("auto-pause"); err != nil {
463+
klog.ErrorS(err, "failed to enable", "service", "auto-pause")
464+
}
465+
}
466+
467+
port := co.CP.Port // api server port
468+
if enable { // if enable then need to calculate the forwarded port
469+
port = constants.AutoPauseProxyPort
470+
if driver.NeedsPortForward(cc.Driver) {
471+
port, err = oci.ForwardedPort(cc.Driver, cc.Name, port)
472+
if err != nil {
473+
klog.ErrorS(err, "failed to get forwarded port for", "auto-pause port", port)
474+
}
475+
}
476+
}
477+
478+
updated, err := kubeconfig.UpdateEndpoint(cc.Name, co.CP.Hostname, port, kubeconfig.PathFromEnv(), kubeconfig.NewExtension())
479+
if err != nil {
480+
klog.ErrorS(err, "failed to update kubeconfig", "auto-pause proxy endpoint")
481+
return err
482+
}
483+
if updated {
484+
klog.Infof("%s context has been updated to point to auto-pause proxy %s:%s", cc.Name, co.CP.Hostname, co.CP.Port)
485+
} else {
486+
klog.Info("no need to update kube-context for auto-pause proxy")
487+
}
488+
489+
return nil
490+
}

‎pkg/addons/config.go

+6
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ var addonPodLabels = map[string]string{
4242

4343
// Addons is a list of all addons
4444
var Addons = []*Addon{
45+
{
46+
name: "auto-pause",
47+
set: SetBool,
48+
callbacks: []setFn{EnableOrDisableAddon, enableOrDisableAutoPause},
49+
},
50+
4551
{
4652
name: "dashboard",
4753
set: SetBool,

‎pkg/drivers/kic/kic.go

+4
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ func (d *Driver) Create() error {
127127
ListenAddress: listAddr,
128128
ContainerPort: constants.RegistryAddonPort,
129129
},
130+
oci.PortMapping{
131+
ListenAddress: listAddr,
132+
ContainerPort: constants.AutoPauseProxyPort,
133+
},
130134
)
131135

132136
exists, err := oci.ContainerExists(d.OCIBinary, params.Name, true)

‎pkg/drivers/kic/types.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ import (
2424

2525
const (
2626
// Version is the current version of kic
27-
Version = "v0.0.17-1613934488-10548"
27+
Version = "v0.0.17-1614202509-10427"
2828
// SHA of the kic base image
29-
baseImageSHA = "5cacd48d07f699a171eedf65ef1490bd59a523ffcd90662e3b66eb838c5a1b5d"
29+
baseImageSHA = "93f2448d272ebad3d564c04474cafe03bb7440149c241d1d010b2e90e14da213"
3030
// The name of the GCR kicbase repository
3131
gcrRepo = "gcr.io/k8s-minikube/kicbase-builds"
3232
// The name of the Dockerhub kicbase repository

‎pkg/minikube/assets/addons.go

+28
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,34 @@ func (a *Addon) IsEnabled(cc *config.ClusterConfig) bool {
7171
// Addons is the list of addons
7272
// TODO: Make dynamically loadable: move this data to a .yaml file within each addon directory
7373
var Addons = map[string]*Addon{
74+
"auto-pause": NewAddon([]*BinAsset{
75+
MustBinAsset(
76+
"deploy/addons/auto-pause/auto-pause.yaml.tmpl",
77+
vmpath.GuestAddonsDir,
78+
"auto-pause.yaml",
79+
"0640"),
80+
MustBinAsset(
81+
"deploy/addons/auto-pause/haproxy.cfg",
82+
"/var/lib/minikube/",
83+
"haproxy.cfg",
84+
"0640"),
85+
MustBinAsset(
86+
"deploy/addons/auto-pause/unpause.lua",
87+
"/var/lib/minikube/",
88+
"unpause.lua",
89+
"0640"),
90+
MustBinAsset(
91+
"deploy/addons/auto-pause/auto-pause.service",
92+
"/etc/systemd/system/",
93+
"auto-pause.service",
94+
"0640"),
95+
96+
//GuestPersistentDir
97+
}, false, "auto-pause", map[string]string{
98+
"haproxy": "haproxy:2.3.5",
99+
}, map[string]string{
100+
"haproxy": "gcr.io",
101+
}),
74102
"dashboard": NewAddon([]*BinAsset{
75103
// We want to create the kubernetes-dashboard ns first so that every subsequent object can be created
76104
MustBinAsset("deploy/addons/dashboard/dashboard-ns.yaml", vmpath.GuestAddonsDir, "dashboard-ns.yaml", "0640"),

‎pkg/minikube/constants/constants.go

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ const (
4141
DockerDaemonPort = 2376
4242
// APIServerPort is the default API server port
4343
APIServerPort = 8443
44+
// AutoPauseProxyPort is the port to be used as a reverse proxy for apiserver port
45+
AutoPauseProxyPort = 32443
46+
4447
// SSHPort is the SSH serviceport on the node vm and container
4548
SSHPort = 22
4649
// RegistryAddonPort os the default registry addon port

‎pkg/minikube/driver/endpoint.go

+10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"fmt"
2121
"net"
2222

23+
"k8s.io/klog/v2"
2324
"k8s.io/minikube/pkg/drivers/kic/oci"
2425
"k8s.io/minikube/pkg/minikube/config"
2526
"k8s.io/minikube/pkg/minikube/constants"
@@ -29,6 +30,9 @@ import (
2930
func ControlPlaneEndpoint(cc *config.ClusterConfig, cp *config.Node, driverName string) (string, net.IP, int, error) {
3031
if NeedsPortForward(driverName) {
3132
port, err := oci.ForwardedPort(cc.Driver, cc.Name, cp.Port)
33+
if err != nil {
34+
klog.Warningf("failed to get forwarded control plane port %v", err)
35+
}
3236
hostname := oci.DaemonHost(driverName)
3337

3438
ip := net.ParseIP(hostname)
@@ -54,3 +58,9 @@ func ControlPlaneEndpoint(cc *config.ClusterConfig, cp *config.Node, driverName
5458
}
5559
return hostname, ip, cp.Port, nil
5660
}
61+
62+
// AutoPauseProxyEndpoint returns the endpoint for the auto-pause (reverse proxy to api-sever)
63+
func AutoPauseProxyEndpoint(cc *config.ClusterConfig, cp *config.Node, driverName string) (string, net.IP, int, error) {
64+
cp.Port = constants.AutoPauseProxyPort
65+
return ControlPlaneEndpoint(cc, cp, driverName)
66+
}

‎pkg/minikube/sysinit/openrc.go

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

120+
// DisableNow not implemented for openRC
121+
func (s *OpenRC) DisableNow(svc string) error {
122+
return fmt.Errorf("disable now is not implemented for OpenRC! PRs to fix are welcomed")
123+
}
124+
120125
// Enable does nothing
121126
func (s *OpenRC) Enable(svc string) error {
122127
return nil
123128
}
124129

130+
// EnableNow not implemented for openRC
131+
func (s *OpenRC) EnableNow(svc string) error {
132+
return fmt.Errorf("enable now is not implemented for OpenRC! PRs to fix are welcomed")
133+
}
134+
125135
// Restart restarts a service
126136
func (s *OpenRC) Restart(svc string) error {
127137
rr, err := s.r.RunCmd(exec.Command("sudo", "service", svc, "restart"))

‎pkg/minikube/sysinit/sysinit.go

+6
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,15 @@ type Manager interface {
4141
// Disable disables a service
4242
Disable(string) error
4343

44+
// Disable disables a service and stops it right after.
45+
DisableNow(string) error
46+
4447
// Enable enables a service
4548
Enable(string) error
4649

50+
// EnableNow enables a service and starts it right after.
51+
EnableNow(string) error
52+
4753
// Start starts a service idempotently
4854
Start(string) error
4955

‎pkg/minikube/sysinit/systemd.go

+15
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ func (s *Systemd) Disable(svc string) error {
5252
return err
5353
}
5454

55+
// DisableNow disables a service and stops it too (not waiting for next restart)
56+
func (s *Systemd) DisableNow(svc string) error {
57+
_, err := s.r.RunCmd(exec.Command("sudo", "systemctl", "disable", "--now", svc))
58+
return err
59+
}
60+
5561
// Enable enables a service
5662
func (s *Systemd) Enable(svc string) error {
5763
if svc == "kubelet" {
@@ -61,6 +67,15 @@ func (s *Systemd) Enable(svc string) error {
6167
return err
6268
}
6369

70+
// Enable enables a service and then activates it too (not waiting for next start)
71+
func (s *Systemd) EnableNow(svc string) error {
72+
if svc == "kubelet" {
73+
return errors.New("please don't enable kubelet as it creates a race condition; if it starts on systemd boot it will pick up /etc/hosts before we have time to configure /etc/hosts")
74+
}
75+
_, err := s.r.RunCmd(exec.Command("sudo", "systemctl", "enable", "--now", svc))
76+
return err
77+
}
78+
6479
// Start starts a service
6580
func (s *Systemd) Start(svc string) error {
6681
if err := s.daemonReload(); err != nil {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ minikube start [flags]
2626
--apiserver-names strings A set of apiserver names which are used in the generated certificate for kubernetes. This can be used if you want to make the apiserver available from outside the machine
2727
--apiserver-port int The apiserver listening port (default 8443)
2828
--auto-update-drivers If set, automatically updates drivers to the latest version. Defaults to true. (default true)
29-
--base-image string The base image to use for docker/podman drivers. Intended for local development. (default "gcr.io/k8s-minikube/kicbase-builds:v0.0.17-1613934488-10548@sha256:5cacd48d07f699a171eedf65ef1490bd59a523ffcd90662e3b66eb838c5a1b5d")
29+
--base-image string The base image to use for docker/podman drivers. Intended for local development. (default "gcr.io/k8s-minikube/kicbase-builds:v0.0.17-1614202509-10427@sha256:93f2448d272ebad3d564c04474cafe03bb7440149c241d1d010b2e90e14da213")
3030
--cache-images If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --driver=none. (default true)
3131
--cni string CNI plug-in to use. Valid options: auto, bridge, calico, cilium, flannel, kindnet, or path to a CNI manifest (default: auto)
3232
--container-runtime string The container runtime to be used (docker, cri-o, containerd). (default "docker")

0 commit comments

Comments
 (0)
Please sign in to comment.