diff --git a/manifests/harvester.yaml b/manifests/harvester.yaml index c0b98248e..e3e4653e3 100644 --- a/manifests/harvester.yaml +++ b/manifests/harvester.yaml @@ -37,6 +37,9 @@ spec: webhook: image: imagePullPolicy: "IfNotPresent" - service: - harvester: - type: LoadBalancer + harvester-load-balancer: + enabled: true + kube-vip: + enabled: true + kube-vip-cloud-provider: + enabled: true diff --git a/pkg/config/templates/harvester-config.yaml b/pkg/config/templates/harvester-config.yaml index 163eaae9b..e18fc3ed5 100644 --- a/pkg/config/templates/harvester-config.yaml +++ b/pkg/config/templates/harvester-config.yaml @@ -9,7 +9,8 @@ spec: config: vip_interface: "{{ .MgmtInterface }}" service: - harvester: - vipMode: "{{ .VipMode }}" - vip: "{{ .Vip }}" - vipHwAddr: "{{ .VipHwAddr }}" + vip: + enabled: true + mode: "{{ .VipMode }}" + ip: "{{ .Vip }}" + hwAddress: "{{ .VipHwAddr }}" diff --git a/pkg/console/dashboard_panels.go b/pkg/console/dashboard_panels.go index 4ddcf81c7..0d4985ef9 100644 --- a/pkg/console/dashboard_panels.go +++ b/pkg/console/dashboard_panels.go @@ -213,9 +213,15 @@ func syncManagementURL(ctx context.Context, g *gocui.Gui) { func doSyncManagementURL(g *gocui.Gui) { managementURL := "Unavailable" - if managementIP := getVIP(); managementIP != "" { + managementIP := getVIP() + if managementIP != "" { managementURL = fmt.Sprintf("https://%s", managementIP) + } else { + if managementIP = getFirstReadyMasterIP(); managementIP != "" { + managementURL = fmt.Sprintf("https://%s:%s", managementIP, harvesterNodePort) + } } + g.Update(func(g *gocui.Gui) error { v, err := g.View("url") if err != nil { @@ -227,8 +233,23 @@ func doSyncManagementURL(g *gocui.Gui) { }) } +func getFirstReadyMasterIP() string { + // get first ready master node's internal ip + cmd := exec.Command("/bin/sh", "-c", `kubectl get no -l 'node-role.kubernetes.io/master=true' --sort-by='.metadata.creationTimestamp' \ +-o jsonpath='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{range @.status.addresses[*]}{@.type}={@.address};{end}{"\n"}{end}' 2>/dev/null \ +| grep 'Ready=True' | head -n 1 | tr ';' '\n' | awk -F '=' '/InternalIP/{printf $2}'`) + cmd.Env = os.Environ() + output, err := cmd.Output() + outStr := string(output) + if err != nil { + logrus.Error(err, outStr) + return "" + } + return outStr +} + func getVIP() string { - out, err := exec.Command("/bin/sh", "-c", `kubectl get service -n harvester-system harvester -o jsonpath='{.status.loadBalancer.ingress[*].ip}'`).Output() + out, err := exec.Command("/bin/sh", "-c", `kubectl get configmap -n harvester-system vip -o jsonpath='{.data.ip}'`).Output() outStr := string(out) if err != nil { logrus.Errorf(err.Error(), outStr)