+
-Our [goal](https://github.com/kubernetes/minikube/blob/master/docs/contributors/principles.md) is to enable fast local development and to support all Kubernetes features that fit. We hope you enjoy it!
+Our [project goals](https://github.com/kubernetes/minikube/blob/master/docs/contributors/principles.md) are to enable fast local development and to support all Kubernetes features that fit. We hope you enjoy it!
## News
+* 2019-03-27 - v1.0.0 released! [[download](https://github.com/kubernetes/minikube/releases/tag/v1.0.0)] [[release notes](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md#version-1000---2019-03-27)]
* 2019-03-06 - v0.35.0 released! [[download](https://github.com/kubernetes/minikube/releases/tag/v0.35.0)] [[release notes](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md#version-0350---2019-03-06)]
* 2019-02-16 - v0.34.1 released! [[download](https://github.com/kubernetes/minikube/releases/tag/v0.34.1)] [[release notes](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md#version-0341---2019-02-16)]
-* 2019-02-15 - v0.34.0 released! [[download](https://github.com/kubernetes/minikube/releases/tag/v0.34.0)] [[release notes](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md#version-0340---2019-02-15)]
-* 2019-01-18 - v0.33.1 released to address [CVE-2019-5736](https://www.openwall.com/lists/oss-security/2019/02/11/2) [[download](https://github.com/kubernetes/minikube/releases/tag/v0.33.1)] [[release notes](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md#version-0331---2019-01-18)]
-* 2019-01-17 - v0.33.0 released! [[download](https://github.com/kubernetes/minikube/releases/tag/v0.33.0)] [[release notes](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md#version-0330---2019-01-17)]
## Features
@@ -56,6 +54,8 @@ As well as developer-friendly features:
## Community
+
+
minikube is a Kubernetes [#sig-cluster-lifecycle](https://github.com/kubernetes/community/tree/master/sig-cluster-lifecycle) project.
* [**#minikube on Kubernetes Slack**](https://kubernetes.slack.com) - Live chat with minikube developers!
diff --git a/cmd/minikube/cmd/cache.go b/cmd/minikube/cmd/cache.go
index b6fdb246ca..7b403f4b90 100644
--- a/cmd/minikube/cmd/cache.go
+++ b/cmd/minikube/cmd/cache.go
@@ -66,20 +66,43 @@ var deleteCacheCmd = &cobra.Command{
},
}
-// LoadCachedImagesInConfigFile loads the images currently in the config file (minikube start)
-func LoadCachedImagesInConfigFile() error {
+func imagesInConfigFile() ([]string, error) {
configFile, err := config.ReadConfig()
if err != nil {
- return err
+ return nil, err
}
if values, ok := configFile[constants.Cache]; ok {
var images []string
for key := range values.(map[string]interface{}) {
images = append(images, key)
}
- return machine.CacheAndLoadImages(images)
+ return images, nil
}
- return nil
+ return []string{}, nil
+}
+
+// CacheImagesInConfigFile caches the images currently in the config file (minikube start)
+func CacheImagesInConfigFile() error {
+ images, err := imagesInConfigFile()
+ if err != nil {
+ return err
+ }
+ if len(images) == 0 {
+ return nil
+ }
+ return machine.CacheImages(images, constants.ImageCacheDir)
+}
+
+// LoadCachedImagesInConfigFile loads the images currently in the config file (minikube start)
+func LoadCachedImagesInConfigFile() error {
+ images, err := imagesInConfigFile()
+ if err != nil {
+ return err
+ }
+ if len(images) == 0 {
+ return nil
+ }
+ return machine.CacheAndLoadImages(images)
}
func init() {
diff --git a/cmd/minikube/cmd/completion.go b/cmd/minikube/cmd/completion.go
index 7de31f9086..eb697b8834 100644
--- a/cmd/minikube/cmd/completion.go
+++ b/cmd/minikube/cmd/completion.go
@@ -105,8 +105,10 @@ func GenerateBashCompletion(w io.Writer, cmd *cobra.Command) error {
// GenerateZshCompletion generates the completion for the zsh shell
func GenerateZshCompletion(out io.Writer, cmd *cobra.Command) error {
- zshInitialization := `#compdef minikube
+ zshAutoloadTag := `#compdef minikube
+`
+ zshInitialization := `
__minikube_bash_source() {
alias shopt=':'
alias _expand=_bash_expand
@@ -239,7 +241,12 @@ __minikube_convert_bash_to_zsh() {
<<'BASH_COMPLETION_EOF'
`
- _, err := out.Write([]byte(boilerPlate))
+ _, err := out.Write([]byte(zshAutoloadTag))
+ if err != nil {
+ return err
+ }
+
+ _, err = out.Write([]byte(boilerPlate))
if err != nil {
return err
}
diff --git a/cmd/minikube/cmd/mount.go b/cmd/minikube/cmd/mount.go
index 4260178135..36c7071837 100644
--- a/cmd/minikube/cmd/mount.go
+++ b/cmd/minikube/cmd/mount.go
@@ -45,8 +45,8 @@ var mountIP string
var mountVersion string
var mountType string
var isKill bool
-var uid int
-var gid int
+var uid string
+var gid string
var mSize int
var options []string
var mode uint
@@ -98,6 +98,7 @@ var mountCmd = &cobra.Command{
}
defer api.Close()
host, err := api.Load(config.GetMachineName())
+
if err != nil {
exit.WithError("Error loading api", err)
}
@@ -144,8 +145,8 @@ var mountCmd = &cobra.Command{
console.OutStyle("mounting", "Mounting host path %s into VM as %s ...", hostPath, vmPath)
console.OutStyle("mount-options", "Mount options:")
console.OutStyle("option", "Type: %s", cfg.Type)
- console.OutStyle("option", "UID: %d", cfg.UID)
- console.OutStyle("option", "GID: %d", cfg.GID)
+ console.OutStyle("option", "UID: %s", cfg.UID)
+ console.OutStyle("option", "GID: %s", cfg.GID)
console.OutStyle("option", "Version: %s", cfg.Version)
console.OutStyle("option", "MSize: %d", cfg.MSize)
console.OutStyle("option", "Mode: %o (%s)", cfg.Mode, cfg.Mode)
@@ -163,22 +164,32 @@ var mountCmd = &cobra.Command{
go func() {
console.OutStyle("fileserver", "Userspace file server: ")
ufs.StartServer(net.JoinHostPort(ip.String(), strconv.Itoa(port)), debugVal, hostPath)
+ console.OutStyle("stopped", "Userspace file server is shutdown")
wg.Done()
}()
}
+ // Use CommandRunner, as the native docker ssh service dies when Ctrl-C is received.
+ runner, err := machine.CommandRunner(host)
+ if err != nil {
+ exit.WithError("Failed to get command runner", err)
+ }
+
// Unmount if Ctrl-C or kill request is received.
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
for sig := range c {
console.OutStyle("unmount", "Unmounting %s ...", vmPath)
- cluster.Unmount(host, vmPath)
+ err := cluster.Unmount(runner, vmPath)
+ if err != nil {
+ console.ErrStyle("failure", "Failed unmount: %v", err)
+ }
exit.WithCode(exit.Interrupted, "Exiting due to %s signal", sig)
}
}()
- err = cluster.Mount(host, ip.String(), vmPath, cfg)
+ err = cluster.Mount(runner, ip.String(), vmPath, cfg)
if err != nil {
exit.WithError("mount failed", err)
}
@@ -194,8 +205,8 @@ func init() {
mountCmd.Flags().StringVar(&mountType, "type", nineP, "Specify the mount filesystem type (supported types: 9p)")
mountCmd.Flags().StringVar(&mountVersion, "9p-version", constants.DefaultMountVersion, "Specify the 9p version that the mount should use")
mountCmd.Flags().BoolVar(&isKill, "kill", false, "Kill the mount process spawned by minikube start")
- mountCmd.Flags().IntVar(&uid, "uid", 1001, "Default user id used for the mount")
- mountCmd.Flags().IntVar(&gid, "gid", 1001, "Default group id used for the mount")
+ mountCmd.Flags().StringVar(&uid, "uid", "docker", "Default user id used for the mount")
+ mountCmd.Flags().StringVar(&gid, "gid", "docker", "Default group id used for the mount")
mountCmd.Flags().UintVar(&mode, "mode", 0755, "File permissions used for the mount")
mountCmd.Flags().StringSliceVar(&options, "options", []string{}, "Additional mount options, such as cache=fscache")
mountCmd.Flags().IntVar(&mSize, "msize", constants.DefaultMsize, "The number of bytes to use for 9p packet payload")
diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go
index f01fe44827..f7b7221c39 100644
--- a/cmd/minikube/cmd/start.go
+++ b/cmd/minikube/cmd/start.go
@@ -87,6 +87,7 @@ const (
hidden = "hidden"
embedCerts = "embed-certs"
noVTXCheck = "no-vtx-check"
+ downloadOnly = "download-only"
)
var (
@@ -135,7 +136,8 @@ func init() {
startCmd.Flags().String(networkPlugin, "", "The name of the network plugin")
startCmd.Flags().Bool(enableDefaultCNI, false, "Enable the default CNI plugin (/etc/cni/net.d/k8s.conf). Used in conjunction with \"--network-plugin=cni\"")
startCmd.Flags().String(featureGates, "", "A set of key=value pairs that describe feature gates for alpha/experimental features.")
- startCmd.Flags().Bool(cacheImages, true, "If true, cache docker images for the current bootstrapper and load them into the machine.")
+ startCmd.Flags().Bool(downloadOnly, false, "If true, only download and cache files for later use - don't install or start anything.")
+ startCmd.Flags().Bool(cacheImages, true, "If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --vm-driver=none.")
startCmd.Flags().Var(&extraOptions, "extra-config",
`A set of key=value pairs that describe configuration that may be passed to different components.
The key should be '.' separated, and the first part before the dot is the component to apply the configuration to.
@@ -174,6 +176,11 @@ func runStart(cmd *cobra.Command, args []string) {
exit.WithError("Failed to generate config", err)
}
+ if viper.GetString(vmDriver) == constants.DriverNone {
+ // Optimization: images will be persistently loaded into the host's container runtime, so no need to duplicate work.
+ viper.Set(cacheImages, false)
+ }
+
var cacheGroup errgroup.Group
beginCacheImages(&cacheGroup, k8sVersion)
@@ -187,6 +194,22 @@ func runStart(cmd *cobra.Command, args []string) {
if err != nil {
exit.WithError("Failed to get machine client", err)
}
+
+ if viper.GetBool(downloadOnly) {
+ if err := cluster.CacheISO(config.MachineConfig); err != nil {
+ exit.WithError("Failed to cache ISO", err)
+ }
+ if err := doCacheBinaries(k8sVersion); err != nil {
+ exit.WithError("Failed to cache binaries", err)
+ }
+ waitCacheImages(&cacheGroup)
+ if err := CacheImagesInConfigFile(); err != nil {
+ exit.WithError("Failed to cache images", err)
+ }
+ console.OutStyle("check", "Download complete!")
+ return
+ }
+
host, preexisting := startHost(m, config.MachineConfig)
ip := validateNetwork(host)
@@ -201,13 +224,18 @@ func runStart(cmd *cobra.Command, args []string) {
}
cr := configureRuntimes(host, runner)
- bs := prepareHostEnvironment(m, config.KubernetesConfig)
+
+ // prepareHostEnvironment uses the downloaded images, so we need to wait for background task completion.
waitCacheImages(&cacheGroup)
+ bs := prepareHostEnvironment(m, config.KubernetesConfig)
+
// The kube config must be update must come before bootstrapping, otherwise health checks may use a stale IP
kubeconfig := updateKubeConfig(host, &config)
bootstrapCluster(bs, cr, runner, config.KubernetesConfig, preexisting)
- validateCluster(bs, cr, runner, ip)
+
+ apiserverPort := config.KubernetesConfig.NodePort
+ validateCluster(bs, cr, runner, ip, apiserverPort)
configureMounts()
if err = LoadCachedImagesInConfigFile(); err != nil {
console.Failure("Unable to load cached images from config file.")
@@ -245,6 +273,11 @@ func validateConfig() {
}
}
+// doCacheBinaries caches Kubernetes binaries in the foreground
+func doCacheBinaries(k8sVersion string) error {
+ return machine.CacheBinariesForBootstrapper(k8sVersion, viper.GetString(cmdcfg.Bootstrapper))
+}
+
// beginCacheImages caches Docker images in the background
func beginCacheImages(g *errgroup.Group, k8sVersion string) {
if !viper.GetBool(cacheImages) {
@@ -256,6 +289,17 @@ func beginCacheImages(g *errgroup.Group, k8sVersion string) {
})
}
+// waitCacheImages blocks until the image cache jobs complete
+func waitCacheImages(g *errgroup.Group) {
+ if !viper.GetBool(cacheImages) {
+ return
+ }
+ console.OutStyle("waiting", "Waiting for image downloads to complete ...")
+ if err := g.Wait(); err != nil {
+ glog.Errorln("Error caching images: ", err)
+ }
+}
+
// generateConfig generates cfg.Config based on flags and supplied arguments
func generateConfig(cmd *cobra.Command, k8sVersion string) (cfg.Config, error) {
r, err := cruntime.New(cruntime.Config{Type: viper.GetString(containerRuntime)})
@@ -511,17 +555,6 @@ func configureRuntimes(h *host.Host, runner bootstrapper.CommandRunner) cruntime
return cr
}
-// waitCacheImages blocks until the image cache jobs complete
-func waitCacheImages(g *errgroup.Group) {
- if !viper.GetBool(cacheImages) {
- return
- }
- console.OutStyle("waiting", "Waiting for image downloads to complete ...")
- if err := g.Wait(); err != nil {
- glog.Errorln("Error caching images: ", err)
- }
-}
-
// bootstrapCluster starts Kubernetes using the chosen bootstrapper
func bootstrapCluster(bs bootstrapper.Bootstrapper, r cruntime.Manager, runner bootstrapper.CommandRunner, kc cfg.KubernetesConfig, preexisting bool) {
console.OutStyle("pulling", "Pulling images required by Kubernetes %s ...", kc.KubernetesVersion)
@@ -546,7 +579,7 @@ func bootstrapCluster(bs bootstrapper.Bootstrapper, r cruntime.Manager, runner b
}
// validateCluster validates that the cluster is well-configured and healthy
-func validateCluster(bs bootstrapper.Bootstrapper, r cruntime.Manager, runner bootstrapper.CommandRunner, ip string) {
+func validateCluster(bs bootstrapper.Bootstrapper, r cruntime.Manager, runner bootstrapper.CommandRunner, ip string, apiserverPort int) {
console.OutStyle("verifying-noline", "Verifying component health ...")
k8sStat := func() (err error) {
st, err := bs.GetKubeletStatus()
@@ -561,7 +594,7 @@ func validateCluster(bs bootstrapper.Bootstrapper, r cruntime.Manager, runner bo
exit.WithLogEntries("kubelet checks failed", err, logs.FindProblems(r, bs, runner))
}
aStat := func() (err error) {
- st, err := bs.GetAPIServerStatus(net.ParseIP(ip))
+ st, err := bs.GetAPIServerStatus(net.ParseIP(ip), apiserverPort)
console.Out(".")
if err != nil || st != state.Running.String() {
return &pkgutil.RetriableError{Err: fmt.Errorf("apiserver status=%s err=%v", st, err)}
diff --git a/cmd/minikube/cmd/status.go b/cmd/minikube/cmd/status.go
index b39810318a..668ee9815a 100644
--- a/cmd/minikube/cmd/status.go
+++ b/cmd/minikube/cmd/status.go
@@ -92,7 +92,13 @@ var statusCmd = &cobra.Command{
glog.Errorln("Error host driver ip status:", err)
}
- apiserverSt, err = clusterBootstrapper.GetAPIServerStatus(ip)
+ apiserverPort, err := pkgutil.GetPortFromKubeConfig(util.GetKubeConfigPath(), config.GetMachineName())
+ if err != nil {
+ // Fallback to presuming default apiserver port
+ apiserverPort = pkgutil.APIServerPort
+ }
+
+ apiserverSt, err = clusterBootstrapper.GetAPIServerStatus(ip, apiserverPort)
if err != nil {
glog.Errorln("Error apiserver status:", err)
} else if apiserverSt != state.Running.String() {
diff --git a/deploy/addons/addon-manager.yaml b/deploy/addons/addon-manager.yaml
index 56f6bb036d..534afc870f 100644
--- a/deploy/addons/addon-manager.yaml
+++ b/deploy/addons/addon-manager.yaml
@@ -19,13 +19,13 @@ metadata:
namespace: kube-system
labels:
component: kube-addon-manager
- version: v8.6
+ version: v9.0
kubernetes.io/minikube-addons: addon-manager
spec:
hostNetwork: true
containers:
- name: kube-addon-manager
- image: {{default "k8s.gcr.io" .ImageRepository}}/kube-addon-manager:v8.6
+ image: {{default "k8s.gcr.io" .ImageRepository}}/kube-addon-manager:v9.0
env:
- name: KUBECONFIG
value: /var/lib/minikube/kubeconfig
diff --git a/deploy/addons/registry/registry-rc.yaml b/deploy/addons/registry/registry-rc.yaml
index aa0a59ee7a..bee3a42ff0 100644
--- a/deploy/addons/registry/registry-rc.yaml
+++ b/deploy/addons/registry/registry-rc.yaml
@@ -23,3 +23,6 @@ spec:
ports:
- containerPort: 5000
protocol: TCP
+ env:
+ - name: REGISTRY_STORAGE_DELETE_ENABLED
+ value: true
diff --git a/deploy/iso/minikube-iso/board/coreos/minikube/linux_defconfig b/deploy/iso/minikube-iso/board/coreos/minikube/linux_defconfig
index e9394abf9f..c770ca5a9f 100644
--- a/deploy/iso/minikube-iso/board/coreos/minikube/linux_defconfig
+++ b/deploy/iso/minikube-iso/board/coreos/minikube/linux_defconfig
@@ -20,7 +20,6 @@ CONFIG_RT_GROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
-CONFIG_CGROUP_NET_PRIO=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
@@ -114,6 +113,7 @@ CONFIG_NETFILTER=y
CONFIG_NETFILTER_NETLINK_ACCT=y
CONFIG_NETFILTER_NETLINK_QUEUE=y
CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_ZONES=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_TIMEOUT=y
CONFIG_NF_CONNTRACK_TIMESTAMP=y
@@ -123,8 +123,6 @@ CONFIG_NF_CONNTRACK_SANE=m
CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CT_NETLINK=m
-CONFIG_NF_SOCKET_IPV4=m
-CONFIG_NF_SOCKET_IPV6=m
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
@@ -229,6 +227,7 @@ CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_NFCT=y
CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_SOCKET_IPV4=m
CONFIG_NF_LOG_ARP=m
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_FILTER=y
@@ -240,6 +239,7 @@ CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=y
CONFIG_IP_NF_RAW=m
CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_NF_SOCKET_IPV6=m
CONFIG_IP6_NF_IPTABLES=y
CONFIG_IP6_NF_MATCH_IPV6HEADER=y
CONFIG_IP6_NF_FILTER=y
@@ -277,6 +277,7 @@ CONFIG_NET_ACT_BPF=m
CONFIG_OPENVSWITCH=m
CONFIG_VSOCKETS=m
CONFIG_VIRTIO_VSOCKETS=m
+CONFIG_CGROUP_NET_PRIO=y
CONFIG_BPF_JIT=y
CONFIG_HAMRADIO=y
CONFIG_CFG80211=y
@@ -428,7 +429,6 @@ CONFIG_RTC_CLASS=y
# CONFIG_RTC_HCTOSYS is not set
CONFIG_DMADEVICES=y
CONFIG_VIRT_DRIVERS=y
-CONFIG_VBOXGUEST=m
CONFIG_VIRTIO_PCI=y
CONFIG_HYPERV=m
CONFIG_HYPERV_UTILS=m
diff --git a/deploy/iso/minikube-iso/package/Config.in b/deploy/iso/minikube-iso/package/Config.in
index 2205935bac..d33f9e3356 100644
--- a/deploy/iso/minikube-iso/package/Config.in
+++ b/deploy/iso/minikube-iso/package/Config.in
@@ -7,7 +7,7 @@ menu "System tools"
source "$BR2_EXTERNAL_MINIKUBE_PATH/package/docker-bin/Config.in"
source "$BR2_EXTERNAL_MINIKUBE_PATH/package/cni-bin/Config.in"
source "$BR2_EXTERNAL_MINIKUBE_PATH/package/cni-plugins-bin/Config.in"
- source "$BR2_EXTERNAL_MINIKUBE_PATH/package/hv-kvp-daemon/Config.in"
+ source "$BR2_EXTERNAL_MINIKUBE_PATH/package/hyperv-daemons/Config.in"
source "$BR2_EXTERNAL_MINIKUBE_PATH/package/gluster/Config.in"
source "$BR2_EXTERNAL_MINIKUBE_PATH/package/vbox-guest/Config.in"
source "$BR2_EXTERNAL_MINIKUBE_PATH/package/containerd-bin/Config.in"
diff --git a/deploy/iso/minikube-iso/package/docker-bin/docker-bin.hash b/deploy/iso/minikube-iso/package/docker-bin/docker-bin.hash
index 995d0c5eb1..09da6e4b90 100644
--- a/deploy/iso/minikube-iso/package/docker-bin/docker-bin.hash
+++ b/deploy/iso/minikube-iso/package/docker-bin/docker-bin.hash
@@ -7,3 +7,4 @@ sha256 692e1c72937f6214b1038def84463018d8e320c8eaf8530546c84c2f8f9c767d docker-
sha256 1270dce1bd7e1838d62ae21d2505d87f16efc1d9074645571daaefdfd0c14054 docker-17.12.1-ce.tgz
sha256 83be159cf0657df9e1a1a4a127d181725a982714a983b2bdcc0621244df93687 docker-18.06.1-ce.tgz
sha256 a979d9a952fae474886c7588da692ee00684cb2421d2c633c7ed415948cf0b10 docker-18.06.2-ce.tgz
+sha256 346f9394393ee8db5f8bd1e229ee9d90e5b36931bdd754308b2ae68884dd6822 docker-18.06.3-ce.tgz
diff --git a/deploy/iso/minikube-iso/package/docker-bin/docker-bin.mk b/deploy/iso/minikube-iso/package/docker-bin/docker-bin.mk
index 0e1fec3935..e1f34f8c73 100644
--- a/deploy/iso/minikube-iso/package/docker-bin/docker-bin.mk
+++ b/deploy/iso/minikube-iso/package/docker-bin/docker-bin.mk
@@ -4,7 +4,7 @@
#
################################################################################
-DOCKER_BIN_VERSION = 18.06.2-ce
+DOCKER_BIN_VERSION = 18.06.3-ce
DOCKER_BIN_SITE = https://download.docker.com/linux/static/stable/x86_64
DOCKER_BIN_SOURCE = docker-$(DOCKER_BIN_VERSION).tgz
diff --git a/deploy/iso/minikube-iso/package/hv-kvp-daemon/Config.in b/deploy/iso/minikube-iso/package/hv-kvp-daemon/Config.in
deleted file mode 100644
index b3c164b3b8..0000000000
--- a/deploy/iso/minikube-iso/package/hv-kvp-daemon/Config.in
+++ /dev/null
@@ -1,4 +0,0 @@
-config BR2_PACKAGE_HV_KVP_DAEMON
- bool "hv-kvp-daemon"
- default y
- depends on BR2_x86_64
diff --git a/deploy/iso/minikube-iso/package/hv-kvp-daemon/hv_kvp_daemon.mk b/deploy/iso/minikube-iso/package/hv-kvp-daemon/hv_kvp_daemon.mk
deleted file mode 100644
index 632bf36fc3..0000000000
--- a/deploy/iso/minikube-iso/package/hv-kvp-daemon/hv_kvp_daemon.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-################################################################################
-#
-# hv-kvp-daemon
-#
-################################################################################
-
-HV_KVP_DAEMON_VERSION = 4.4.27
-HV_KVP_DAEMON_SITE = https://www.kernel.org/pub/linux/kernel/v${HV_KVP_DAEMON_VERSION%%.*}.x
-HV_KVP_DAEMON_SOURCE = linux-$(HV_KVP_DAEMON_VERSION).tar.xz
-
-define HV_KVP_DAEMON_BUILD_CMDS
- $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D)/tools/hv/
-endef
-
-define HV_KVP_DAEMON_INSTALL_TARGET_CMDS
- $(INSTALL) -D -m 0755 \
- $(@D)/tools/hv/hv_kvp_daemon \
- $(TARGET_DIR)/usr/sbin/hv_kvp_daemon
-endef
-
-define HV_KVP_DAEMON_INSTALL_INIT_SYSTEMD
- $(INSTALL) -D -m 644 \
- $(BR2_EXTERNAL_MINIKUBE_PATH)/package/hv-kvp-daemon/hv_kvp_daemon.service \
- $(TARGET_DIR)/usr/lib/systemd/system/hv_kvp_daemon.service
-
- ln -fs /usr/lib/systemd/system/hv_kvp_daemon.service \
- $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/hv_kvp_daemon.service
-endef
-
-$(eval $(generic-package))
diff --git a/deploy/iso/minikube-iso/package/hv-kvp-daemon/hv_kvp_daemon.service b/deploy/iso/minikube-iso/package/hv-kvp-daemon/hv_kvp_daemon.service
deleted file mode 100644
index 8dc1336cfd..0000000000
--- a/deploy/iso/minikube-iso/package/hv-kvp-daemon/hv_kvp_daemon.service
+++ /dev/null
@@ -1,15 +0,0 @@
-[Unit]
-Description=Hyper-V Key Value Pair Daemon
-Documentation=https://technet.microsoft.com/en-us/library/dn798287(v=ws.11).aspx
-ConditionVirtualization=microsoft
-
-
-[Service]
-Type=simple
-Restart=always
-RestartSec=3
-
-ExecStart=/usr/sbin/hv_kvp_daemon -n
-
-[Install]
-WantedBy=multi-user.target
diff --git a/deploy/iso/minikube-iso/package/hyperv-daemons/70-hv_fcopy.rules b/deploy/iso/minikube-iso/package/hyperv-daemons/70-hv_fcopy.rules
new file mode 100644
index 0000000000..a186817c38
--- /dev/null
+++ b/deploy/iso/minikube-iso/package/hyperv-daemons/70-hv_fcopy.rules
@@ -0,0 +1 @@
+SUBSYSTEM=="misc", KERNEL=="vmbus/hv_fcopy", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv_fcopy_daemon.service"
diff --git a/deploy/iso/minikube-iso/package/hyperv-daemons/70-hv_kvp.rules b/deploy/iso/minikube-iso/package/hyperv-daemons/70-hv_kvp.rules
new file mode 100644
index 0000000000..7193fdda45
--- /dev/null
+++ b/deploy/iso/minikube-iso/package/hyperv-daemons/70-hv_kvp.rules
@@ -0,0 +1 @@
+SUBSYSTEM=="misc", KERNEL=="vmbus/hv_kvp", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv_kvp_daemon.service"
diff --git a/deploy/iso/minikube-iso/package/hyperv-daemons/70-hv_vss.rules b/deploy/iso/minikube-iso/package/hyperv-daemons/70-hv_vss.rules
new file mode 100644
index 0000000000..1274dec1eb
--- /dev/null
+++ b/deploy/iso/minikube-iso/package/hyperv-daemons/70-hv_vss.rules
@@ -0,0 +1 @@
+SUBSYSTEM=="misc", KERNEL=="vmbus/hv_vss", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv_vss_daemon.service"
diff --git a/deploy/iso/minikube-iso/package/hyperv-daemons/Config.in b/deploy/iso/minikube-iso/package/hyperv-daemons/Config.in
new file mode 100644
index 0000000000..834b31bdcb
--- /dev/null
+++ b/deploy/iso/minikube-iso/package/hyperv-daemons/Config.in
@@ -0,0 +1,4 @@
+config BR2_PACKAGE_HYPERV_DAEMONS
+ bool "hyperv-daemons"
+ default y
+ depends on BR2_x86_64
diff --git a/deploy/iso/minikube-iso/package/hyperv-daemons/hv_fcopy_daemon.service b/deploy/iso/minikube-iso/package/hyperv-daemons/hv_fcopy_daemon.service
new file mode 100644
index 0000000000..88fed6f5ad
--- /dev/null
+++ b/deploy/iso/minikube-iso/package/hyperv-daemons/hv_fcopy_daemon.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Hyper-V FCOPY Daemon
+Documentation=https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/integration-services#hyper-v-guest-service-interface
+BindsTo=sys-devices-virtual-misc-vmbus\x21hv_fcopy.device
+
+[Service]
+ExecStart=/usr/sbin/hv_fcopy_daemon -n
+
+[Install]
+WantedBy=multi-user.target
diff --git a/deploy/iso/minikube-iso/package/hyperv-daemons/hv_kvp_daemon.service b/deploy/iso/minikube-iso/package/hyperv-daemons/hv_kvp_daemon.service
new file mode 100644
index 0000000000..6cd7e9d6c1
--- /dev/null
+++ b/deploy/iso/minikube-iso/package/hyperv-daemons/hv_kvp_daemon.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Hyper-V Key Value Pair Daemon
+Documentation=https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/integration-services#hyper-v-data-exchange-service-kvp
+BindsTo=sys-devices-virtual-misc-vmbus\x21hv_kvp.device
+
+[Service]
+ExecStart=/usr/sbin/hv_kvp_daemon -n
+
+[Install]
+WantedBy=multi-user.target
diff --git a/deploy/iso/minikube-iso/package/hyperv-daemons/hv_vss_daemon.service b/deploy/iso/minikube-iso/package/hyperv-daemons/hv_vss_daemon.service
new file mode 100644
index 0000000000..d12aa1dded
--- /dev/null
+++ b/deploy/iso/minikube-iso/package/hyperv-daemons/hv_vss_daemon.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Hyper-V VSS Daemon
+Documentation=https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/integration-services#hyper-v-volume-shadow-copy-requestor
+BindsTo=sys-devices-virtual-misc-vmbus\x21hv_vss.device
+
+[Service]
+ExecStart=/usr/sbin/hv_vss_daemon -n
+
+[Install]
+WantedBy=multi-user.target
diff --git a/deploy/iso/minikube-iso/package/hyperv-daemons/hyperv-daemons.mk b/deploy/iso/minikube-iso/package/hyperv-daemons/hyperv-daemons.mk
new file mode 100644
index 0000000000..d0fadf5b1c
--- /dev/null
+++ b/deploy/iso/minikube-iso/package/hyperv-daemons/hyperv-daemons.mk
@@ -0,0 +1,67 @@
+################################################################################
+#
+# hyperv-daemons
+#
+################################################################################
+
+HYPERV_DAEMONS_VERSION = 4.15.1
+HYPERV_DAEMONS_SITE = https://www.kernel.org/pub/linux/kernel/v${HYPERV_DAEMONS_VERSION%%.*}.x
+HYPERV_DAEMONS_SOURCE = linux-$(HYPERV_DAEMONS_VERSION).tar.xz
+
+define HYPERV_DAEMONS_BUILD_CMDS
+ $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D)/tools/hv/
+endef
+
+define HYPERV_DAEMONS_INSTALL_TARGET_CMDS
+ $(INSTALL) -D -m 0755 \
+ $(@D)/tools/hv/hv_fcopy_daemon \
+ $(TARGET_DIR)/usr/sbin/hv_fcopy_daemon
+
+ $(INSTALL) -D -m 0755 \
+ $(@D)/tools/hv/hv_kvp_daemon \
+ $(TARGET_DIR)/usr/sbin/hv_kvp_daemon
+ $(INSTALL) -D -m 0755 \
+ $(@D)/tools/hv/hv_get_dhcp_info.sh \
+ $(TARGET_DIR)/usr/libexec/hypervkvpd/hv_get_dhcp_info
+ $(INSTALL) -D -m 0755 \
+ $(@D)/tools/hv/hv_get_dns_info.sh \
+ $(TARGET_DIR)/usr/libexec/hypervkvpd/hv_get_dns_info
+ $(INSTALL) -D -m 0755 \
+ $(@D)/tools/hv/hv_set_ifconfig.sh \
+ $(TARGET_DIR)/usr/libexec/hypervkvpd/hv_set_ifconfig
+
+ $(INSTALL) -D -m 0755 \
+ $(@D)/tools/hv/hv_vss_daemon \
+ $(TARGET_DIR)/usr/sbin/hv_vss_daemon
+endef
+
+define HYPERV_DAEMONS_INSTALL_INIT_SYSTEMD
+ $(INSTALL) -D -m 644 \
+ $(BR2_EXTERNAL_MINIKUBE_PATH)/package/hyperv-daemons/70-hv_fcopy.rules \
+ $(TARGET_DIR)/etc/udev/rules.d/70-hv_fcopy.rules
+ $(INSTALL) -D -m 644 \
+ $(BR2_EXTERNAL_MINIKUBE_PATH)/package/hyperv-daemons/70-hv_kvp.rules \
+ $(TARGET_DIR)/etc/udev/rules.d/70-hv_kvp.rules
+ $(INSTALL) -D -m 644 \
+ $(BR2_EXTERNAL_MINIKUBE_PATH)/package/hyperv-daemons/70-hv_vss.rules \
+ $(TARGET_DIR)/etc/udev/rules.d/70-hv_vss.rules
+
+ $(INSTALL) -D -m 644 \
+ $(BR2_EXTERNAL_MINIKUBE_PATH)/package/hyperv-daemons/hv_fcopy_daemon.service \
+ $(TARGET_DIR)/usr/lib/systemd/system/hv_fcopy_daemon.service
+ $(INSTALL) -D -m 644 \
+ $(BR2_EXTERNAL_MINIKUBE_PATH)/package/hyperv-daemons/hv_kvp_daemon.service \
+ $(TARGET_DIR)/usr/lib/systemd/system/hv_kvp_daemon.service
+ $(INSTALL) -D -m 644 \
+ $(BR2_EXTERNAL_MINIKUBE_PATH)/package/hyperv-daemons/hv_vss_daemon.service \
+ $(TARGET_DIR)/usr/lib/systemd/system/hv_vss_daemon.service
+
+ ln -fs /usr/lib/systemd/system/hv_fcopy_daemon.service \
+ $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/hv_fcopy_daemon.service
+ ln -fs /usr/lib/systemd/system/hv_kvp_daemon.service \
+ $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/hv_kvp_daemon.service
+ ln -fs /usr/lib/systemd/system/hv_vss_daemon.service \
+ $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/hv_vss_daemon.service
+endef
+
+$(eval $(generic-package))
diff --git a/deploy/minikube/releases.json b/deploy/minikube/releases.json
index c3bcb33d50..bce02f2e6c 100644
--- a/deploy/minikube/releases.json
+++ b/deploy/minikube/releases.json
@@ -1,4 +1,12 @@
[
+ {
+ "name": "v1.0.0",
+ "checksums": {
+ "darwin": "865bd3a13c1ad3b7732b2bea35b26fef150f2b3cbfc257c5d1835527d1b331e9",
+ "linux": "a315869f81aae782ecc6ff2a6de4d0ab3a17ca1840d1d8e6eea050a8dd05907f",
+ "windows": "a9e629911498ce774681504abe1797c1957e29d100d40c80c26ac54e22716a85"
+ }
+ },
{
"name": "v0.35.0",
"checksums": {
diff --git a/docs/README.md b/docs/README.md
index d76126f0fa..ad3a47b749 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -41,3 +41,5 @@
* **Accessing etcd from inside the cluster** ([accessing_etcd.md](accessing_etcd.md))
* **Networking** ([networking.md](networking.md)): FAQ about networking between the host and minikube VM
+
+* **Offline** ([offline.md](offline.md)): Details about using minikube offline
diff --git a/docs/contributors/releasing_minikube.md b/docs/contributors/releasing_minikube.md
index f35b8643ab..29822c494b 100644
--- a/docs/contributors/releasing_minikube.md
+++ b/docs/contributors/releasing_minikube.md
@@ -78,6 +78,10 @@ This step uses the git tag to publish new binaries to GCS and create a github re
* For `ISO_SHA256`, run: `gsutil cat gs://minikube/iso/minikube-v" lines in HTML files). That may be
+// because this is the only method of the 3 that has a *concept* of
+// "junk"