diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
index 39f56ee96a..f1866ac339 100644
--- a/.github/workflows/master.yml
+++ b/.github/workflows/master.yml
@@ -80,6 +80,8 @@ jobs:
         continue-on-error: false
   # Run the following integration tests after the build_minikube
   # They will run in parallel and use the binaries in previous step
+  # Run the following integration tests after the build_minikube
+  # They will run in parallel and use the binaries in previous step
   functional_docker_ubuntu:
     needs: [build_minikube]
     env:
@@ -194,6 +196,16 @@ jobs:
         run: |
           brew install docker-machine docker
           sudo docker --version
+      - name: Info
+        shell: bash
+        run: |
+          hostname
+          VBoxManage --version
+          sysctl hw.physicalcpu hw.logicalcpu 
+      - name: Disable firewall
+        run: |
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw -k
       - name: Download Binaries
         uses: actions/download-artifact@v1
         with:
@@ -666,6 +678,16 @@ jobs:
         run: |
           brew install docker-machine docker
           sudo docker --version
+      - name: Info
+        shell: bash
+        run: |
+          hostname
+          VBoxManage --version
+          sysctl hw.physicalcpu hw.logicalcpu 
+      - name: Disable firewall
+        run: |
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw -k      
       - name: Download Binaries
         uses: actions/download-artifact@v1
         with:
@@ -830,6 +852,16 @@ jobs:
         uses: actions/download-artifact@v1
         with:
           name: minikube_binaries
+      - name: Info
+        shell: bash
+        run: |
+          hostname
+          VBoxManage --version
+          sysctl hw.physicalcpu hw.logicalcpu 
+      - name: Disable firewall
+        run: |
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw -k
       - name: Run Integration Test
         continue-on-error: true
         # bash {0} to allow test to continue to next step. in case of
@@ -988,6 +1020,16 @@ jobs:
         uses: actions/download-artifact@v1
         with:
           name: minikube_binaries
+      - name: Info
+        shell: bash
+        run: |
+          hostname
+          VBoxManage --version
+          sysctl hw.physicalcpu hw.logicalcpu 
+      - name: Disable firewall
+        run: |
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw -k
       - name: Run Integration Test
         continue-on-error: false
         # bash {0} to allow test to continue to next step. in case of
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index 41bfbbc990..4711a151b8 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -192,6 +192,16 @@ jobs:
         run: |
           brew install docker-machine docker
           sudo docker --version
+      - name: Info
+        shell: bash
+        run: |
+          hostname
+          VBoxManage --version
+          sysctl hw.physicalcpu hw.logicalcpu 
+      - name: Disable firewall
+        run: |
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw -k
       - name: Download Binaries
         uses: actions/download-artifact@v1
         with:
@@ -664,6 +674,16 @@ jobs:
         run: |
           brew install docker-machine docker
           sudo docker --version
+      - name: Info
+        shell: bash
+        run: |
+          hostname
+          VBoxManage --version
+          sysctl hw.physicalcpu hw.logicalcpu 
+      - name: Disable firewall
+        run: |
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw -k      
       - name: Download Binaries
         uses: actions/download-artifact@v1
         with:
@@ -828,6 +848,16 @@ jobs:
         uses: actions/download-artifact@v1
         with:
           name: minikube_binaries
+      - name: Info
+        shell: bash
+        run: |
+          hostname
+          VBoxManage --version
+          sysctl hw.physicalcpu hw.logicalcpu 
+      - name: Disable firewall
+        run: |
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw -k
       - name: Run Integration Test
         continue-on-error: true
         # bash {0} to allow test to continue to next step. in case of
@@ -986,6 +1016,16 @@ jobs:
         uses: actions/download-artifact@v1
         with:
           name: minikube_binaries
+      - name: Info
+        shell: bash
+        run: |
+          hostname
+          VBoxManage --version
+          sysctl hw.physicalcpu hw.logicalcpu 
+      - name: Disable firewall
+        run: |
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
+          sudo /usr/libexec/ApplicationFirewall/socketfilterfw -k
       - name: Run Integration Test
         continue-on-error: false
         # bash {0} to allow test to continue to next step. in case of
diff --git a/.travis.yml b/.travis.yml
index f22a5e2bf4..60b85161f6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,7 +3,7 @@
 os: linux
 language: go
 go:
-  - 1.13.9
+  - 1.14.4
 env:
   global:
     - GOPROXY=https://proxy.golang.org
@@ -11,7 +11,7 @@ matrix:
   include:
     - language: go
       name: Code Lint
-      go: 1.13.9
+      go: 1.14.4
       env:
         - TESTSUITE=lintall
       before_install:
@@ -20,7 +20,7 @@ matrix:
 
     - language: go
       name: Unit Test
-      go: 1.13.9
+      go: 1.14.4
       env:
         - TESTSUITE=unittest
       before_install:
@@ -29,7 +29,7 @@ matrix:
 
     - language: go
       name: Build
-      go: 1.13.9
+      go: 1.14.4
       script: make
 after_success:
   - bash <(curl -s https://codecov.io/bash)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ace5fa8836..6c0834aa54 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,35 @@
 # Release Notes
 
+## Version 1.12.0 - 2020-07-09
+
+Features:
+
+* new addon : pod-security-policy [#8454](https://github.com/kubernetes/minikube/pull/8454)
+* new --extra-config option to config "scheduler" [#8147](https://github.com/kubernetes/minikube/pull/8147)
+
+ISO Changes:
+
+* Upgrade Docker, from 19.03.11 to 19.03.12 [#8643](https://github.com/kubernetes/minikube/pull/8643)
+* Upgrade crio to 1.18.2 [#8645](https://github.com/kubernetes/minikube/pull/8645)
+
+Bug fixes:
+
+* none: Fix 'minikube delete' issues when the apiserver is down  [#8664](https://github.com/kubernetes/minikube/pull/8664)
+
+Huge thank you for this release towards our contributors:
+
+- Anders F Björklund
+- Ilya Danilkin
+- Jani Poikela
+- Li Zhijian
+- Matt Broberg
+- Medya Ghazizadeh
+- Priya Wadhwa
+- Sharif Elgamal
+- Thomas Strömberg
+- colvin
+- vinu2003
+
 ## Version 1.12.0-beta.1 - 2020-07-01
 
 Features:
@@ -9,7 +39,7 @@ Features:
 * Reduce coredns replicas from 2 to 1 [#8552](https://github.com/kubernetes/minikube/pull/8552)
 * Allow passing in extra args to etcd via command line [#8551](https://github.com/kubernetes/minikube/pull/8551)
 
-Minor Impovements:
+Minor Improvements:
 
 * Kernel with CONFIG_IKHEADERS for BPF tools on Kubernetes [#8582](https://github.com/kubernetes/minikube/pull/8582)
 * CNI: Update CRIO netconfig with matching subnet [#8570](https://github.com/kubernetes/minikube/pull/8570)
@@ -20,7 +50,6 @@ Minor Impovements:
 * Gracefully exit if container runtime is misspelled [#8593](https://github.com/kubernetes/minikube/pull/8593)
 * add verification for enabling ingress, registry and gvisor addons [#8563](https://github.com/kubernetes/minikube/pull/8563)
 * Disable containerd from starting up at boot [#8621](https://github.com/kubernetes/minikube/pull/8621)
-* Upgrade podman to 2.0.0 [#8539](https://github.com/kubernetes/minikube/pull/8539)
 * Bump Dashboard to v2.0.1 [#8294](https://github.com/kubernetes/minikube/pull/8294)
 * Check for iptables file before determining container is running [#8565](https://github.com/kubernetes/minikube/pull/8565)
 
diff --git a/Makefile b/Makefile
old mode 100755
new mode 100644
index 689c933547..4cbddae67c
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@
 # Bump these on release - and please check ISO_VERSION for correctness.
 VERSION_MAJOR ?= 1
 VERSION_MINOR ?= 12
-VERSION_BUILD ?= 0-beta.1
+VERSION_BUILD ?= 0
 RAW_VERSION=$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_BUILD)
 VERSION ?= v$(RAW_VERSION)
 
@@ -23,13 +23,13 @@ KUBERNETES_VERSION ?= $(shell egrep "DefaultKubernetesVersion =" pkg/minikube/co
 KIC_VERSION ?= $(shell egrep "Version =" pkg/drivers/kic/types.go | cut -d \" -f2)
 
 # Default to .0 for higher cache hit rates, as build increments typically don't require new ISO versions
-ISO_VERSION ?= v1.11.0
+ISO_VERSION ?= v$(VERSION_MAJOR).$(VERSION_MINOR).0
 # Dashes are valid in semver, but not Linux packaging. Use ~ to delimit alpha/beta
 DEB_VERSION ?= $(subst -,~,$(RAW_VERSION))
 RPM_VERSION ?= $(DEB_VERSION)
 
 # used by hack/jenkins/release_build_and_upload.sh and KVM_BUILD_IMAGE, see also BUILD_IMAGE below
-GO_VERSION ?= 1.13.9
+GO_VERSION ?= 1.14.4
 
 INSTALL_SIZE ?= $(shell du out/minikube-windows-amd64.exe | cut -f1)
 BUILDROOT_BRANCH ?= 2019.02.11
@@ -41,8 +41,8 @@ COMMIT ?= $(if $(shell git status --porcelain --untracked-files=no),"${COMMIT_NO
 
 HYPERKIT_BUILD_IMAGE 	?= karalabe/xgo-1.12.x
 # NOTE: "latest" as of 2020-05-13. kube-cross images aren't updated as often as Kubernetes
-# https://github.com/kubernetes/kubernetes/blob/release-1.18/build/build-image/cross/VERSION
-BUILD_IMAGE 	?= us.gcr.io/k8s-artifacts-prod/build-image/kube-cross:v$(GO_VERSION)-5
+# https://github.com/kubernetes/kubernetes/blob/master/build/build-image/cross/VERSION
+BUILD_IMAGE 	?= us.gcr.io/k8s-artifacts-prod/build-image/kube-cross:v$(GO_VERSION)-2
 ISO_BUILD_IMAGE ?= $(REGISTRY)/buildroot-image
 KVM_BUILD_IMAGE ?= $(REGISTRY)/kvm-build-image:$(GO_VERSION)
 
diff --git a/cmd/minikube/cmd/config/profile.go b/cmd/minikube/cmd/config/profile.go
index 171d90a3bd..9384f038bf 100644
--- a/cmd/minikube/cmd/config/profile.go
+++ b/cmd/minikube/cmd/config/profile.go
@@ -47,7 +47,7 @@ var ProfileCmd = &cobra.Command{
 		// Check whether the profile name is container friendly
 		if !config.ProfileNameValid(profile) {
 			out.WarningT("Profile name '{{.profilename}}' is not valid", out.V{"profilename": profile})
-			exit.UsageT("Only alphanumeric, dots, underscores and dashes '-' are permitted. Minimum 2 characters, starting by alphanumeric.")
+			exit.UsageT("Only alphanumeric and dashes '-' are permitted. Minimum 1 character, starting with alphanumeric.")
 		}
 		/**
 		we need to add code over here to check whether the profile
diff --git a/cmd/minikube/cmd/mount.go b/cmd/minikube/cmd/mount.go
index ec64cd6638..28ea923e7c 100644
--- a/cmd/minikube/cmd/mount.go
+++ b/cmd/minikube/cmd/mount.go
@@ -151,14 +151,14 @@ var mountCmd = &cobra.Command{
 			bindIP = "127.0.0.1"
 		}
 		out.T(out.Mounting, "Mounting host path {{.sourcePath}} into VM as {{.destinationPath}} ...", out.V{"sourcePath": hostPath, "destinationPath": vmPath})
-		out.T(out.Option, "Mount type:   {{.name}}", out.V{"type": cfg.Type})
-		out.T(out.Option, "User ID:      {{.userID}}", out.V{"userID": cfg.UID})
-		out.T(out.Option, "Group ID:     {{.groupID}}", out.V{"groupID": cfg.GID})
-		out.T(out.Option, "Version:      {{.version}}", out.V{"version": cfg.Version})
-		out.T(out.Option, "Message Size: {{.size}}", out.V{"size": cfg.MSize})
-		out.T(out.Option, "Permissions:  {{.octalMode}} ({{.writtenMode}})", out.V{"octalMode": fmt.Sprintf("%o", cfg.Mode), "writtenMode": cfg.Mode})
-		out.T(out.Option, "Options:      {{.options}}", out.V{"options": cfg.Options})
-		out.T(out.Option, "Bind Address: {{.Address}}", out.V{"Address": net.JoinHostPort(bindIP, fmt.Sprint(port))})
+		out.Infof("Mount type:   {{.name}}", out.V{"type": cfg.Type})
+		out.Infof("User ID:      {{.userID}}", out.V{"userID": cfg.UID})
+		out.Infof("Group ID:     {{.groupID}}", out.V{"groupID": cfg.GID})
+		out.Infof("Version:      {{.version}}", out.V{"version": cfg.Version})
+		out.Infof("Message Size: {{.size}}", out.V{"size": cfg.MSize})
+		out.Infof("Permissions:  {{.octalMode}} ({{.writtenMode}})", out.V{"octalMode": fmt.Sprintf("%o", cfg.Mode), "writtenMode": cfg.Mode})
+		out.Infof("Options:      {{.options}}", out.V{"options": cfg.Options})
+		out.Infof("Bind Address: {{.Address}}", out.V{"Address": net.JoinHostPort(bindIP, fmt.Sprint(port))})
 
 		var wg sync.WaitGroup
 		if cfg.Type == nineP {
diff --git a/cmd/minikube/cmd/root_test.go b/cmd/minikube/cmd/root_test.go
index b0c29ca4b1..8658fc9b10 100644
--- a/cmd/minikube/cmd/root_test.go
+++ b/cmd/minikube/cmd/root_test.go
@@ -115,7 +115,7 @@ func hideEnv(t *testing.T) func(t *testing.T) {
 func TestPreRunDirectories(t *testing.T) {
 	// Make sure we create the required directories.
 	tempDir := tests.MakeTempDir()
-	defer os.RemoveAll(tempDir)
+	defer tests.RemoveTempDir(tempDir)
 
 	runCommand(RootCmd.PersistentPreRun)
 
diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go
index a3afc7451c..1d4633ea20 100644
--- a/cmd/minikube/cmd/start.go
+++ b/cmd/minikube/cmd/start.go
@@ -148,7 +148,7 @@ func runStart(cmd *cobra.Command, args []string) {
 
 	if !config.ProfileNameValid(ClusterFlagValue()) {
 		out.WarningT("Profile name '{{.name}}' is not valid", out.V{"name": ClusterFlagValue()})
-		exit.UsageT("Only alphanumeric, dots, underscores and dashes '-' are permitted. Minimum 2 characters, starting by alphanumeric.")
+		exit.UsageT("Only alphanumeric and dashes '-' are permitted. Minimum 1 character, starting with alphanumeric.")
 	}
 	existing, err := config.Load(ClusterFlagValue())
 	if err != nil && !config.IsNotExist(err) {
@@ -156,6 +156,7 @@ func runStart(cmd *cobra.Command, args []string) {
 	}
 
 	validateSpecifiedDriver(existing)
+	validateKubernetesVersion(existing)
 	ds, alts, specified := selectDriver(existing)
 	starter, err := provisionWithDriver(cmd, ds, existing)
 	if err != nil {
@@ -361,7 +362,7 @@ func displayEnviron(env []string) {
 		k := bits[0]
 		v := bits[1]
 		if strings.HasPrefix(k, "MINIKUBE_") || k == constants.KubeconfigEnvVar {
-			out.T(out.Option, "{{.key}}={{.value}}", out.V{"key": k, "value": v})
+			out.Infof("{{.key}}={{.value}}", out.V{"key": k, "value": v})
 		}
 	}
 }
@@ -524,7 +525,7 @@ func selectDriver(existing *config.ClusterConfig) (registry.DriverState, []regis
 	if pick.Name == "" {
 		out.T(out.ThumbsDown, "Unable to pick a default driver. Here is what was considered, in preference order:")
 		for _, r := range rejects {
-			out.T(out.Option, "{{ .name }}: {{ .rejection }}", out.V{"name": r.Name, "rejection": r.Rejection})
+			out.Infof("{{ .name }}: {{ .rejection }}", out.V{"name": r.Name, "rejection": r.Rejection})
 		}
 		out.T(out.Workaround, "Try specifying a --driver, or see https://minikube.sigs.k8s.io/docs/start/")
 		os.Exit(exit.Unavailable)
@@ -903,6 +904,20 @@ func validateFlags(cmd *cobra.Command, drvName string) {
 		}
 	}
 
+	// validate kubeadm extra args
+	if invalidOpts := bsutil.FindInvalidExtraConfigFlags(config.ExtraOptions); len(invalidOpts) > 0 {
+		out.ErrT(
+			out.Warning,
+			"These --extra-config parameters are invalid: {{.invalid_extra_opts}}",
+			out.V{"invalid_extra_opts": invalidOpts},
+		)
+		exit.WithCodeT(
+			exit.Config,
+			"Valid components are: {{.valid_extra_opts}}",
+			out.V{"valid_extra_opts": bsutil.KubeadmExtraConfigOpts},
+		)
+	}
+
 	// check that kubeadm extra args contain only allowed parameters
 	for param := range config.ExtraOptions.AsMap().Get(bsutil.Kubeadm) {
 		if !config.ContainsParam(bsutil.KubeadmExtraArgsAllowed[bsutil.KubeadmCmdParam], param) &&
@@ -974,6 +989,10 @@ func autoSetDriverOptions(cmd *cobra.Command, drvName string) (err error) {
 	hints := driver.FlagDefaults(drvName)
 	if len(hints.ExtraOptions) > 0 {
 		for _, eo := range hints.ExtraOptions {
+			if config.ExtraOptions.Exists(eo) {
+				glog.Infof("skipping extra-config %q.", eo)
+				continue
+			}
 			glog.Infof("auto setting extra-config to %q.", eo)
 			err = config.ExtraOptions.Set(eo)
 			if err != nil {
@@ -1000,26 +1019,9 @@ func autoSetDriverOptions(cmd *cobra.Command, drvName string) (err error) {
 	return err
 }
 
-// getKubernetesVersion ensures that the requested version is reasonable
-func getKubernetesVersion(old *config.ClusterConfig) string {
-	paramVersion := viper.GetString(kubernetesVersion)
-
-	// try to load the old version first if the user didn't specify anything
-	if paramVersion == "" && old != nil {
-		paramVersion = old.KubernetesConfig.KubernetesVersion
-	}
-
-	if paramVersion == "" || strings.EqualFold(paramVersion, "stable") {
-		paramVersion = constants.DefaultKubernetesVersion
-	} else if strings.EqualFold(paramVersion, "latest") {
-		paramVersion = constants.NewestKubernetesVersion
-	}
-
-	nvs, err := semver.Make(strings.TrimPrefix(paramVersion, version.VersionPrefix))
-	if err != nil {
-		exit.WithCodeT(exit.Data, `Unable to parse "{{.kubernetes_version}}": {{.error}}`, out.V{"kubernetes_version": paramVersion, "error": err})
-	}
-	nv := version.VersionPrefix + nvs.String()
+// validateKubernetesVersion ensures that the requested version is reasonable
+func validateKubernetesVersion(old *config.ClusterConfig) {
+	nvs, _ := semver.Make(strings.TrimPrefix(getKubernetesVersion(old), version.VersionPrefix))
 
 	oldestVersion, err := semver.Make(strings.TrimPrefix(constants.OldestKubernetesVersion, version.VersionPrefix))
 	if err != nil {
@@ -1040,7 +1042,7 @@ func getKubernetesVersion(old *config.ClusterConfig) string {
 	}
 
 	if old == nil || old.KubernetesConfig.KubernetesVersion == "" {
-		return nv
+		return
 	}
 
 	ovs, err := semver.Make(strings.TrimPrefix(old.KubernetesConfig.KubernetesVersion, version.VersionPrefix))
@@ -1049,7 +1051,6 @@ func getKubernetesVersion(old *config.ClusterConfig) string {
 	}
 
 	if nvs.LT(ovs) {
-		nv = version.VersionPrefix + ovs.String()
 		profileArg := ""
 		if old.Name != constants.DefaultClusterName {
 			profileArg = fmt.Sprintf(" -p %s", old.Name)
@@ -1077,5 +1078,26 @@ func getKubernetesVersion(old *config.ClusterConfig) string {
 	if defaultVersion.GT(nvs) {
 		out.T(out.New, "Kubernetes {{.new}} is now available. If you would like to upgrade, specify: --kubernetes-version={{.prefix}}{{.new}}", out.V{"prefix": version.VersionPrefix, "new": defaultVersion})
 	}
-	return nv
+}
+
+func getKubernetesVersion(old *config.ClusterConfig) string {
+	paramVersion := viper.GetString(kubernetesVersion)
+
+	// try to load the old version first if the user didn't specify anything
+	if paramVersion == "" && old != nil {
+		paramVersion = old.KubernetesConfig.KubernetesVersion
+	}
+
+	if paramVersion == "" || strings.EqualFold(paramVersion, "stable") {
+		paramVersion = constants.DefaultKubernetesVersion
+	} else if strings.EqualFold(paramVersion, "latest") {
+		paramVersion = constants.NewestKubernetesVersion
+	}
+
+	nvs, err := semver.Make(strings.TrimPrefix(paramVersion, version.VersionPrefix))
+	if err != nil {
+		exit.WithCodeT(exit.Data, `Unable to parse "{{.kubernetes_version}}": {{.error}}`, out.V{"kubernetes_version": paramVersion, "error": err})
+	}
+
+	return version.VersionPrefix + nvs.String()
 }
diff --git a/deploy/addons/pod-security-policy/pod-security-policy.yaml.tmpl b/deploy/addons/pod-security-policy/pod-security-policy.yaml.tmpl
new file mode 100644
index 0000000000..fa4171fa91
--- /dev/null
+++ b/deploy/addons/pod-security-policy/pod-security-policy.yaml.tmpl
@@ -0,0 +1,132 @@
+---
+apiVersion: policy/v1beta1
+kind: PodSecurityPolicy
+metadata:
+  name: privileged
+  annotations:
+    seccomp.security.alpha.kubernetes.io/allowedProfileNames: "*"
+  labels:
+    addonmanager.kubernetes.io/mode: EnsureExists
+spec:
+  privileged: true
+  allowPrivilegeEscalation: true
+  allowedCapabilities:
+  - "*"
+  volumes:
+  - "*"
+  hostNetwork: true
+  hostPorts:
+  - min: 0
+    max: 65535
+  hostIPC: true
+  hostPID: true
+  runAsUser:
+    rule: 'RunAsAny'
+  seLinux:
+    rule: 'RunAsAny'
+  supplementalGroups:
+    rule: 'RunAsAny'
+  fsGroup:
+    rule: 'RunAsAny'
+---
+apiVersion: policy/v1beta1
+kind: PodSecurityPolicy
+metadata:
+  name: restricted
+  labels:
+    addonmanager.kubernetes.io/mode: EnsureExists
+spec:
+  privileged: false
+  allowPrivilegeEscalation: false
+  requiredDropCapabilities:
+    - ALL
+  volumes:
+    - 'configMap'
+    - 'emptyDir'
+    - 'projected'
+    - 'secret'
+    - 'downwardAPI'
+    - 'persistentVolumeClaim'
+  hostNetwork: false
+  hostIPC: false
+  hostPID: false
+  runAsUser:
+    rule: 'MustRunAsNonRoot'
+  seLinux:
+    rule: 'RunAsAny'
+  supplementalGroups:
+    rule: 'MustRunAs'
+    ranges:
+      # Forbid adding the root group.
+      - min: 1
+        max: 65535
+  fsGroup:
+    rule: 'MustRunAs'
+    ranges:
+      # Forbid adding the root group.
+      - min: 1
+        max: 65535
+  readOnlyRootFilesystem: false
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: psp:privileged
+  labels:
+    addonmanager.kubernetes.io/mode: EnsureExists
+rules:
+- apiGroups: ['policy']
+  resources: ['podsecuritypolicies']
+  verbs:     ['use']
+  resourceNames:
+  - privileged
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: psp:restricted
+  labels:
+    addonmanager.kubernetes.io/mode: EnsureExists
+rules:
+- apiGroups: ['policy']
+  resources: ['podsecuritypolicies']
+  verbs:     ['use']
+  resourceNames:
+  - restricted
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: default:restricted
+  labels:
+    addonmanager.kubernetes.io/mode: EnsureExists
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: psp:restricted
+subjects:
+- kind: Group
+  name: system:authenticated
+  apiGroup: rbac.authorization.k8s.io
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: default:privileged
+  namespace: kube-system
+  labels:
+    addonmanager.kubernetes.io/mode: EnsureExists
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: psp:privileged
+subjects:
+- kind: Group
+  name: system:masters
+  apiGroup: rbac.authorization.k8s.io
+- kind: Group
+  name: system:nodes
+  apiGroup: rbac.authorization.k8s.io
+- kind: Group
+  name: system:serviceaccounts:kube-system
+  apiGroup: rbac.authorization.k8s.io
diff --git a/deploy/iso/minikube-iso/package/cni-plugins/Config.in b/deploy/iso/minikube-iso/package/cni-plugins/Config.in
index cdca8f72dd..9566518974 100644
--- a/deploy/iso/minikube-iso/package/cni-plugins/Config.in
+++ b/deploy/iso/minikube-iso/package/cni-plugins/Config.in
@@ -2,4 +2,4 @@ config BR2_PACKAGE_CNI_PLUGINS
 	bool "cni-plugins"
 	default y
 	depends on BR2_x86_64
-	depends on BR2_PACKAGE_HOST_GO_TARGET_ARCH_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_ARCH_SUPPORTS
diff --git a/deploy/iso/minikube-iso/package/cni/Config.in b/deploy/iso/minikube-iso/package/cni/Config.in
index b711219701..ca60da49fc 100644
--- a/deploy/iso/minikube-iso/package/cni/Config.in
+++ b/deploy/iso/minikube-iso/package/cni/Config.in
@@ -2,4 +2,4 @@ config BR2_PACKAGE_CNI
 	bool "cni"
 	default y
 	depends on BR2_x86_64
-	depends on BR2_PACKAGE_HOST_GO_TARGET_ARCH_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_ARCH_SUPPORTS
diff --git a/deploy/iso/minikube-iso/package/conmon/Config.in b/deploy/iso/minikube-iso/package/conmon/Config.in
index 6d4df09cf9..0dd4344dc9 100644
--- a/deploy/iso/minikube-iso/package/conmon/Config.in
+++ b/deploy/iso/minikube-iso/package/conmon/Config.in
@@ -1,7 +1,7 @@
 config BR2_PACKAGE_CONMON
 	bool "conmon"
-	depends on BR2_PACKAGE_HOST_GO_TARGET_ARCH_SUPPORTS
-	depends on BR2_PACKAGE_HOST_GO_TARGET_CGO_LINKING_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_ARCH_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_CGO_LINKING_SUPPORTS
 	depends on BR2_TOOLCHAIN_HAS_THREADS
 	select BR2_PACKAGE_LIBGLIB2
 	select BR2_PACKAGE_SYSTEMD
diff --git a/deploy/iso/minikube-iso/package/containerd-bin/Config.in b/deploy/iso/minikube-iso/package/containerd-bin/Config.in
index fc5f328248..988ab2c4db 100644
--- a/deploy/iso/minikube-iso/package/containerd-bin/Config.in
+++ b/deploy/iso/minikube-iso/package/containerd-bin/Config.in
@@ -2,8 +2,8 @@ config BR2_PACKAGE_CONTAINERD_BIN
 	bool "containerd-bin"
 	default y
 	depends on BR2_x86_64
-	depends on BR2_PACKAGE_HOST_GO_TARGET_ARCH_SUPPORTS
-	depends on BR2_PACKAGE_HOST_GO_TARGET_CGO_LINKING_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_ARCH_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_CGO_LINKING_SUPPORTS
 	depends on BR2_TOOLCHAIN_HAS_THREADS
 	depends on BR2_USE_MMU # lvm2
 	depends on !BR2_STATIC_LIBS # lvm2
diff --git a/deploy/iso/minikube-iso/package/crio-bin/Config.in b/deploy/iso/minikube-iso/package/crio-bin/Config.in
index 22d2c45e9d..3dd6743912 100644
--- a/deploy/iso/minikube-iso/package/crio-bin/Config.in
+++ b/deploy/iso/minikube-iso/package/crio-bin/Config.in
@@ -2,8 +2,8 @@ config BR2_PACKAGE_CRIO_BIN
 	bool "crio-bin"
 	default y
 	depends on BR2_x86_64
-	depends on BR2_PACKAGE_HOST_GO_TARGET_ARCH_SUPPORTS
-	depends on BR2_PACKAGE_HOST_GO_TARGET_CGO_LINKING_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_ARCH_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_CGO_LINKING_SUPPORTS
 	depends on BR2_TOOLCHAIN_HAS_THREADS
 	depends on BR2_USE_MMU # lvm2
 	depends on !BR2_STATIC_LIBS # lvm2
diff --git a/deploy/iso/minikube-iso/package/crio-bin/conmon-config.h b/deploy/iso/minikube-iso/package/crio-bin/conmon-config.h
new file mode 100755
index 0000000000..1783492d0d
--- /dev/null
+++ b/deploy/iso/minikube-iso/package/crio-bin/conmon-config.h
@@ -0,0 +1,9 @@
+
+#if !defined(CONFIG_H)
+#define CONFIG_H
+
+#define BUF_SIZE 8192
+#define STDIO_BUF_SIZE 8192
+#define DEFAULT_SOCKET_PATH "/var/run/crio"
+
+#endif // CONFIG_H
diff --git a/deploy/iso/minikube-iso/package/crio-bin/crio-bin.hash b/deploy/iso/minikube-iso/package/crio-bin/crio-bin.hash
index debd789bc5..d0f12d3d77 100644
--- a/deploy/iso/minikube-iso/package/crio-bin/crio-bin.hash
+++ b/deploy/iso/minikube-iso/package/crio-bin/crio-bin.hash
@@ -12,6 +12,3 @@ sha256 05f9614c4d5970b4662499b84c270b0ab953596ee863dcd09c9dc7a2d2f09789 v1.16.0.
 sha256 57e1ee990ef2d5af8b32c33a21b4998682608e3556dcf1d3349666f55e7d95b9 v1.16.1.tar.gz
 sha256 23a797762e4544ee7c171ef138cfc1141a3f0acc2838d9965c2a58e53b16c3ae v1.17.0.tar.gz
 sha256 7967e9218fdfb59d6005a9e19c1668469bc5566c2a35927cffe7de8656bb22c7 v1.17.1.tar.gz
-sha256 865ded95aceb3a33a391b252522682de6b37b39498704c490b3a321dbefaafcb v1.18.0.tar.gz
-sha256 794ddc36c2a20fde91fc6cc2c6f02ebdaea85c69b51b67f3994090dbbdbc2a50 v1.18.1.tar.gz
-sha256 25dc558fbabc987bd58c7eab5230121b258a7b0eb34a49dc6595f1c6f3969116 v1.18.2.tar.gz
diff --git a/deploy/iso/minikube-iso/package/crio-bin/crio-bin.mk b/deploy/iso/minikube-iso/package/crio-bin/crio-bin.mk
index c7181af967..f1a58a31b7 100644
--- a/deploy/iso/minikube-iso/package/crio-bin/crio-bin.mk
+++ b/deploy/iso/minikube-iso/package/crio-bin/crio-bin.mk
@@ -4,8 +4,8 @@
 #
 ################################################################################
 
-CRIO_BIN_VERSION = v1.18.2
-CRIO_BIN_COMMIT = 7f261aeebffed079b4475dde8b9d602b01973d33
+CRIO_BIN_VERSION = v1.17.1
+CRIO_BIN_COMMIT = ee2de87bd8e2a7a84799476cb4fc4ce8a78fdf6d
 CRIO_BIN_SITE = https://github.com/cri-o/cri-o/archive
 CRIO_BIN_SOURCE = $(CRIO_BIN_VERSION).tar.gz
 CRIO_BIN_DEPENDENCIES = host-go libgpgme
@@ -32,7 +32,7 @@ endef
 
 define CRIO_BIN_BUILD_CMDS
 	mkdir -p $(@D)/bin
-	$(CRIO_BIN_ENV) $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D) COMMIT_NO=$(CRIO_BIN_COMMIT) PREFIX=/usr binaries
+	$(CRIO_BIN_ENV) $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D) GIT_COMMIT=$(CRIO_BIN_COMMIT) PREFIX=/usr binaries
 endef
 
 define CRIO_BIN_INSTALL_TARGET_CMDS
diff --git a/deploy/iso/minikube-iso/package/crio-bin/crio.conf b/deploy/iso/minikube-iso/package/crio-bin/crio.conf
index efbfae47d6..36dc1725ea 100644
--- a/deploy/iso/minikube-iso/package/crio-bin/crio.conf
+++ b/deploy/iso/minikube-iso/package/crio-bin/crio.conf
@@ -35,15 +35,8 @@ storage_driver = "overlay"
 # the kubelet. The log directory specified must be an absolute directory.
 log_dir = "/var/log/crio/pods"
 
-# Location for CRI-O to lay down the temporary version file.
-# It is used to check if crio wipe should wipe containers, which should
-# always happen on a node reboot
-version_file = "/var/run/crio/version"
-
-# Location for CRI-O to lay down the persistent version file.
-# It is used to check if crio wipe should wipe images, which should
-# only happen when CRI-O has been upgraded
-version_file_persist = "/var/lib/crio/version"
+# Location for CRI-O to lay down the version file
+version_file = "/var/lib/crio/version"
 
 # The crio.api table contains settings for the kubelet/gRPC interface.
 [crio.api]
@@ -51,11 +44,13 @@ version_file_persist = "/var/lib/crio/version"
 # Path to AF_LOCAL socket on which CRI-O will listen.
 listen = "/var/run/crio/crio.sock"
 
+# Host IP considered as the primary IP to use by CRI-O for things such as host network IP.
+host_ip = ""
+
 # IP address on which the stream server will listen.
 stream_address = "127.0.0.1"
 
-# The port on which the stream server will listen. If the port is set to "0", then
-# CRI-O will allocate a random free port number.
+# The port on which the stream server will listen.
 stream_port = "0"
 
 # Enable encrypted TLS transport of the stream server.
@@ -99,10 +94,6 @@ default_runtime = "runc"
 # If true, the runtime will not use pivot_root, but instead use MS_MOVE.
 no_pivot = false
 
-# decryption_keys_path is the path where the keys required for
-# image decryption are stored. This option supports live configuration reload.
-decryption_keys_path = "/etc/crio/keys/"
-
 # Path to the conmon binary, used for monitoring the OCI runtime.
 # Will be searched for using $PATH if empty.
 conmon = "/usr/libexec/crio/conmon"
@@ -116,26 +107,17 @@ conmon_env = [
 	"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
 ]
 
-# Additional environment variables to set for all the
-# containers. These are overridden if set in the
-# container image spec or in the container runtime configuration.
-default_env = [
-]
-
 # If true, SELinux will be used for pod separation on the host.
 selinux = false
 
 # Path to the seccomp.json profile which is used as the default seccomp profile
 # for the runtime. If not specified, then the internal default seccomp profile
-# will be used. This option supports live configuration reload.
+# will be used.
 seccomp_profile = ""
 
 # Used to change the name of the default AppArmor profile of CRI-O. The default
-# profile name is "crio-default". This profile only takes effect if the user
-# does not specify a profile via the Kubernetes Pod's metadata annotation. If
-# the profile is set to "unconfined", then this equals to disabling AppArmor.
-# This option supports live configuration reload.
-apparmor_profile = "crio-default"
+# profile name is "crio-default-" followed by the version string of CRI-O.
+apparmor_profile = "crio-default-1.16.1"
 
 # Cgroup management implementation used for the runtime.
 cgroup_manager = "systemd"
@@ -144,15 +126,17 @@ cgroup_manager = "systemd"
 # only the capabilities defined in the containers json file by the user/kube
 # will be added.
 default_capabilities = [
-	"CHOWN",
-	"DAC_OVERRIDE",
-	"FSETID",
-	"FOWNER",
-	"SETGID",
-	"SETUID",
-	"SETPCAP",
-	"NET_BIND_SERVICE",
-	"KILL",
+	"CHOWN", 
+	"DAC_OVERRIDE", 
+	"FSETID", 
+	"FOWNER", 
+	"NET_RAW", 
+	"SETGID", 
+	"SETUID", 
+	"SETPCAP", 
+	"NET_BIND_SERVICE", 
+	"SYS_CHROOT", 
+	"KILL", 
 ]
 
 # List of default sysctls. If it is empty or commented out, only the sysctls
@@ -167,10 +151,8 @@ default_sysctls = [
 additional_devices = [
 ]
 
-# Path to OCI hooks directories for automatically executed hooks. If one of the
-# directories does not exist, then CRI-O will automatically skip them.
+# Path to OCI hooks directories for automatically executed hooks.
 hooks_dir = [
-	"/usr/share/containers/oci/hooks.d",
 ]
 
 # List of default mounts for each container. **Deprecated:** this option will
@@ -218,13 +200,9 @@ bind_mount_prefix = ""
 read_only = false
 
 # Changes the verbosity of the logs based on the level it is set to. Options
-# are fatal, panic, error, warn, info, debug and trace. This option supports
-# live configuration reload.
-log_level = "info"
-
-# Filter the log messages by the provided regular expression.
-# This option supports live configuration reload.
-log_filter = ""
+# are fatal, panic, error, warn, info, and debug. This option supports live
+# configuration reload.
+log_level = "error"
 
 # The UID mappings for the user namespace of each container. A range is
 # specified in the form containerUID:HostUID:Size. Multiple ranges must be
@@ -237,23 +215,12 @@ uid_mappings = ""
 gid_mappings = ""
 
 # The minimal amount of time in seconds to wait before issuing a timeout
-# regarding the proper termination of the container. The lowest possible
-# value is 30s, whereas lower values are not considered by CRI-O.
-ctr_stop_timeout = 30
+# regarding the proper termination of the container.
+ctr_stop_timeout = 0
 
-# **DEPRECATED** this option is being replaced by manage_ns_lifecycle, which is described below.
-# manage_network_ns_lifecycle = false
-
-# manage_ns_lifecycle determines whether we pin and remove namespaces
-# and manage their lifecycle
-manage_ns_lifecycle = false
-
-# The directory where the state of the managed namespaces gets tracked.
-# Only used when manage_ns_lifecycle is true.
-namespaces_dir = "/var/run"
-
-# pinns_path is the path to find the pinns binary, which is needed to manage namespace lifecycle
-pinns_path = "/usr/bin/pinns"
+# ManageNetworkNSLifecycle determines whether we pin and remove network namespace
+# and manage its lifecycle.
+manage_network_ns_lifecycle = false
 
 # The "crio.runtime.runtimes" table defines a list of OCI compatible runtimes.
 # The runtime to use is picked based on the runtime_handler provided by the CRI.
@@ -314,7 +281,7 @@ global_auth_file = ""
 
 # The image used to instantiate infra containers.
 # This option supports live configuration reload.
-pause_image = "k8s.gcr.io/pause:3.2"
+pause_image = "k8s.gcr.io/pause:3.1"
 
 # The path to a file containing credentials specific for pulling the pause_image from
 # above. The file is similar to that of /var/lib/kubelet/config.json
@@ -357,10 +324,6 @@ registries = [
 # CNI plugins.
 [crio.network]
 
-# The default CNI network name to be selected. If not set or "", then
-# CRI-O will pick-up the first one found in network_dir.
-# cni_default_network = ""
-
 # Path to the directory where CNI configuration files are located.
 network_dir = "/etc/cni/net.d/"
 
diff --git a/deploy/iso/minikube-iso/package/crio-bin/crio.conf.default b/deploy/iso/minikube-iso/package/crio-bin/crio.conf.default
index 2696dc4a10..e456ca42da 100644
--- a/deploy/iso/minikube-iso/package/crio-bin/crio.conf.default
+++ b/deploy/iso/minikube-iso/package/crio-bin/crio.conf.default
@@ -35,15 +35,8 @@
 # the kubelet. The log directory specified must be an absolute directory.
 log_dir = "/var/log/crio/pods"
 
-# Location for CRI-O to lay down the temporary version file.
-# It is used to check if crio wipe should wipe containers, which should
-# always happen on a node reboot
-version_file = "/var/run/crio/version"
-
-# Location for CRI-O to lay down the persistent version file.
-# It is used to check if crio wipe should wipe images, which should
-# only happen when CRI-O has been upgraded
-version_file_persist = "/var/lib/crio/version"
+# Location for CRI-O to lay down the version file
+version_file = "/var/lib/crio/version"
 
 # The crio.api table contains settings for the kubelet/gRPC interface.
 [crio.api]
@@ -51,11 +44,13 @@ version_file_persist = "/var/lib/crio/version"
 # Path to AF_LOCAL socket on which CRI-O will listen.
 listen = "/var/run/crio/crio.sock"
 
+# Host IP considered as the primary IP to use by CRI-O for things such as host network IP.
+host_ip = ""
+
 # IP address on which the stream server will listen.
 stream_address = "127.0.0.1"
 
-# The port on which the stream server will listen. If the port is set to "0", then
-# CRI-O will allocate a random free port number.
+# The port on which the stream server will listen.
 stream_port = "0"
 
 # Enable encrypted TLS transport of the stream server.
@@ -99,10 +94,6 @@ default_runtime = "runc"
 # If true, the runtime will not use pivot_root, but instead use MS_MOVE.
 no_pivot = false
 
-# decryption_keys_path is the path where the keys required for
-# image decryption are stored. This option supports live configuration reload.
-decryption_keys_path = "/etc/crio/keys/"
-
 # Path to the conmon binary, used for monitoring the OCI runtime.
 # Will be searched for using $PATH if empty.
 conmon = ""
@@ -116,43 +107,36 @@ conmon_env = [
 	"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
 ]
 
-# Additional environment variables to set for all the
-# containers. These are overridden if set in the
-# container image spec or in the container runtime configuration.
-default_env = [
-]
-
 # If true, SELinux will be used for pod separation on the host.
 selinux = false
 
 # Path to the seccomp.json profile which is used as the default seccomp profile
 # for the runtime. If not specified, then the internal default seccomp profile
-# will be used. This option supports live configuration reload.
+# will be used.
 seccomp_profile = ""
 
 # Used to change the name of the default AppArmor profile of CRI-O. The default
-# profile name is "crio-default". This profile only takes effect if the user
-# does not specify a profile via the Kubernetes Pod's metadata annotation. If
-# the profile is set to "unconfined", then this equals to disabling AppArmor.
-# This option supports live configuration reload.
-apparmor_profile = "crio-default"
+# profile name is "crio-default-" followed by the version string of CRI-O.
+apparmor_profile = "crio-default-1.16.1"
 
 # Cgroup management implementation used for the runtime.
-cgroup_manager = "systemd"
+cgroup_manager = "cgroupfs"
 
 # List of default capabilities for containers. If it is empty or commented out,
 # only the capabilities defined in the containers json file by the user/kube
 # will be added.
 default_capabilities = [
-	"CHOWN",
-	"DAC_OVERRIDE",
-	"FSETID",
-	"FOWNER",
-	"SETGID",
-	"SETUID",
-	"SETPCAP",
-	"NET_BIND_SERVICE",
-	"KILL",
+	"CHOWN", 
+	"DAC_OVERRIDE", 
+	"FSETID", 
+	"FOWNER", 
+	"NET_RAW", 
+	"SETGID", 
+	"SETUID", 
+	"SETPCAP", 
+	"NET_BIND_SERVICE", 
+	"SYS_CHROOT", 
+	"KILL", 
 ]
 
 # List of default sysctls. If it is empty or commented out, only the sysctls
@@ -167,10 +151,8 @@ default_sysctls = [
 additional_devices = [
 ]
 
-# Path to OCI hooks directories for automatically executed hooks. If one of the
-# directories does not exist, then CRI-O will automatically skip them.
+# Path to OCI hooks directories for automatically executed hooks.
 hooks_dir = [
-	"/usr/share/containers/oci/hooks.d",
 ]
 
 # List of default mounts for each container. **Deprecated:** this option will
@@ -218,13 +200,9 @@ bind_mount_prefix = ""
 read_only = false
 
 # Changes the verbosity of the logs based on the level it is set to. Options
-# are fatal, panic, error, warn, info, debug and trace. This option supports
-# live configuration reload.
-log_level = "info"
-
-# Filter the log messages by the provided regular expression.
-# This option supports live configuration reload.
-log_filter = ""
+# are fatal, panic, error, warn, info, and debug. This option supports live
+# configuration reload.
+log_level = "error"
 
 # The UID mappings for the user namespace of each container. A range is
 # specified in the form containerUID:HostUID:Size. Multiple ranges must be
@@ -237,23 +215,12 @@ uid_mappings = ""
 gid_mappings = ""
 
 # The minimal amount of time in seconds to wait before issuing a timeout
-# regarding the proper termination of the container. The lowest possible
-# value is 30s, whereas lower values are not considered by CRI-O.
-ctr_stop_timeout = 30
+# regarding the proper termination of the container.
+ctr_stop_timeout = 0
 
-# **DEPRECATED** this option is being replaced by manage_ns_lifecycle, which is described below.
-# manage_network_ns_lifecycle = false
-
-# manage_ns_lifecycle determines whether we pin and remove namespaces
-# and manage their lifecycle
-manage_ns_lifecycle = false
-
-# The directory where the state of the managed namespaces gets tracked.
-# Only used when manage_ns_lifecycle is true.
-namespaces_dir = "/var/run"
-
-# pinns_path is the path to find the pinns binary, which is needed to manage namespace lifecycle
-pinns_path = ""
+# ManageNetworkNSLifecycle determines whether we pin and remove network namespace
+# and manage its lifecycle.
+manage_network_ns_lifecycle = false
 
 # The "crio.runtime.runtimes" table defines a list of OCI compatible runtimes.
 # The runtime to use is picked based on the runtime_handler provided by the CRI.
@@ -314,7 +281,7 @@ global_auth_file = ""
 
 # The image used to instantiate infra containers.
 # This option supports live configuration reload.
-pause_image = "k8s.gcr.io/pause:3.2"
+pause_image = "k8s.gcr.io/pause:3.1"
 
 # The path to a file containing credentials specific for pulling the pause_image from
 # above. The file is similar to that of /var/lib/kubelet/config.json
@@ -356,10 +323,6 @@ image_volumes = "mkdir"
 # CNI plugins.
 [crio.network]
 
-# The default CNI network name to be selected. If not set or "", then
-# CRI-O will pick-up the first one found in network_dir.
-# cni_default_network = ""
-
 # Path to the directory where CNI configuration files are located.
 network_dir = "/etc/cni/net.d/"
 
diff --git a/deploy/iso/minikube-iso/package/podman/Config.in b/deploy/iso/minikube-iso/package/podman/Config.in
index d73162af7f..f0d92a2cdc 100644
--- a/deploy/iso/minikube-iso/package/podman/Config.in
+++ b/deploy/iso/minikube-iso/package/podman/Config.in
@@ -2,8 +2,8 @@ config BR2_PACKAGE_PODMAN
 	bool "podman"
 	default y
 	depends on BR2_x86_64
-	depends on BR2_PACKAGE_HOST_GO_TARGET_ARCH_SUPPORTS
-	depends on BR2_PACKAGE_HOST_GO_TARGET_CGO_LINKING_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_ARCH_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_CGO_LINKING_SUPPORTS
 	depends on BR2_TOOLCHAIN_HAS_THREADS
 	select BR2_PACKAGE_RUNC_MASTER
 	select BR2_PACKAGE_CONMON
diff --git a/deploy/iso/minikube-iso/package/runc-master/Config.in b/deploy/iso/minikube-iso/package/runc-master/Config.in
index e3e4a58454..c33153880e 100644
--- a/deploy/iso/minikube-iso/package/runc-master/Config.in
+++ b/deploy/iso/minikube-iso/package/runc-master/Config.in
@@ -1,7 +1,7 @@
 config BR2_PACKAGE_RUNC_MASTER
 	bool "runc-master"
-	depends on BR2_PACKAGE_HOST_GO_TARGET_ARCH_SUPPORTS
-	depends on BR2_PACKAGE_HOST_GO_TARGET_CGO_LINKING_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_ARCH_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_CGO_LINKING_SUPPORTS
 	depends on BR2_TOOLCHAIN_HAS_THREADS
 	help
 	  runC is a CLI tool for spawning and running containers
@@ -12,6 +12,6 @@ config BR2_PACKAGE_RUNC_MASTER
 	  https://github.com/opencontainers/runc
 
 comment "runc needs a toolchain w/ threads"
-	depends on BR2_PACKAGE_HOST_GO_TARGET_ARCH_SUPPORTS && \
-		BR2_PACKAGE_HOST_GO_TARGET_CGO_LINKING_SUPPORTS
+	depends on BR2_PACKAGE_HOST_GO_ARCH_SUPPORTS && \
+		BR2_PACKAGE_HOST_GO_CGO_LINKING_SUPPORTS
 	depends on !BR2_TOOLCHAIN_HAS_THREADS
diff --git a/deploy/minikube/releases.json b/deploy/minikube/releases.json
index 39316b8095..32bf94966c 100644
--- a/deploy/minikube/releases.json
+++ b/deploy/minikube/releases.json
@@ -1,4 +1,12 @@
 [
+  {
+      "name": "v1.12.0",
+      "checksums": {
+          "darwin": "7f6c6eeca19d6b16c9043cfc96a42408bbdec8ba90c01bd025249ca855a1362c",
+          "linux": "3501b6c2be48183affa9497e7db6d751d92e1536267268b73ad1a936a2977122",
+          "windows": "a5f8666d762146cc7d85916bcb2d6b7246162e4706f10e5c12a795b9d07ea6c4"
+      }
+  },
   {
       "name": "v1.11.0",
       "checksums": {
diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh
index 943048421c..3add7c710a 100755
--- a/hack/jenkins/common.sh
+++ b/hack/jenkins/common.sh
@@ -31,7 +31,7 @@ export KUBECONFIG="${TEST_HOME}/kubeconfig"
 export PATH=$PATH:"/usr/local/bin/:/usr/local/go/bin/:$GOPATH/bin"
 
 # installing golang so we could do go get for gopogh
-sudo ./installers/check_install_golang.sh "1.13.9" "/usr/local" || true
+sudo ./installers/check_install_golang.sh "1.14.4" "/usr/local" || true
 
 docker rm -f -v $(docker ps -aq) >/dev/null 2>&1 || true
 docker volume prune -f || true
diff --git a/pkg/addons/config.go b/pkg/addons/config.go
index 96e2617efa..7bdb1c2250 100644
--- a/pkg/addons/config.go
+++ b/pkg/addons/config.go
@@ -156,4 +156,9 @@ var Addons = []*Addon{
 		set:       SetBool,
 		callbacks: []setFn{enableOrDisableAddon},
 	},
+	{
+		name:      "pod-security-policy",
+		set:       SetBool,
+		callbacks: []setFn{enableOrDisableAddon},
+	},
 }
diff --git a/pkg/drivers/common_test.go b/pkg/drivers/common_test.go
index 98982b9b36..cc250e03de 100644
--- a/pkg/drivers/common_test.go
+++ b/pkg/drivers/common_test.go
@@ -27,7 +27,7 @@ import (
 
 func Test_createDiskImage(t *testing.T) {
 	tmpdir := tests.MakeTempDir()
-	defer os.RemoveAll(tmpdir)
+	defer tests.RemoveTempDir(tmpdir)
 
 	sshPath := filepath.Join(tmpdir, "ssh")
 	if err := ioutil.WriteFile(sshPath, []byte("mysshkey"), 0644); err != nil {
diff --git a/pkg/drivers/hyperkit/network_test.go b/pkg/drivers/hyperkit/network_test.go
index 3bd538a66b..c8b6d1283a 100644
--- a/pkg/drivers/hyperkit/network_test.go
+++ b/pkg/drivers/hyperkit/network_test.go
@@ -20,7 +20,6 @@ package hyperkit
 
 import (
 	"io/ioutil"
-	"os"
 	"path/filepath"
 	"testing"
 
@@ -51,7 +50,7 @@ var validLeases = []byte(`{
 
 func Test_getIpAddressFromFile(t *testing.T) {
 	tmpdir := tests.MakeTempDir()
-	defer os.RemoveAll(tmpdir)
+	defer tests.RemoveTempDir(tmpdir)
 
 	dhcpFile := filepath.Join(tmpdir, "dhcp")
 	if err := ioutil.WriteFile(dhcpFile, validLeases, 0644); err != nil {
diff --git a/pkg/drivers/kic/oci/oci.go b/pkg/drivers/kic/oci/oci.go
index 9ef0575f07..3ef6a94cfb 100644
--- a/pkg/drivers/kic/oci/oci.go
+++ b/pkg/drivers/kic/oci/oci.go
@@ -126,8 +126,6 @@ func CreateContainerNode(p CreateParams) error {
 		// for now this is what we want. in the future we may revisit this.
 		"--privileged",
 		"--security-opt", "seccomp=unconfined", //  ignore seccomp
-		// ignore apparmore github actions docker: https://github.com/kubernetes/minikube/issues/7624
-		"--security-opt", "apparmor=unconfined",
 		"--tmpfs", "/tmp", // various things depend on working /tmp
 		"--tmpfs", "/run", // systemd wants a writable /run
 		// logs,pods be stroed on  filesystem vs inside container,
@@ -150,6 +148,8 @@ func CreateContainerNode(p CreateParams) error {
 	}
 	if p.OCIBinary == Docker {
 		runArgs = append(runArgs, "--volume", fmt.Sprintf("%s:/var", p.Name))
+		// ignore apparmore github actions docker: https://github.com/kubernetes/minikube/issues/7624
+		runArgs = append(runArgs, "--security-opt", "apparmor=unconfined")
 	}
 
 	runArgs = append(runArgs, fmt.Sprintf("--cpus=%s", p.CPUs))
diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go
index 67403a4c14..6d57174252 100644
--- a/pkg/minikube/assets/addons.go
+++ b/pkg/minikube/assets/addons.go
@@ -81,6 +81,14 @@ var Addons = map[string]*Addon{
 			"0640",
 			false),
 	}, true, "default-storageclass"),
+	"pod-security-policy": NewAddon([]*BinAsset{
+		MustBinAsset(
+			"deploy/addons/pod-security-policy/pod-security-policy.yaml.tmpl",
+			vmpath.GuestAddonsDir,
+			"pod-security-policy.yaml",
+			"0640",
+			false),
+	}, false, "pod-security-policy"),
 	"storage-provisioner": NewAddon([]*BinAsset{
 		MustBinAsset(
 			"deploy/addons/storage-provisioner/storage-provisioner.yaml.tmpl",
diff --git a/pkg/minikube/bootstrapper/bsutil/extraconfig.go b/pkg/minikube/bootstrapper/bsutil/extraconfig.go
index 0f64b89f10..946d087836 100644
--- a/pkg/minikube/bootstrapper/bsutil/extraconfig.go
+++ b/pkg/minikube/bootstrapper/bsutil/extraconfig.go
@@ -95,6 +95,21 @@ func CreateFlagsFromExtraArgs(extraOptions config.ExtraOptionSlice) string {
 	return convertToFlags(kubeadmExtraOpts)
 }
 
+// FindInvalidExtraConfigFlags returns all invalid 'extra-config' options
+func FindInvalidExtraConfigFlags(opts config.ExtraOptionSlice) []string {
+	invalidOptsMap := make(map[string]struct{})
+	var invalidOpts []string
+	for _, extraOpt := range opts {
+		if _, ok := componentToKubeadmConfigKey[extraOpt.Component]; !ok {
+			if _, ok := invalidOptsMap[extraOpt.Component]; !ok {
+				invalidOpts = append(invalidOpts, extraOpt.Component)
+				invalidOptsMap[extraOpt.Component] = struct{}{}
+			}
+		}
+	}
+	return invalidOpts
+}
+
 // extraConfigForComponent generates a map of flagname-value pairs for a k8s
 // component.
 func extraConfigForComponent(component string, opts config.ExtraOptionSlice, version semver.Version) (map[string]string, error) {
@@ -133,20 +148,12 @@ func defaultOptionsForComponentAndVersion(component string, version semver.Versi
 
 // newComponentOptions creates a new componentOptions
 func newComponentOptions(opts config.ExtraOptionSlice, version semver.Version, featureGates string, cp config.Node) ([]componentOptions, error) {
+	if invalidOpts := FindInvalidExtraConfigFlags(opts); len(invalidOpts) > 0 {
+		return nil, fmt.Errorf("unknown components %v. valid components are: %v", invalidOpts, KubeadmExtraConfigOpts)
+	}
+
 	var kubeadmExtraArgs []componentOptions
-	for _, extraOpt := range opts {
-		if _, ok := componentToKubeadmConfigKey[extraOpt.Component]; !ok {
-			return nil, fmt.Errorf("unknown component %q. valid components are: %v", componentToKubeadmConfigKey, componentToKubeadmConfigKey)
-		}
-	}
-
-	keys := []string{}
-	for k := range componentToKubeadmConfigKey {
-		keys = append(keys, k)
-	}
-	sort.Strings(keys)
-
-	for _, component := range keys {
+	for _, component := range KubeadmExtraConfigOpts {
 		kubeadmComponentKey := componentToKubeadmConfigKey[component]
 		if kubeadmComponentKey == "" {
 			continue
diff --git a/pkg/minikube/bootstrapper/bsutil/extraconfig_test.go b/pkg/minikube/bootstrapper/bsutil/extraconfig_test.go
new file mode 100644
index 0000000000..cb43a77f15
--- /dev/null
+++ b/pkg/minikube/bootstrapper/bsutil/extraconfig_test.go
@@ -0,0 +1,59 @@
+/*
+Copyright 2016 The Kubernetes Authors All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package bsutil will eventually be renamed to kubeadm package after getting rid of older one
+package bsutil
+
+import (
+	"reflect"
+	"testing"
+
+	"k8s.io/minikube/pkg/minikube/config"
+)
+
+func TestFindInvalidExtraConfigFlags(t *testing.T) {
+	defaultOpts := getExtraOpts()
+	badOption1 := config.ExtraOption{Component: "bad_option_1"}
+	badOption2 := config.ExtraOption{Component: "bad_option_2"}
+	tests := []struct {
+		name string
+		opts config.ExtraOptionSlice
+		want []string
+	}{
+		{
+			name: "with valid options only",
+			opts: defaultOpts,
+			want: nil,
+		},
+		{
+			name: "with invalid options",
+			opts: append(defaultOpts, badOption1, badOption2),
+			want: []string{"bad_option_1", "bad_option_2"},
+		},
+		{
+			name: "with invalid options and duplicates",
+			opts: append(defaultOpts, badOption2, badOption1, badOption1),
+			want: []string{"bad_option_2", "bad_option_1"},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := FindInvalidExtraConfigFlags(tt.opts); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("FindInvalidExtraConfigFlags() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/pkg/minikube/bootstrapper/bsutil/kubeadm.go b/pkg/minikube/bootstrapper/bsutil/kubeadm.go
index 7fa1f157df..db5e24485f 100644
--- a/pkg/minikube/bootstrapper/bsutil/kubeadm.go
+++ b/pkg/minikube/bootstrapper/bsutil/kubeadm.go
@@ -147,15 +147,26 @@ func GenerateKubeadmYAML(cc config.ClusterConfig, n config.Node, r cruntime.Mana
 // These are the components that can be configured
 // through the "extra-config"
 const (
-	Kubelet           = "kubelet"
-	Kubeadm           = "kubeadm"
 	Apiserver         = "apiserver"
-	Scheduler         = "scheduler"
 	ControllerManager = "controller-manager"
-	Kubeproxy         = "kube-proxy"
+	Scheduler         = "scheduler"
 	Etcd              = "etcd"
+	Kubeadm           = "kubeadm"
+	Kubeproxy         = "kube-proxy"
+	Kubelet           = "kubelet"
 )
 
+// KubeadmExtraConfigOpts is a list of allowed "extra-config" components
+var KubeadmExtraConfigOpts = []string{
+	Apiserver,
+	ControllerManager,
+	Scheduler,
+	Etcd,
+	Kubeadm,
+	Kubelet,
+	Kubeproxy,
+}
+
 // InvokeKubeadm returns the invocation command for Kubeadm
 func InvokeKubeadm(version string) string {
 	return fmt.Sprintf("sudo env PATH=%s:$PATH kubeadm", binRoot(version))
diff --git a/pkg/minikube/bootstrapper/bsutil/kverify/api_server.go b/pkg/minikube/bootstrapper/bsutil/kverify/api_server.go
index d98b069c7e..2fc1566bd1 100644
--- a/pkg/minikube/bootstrapper/bsutil/kverify/api_server.go
+++ b/pkg/minikube/bootstrapper/bsutil/kverify/api_server.go
@@ -205,7 +205,13 @@ func apiServerHealthz(hostname string, port int) (state.State, error) {
 		return nil
 	}
 
-	err = retry.Local(check, 8*time.Second)
+	err = retry.Local(check, 5*time.Second)
+
+	// Don't propagate 'Stopped' upwards as an error message, as clients may interpret the err
+	// as an inability to get status. We need it for retry.Local, however.
+	if st == state.Stopped {
+		return st, nil
+	}
 	return st, err
 }
 
diff --git a/pkg/minikube/bootstrapper/certs_test.go b/pkg/minikube/bootstrapper/certs_test.go
index 4f93aad180..d4226283d9 100644
--- a/pkg/minikube/bootstrapper/certs_test.go
+++ b/pkg/minikube/bootstrapper/certs_test.go
@@ -30,7 +30,7 @@ import (
 
 func TestSetupCerts(t *testing.T) {
 	tempDir := tests.MakeTempDir()
-	defer os.RemoveAll(tempDir)
+	defer tests.RemoveTempDir(tempDir)
 
 	k8s := config.KubernetesConfig{
 		APIServerName: constants.APIServerName,
diff --git a/pkg/minikube/bootstrapper/kubeadm/errors.go b/pkg/minikube/bootstrapper/kubeadm/errors.go
index ac0f89452c..a71648ad83 100644
--- a/pkg/minikube/bootstrapper/kubeadm/errors.go
+++ b/pkg/minikube/bootstrapper/kubeadm/errors.go
@@ -16,7 +16,17 @@ limitations under the License.
 
 package kubeadm
 
-import "errors"
+import (
+	"errors"
+	"fmt"
+)
+
+// max minutes wait for kubeadm init. usually finishes in less than 1 minute.
+// giving it a generous timeout for possible super slow machines.
+const initTimeoutMinutes = 10
+
+// max seconds to wait for running kubectl apply manifests to the cluster to exit
+const applyTimeoutSeconds = 10
 
 // FailFastError type is an error that could not be solved by trying again
 type FailFastError struct {
@@ -30,3 +40,6 @@ func (f *FailFastError) Error() string {
 // ErrNoExecLinux is thrown on linux when the kubeadm binaries are mounted in a noexec volume on Linux as seen in https://github.com/kubernetes/minikube/issues/8327#issuecomment-651288459
 // this error could be seen on docker/podman or none driver.
 var ErrNoExecLinux = &FailFastError{errors.New("mounted kubeadm binary is not executable")}
+
+// ErrInitTimedout is thrown if kubeadm init takes longer than max time allowed
+var ErrInitTimedout = fmt.Errorf("kubeadm init timed out in %d minutes", initTimeoutMinutes)
diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go
index b4b2650e5f..e04f98f6c5 100644
--- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go
+++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go
@@ -225,9 +225,15 @@ func (k *Bootstrapper) init(cfg config.ClusterConfig) error {
 	}
 
 	conf := bsutil.KubeadmYamlPath
-	c := exec.Command("/bin/bash", "-c", fmt.Sprintf("%s init --config %s %s --ignore-preflight-errors=%s",
+	ctx, cancel := context.WithTimeout(context.Background(), initTimeoutMinutes*time.Minute)
+	defer cancel()
+	c := exec.CommandContext(ctx, "/bin/bash", "-c", fmt.Sprintf("%s init --config %s %s --ignore-preflight-errors=%s",
 		bsutil.InvokeKubeadm(cfg.KubernetesConfig.KubernetesVersion), conf, extraFlags, strings.Join(ignore, ",")))
 	if _, err := k.c.RunCmd(c); err != nil {
+		if ctx.Err() == context.DeadlineExceeded {
+			return ErrInitTimedout
+		}
+
 		if strings.Contains(err.Error(), "'kubeadm': Permission denied") {
 			return ErrNoExecLinux
 		}
@@ -829,8 +835,7 @@ func (k *Bootstrapper) applyNodeLabels(cfg config.ClusterConfig) error {
 	commitLbl := "minikube.k8s.io/commit=" + version.GetGitCommitID()
 	nameLbl := "minikube.k8s.io/name=" + cfg.Name
 
-	// Allow no more than 5 seconds for applying labels
-	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	ctx, cancel := context.WithTimeout(context.Background(), applyTimeoutSeconds*time.Second)
 	defer cancel()
 	// example:
 	// sudo /var/lib/minikube/binaries/<version>/kubectl label nodes minikube.k8s.io/version=<version> minikube.k8s.io/commit=aa91f39ffbcf27dcbb93c4ff3f457c54e585cf4a-dirty minikube.k8s.io/name=p1 minikube.k8s.io/updated_at=2020_02_20T12_05_35_0700 --all --overwrite --kubeconfig=/var/lib/minikube/kubeconfig
@@ -839,6 +844,9 @@ func (k *Bootstrapper) applyNodeLabels(cfg config.ClusterConfig) error {
 		fmt.Sprintf("--kubeconfig=%s", path.Join(vmpath.GuestPersistentDir, "kubeconfig")))
 
 	if _, err := k.c.RunCmd(cmd); err != nil {
+		if ctx.Err() == context.DeadlineExceeded {
+			return errors.Wrapf(err, "timeout apply labels")
+		}
 		return errors.Wrapf(err, "applying node labels")
 	}
 	return nil
diff --git a/pkg/minikube/cni/flannel.go b/pkg/minikube/cni/flannel.go
index 4986b4d12e..fea691e6fa 100644
--- a/pkg/minikube/cni/flannel.go
+++ b/pkg/minikube/cni/flannel.go
@@ -17,6 +17,9 @@ limitations under the License.
 package cni
 
 import (
+	"os/exec"
+
+	"github.com/pkg/errors"
 	"k8s.io/minikube/pkg/minikube/config"
 )
 
@@ -637,6 +640,12 @@ func (c Flannel) String() string {
 
 // Apply enables the CNI
 func (c Flannel) Apply(r Runner) error {
+	// Mostly applicable to the 'none' driver
+	_, err := r.RunCmd(exec.Command("stat", "/opt/cni/bin/portmap"))
+	if err != nil {
+		return errors.Wrap(err, "required 'portmap' CNI plug-in not found")
+	}
+
 	return applyManifest(c.cc, r, manifestAsset([]byte(flannelTmpl)))
 }
 
diff --git a/pkg/minikube/cni/kindnet.go b/pkg/minikube/cni/kindnet.go
index 6178c6715f..cf7a183019 100644
--- a/pkg/minikube/cni/kindnet.go
+++ b/pkg/minikube/cni/kindnet.go
@@ -18,6 +18,7 @@ package cni
 
 import (
 	"bytes"
+	"os/exec"
 	"text/template"
 
 	"github.com/pkg/errors"
@@ -168,6 +169,12 @@ func (c KindNet) manifest() (assets.CopyableFile, error) {
 
 // Apply enables the CNI
 func (c KindNet) Apply(r Runner) error {
+	// This is mostly applicable to the 'none' driver
+	_, err := r.RunCmd(exec.Command("stat", "/opt/cni/bin/portmap"))
+	if err != nil {
+		return errors.Wrap(err, "required 'portmap' CNI plug-in not found")
+	}
+
 	m, err := c.manifest()
 	if err != nil {
 		return errors.Wrap(err, "manifest")
diff --git a/pkg/minikube/config/extra_options.go b/pkg/minikube/config/extra_options.go
index d2ced45963..c8eb68924e 100644
--- a/pkg/minikube/config/extra_options.go
+++ b/pkg/minikube/config/extra_options.go
@@ -19,6 +19,8 @@ package config
 import (
 	"fmt"
 	"strings"
+
+	"github.com/golang/glog"
 )
 
 // ExtraOption is an extra option
@@ -38,6 +40,29 @@ type ExtraOptionSlice []ExtraOption
 // ComponentExtraOptionMap maps components to their extra opts, which is a map of keys to values
 type ComponentExtraOptionMap map[string]map[string]string
 
+// Exists returns true if component.key (parsed from value) is already in ExtraOptionSlice
+func (es *ExtraOptionSlice) Exists(value string) bool {
+	// The component is the value before the first dot.
+	componentSplit := strings.SplitN(value, ".", 2)
+	if len(componentSplit) != 2 {
+		glog.Errorf("invalid value: must contain at least one period: %q", value)
+		return false
+	}
+
+	keySplit := strings.SplitN(componentSplit[1], "=", 2)
+	if len(keySplit) != 2 {
+		glog.Errorf("invalid value: must contain one equal sign: %q", value)
+		return false
+	}
+
+	for _, opt := range *es {
+		if opt.Component == componentSplit[0] && opt.Key == keySplit[0] {
+			return true
+		}
+	}
+	return false
+}
+
 // Set parses the string value into a slice
 func (es *ExtraOptionSlice) Set(value string) error {
 	// The component is the value before the first dot.
diff --git a/pkg/minikube/config/extra_options_test.go b/pkg/minikube/config/extra_options_test.go
index cce3463ab8..a595a0636d 100644
--- a/pkg/minikube/config/extra_options_test.go
+++ b/pkg/minikube/config/extra_options_test.go
@@ -79,6 +79,29 @@ func TestValidFlags(t *testing.T) {
 	}
 }
 
+func TestExists(t *testing.T) {
+	extraOptions := ExtraOptionSlice{
+		ExtraOption{Component: "c1", Key: "bar", Value: "c1-bar"},
+		ExtraOption{Component: "c1", Key: "baz", Value: "c1-baz"},
+		ExtraOption{Component: "c2", Key: "bar", Value: "c2-bar"},
+	}
+
+	for _, tc := range []struct {
+		searchString string
+		expRes       bool
+	}{
+		{"c1.bar=bar", true},
+		{"c1.foo=foo", false},
+		{"c2.bar=bar", true},
+		{"c2.baz=baz", false},
+		{"c3.baz=baz", false},
+	} {
+		if res := extraOptions.Exists(tc.searchString); res != tc.expRes {
+			t.Errorf("Unexpected value. Expected %t, got %t", tc.expRes, res)
+		}
+	}
+}
+
 func TestGet(t *testing.T) {
 	extraOptions := ExtraOptionSlice{
 		ExtraOption{Component: "c1", Key: "bar", Value: "c1-bar"},
diff --git a/pkg/minikube/config/profile.go b/pkg/minikube/config/profile.go
index 80e52fc75c..b5baf5ed4f 100644
--- a/pkg/minikube/config/profile.go
+++ b/pkg/minikube/config/profile.go
@@ -84,13 +84,13 @@ func PrimaryControlPlane(cc *ClusterConfig) (Node, error) {
 	return cp, nil
 }
 
-// ProfileNameValid checks if the profile name is container name friendly
+// ProfileNameValid checks if the profile name is container name and DNS hostname/label friendly.
 func ProfileNameValid(name string) bool {
+	// RestrictedNamePattern describes the characters allowed to represent a profile's name
+	const RestrictedNamePattern = `(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])`
 
-	// RestrictedNameChars collects the characters allowed to represent a name
-	const RestrictedNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]`
+	var validName = regexp.MustCompile(`^` + RestrictedNamePattern + `$`)
 
-	var validName = regexp.MustCompile(`^` + RestrictedNameChars + `+$`)
 	return validName.MatchString(name)
 }
 
@@ -181,6 +181,7 @@ func SaveProfile(name string, cfg *ClusterConfig, miniHome ...string) error {
 	if err = os.Rename(tf.Name(), path); err != nil {
 		return err
 	}
+
 	return nil
 }
 
diff --git a/pkg/minikube/config/profile_test.go b/pkg/minikube/config/profile_test.go
index 92e580f9f2..ffeb29c3ec 100644
--- a/pkg/minikube/config/profile_test.go
+++ b/pkg/minikube/config/profile_test.go
@@ -73,24 +73,38 @@ func TestListProfiles(t *testing.T) {
 }
 
 func TestProfileNameValid(t *testing.T) {
-	var testCases = []struct {
-		name     string
-		expected bool
-	}{
-		{"meaningful_name", true},
-		{"meaningful_name@", false},
-		{"n_a_m_e_2", true},
-		{"n", false},
-		{"_name", false},
-		{"N__a.M--E12567", true},
-	}
-	for _, tt := range testCases {
-		got := ProfileNameValid(tt.name)
-		if got != tt.expected {
-			t.Errorf("expected ProfileNameValid(%s)=%t but got %t ", tt.name, tt.expected, got)
-		}
+	var testCases = map[string]bool{
+		"profile":             true,
+		"pro-file":            true,
+		"profile1":            true,
+		"pro-file1":           true,
+		"1st-profile":         true,
+		"1st-2nd-3rd-profile": true,
+		"n":                   true,
+		"1":                   true,
+		"12567":               true,
+
+		"pro file":         false,
+		"pro-file-":        false,
+		"-profile":         false,
+		"meaningful_name":  false,
+		"meaningful_name@": false,
+		"n_a_m_e_2":        false,
+		"_name":            false,
+		"N__a.M--E12567":   false,
 	}
 
+	for name, exp := range testCases {
+		name, exp := name, exp // capture range variables
+
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+			got := ProfileNameValid(name)
+			if got != exp {
+				t.Errorf("expected ProfileNameValid(%s)=%t but got %t ", name, exp, got)
+			}
+		})
+	}
 }
 
 func TestProfileNameInReservedKeywords(t *testing.T) {
diff --git a/pkg/minikube/kubeconfig/context_test.go b/pkg/minikube/kubeconfig/context_test.go
index 7725294441..a7bcc4af30 100644
--- a/pkg/minikube/kubeconfig/context_test.go
+++ b/pkg/minikube/kubeconfig/context_test.go
@@ -26,6 +26,7 @@ import (
 func TestDeleteContext(t *testing.T) {
 	// See kubeconfig_test
 	fn := tempFile(t, kubeConfigWithoutHTTPS)
+	defer os.Remove(fn)
 	if err := DeleteContext("la-croix", fn); err != nil {
 		t.Fatal(err)
 	}
diff --git a/pkg/minikube/kubeconfig/kubeconfig_test.go b/pkg/minikube/kubeconfig/kubeconfig_test.go
index 8a0df17120..54e585b5d5 100644
--- a/pkg/minikube/kubeconfig/kubeconfig_test.go
+++ b/pkg/minikube/kubeconfig/kubeconfig_test.go
@@ -263,6 +263,7 @@ func TestVerifyEndpoint(t *testing.T) {
 		t.Run(test.description, func(t *testing.T) {
 			t.Parallel()
 			configFilename := tempFile(t, test.existing)
+			defer os.Remove(configFilename)
 			err := VerifyEndpoint("minikube", test.hostname, test.port, configFilename)
 			if err != nil && !test.err {
 				t.Errorf("Got unexpected error: %v", err)
@@ -330,6 +331,7 @@ func TestUpdateIP(t *testing.T) {
 		t.Run(test.description, func(t *testing.T) {
 			t.Parallel()
 			configFilename := tempFile(t, test.existing)
+			defer os.Remove(configFilename)
 			statusActual, err := UpdateEndpoint("minikube", test.hostname, test.port, configFilename)
 			if err != nil && !test.err {
 				t.Errorf("Got unexpected error: %v", err)
@@ -419,6 +421,7 @@ func Test_Endpoint(t *testing.T) {
 	for _, test := range tests {
 		t.Run(test.description, func(t *testing.T) {
 			configFilename := tempFile(t, test.cfg)
+			defer os.Remove(configFilename)
 			hostname, port, err := Endpoint("minikube", configFilename)
 			if err != nil && !test.err {
 				t.Errorf("Got unexpected error: %v", err)
diff --git a/pkg/minikube/machine/client_test.go b/pkg/minikube/machine/client_test.go
index b2cafc9428..cb9091fb51 100644
--- a/pkg/minikube/machine/client_test.go
+++ b/pkg/minikube/machine/client_test.go
@@ -19,18 +19,15 @@ package machine
 import (
 	"bufio"
 	"fmt"
-	"io/ioutil"
-	"log"
 	"net"
 	"os"
-	"path/filepath"
 	"testing"
 
 	"github.com/docker/machine/libmachine/drivers/plugin/localbinary"
 
 	"k8s.io/minikube/pkg/minikube/driver"
-	"k8s.io/minikube/pkg/minikube/localpath"
 	_ "k8s.io/minikube/pkg/minikube/registry/drvs/virtualbox"
+	testutil "k8s.io/minikube/pkg/minikube/tests"
 )
 
 const vboxConfig = `
@@ -113,24 +110,9 @@ func TestLocalClientNewHost(t *testing.T) {
 	}
 }
 
-func makeTempDir() string {
-	tempDir, err := ioutil.TempDir("", "minipath")
-	if err != nil {
-		log.Fatal(err)
-	}
-	tempDir = filepath.Join(tempDir, ".minikube")
-	os.Setenv(localpath.MinikubeHome, tempDir)
-	return localpath.MiniPath()
-}
-
 func TestRunNotDriver(t *testing.T) {
-	tempDir := makeTempDir()
-	defer func() { //clean up tempdir
-		err := os.RemoveAll(tempDir)
-		if err != nil {
-			t.Errorf("failed to clean up temp folder  %q", tempDir)
-		}
-	}()
+	tempDir := testutil.MakeTempDir()
+	defer testutil.RemoveTempDir(tempDir)
 	StartDriver()
 	if !localbinary.CurrentBinaryIsDockerMachine {
 		t.Fatal("CurrentBinaryIsDockerMachine not set. This will break driver initialization.")
@@ -140,8 +122,8 @@ func TestRunNotDriver(t *testing.T) {
 func TestRunDriver(t *testing.T) {
 	// This test is a bit complicated. It verifies that when the root command is
 	// called with the proper environment variables, we setup the libmachine driver.
-	tempDir := makeTempDir()
-	defer os.RemoveAll(tempDir)
+	tempDir := testutil.MakeTempDir()
+	defer testutil.RemoveTempDir(tempDir)
 
 	os.Setenv(localbinary.PluginEnvKey, localbinary.PluginEnvVal)
 	os.Setenv(localbinary.PluginEnvDriverName, driver.VirtualBox)
diff --git a/pkg/minikube/machine/filesync_test.go b/pkg/minikube/machine/filesync_test.go
index a69be410f0..a766ce0f1e 100644
--- a/pkg/minikube/machine/filesync_test.go
+++ b/pkg/minikube/machine/filesync_test.go
@@ -17,26 +17,16 @@ limitations under the License.
 package machine
 
 import (
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
 	"k8s.io/minikube/pkg/minikube/localpath"
+	testutil "k8s.io/minikube/pkg/minikube/tests"
 	"k8s.io/minikube/pkg/minikube/vmpath"
 )
 
-func setupTestDir() (string, error) {
-	path, err := ioutil.TempDir("", "minipath")
-	if err != nil {
-		return "", err
-	}
-
-	os.Setenv(localpath.MinikubeHome, path)
-	return path, err
-}
-
 func TestAssetsFromDir(t *testing.T) {
 	tests := []struct {
 		description string
@@ -107,17 +97,8 @@ func TestAssetsFromDir(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.description, func(t *testing.T) {
-			testDir, err := setupTestDir()
-			defer func() { //clean up tempdir
-				err := os.RemoveAll(testDir)
-				if err != nil {
-					t.Errorf("failed to clean up temp folder  %q", testDir)
-				}
-			}()
-			if err != nil {
-				t.Errorf("got unexpected error creating test dir: %v", err)
-				return
-			}
+			testDir := testutil.MakeTempDir()
+			defer testutil.RemoveTempDir(testDir)
 
 			testDirs = append(testDirs, testDir)
 			testFileBaseDir := filepath.Join(testDir, test.baseDir)
diff --git a/pkg/minikube/node/config.go b/pkg/minikube/node/config.go
index 2b1db4e9a9..92ef4c65ca 100644
--- a/pkg/minikube/node/config.go
+++ b/pkg/minikube/node/config.go
@@ -41,10 +41,10 @@ func showVersionInfo(k8sVersion string, cr cruntime.Manager) {
 	register.Reg.SetStep(register.PreparingKubernetes)
 	out.T(cr.Style(), "Preparing Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}} ...", out.V{"k8sVersion": k8sVersion, "runtime": cr.Name(), "runtimeVersion": version})
 	for _, v := range config.DockerOpt {
-		out.T(out.Option, "opt {{.docker_option}}", out.V{"docker_option": v})
+		out.Infof("opt {{.docker_option}}", out.V{"docker_option": v})
 	}
 	for _, v := range config.DockerEnv {
-		out.T(out.Option, "env {{.docker_env}}", out.V{"docker_env": v})
+		out.Infof("env {{.docker_env}}", out.V{"docker_env": v})
 	}
 }
 
diff --git a/pkg/minikube/node/start.go b/pkg/minikube/node/start.go
index 873d7df3a3..e118e08476 100644
--- a/pkg/minikube/node/start.go
+++ b/pkg/minikube/node/start.go
@@ -289,7 +289,7 @@ func setupKubeAdm(mAPI libmachine.API, cfg config.ClusterConfig, n config.Node,
 		exit.WithError("Failed to get bootstrapper", err)
 	}
 	for _, eo := range config.ExtraOptions {
-		out.T(out.Option, "{{.extra_option_component_name}}.{{.key}}={{.value}}", out.V{"extra_option_component_name": eo.Component, "key": eo.Key, "value": eo.Value})
+		out.Infof("{{.extra_option_component_name}}.{{.key}}={{.value}}", out.V{"extra_option_component_name": eo.Component, "key": eo.Key, "value": eo.Value})
 	}
 	// Loads cached images, generates config files, download binaries
 	// update cluster and set up certs
@@ -424,7 +424,7 @@ func validateNetwork(h *host.Host, r command.Runner, imageRepository string) (st
 				out.T(out.Internet, "Found network options:")
 				optSeen = true
 			}
-			out.T(out.Option, "{{.key}}={{.value}}", out.V{"key": k, "value": v})
+			out.Infof("{{.key}}={{.value}}", out.V{"key": k, "value": v})
 			ipExcluded := proxy.IsIPExcluded(ip) // Skip warning if minikube ip is already in NO_PROXY
 			k = strings.ToUpper(k)               // for http_proxy & https_proxy
 			if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !ipExcluded && !warnedOnce {
diff --git a/pkg/minikube/notify/notify_test.go b/pkg/minikube/notify/notify_test.go
index 8f926daea6..46e44d5589 100644
--- a/pkg/minikube/notify/notify_test.go
+++ b/pkg/minikube/notify/notify_test.go
@@ -43,7 +43,7 @@ func TestMaybePrintUpdateTextFromGithub(t *testing.T) {
 
 func TestShouldCheckURL(t *testing.T) {
 	tempDir := tests.MakeTempDir()
-	defer os.RemoveAll(tempDir)
+	defer tests.RemoveTempDir(tempDir)
 
 	lastUpdateCheckFilePath := filepath.Join(tempDir, "last_update_check")
 
@@ -152,7 +152,7 @@ func TestGetLatestVersionFromURLMalformed(t *testing.T) {
 
 func TestMaybePrintUpdateText(t *testing.T) {
 	tempDir := tests.MakeTempDir()
-	defer os.RemoveAll(tempDir)
+	defer tests.RemoveTempDir(tempDir)
 	outputBuffer := tests.NewFakeFile()
 	out.SetErrFile(outputBuffer)
 
diff --git a/pkg/minikube/out/out.go b/pkg/minikube/out/out.go
index a8b163de14..9a37e860fc 100644
--- a/pkg/minikube/out/out.go
+++ b/pkg/minikube/out/out.go
@@ -69,6 +69,10 @@ type V map[string]interface{}
 
 // T writes a stylized and templated message to stdout
 func T(style StyleEnum, format string, a ...V) {
+	if style == Option {
+		Infof(format, a...)
+		return
+	}
 	outStyled := ApplyTemplateFormatting(style, useColor, format, a...)
 	if JSON {
 		register.PrintStep(outStyled)
@@ -77,6 +81,12 @@ func T(style StyleEnum, format string, a ...V) {
 	String(outStyled)
 }
 
+// Infof is used for informational logs (options, env variables, etc)
+func Infof(format string, a ...V) {
+	outStyled := ApplyTemplateFormatting(Option, useColor, format, a...)
+	String(outStyled)
+}
+
 // String writes a basic formatted string to stdout
 func String(format string, a ...interface{}) {
 	// Flush log buffer so that output order makes sense
diff --git a/pkg/minikube/tests/dir_utils.go b/pkg/minikube/tests/dir_utils.go
index 361d4752ac..795742b772 100644
--- a/pkg/minikube/tests/dir_utils.go
+++ b/pkg/minikube/tests/dir_utils.go
@@ -45,6 +45,13 @@ func MakeTempDir() string {
 	return localpath.MiniPath()
 }
 
+func RemoveTempDir(tempdir string) {
+	if filepath.Base(tempdir) == ".minikube" {
+		tempdir = filepath.Dir(tempdir)
+	}
+	os.RemoveAll(tempdir)
+}
+
 // FakeFile satisfies fdWriter
 type FakeFile struct {
 	b bytes.Buffer
diff --git a/pkg/util/retry/retry.go b/pkg/util/retry/retry.go
index 8bdacf4610..cc2b534575 100644
--- a/pkg/util/retry/retry.go
+++ b/pkg/util/retry/retry.go
@@ -36,6 +36,7 @@ func Local(callback func() error, maxTime time.Duration) error {
 	b.InitialInterval = 250 * time.Millisecond
 	b.RandomizationFactor = 0.25
 	b.Multiplier = 1.25
+	b.MaxElapsedTime = maxTime
 	return backoff.RetryNotify(callback, b, notify)
 }
 
diff --git a/site/content/en/docs/commands/start.md b/site/content/en/docs/commands/start.md
index c69c0dca51..d333ffd959 100644
--- a/site/content/en/docs/commands/start.md
+++ b/site/content/en/docs/commands/start.md
@@ -66,7 +66,7 @@ minikube start [flags]
       --insecure-registry strings         Insecure Docker registries to pass to the Docker daemon.  The default service CIDR range will automatically be added.
       --install-addons                    If set, install addons. Defaults to true. (default true)
       --interactive                       Allow user prompts for more information (default true)
-      --iso-url strings                   Locations to fetch the minikube ISO from. (default [https://storage.googleapis.com/minikube/iso/minikube-v1.11.0.iso,https://github.com/kubernetes/minikube/releases/download/v1.11.0/minikube-v1.11.0.iso,https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.11.0.iso])
+      --iso-url strings                   Locations to fetch the minikube ISO from. (default [https://storage.googleapis.com/minikube/iso/minikube-v1.12.0.iso,https://github.com/kubernetes/minikube/releases/download/v1.12.0/minikube-v1.12.0.iso,https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.12.0.iso])
       --keep-context                      This will keep the existing kubectl context and will create a minikube context.
       --kubernetes-version string         The Kubernetes version that the minikube VM will use (ex: v1.2.3, 'stable' for v1.18.3, 'latest' for v1.18.4-rc.0). Defaults to 'stable'.
       --kvm-gpu                           Enable experimental NVIDIA GPU support in minikube
diff --git a/site/content/en/docs/drivers/includes/podman_usage.inc b/site/content/en/docs/drivers/includes/podman_usage.inc
index 22c71a96f8..63940a3c54 100644
--- a/site/content/en/docs/drivers/includes/podman_usage.inc
+++ b/site/content/en/docs/drivers/includes/podman_usage.inc
@@ -1,20 +1,22 @@
-## experimental
+## Experimental
 
-This is an experimental driver. please use it only for experimental reasons.
-for a better kubernetes in container experience, use docker [driver]({{< ref "/docs/drivers/docker/" >}})
-
-## Install Podman
-
-- [Podman](https://podman.io/getting-started/installation.html)
+This is an experimental driver. Please use it only for experimental reasons until it has reached maturity. For a more reliable minikube experience, use a non-experimental driver, like [Docker]({{< ref "/docs/drivers/docker.md" >}}).
 
 ## Usage
 
-Start a cluster using the podman driver:
+It's recommended to run minikube with the podman driver and [CRI-O container runtime](https://https://cri-o.io/): 
 
 ```shell
-minikube start --driver=podman
+minikube start --driver=podman --container-runtime=cri-o
 ```
-To make docker the default driver:
+
+Alternatively, start minikube with the podman driver only: 
+
+```shell
+minikube start --driver=podman 
+```
+
+To make podman the default driver: 
 
 ```shell
 minikube config set driver podman
diff --git a/site/content/en/docs/drivers/kvm2.md b/site/content/en/docs/drivers/kvm2.md
index 52f19be12b..6ec2e8428d 100644
--- a/site/content/en/docs/drivers/kvm2.md
+++ b/site/content/en/docs/drivers/kvm2.md
@@ -37,6 +37,10 @@ The `minikube start` command supports 3 additional kvm specific flags:
 
 Also see [co/kvm2 open issues](https://github.com/kubernetes/minikube/labels/co%2Fkvm2)
 
+### Nested Virtulization
+
+If you are running KVM in a nested virtualization environment ensure your config the kernel modules correctly follow either [this](https://stafwag.github.io/blog/blog/2018/06/04/nested-virtualization-in-kvm/)  or [this](VM follow to config the kernel modules. also https://computingforgeeks.com/how-to-install-kvm-virtualization-on-debian/) tutorial.
+
 ## Troubleshooting
 * Run `virt-host-validate` and check for the suggestions.
 * Run `minikube start --alsologtostderr -v=7` to debug crashes
diff --git a/site/content/en/docs/drivers/podman.md b/site/content/en/docs/drivers/podman.md
index 286429b0ef..d1e8271306 100644
--- a/site/content/en/docs/drivers/podman.md
+++ b/site/content/en/docs/drivers/podman.md
@@ -11,21 +11,36 @@ aliases:
 This driver is experimental and in active development. Help wanted!
 {{% /pageinfo %}}
 
-The podman driver is another kubernetes in container driver for minikube. similar to [docker](https://minikube.sigs.k8s.io/docs/drivers/docker/) driver. The podman driver is  experimental, and only supported on Linux and macOS (with a remote podman server).
+The podman driver is an alternative container runtime to the [Docker]({{< ref "/docs/drivers/docker.md" >}}) driver.
 
 ## Requirements
 
-- Install [Podman](https://podman.io/getting-started/installation) 
-- amd64 system 
+- Linux or macOS operating systems on amd64 architecture 
+- Install [podman](https://podman.io/getting-started/installation.html)
 
-## Try it with CRI-O container runtime.
-
-```shell
-minikube start --driver=podman --container-runtime=cri-o
-```
 
 {{% readfile file="/docs/drivers/includes/podman_usage.inc" %}}
 
 ## Known Issues
 
 - Podman driver is not supported on non-amd64 architectures such as arm yet. For non-amd64 archs please use [other drivers]({{< ref "/docs/drivers/_index.md" >}}) 
+- Podman requirements passwordless running of sudo. If you run into an error about sudo, do the following: 
+
+```shell
+$ sudo visudo
+```
+Then append the following to the section *at the very bottom* of the file where `username` is your user account.
+
+```shell
+username ALL=(ALL) NOPASSWD: /usr/bin/podman
+```
+
+Be sure this text is *after* `#includedir /etc/sudoers.d`. To confirm it worked, try: 
+
+```shell
+sudo -k -n podman version
+```
+
+## Troubleshooting
+
+- Run `minikube start --alsologtostderr -v=7` to debug errors and crashes
diff --git a/site/content/en/docs/handbook/registry.md b/site/content/en/docs/handbook/registry.md
index ff8c6b54a5..0b04a6f364 100644
--- a/site/content/en/docs/handbook/registry.md
+++ b/site/content/en/docs/handbook/registry.md
@@ -107,4 +107,4 @@ docker push localhost:5000/myimage
 
 After the image is pushed, refer to it by `localhost:5000/{name}` in kubectl specs.
 
-## 
\ No newline at end of file
+## 
diff --git a/site/content/en/docs/tutorials/using_psp.md b/site/content/en/docs/tutorials/using_psp.md
index b77fc4c46f..38123c73c0 100644
--- a/site/content/en/docs/tutorials/using_psp.md
+++ b/site/content/en/docs/tutorials/using_psp.md
@@ -13,18 +13,33 @@ This tutorial explains how to start minikube with Pod Security Policies (PSP) en
 
 ## Prerequisites
 
-- Minikube 1.5.2 with Kubernetes 1.16.x or higher
+- Minikube 1.11.1 with Kubernetes 1.16.x or higher
 
 ## Tutorial
 
-Before starting minikube, you need to give it the PSP YAMLs in order to allow minikube to bootstrap.  
+Start minikube with the `PodSecurityPolicy` admission controller and the
+`pod-security-policy` addon enabled.
 
-Create the directory:  
+`minikube start --extra-config=apiserver.enable-admission-plugins=PodSecurityPolicy --addons=pod-security-policy`
+
+The `pod-security-policy` addon must be enabled along with the admission
+controller to prevent issues during bootstrap.
+
+## Older versions of minikube
+
+Older versions of minikube do not ship with the `pod-security-policy` addon, so
+the policies that addon enables must be separately applied to the cluster.
+
+## Minikube 1.5.2 through 1.6.2
+
+Before starting minikube, you need to give it the PSP YAMLs in order to allow minikube to bootstrap.
+
+Create the directory:
 `mkdir -p ~/.minikube/files/etc/kubernetes/addons`
 
 Copy the YAML below into this file: `~/.minikube/files/etc/kubernetes/addons/psp.yaml`
 
-Now start minikube:  
+Now start minikube:
 `minikube start --extra-config=apiserver.enable-admission-plugins=PodSecurityPolicy`
 
 ```yaml
@@ -161,3 +176,24 @@ subjects:
   name: system:serviceaccounts:kube-system
   apiGroup: rbac.authorization.k8s.io
 ```
+
+### Minikube between 1.6.2 and 1.11.1
+
+With minikube versions greater than 1.6.2 and less than 1.11.1, the YAML files
+shown above will not be automatically applied to the cluster. You may have
+errors during bootstrap of the cluster if the admission controller is enabled.
+
+To use Pod Security Policies with these versions of minikube, first start a
+cluster without the `PodSecurityPolicy` admission controller enabled.
+
+Next, apply the YAML shown above to the cluster.
+
+Finally, stop the cluster and then restart it with the admission controller
+enabled.
+
+```
+minikube start
+kubectl apply -f /path/to/psp.yaml
+minikube stop
+minikube start --extra-config=apiserver.enable-admission-plugins=PodSecurityPolicy
+```
diff --git a/test.sh b/test.sh
index 79a3501648..82b3cb2bf2 100755
--- a/test.sh
+++ b/test.sh
@@ -67,6 +67,7 @@ then
         ${pkgs} \
         && echo ok || ((exitcode += 32))
     tail -n +2 "${cov_tmp}" >>"${COVERAGE_PATH}"
+    rm ${cov_tmp}
 fi
 
 exit "${exitcode}"
diff --git a/test/integration/net_test.go b/test/integration/net_test.go
index 0cd148eecb..c69094bcdf 100644
--- a/test/integration/net_test.go
+++ b/test/integration/net_test.go
@@ -90,7 +90,16 @@ func TestNetworkPlugins(t *testing.T) {
 				}
 				if !t.Failed() {
 					t.Run("KubeletFlags", func(t *testing.T) {
-						rr, err := Run(t, exec.CommandContext(ctx, Target(), "ssh", "-p", profile, "pgrep -a kubelet"))
+						var rr *RunResult
+						var err error
+
+						// none does not support 'minikube ssh'
+						if NoneDriver() {
+							rr, err = Run(t, exec.CommandContext(ctx, "pgrep", "-a", "kubelet"))
+						} else {
+							rr, err = Run(t, exec.CommandContext(ctx, Target(), "ssh", "-p", profile, "pgrep -a kubelet"))
+						}
+
 						if err != nil {
 							t.Fatalf("ssh failed: %v", err)
 						}