diff --git a/deploy/charts/harvester/templates/configmap.yaml b/deploy/charts/harvester/templates/configmap.yaml index 4307dcfbfd..7633ba856b 100644 --- a/deploy/charts/harvester/templates/configmap.yaml +++ b/deploy/charts/harvester/templates/configmap.yaml @@ -4,6 +4,20 @@ metadata: name: kubevip namespace: kube-system data: -{{- if and (eq .Values.service.harvester.vipMode "static") .Values.service.harvester.vip }} - cidr-harvester-system: {{ .Values.service.harvester.vip }}/32 +{{- if and (eq .Values.service.vip.mode "static") .Values.service.vip.ip }} + cidr-cattle-system: {{ .Values.service.vip.ip }}/32 {{- end }} + +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: vip +data: + enabled: {{ .Values.service.vip.enabled | quote }} + serviceType: {{ .Values.service.vip.type }} + ip: {{ .Values.service.vip.ip | quote }} + mode: {{ .Values.service.vip.mode }} + hwAddress: {{ .Values.service.vip.hwAddress | quote }} + loadBalancerIP: {{ .Values.service.vip.loadBalancerIP | quote }} diff --git a/deploy/charts/harvester/templates/service.yaml b/deploy/charts/harvester/templates/service.yaml index daa6a6f2a3..30bb6ced32 100644 --- a/deploy/charts/harvester/templates/service.yaml +++ b/deploy/charts/harvester/templates/service.yaml @@ -2,17 +2,8 @@ apiVersion: v1 kind: Service metadata: - # NB(thxCode): name should not be customized as below: - # name: {{ template "harvester.fullname" . }} - # because we can easily confirm this resource from the corresponding namespace. name: harvester annotations: -{{- if and (eq .Values.service.harvester.type "LoadBalancer") (eq .Values.service.harvester.vipMode "DHCP") }} -{{- if and .Values.service.harvester.vip .Values.service.harvester.vipHwAddr }} - kube-vip.io/requestedIP: {{ .Values.service.harvester.vip }} - kube-vip.io/hwaddr: {{ .Values.service.harvester.vipHwAddr }} -{{- end }} -{{- end }} labels: {{ include "harvester.labels" . | indent 4 }} app.kubernetes.io/name: harvester @@ -27,11 +18,6 @@ spec: {{ include "harvester.labels" . | indent 4 }} app.kubernetes.io/name: harvester app.kubernetes.io/component: apiserver -{{- if and (eq .Values.service.harvester.type "LoadBalancer") (eq .Values.service.harvester.vipMode "DHCP") }} - loadBalancerIP: "0.0.0.0" -{{- else}} - loadBalancerIP: {{ .Values.service.harvester.loadBalancerIP }} -{{- end }} ports: {{- if gt (.Values.service.harvester.httpsPort | int) 0 }} - name: https diff --git a/deploy/charts/harvester/values.yaml b/deploy/charts/harvester/values.yaml index 53848924d7..60f265b990 100644 --- a/deploy/charts/harvester/values.yaml +++ b/deploy/charts/harvester/values.yaml @@ -218,9 +218,9 @@ service: # httpsNodePort: 30443 ## Specify the port of HTTPs endpoint. - ## defaults to "443". + ## defaults to "8443". ## - httpsPort: 443 + httpsPort: 8443 ## Specify the port of golang pprof endpoint. ## defaults to "6060". @@ -242,16 +242,24 @@ service: ## defaults to "ClientIP". sessionAffinity: ClientIP + # specify the vip service configs + vip: + enabled: false + + ## Specify the VIP service type + ## select from [ClusterIP, NodePort, LoadBalancer], + type: LoadBalancer + ## Specify the loadBalancerIP loadBalancerIP: "" ## kube-vip annotations help to get the vip ## Specify the mode of vip, - ## select from ["DHCP", "static"], - ## defaults to "DHCP". - vipMode: "static" - vip: "" - vipHwAddr: "" + ## select from ["dhcp", "static"], + ## defaults to "static". + mode: "static" + ip: "" + hwAddress: "" ## Specify the lifecycle jobs. ## @@ -405,14 +413,14 @@ webhook: httpsPort: 9443 harvester-load-balancer: - enabled: true + enabled: false image: imagePullPolicy: Always repository: rancher/harvester-load-balancer tag: master-head kube-vip: - enabled: true + enabled: false image: repository: plndr/kube-vip tag: v0.3.7 @@ -420,7 +428,7 @@ kube-vip: vip_interface: eth0 kube-vip-cloud-provider: - enabled: true + enabled: false image: repository: kubevip/kube-vip-cloud-provider tag: 0.1 \ No newline at end of file diff --git a/pkg/controller/master/rancher/embedded_rancher.go b/pkg/controller/master/rancher/embedded_rancher.go index 5bc1b3fb18..f5d03a285d 100644 --- a/pkg/controller/master/rancher/embedded_rancher.go +++ b/pkg/controller/master/rancher/embedded_rancher.go @@ -3,10 +3,12 @@ package rancher import ( rancherv3api "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" "github.com/sirupsen/logrus" + + "github.com/harvester/harvester/pkg/settings" ) var UpdateRancherUISettings = map[string]string{ - "ui-dashboard-index": "https://releases.rancher.com/harvester-ui/dashboard/latest/index.html", + "ui-dashboard-index": settings.DefaultDashboardUIURL, "ui-offline-preferred": "false", "ui-pl": "Harvester", } diff --git a/pkg/controller/master/rancher/register.go b/pkg/controller/master/rancher/register.go index 235f9c4e13..b0baa2e407 100644 --- a/pkg/controller/master/rancher/register.go +++ b/pkg/controller/master/rancher/register.go @@ -2,7 +2,10 @@ package rancher import ( "context" + "strconv" + "strings" + "github.com/mitchellh/mapstructure" rancherv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" ctlcorev1 "github.com/rancher/wrangler/pkg/generated/controllers/core/v1" corev1 "k8s.io/api/core/v1" @@ -18,20 +21,38 @@ const ( cattleSystemNamespaceName = "cattle-system" rancherExposeServiceName = "rancher-expose" rancherAppLabelName = "app" + + vipConfigmapName = "vip" + vipDHCPMode = "dhcp" + vipDHCPLoadBalancerIP = "0.0.0.0" ) type Handler struct { RancherSettings rancherv3.SettingClient Services ctlcorev1.ServiceClient + Configmaps ctlcorev1.ConfigMapClient + Namespace string +} + +type VIPConfig struct { + Enabled string `json:"enabled,omitempty"` + ServiceType corev1.ServiceType `json:"serviceType,omitempty"` + IP string `json:"ip,omitempty"` + Mode string `json:"mode,omitempty"` + HwAddress string `json:"hwAddress,omitempty"` + LoadBalancerIP string `json:"loadBalancerIP,omitempty"` } func Register(ctx context.Context, management *config.Management, options config.Options) error { if options.RancherEmbedded { rancherSettings := management.RancherManagementFactory.Management().V3().Setting() services := management.CoreFactory.Core().V1().Service() + configmaps := management.CoreFactory.Core().V1().ConfigMap() h := Handler{ RancherSettings: rancherSettings, Services: services, + Configmaps: configmaps, + Namespace: options.Namespace, } rancherSettings.OnChange(ctx, controllerRancherName, h.RancherSettingOnChange) @@ -40,12 +61,19 @@ func Register(ctx context.Context, management *config.Management, options config return nil } +// registerRancherExposeService help to create rancher-expose svc in the cattle-system namespace, +// by default it is nodePort, if the VIP is enabled it will be set to LoadBalancer type service. func (h *Handler) registerRancherExposeService() error { _, err := h.Services.Get(cattleSystemNamespaceName, rancherExposeServiceName, v1.GetOptions{}) if err != nil && !apierrors.IsNotFound(err) { return err } if apierrors.IsNotFound(err) { + vip, err := h.getVipConfig() + if err != nil { + return err + } + svc := &corev1.Service{ ObjectMeta: v1.ObjectMeta{ Name: rancherExposeServiceName, @@ -67,9 +95,40 @@ func (h *Handler) registerRancherExposeService() error { }, }, } + + // set vip loadBalancer type and ip + enabled, err := strconv.ParseBool(vip.Enabled) + if err != nil { + return err + } + if enabled && vip.ServiceType == corev1.ServiceTypeLoadBalancer { + svc.Spec.Type = vip.ServiceType + svc.Spec.LoadBalancerIP = vip.LoadBalancerIP + if strings.ToLower(vip.Mode) == vipDHCPMode { + svc.Annotations = map[string]string{ + "kube-vip.io/requestedIP": vip.IP, + "kube-vip.io/hwaddr": vip.HwAddress, + } + svc.Spec.LoadBalancerIP = vipDHCPLoadBalancerIP + } + } + if _, err := h.Services.Create(svc); err != nil { return err } } return nil } + +func (h *Handler) getVipConfig() (*VIPConfig, error) { + vipConfig := &VIPConfig{} + conf, err := h.Configmaps.Get(h.Namespace, vipConfigmapName, v1.GetOptions{}) + if err != nil { + return nil, err + } + + if err := mapstructure.Decode(conf.Data, vipConfig); err != nil { + return nil, err + } + return vipConfig, nil +} diff --git a/pkg/settings/settings.go b/pkg/settings/settings.go index 94a14be63f..e584f7bb7f 100644 --- a/pkg/settings/settings.go +++ b/pkg/settings/settings.go @@ -17,7 +17,7 @@ var ( APIUIVersion = NewSetting("api-ui-version", "1.1.9") // Please update the HARVESTER_API_UI_VERSION in package/Dockerfile when updating the version here. ServerVersion = NewSetting("server-version", "dev") - LocalUIIndex = NewSetting("local-ui-index", "https://releases.rancher.com/harvester-ui/dashboard/latest/index.html") + LocalUIIndex = NewSetting("local-ui-index", DefaultDashboardUIURL) UIPath = NewSetting("ui-path", "/usr/share/harvester/harvester") APIUISource = NewSetting("api-ui-source", "auto") // Options are 'auto', 'external' or 'bundled' VolumeSnapshotClass = NewSetting("volume-snapshot-class", "longhorn") @@ -31,7 +31,10 @@ var ( DefaultStorageClass = NewSetting("default-storage-class", "longhorn") ) -const BackupTargetSettingName = "backup-target" +const ( + BackupTargetSettingName = "backup-target" + DefaultDashboardUIURL = "https://releases.rancher.com/harvester-ui/dashboard/latest/index.html" +) func init() { if InjectDefaults == "" {