From 1d543656ed26e9c7b1087bc065b8e78e535a7610 Mon Sep 17 00:00:00 2001 From: Matt Rickard Date: Thu, 7 Sep 2017 20:32:25 -0700 Subject: [PATCH] Add restart for kube-proxy --- pkg/minikube/bootstrapper/kubeadm/kubeadm.go | 13 ++- pkg/minikube/bootstrapper/kubeadm/util.go | 83 ++++++++++++++++++++ 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 73f46ce7d98b..925ef77a51f3 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -83,6 +83,7 @@ networking: serviceSubnet: {{.ServiceCIDR}} etcd: dataDir: {{.EtcdDataDir}} +nodeName: {{.NodeName}} ` func NewKubeadmBootstrapper(api libmachine.API) (*KubeadmBootstrapper, error) { @@ -198,7 +199,7 @@ func addAddons(files *[]assets.CopyableFile) error { func (k *KubeadmBootstrapper) RestartCluster(k8s bootstrapper.KubernetesConfig) error { restoreTmpl := ` sudo kubeadm alpha phase certs all --config {{.KubeadmConfigFile}} && - sudo /usr/bin/kubeadm alpha phase kubeconfig all --config {{.KubeadmConfigFile}} --node-name {{.NodeName}} && + sudo /usr/bin/kubeadm alpha phase kubeconfig all --config {{.KubeadmConfigFile}} && sudo /usr/bin/kubeadm alpha phase controlplane all --config {{.KubeadmConfigFile}} && sudo /usr/bin/kubeadm alpha phase etcd local --config {{.KubeadmConfigFile}} ` @@ -206,10 +207,8 @@ func (k *KubeadmBootstrapper) RestartCluster(k8s bootstrapper.KubernetesConfig) opts := struct { KubeadmConfigFile string - NodeName string }{ KubeadmConfigFile: constants.KubeadmConfigFile, - NodeName: k8s.NodeName, } b := bytes.Buffer{} @@ -221,6 +220,10 @@ func (k *KubeadmBootstrapper) RestartCluster(k8s bootstrapper.KubernetesConfig) return errors.Wrapf(err, "running cmd: %s", b.String()) } + if err := restartKubeProxy(k8s); err != nil { + return errors.Wrap(err, "restarting kube-proxy") + } + return nil } @@ -297,6 +300,7 @@ func (k *KubeadmBootstrapper) generateConfig(k8s bootstrapper.KubernetesConfig) APIServerPort int KubernetesVersion string EtcdDataDir string + NodeName string }{ CertDir: util.DefaultCertPath, ServiceCIDR: util.DefaultInsecureRegistry, @@ -304,6 +308,7 @@ func (k *KubeadmBootstrapper) generateConfig(k8s bootstrapper.KubernetesConfig) APIServerPort: util.APIServerPort, KubernetesVersion: k8s.KubernetesVersion, EtcdDataDir: "/data", //TODO(r2d4): change to something else persisted + NodeName: k8s.NodeName, } b := bytes.Buffer{} @@ -318,7 +323,7 @@ func maybeDownloadAndCache(binary, version string) (string, error) { targetDir := constants.MakeMiniPath("cache", version) targetFilepath := filepath.Join(targetDir, binary) - _, err := os.Stat(targetDir) + _, err := os.Stat(targetFilepath) // If it exists, do no verification and continue if err == nil { return targetFilepath, nil diff --git a/pkg/minikube/bootstrapper/kubeadm/util.go b/pkg/minikube/bootstrapper/kubeadm/util.go index a89fe8456b89..2d67864c3e56 100644 --- a/pkg/minikube/bootstrapper/kubeadm/util.go +++ b/pkg/minikube/bootstrapper/kubeadm/util.go @@ -17,16 +17,22 @@ limitations under the License. package kubeadm import ( + "bytes" "encoding/json" + "html/template" "github.com/pkg/errors" apierrs "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/strategicpatch" clientv1 "k8s.io/client-go/pkg/api/v1" rbacv1beta1 "k8s.io/client-go/pkg/apis/rbac/v1beta1" + "k8s.io/minikube/pkg/minikube/bootstrapper" "k8s.io/minikube/pkg/minikube/service" + "k8s.io/minikube/pkg/util" ) const masterTaint = "node-role.kubernetes.io/master" @@ -107,3 +113,80 @@ func elevateKubeSystemPrivileges() error { } return nil } + +const ( + kubeconfigConf = "kubeconfig.conf" + kubeProxyConfigmapTmpl = `apiVersion: v1 +kind: Config +clusters: +- cluster: + certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + server: https://{{.AdvertiseAddress}}:{{.APIServerPort}} + name: default +contexts: +- context: + cluster: default + namespace: default + user: default + name: default +current-context: default +users: +- name: default + user: + tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token +` +) + +func restartKubeProxy(k8s bootstrapper.KubernetesConfig) error { + client, err := util.GetClient() + if err != nil { + return errors.Wrap(err, "getting k8s client") + } + + selector := labels.SelectorFromSet(labels.Set(map[string]string{"k8s-app": "kube-proxy"})) + if err := util.WaitForPodsWithLabelRunning(client, "kube-system", selector); err != nil { + return errors.Wrap(err, "waiting for kube-proxy to be up for configmap update") + } + + cfgMap, err := client.CoreV1().ConfigMaps("kube-system").Get("kube-proxy", metav1.GetOptions{}) + if err != nil { + return errors.Wrap(err, "getting kube-proxy configmap") + } + + t := template.Must(template.New("kubeProxyTmpl").Parse(kubeProxyConfigmapTmpl)) + opts := struct { + AdvertiseAddress string + APIServerPort int + }{ + AdvertiseAddress: k8s.NodeIP, + APIServerPort: util.APIServerPort, + } + + kubeconfig := bytes.Buffer{} + if err := t.Execute(&kubeconfig, opts); err != nil { + return errors.Wrap(err, "executing kube proxy configmap template") + } + + data := map[string]string{ + kubeconfigConf: kubeconfig.String(), + } + + cfgMap.Data = data + if _, err := client.CoreV1().ConfigMaps("kube-system").Update(cfgMap); err != nil { + return errors.Wrap(err, "updating configmap") + } + + pods, err := client.CoreV1().Pods("kube-system").List(metav1.ListOptions{ + LabelSelector: "k8s-app=kube-proxy", + }) + if err != nil { + return errors.Wrap(err, "listing kube-proxy pods") + } + for _, pod := range pods.Items { + if err := client.CoreV1().Pods(pod.Namespace).Delete(pod.Name, &metav1.DeleteOptions{}); err != nil { + return errors.Wrapf(err, "deleting pod %+v", pod) + } + } + + return nil +}