1"use strict";(self.webpackChunkspectro_cloud_docs=self.webpackChunkspectro_cloud_docs||[]).push([["12671"],{158817:function(e,s,n){n.r(s),n.d(s,{frontMatter:()=>l,toc:()=>a,default:()=>h,metadata:()=>t,assets:()=>c,contentTitle:()=>d});var t=JSON.parse('{"id":"clusters/edge/networking/kubevip","title":"Publish Cluster Services with Kube-vip","description":"Guide to publishing cluster services with kube-vip.","source":"@site/docs/docs-content/clusters/edge/networking/kubevip.md","sourceDirName":"clusters/edge/networking","slug":"/clusters/edge/networking/kubevip","permalink":"/clusters/edge/networking/kubevip","draft":false,"unlisted":false,"editUrl":"https://github.com/spectrocloud/librarium/blob/master/docs/docs-content/clusters/edge/networking/kubevip.md","tags":[{"inline":true,"label":"edge","permalink":"/tags/edge"}],"version":"current","lastUpdatedAt":1777826507000,"sidebarPosition":30,"frontMatter":{"sidebar_label":"Publish Cluster Services with Kube-vip","title":"Publish Cluster Services with Kube-vip","description":"Guide to publishing cluster services with kube-vip.","hide_table_of_contents":false,"sidebar_position":30,"tags":["edge"]},"sidebar":"docSidebar","previous":{"title":"Networking","permalink":"/clusters/edge/networking/"},"next":{"title":"Enable Overlay Network","permalink":"/clusters/edge/networking/vxlan-overlay"}}'),r=n(474848),i=n(884429);let l={sidebar_label:"Publish Cluster Services with Kube-vip",title:"Publish Cluster Services with Kube-vip",description:"Guide to publishing cluster services with kube-vip.",hide_table_of_contents:!1,sidebar_position:30,tags:["edge"]},d,c={},a=[{value:"Default Values",id:"default-values",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Enablement",id:"enablement",level:2},{value:"Validation",id:"validation",level:2}];function o(e){let s={a:"a",admonition:"admonition",code:"code",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(s.p,{children:["You can use kube-vip to provide a virtual IP address for your cluster and use it to expose a service of type\n",(0,r.jsx)(s.code,{children:"LoadBalancer"})," on the external network. You can have kube-vip dynamically request IP addresses or use a static IP\naddress."]}),"\n",(0,r.jsxs)(s.p,{children:["Kube-vip supports DHCP environments and can request additional IP address from the DHCP server automatically. Using\nkube-vip, you can expose services inside your cluster externally with a virtual IP address even if you do not have\ncontrol over your host's network. Kube-vip can also act as a load balancer for both your control plane and Kubernetes\nservices of type ",(0,r.jsx)(s.code,{children:"LoadBalancer"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"default-values",children:"Default Values"}),"\n",(0,r.jsxs)(s.p,{children:["Kube-vip has many environment variables you can use to customize its behavior. To set values for kube-vip, use the\n",(0,r.jsx)(s.code,{children:"cluster.kubevipArgs"})," parameter. For a complete list of environment variables, refer to the\n",(0,r.jsx)(s.a,{href:"https://kube-vip.io/docs/installation/flags/?query=vip_interface#environment-variables",children:"kube-vip documentation"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["By default, Palette uses the following ",(0,r.jsx)(s.code,{children:"cluster.kubevipArgs"})," values during initial cluster deployment. You can change\nthese values when deploying a cluster or performing Day-2 cluster operations."]}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Environment Variable"}),(0,r.jsx)(s.th,{children:"Description"}),(0,r.jsx)(s.th,{children:"Default Value"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"vip_arp"})}),(0,r.jsx)(s.td,{children:"Enables ARP broadcasts from leader."}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"true"})})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"port"})}),(0,r.jsxs)(s.td,{children:["Specifies the port number that ",(0,r.jsx)(s.code,{children:"kube-vip"})," will use."]}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"6443"})})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"vip_cidr"})}),(0,r.jsxs)(s.td,{children:["Sets the CIDR notation for the Virtual IP. A value of ",(0,r.jsx)(s.code,{children:"32"})," denotes a single IP address in IPv4."]}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"32"})})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"cp_enable"})}),(0,r.jsx)(s.td,{children:"Enables kube-vip control plane functionality."}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"true"})})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"cp_namespace"})}),(0,r.jsx)(s.td,{children:"The namespace where the lease will reside."}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"kube-system"})})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"vip_ddns"})}
1),(0,r.jsx)(s.td,{children:"Enables Dynamic DNS support."}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"{{ .DDNS}}"})})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"vip_leaderelection"})}),(0,r.jsx)(s.td,{children:"Enables Kubernetes LeaderElection."}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"true"})})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"vip_leaseduration"})}),(0,r.jsx)(s.td,{children:"Sets the lease duration in seconds."}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"5"})})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"vip_renewdeadline"})}),(0,r.jsx)(s.td,{children:"Specifies the deadline in seconds for renewing the lease."}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"3"})})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"vip_retryperiod"})}),(0,r.jsx)(s.td,{children:"Number of times the leader holds the lease for."}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"1"})})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"address"})}),(0,r.jsx)(s.td,{children:"Template placeholder for the virtual IP address."}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"{{ .VIP}}"})})]})]})]}),"\n",(0,r.jsx)(s.admonition,{type:"warning",children:(0,r.jsxs)(s.p,{children:["Do not modify the default ",(0,r.jsx)(s.code,{children:"address"})," value. Changing this value makes the cluster inaccessible. If no value is provided\nfor the ",(0,r.jsx)(s.code,{children:"vip_ddns"})," variable, it defaults to ",(0,r.jsx)(s.code,{children:"false"})," if the ",(0,r.jsx)(s.code,{children:"address"})," is a valid IP address and ",(0,r.jsx)(s.code,{children:"true"})," if it is a domain\nname."]})}),"\n",(0,r.jsx)(s.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"At least one Edge device with x86_64 or AMD64 processor architecture registered in your Palette account"}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"enablement",children:"Enablement"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Log in to ",(0,r.jsx)(s.a,{href:"https://console.spectrocloud.com/",children:"Palette"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["From the left ",(0,r.jsx)(s.strong,{children:"Main Menu"})," click ",(0,r.jsx)(s.strong,{children:"Clusters"})," and select ",(0,r.jsx)(s.strong,{children:"Add a New Cluster"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Choose ",(0,r.jsx)(s.strong,{children:"Edge Native"})," for the cluster type and click ",(0,r.jsx)(s.strong,{children:"Start Edge Native Configuration"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Give the cluster a name, description, and tags. Click on ",(0,r.jsx)(s.strong,{children:"Next"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Select the cluster profile that you plan to use to deploy your cluster with. Click ",(0,r.jsx)(s.strong,{children:"Next"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["In the ",(0,r.jsx)(s.strong,{children:"Parameters"})," step, click on the Kubernetes layer of your profile. In the YAML file for the Kubernetes layer\nof your cluster profile, add the following parameters."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:'cluster:\n kubevipArgs:\n vip_interface: "INTERFACE_NAME"\n svc_enable: true\n vip_servicesinterface: "INTERFACE_NAME"\n'})}),"\n",(0,r.jsx)(s.p,{children:"These are kube-vip environment variables that enable kube-vip to provide load balancing services for Kubernetes\nservices and specify which network interface will be used by kube-vip for handling traffic to the Kubernetes API\nserver and Kubernetes services. The following table provides you guidance on how to choose the values for each\nparameter:"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:(0,r.jsx)(s.strong,{children:"Parameter"})}),(0,r.jsx)(s.th,{children:(0,r.jsx)(s.strong,{children:"Description"})})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"vip_interface"})}),(0,r.jsxs)(s.td,{children:["Specifies the Network Interface Controller (NIC) that kube-vip will use for handling traffic to the Kubernetes API. If you do not specify ",(0,r.jsx)(s.code,{children:"vip_serviceinterface"}),", kube-vip will also use this interface for handling traffic to LoadBalancer-type services."]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"svc_enable"})}),(0,r.jsx)(s.td,{children:"Enables kube-vip to handle traffic for services of type LoadBalancer."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"vip_serviceinterface"})}),(0,r.jsxs)(s.td,{children:["Specifies the NIC that kube-vip will use for handling traffic to LoadBalancer-type services. If your cluster has network overlay enabled, or if your host has multiple NICs and you want to publish services on a different NIC than the one used by Kubernetes, you should specify the name of the NIC as the value of this parameter. If this parameter is not specified and you have set ",(0,r.jsx)(s.code,{children:"svc_enable"})," to ",(0,r.jsx)(s.code,{children:"true"}),", kube-vip will use the NIC you specified in ",(0,r.jsx)(s.code,{children:"vip_interface"})," to handle traffic to LoadBalancer-type services."]})]})]})]}),"\n",(0,r.jsxs)(s.ol,{start:"8",children:["\n",(0,r.jsxs)(s.li,{children:["Next, in layer of your cluster profile that has the service you want to expose, add two parameters\n",(0,r.jsx)(s.code,{children:"loadBalancerIP: IP_ADDRESS"})," and ",(0,r.jsx)(s.code,{children:"loadBalancerClass: kube-vip.io/kube-vip-class"})," to the service spec. The following\nexample manifest displays the usage of these two parameters."]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["If you are deploying in a DHCP environment, use ",(0,r.jsx)(s.code,{children:"0.0.0.0"})," as the value for the ",(0,r.jsx)(s.code,{children:"loadBalancerIP"})," parameter. If you want\nkube-vip to use a static IP, specify the IP address and make sure it's unused by other hosts in the network. The\nfollowing example manifest displays the usage of these two parameters."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",metastring:"{7-8}",children:"apiVersion: v1\nkind: Service\nmetadata:\n name: http-app-svc\n namespace: myapp\nspec:\n loadBalancerIP: 0.0.0.0\n loadBalancerClass: kube-vip.io/kube-vip-class\n ports:\n - port: 80\n protocol: TCP\n targetPort: http\n selector:\n app.kubernetes.io/name: http-app\n type: LoadBalancer\n"})}),"\n",(0,r.jsxs)(s.ol,{start:"9",children:["\n",(0,r.jsxs)(s.li,{children:["Click ",(0,r.jsx)(s.strong,{children:"Next"})," and finish the rest of the configurations. For more information, refer to\n",(0,r.jsx)(s.a,{href:"/clusters/edge/site-deployment/cluster-deployment",children:"Create Cluster Definition"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["When the cluster finishes deploying, kube-vip adds an annotation named ",(0,r.jsx)(s.code,{children:"kube-vip.io/requestedIP"})," to the Service resource\nto document which IP address it has received from the external network. Whenever kube-vip restarts, it will attempt to\nre-request the same IP address for that service. You can remove the annotation to make kube-vip request a fresh address\nwith the following command. Replace ",(0,r.jsx)(s.code,{children:"SERVICE_NAME"})," with the name of your service, and make sure to include the minus\nsymbol",(0,r.jsx)(s.code,{children:"-"})," at the end of the annotation."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-shell",children:"kubectl annotate service SERVICE_NAME kube-vip.io/requestedIP-\n"})}),"\n",(0,r.jsx)(s.h2,{id:"validation",children:"Validation"}),"\n",(0,r.jsx)(s.p,{children:"Use the following steps to validate that kube-vip has been set up correctly and is performing load balancing services\nfor your cluster."}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["Access the cluster via kubectl CLI. For more information, refer to\n",(0,r.jsx)(s.a,{href:"/clusters/cluster-management/palette-webctl",children:"Access Cluster with CLI"}),"."]}),"\n",(0,r.jsxs)(s.li,{children:["Issue the command ",(0,r.jsx)(s.code,{children:"kubectl get service SERVICE_NAME"})," and replace ",(0,r.jsx)(s.code,{children:"SERVICE_NAME"})," with the name of the service you\nconfigure with kube-vip. The output of the command displays the external IP address that kube-vip has received from\nthe external network or the IP address you specified in the ",(0,r.jsx)(s.code,{children:"loadBalancerIP"})," parameter."]}),"\n"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-shell",children:"kubectl get service http-app-svc\n"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-hideClipboard",children:"NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nhttp-app-svc LoadBalancer 10.100.200.10 10.10.1.100 80:30720/TCP 5m\n"})}),"\n",(0,r.jsxs)(s.p,{children:["In the above example, the external IP ",(0,r.jsx)(s.code,{children:"10.10.1.100"})," is the IP address that kube-vip received from the DHCP server or the\nIP address you specified in the ",(0,r.jsx)(s.code,{children:"loadBalancerIP"})," parameter."]})]})}function h(e={}){let{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},884429:function(e,s,n){n.d(s,{R:()=>l,x:()=>d});var t=n(296540);let r={},i=t.createContext(r);function l(e){let s=t.useContext(i);return t.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.