1"use strict";(self.webpackChunktigera_docs=self.webpackChunktigera_docs||[]).push([[2992],{15680:(e,r,a)=>{a.d(r,{xA:()=>d,yg:()=>y});var t=a(96540);function n(e,r,a){return r in e?Object.defineProperty(e,r,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[r]=a,e}function i(e,r){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),a.push.apply(a,t)}return a}function o(e){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?i(Object(a),!0).forEach((function(r){n(e,r,a[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(a,r))}))}return e}function s(e,r){if(null==e)return{};var a,t,n=function(e,r){if(null==e)return{};var a,t,n={},i=Object.keys(e);for(t=0;t<i.length;t++)a=i[t],r.indexOf(a)>=0||(n[a]=e[a]);return n}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t<i.length;t++)a=i[t],r.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=t.createContext({}),c=function(e){var r=t.useContext(l),a=r;return e&&(a="function"==typeof e?e(r):o(o({},r),e)),a},d=function(e){var r=c(e.components);return t.createElement(l.Provider,{value:r},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},g=t.forwardRef((function(e,r){var a=e.components,n=e.mdxType,i=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(a),g=n,y=p["".concat(l,".").concat(g)]||p[g]||u[g]||i;return a?t.createElement(y,o(o({ref:r},d),{},{components:a})):t.createElement(y,o({ref:r},d))}));function y(e,r){var a=arguments,n=r&&r.mdxType;if("string"==typeof e||n){var i=a.length,o=new Array(i);o[0]=g;var s={};for(var l in r)hasOwnProperty.call(r,l)&&(s[l]=r[l]);s.originalType=e,s[p]="string"==typeof e?e:n,o[1]=s;for(var c=2;c<i;c++)o[c]=a[c];return t.createElement.apply(null,o)}return t.createElement.apply(null,a)}g.displayName="MDXCreateElement"},72750:(e,r,a)=>{a.r(r),a.d(r,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var t=a(58168),n=(a(96540),a(15680));const i={description:"Configure Calico to advertise Kubernetes service cluster IPs and external IPs outside the cluster using BGP."},o="Advertise Kubernetes service IP addresses",s={unversionedId:"networking/configuring/advertise-service-ips",id:"version-3.26/networking/configuring/advertise-service-ips",title:"Advertise Kubernetes service IP addresses",description:"Configure Calico to advertise Kubernetes service cluster IPs and external IPs outside the cluster using BGP.",source:"@site/calico_versioned_docs/version-3.26/networking/configuring/advertise-service-ips.mdx",sourceDirName:"networking/configuring",slug:"/networking/configuring/advertise-service-ips",permalink:"/calico/3.26/networking/configuring/advertise-service-ips",draft:!1,editUrl:"https://github.com/tigera/docs/edit/main/calico_versioned_docs/version-3.26/networking/configuring/advertise-service-ips.mdx",tags:[],version:"3.26",frontMatter:{description:"Configure Calico to advertise Kubernetes service cluster IPs and external IPs outside the cluster using BGP."},sidebar:"calicoSidebar",previous:{title:"Overlay networking",permalink:"/calico/3.26/networking/configuring/vxlan-ipip"},next:{title:"Configure MTU to maximize network performance",permalink:"/calico/3.26/networking/configuring/mtu"}},l={},c=[{value:"Big picture",id:"big-picture",level:2},{value:"Value",id:"value",level:2},{value:"Concepts",id:"concepts",level:2},{value:"BGP makes it easy",id:"bgp-makes-it-easy",level:3},{value:"Advertising service IPs: quick glance",id:"advertising-service-ips-quick-glance",level:3},{value:"Tips for success",id:"tips-for-success",level:3},{value:"Before you begin...",id:"before-you-begin",level:2},{value:"How to",id:"how-to",level:2},{value:"Advertise service cluster IP addresses",id:"advertise-service-cluster-ip-addresses",level:3},{value:"Advertise service external IP addresses",id:"advertise-service-external-ip-addresses",level:3},{value:"Advertise service load balancer IP addresses",id:"advertise-service-load-balancer-ip-addresses",level:3}
1,{value:"Exclude certain nodes from advertisement",id:"exclude-certain-nodes-from-advertisement",level:3},{value:"Tutorial",id:"tutorial",level:2},{value:"Additional resources",id:"additional-resources",level:2}],d={toc:c},p="wrapper";function u(e){let{components:r,...a}=e;return(0,n.yg)(p,(0,t.A)({},d,a,{components:r,mdxType:"MDXLayout"}),(0,n.yg)("h1",{id:"advertise-kubernetes-service-ip-addresses"},"Advertise Kubernetes service IP addresses"),(0,n.yg)("h2",{id:"big-picture"},"Big picture"),(0,n.yg)("p",null,"Enable Calico to advertise Kubernetes service IPs outside a cluster. Calico supports advertising a service\u2019s cluster IPs and external IPs."),(0,n.yg)("h2",{id:"value"},"Value"),(0,n.yg)("p",null,"Typically, Kubernetes service cluster IPs are accessible only within the cluster, so external access to the service requires a dedicated load balancer or ingress controller. In cases where a service\u2019s cluster IP is not routable, the service can be accessed using its external IP."),(0,n.yg)("p",null,"Just as Calico supports advertising ",(0,n.yg)("strong",{parentName:"p"},"pod IPs")," over BGP, it also supports advertising Kubernetes ",(0,n.yg)("strong",{parentName:"p"},"service IPs")," outside a cluster over BGP. This avoids the need for a dedicated load balancer. This feature also supports equal cost multi-path (ECMP) load balancing across nodes in the cluster, as well as source IP address preservation for local services when you need more control."),(0,n.yg)("h2",{id:"concepts"},"Concepts"),(0,n.yg)("h3",{id:"bgp-makes-it-easy"},"BGP makes it easy"),(0,n.yg)("p",null,"In Kubernetes, all requests for a service are redirected to an appropriate endpoint (pod) backing that service. Because Calico uses BGP, external traffic can be routed directly to Kubernetes services by advertising Kubernetes service IPs into the BGP network."),(0,n.yg)("p",null,"If your deployment is configured to peer with BGP routers outside the cluster, those routers (plus any other upstream places the routers propagate to) can send traffic to a Kubernetes service IP for routing to one of the available endpoints for that service."),(0,n.yg)("h3",{id:"advertising-service-ips-quick-glance"},"Advertising service IPs: quick glance"),(0,n.yg)("p",null,"Calico implements the Kubernetes ",(0,n.yg)("strong",{parentName:"p"},"externalTrafficPolicy")," using kube-proxy to direct incoming traffic to a correct pod. Advertisement is handled differently based on the service type that you configure for your service."),(0,n.yg)("table",null,(0,n.yg)("thead",{parentName:"table"},(0,n.yg)("tr",{parentName:"thead"},(0,n.yg)("th",{parentName:"tr",align:null},(0,n.yg)("strong",{parentName:"th"},"Service mode")),(0,n.yg)("th",{parentName:"tr",align:null},(0,n.yg)("strong",{parentName:"th"},"Cluster IP advertisement")),(0,n.yg)("th",{parentName:"tr",align:null},(0,n.yg)("strong",{parentName:"th"},"Traffic is...")),(0,n.yg)("th",{parentName:"tr",align:null},"Source IP address is..."))),(0,n.yg)("tbody",{parentName:"table"},(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},"Cluster (default)"),(0,n.yg)("td",{parentName:"tr",align:null},"All nodes in the cluster statically advertise a route to the service CIDR."),(0,n.yg)("td",{parentName:"tr",align:null},"Load balanced across nodes in the cluster using ECMP, then forwarded to appropriate pod in the service using SNAT. May incur second hop to another node, but good overall load balancing."),(0,n.yg)("td",{parentName:"tr",align:null},"Obscured by SNAT")),(0,n.yg)("tr",{parentName:"tbody"},(0,n.yg)("td",{parentName:"tr",align:null},"Local"),(0,n.yg)("td",{parentName:"tr",align:null},"The nodes with a pod backing the service advertise a specific route (/32 or /128) to the service's IP."),(0,n.yg)("td",{parentName:"tr",align:null},"Load balanced across nodes with endpoints for the service. Avoids second hop for LoadBalancer and NodePort type services, traffic may be unevenly load balanced. (Other traffic is load balanced across nodes in the cluster.)"),(0,n.yg)("td",{parentName:"tr",align:null},"Preserved")))),(0,n.yg)("p",null,"If your Calico deployment is configured to peer with BGP routers outside the cluster, those routers - plus any further upstream places that those routers propagate to - will be able to send traffic to a Kubernetes service cluster IP, and that traffic is routed to one of the available endpoints for that service."),(0,n.yg)("h3",{id:"tips-for-success"},"Tips for success"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},"Generally, we recommend using \u201cLocal\u201d for the following reasons:",(0,n.yg)("ul",{parentName:"li"},(0,n.yg)("li",{parentName:"ul"},"If any of your network policy uses rules to match by specific source IP addresses, using Local is the obvious choice because the source IP address is not altered, and the policy will still work."),(0,n.yg)("li",{parentName:"ul"},"Return traffic is routed directly to the source IP because \u201cLocal\u201d services do not require undoing the source NAT (unlike \u201cCluster\u201d services)."))),(0,n.yg)("li",{parentName:"ul"},"Cluster IP advertisement works best with a ToR that supports ECMP. Otherwise, all traffic for a given route is directed to a single node.")),(0,n.yg)("h2",{id:"before-you-begin"},"Before you begin..."),(0,n.yg)("p",null,(0,n.yg)("strong",{parentName:"p"},"Required")),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("a",{parentName:"li",href:"/calico/3.26/networking/configuring/bgp"},"Configure BGP peering")," between Calico and your network infrastru
1cture"),(0,n.yg)("li",{parentName:"ul"},"For ECMP load balancing to services, the upstream routers must be configured to use BGP multipath."),(0,n.yg)("li",{parentName:"ul"},"You need at least one external node outside the cluster that acts as a router, route reflector, or ToR that is peered with calico nodes inside the cluster."),(0,n.yg)("li",{parentName:"ul"},"Services must be configured with the correct service mode (\u201cCluster\u201d or \u201cLocal\u201d) for your implementation. For ",(0,n.yg)("inlineCode",{parentName:"li"},"externalTrafficPolicy: Local"),", the service must be type ",(0,n.yg)("inlineCode",{parentName:"li"},"LoadBalancer")," or ",(0,n.yg)("inlineCode",{parentName:"li"},"NodePort"),".")),(0,n.yg)("p",null,(0,n.yg)("strong",{parentName:"p"},"Limitations")),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("p",{parentName:"li"},"OpenShift, versions 4.5 and 4.6",(0,n.yg)("br",{parentName:"p"}),"\n","There is a ",(0,n.yg)("a",{parentName:"p",href:"https://github.com/kubernetes/kubernetes/issues/91374"},"bug")," where the source IP is not preserved by NodePort services or traffic via a Service ExternalIP with externalTrafficPolicy:Local."),(0,n.yg)("p",{parentName:"li"},"OpenShift users on v4.5 or v4.6 can use this ",(0,n.yg)("a",{parentName:"p",href:"https://docs.openshift.com/container-platform/4.7/nodes/clusters/nodes-cluster-enabling-features.html"},"workaround to avoid SNAT with ExternalIP"),":"),(0,n.yg)("pre",{parentName:"li"},(0,n.yg)("code",{parentName:"pre"}," oc edit featuregates.config.openshift.io cluster\n spec:\n customNoUpgrade:\n enabled:\n - ExternalPolicyForExternalIP\n")),(0,n.yg)("p",{parentName:"li"},"Kubernetes users on version v1.18 or v1.19 can enable source IP preservation for NodePort services using the ExternalPolicyForExternalIP feature gate."),(0,n.yg)("p",{parentName:"li"},"Source IP preservation for NodePort and services and ExternalIPs is enabled by default in OpenShift v4.7+, and Kubernetes v1.20+."))),(0,n.yg)("h2",{id:"how-to"},"How to"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("a",{parentName:"li",href:"#advertise-service-cluster-ip-addresses"},"Advertise service cluster IP addresses")),(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("a",{parentName:"li",href:"#advertise-service-external-ip-addresses"},"Advertise service external IP addresses")),(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("a",{parentName:"li",href:"#advertise-service-load-balancer-ip-addresses"},"Advertise service load balancer IP addresses")),(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("a",{parentName:"li",href:"#exclude-certain-nodes-from-advertisement"},"Exclude certain nodes from advertisement"))),(0,n.yg)("h3",{id:"advertise-service-cluster-ip-addresses"},"Advertise service cluster IP addresses"),(0,n.yg)("ol",null,(0,n.yg)("li",{parentName:"ol"},(0,n.yg)("p",{parentName:"li"},"Determine the service cluster IP range. (Or ranges, if your cluster is ",(0,n.yg)("a",{parentName:"p",href:"/calico/3.26/networking/ipam/ipv6"},"dual stack"),".)"),(0,n.yg)("p",{parentName:"li"},"The range(s) for your cluster can be inferred from the ",(0,n.yg)("inlineCode",{parentName:"p"},"--service-cluster-ip-range")," option passed to the Kubernetes API server. For help, see the ",(0,n.yg)("a",{parentName:"p",href:"https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/"},"Kubernetes API server reference guide"),".")),(0,n.yg)("li",{parentName:"ol"},(0,n.yg)("p",{parentName:"li"},"Check to see if you have a default BGPConfiguration."),(0,n.yg)("pre",{parentName:"li"},(0,n.yg)("code",{parentName:"pre",className:"language-bash"},"calicoctl get bgpconfig default\n"))),(0,n.yg)("li",{parentName:"ol"},(0,n.yg)("p",{parentName:"li"},"Based on above results, update or create a BGPConfiguration."),(0,n.yg)("p",{parentName:"li"},(0,n.yg)("strong",{parentName:"p"},"Update default BGPConfiguration"),'\nPatch the BGPConfiguration using the following command, using your own service cluster IP CIDR in place of "10.0.0.0/24":'),(0,n.yg)("pre",{parentName:"li"},(0,n.yg)("code",{parentName:"pre",className:"language-bash"},'calicoctl patch bgpconfig default --patch \\\n \'{"spec": {"serviceClusterIPs": [{"cidr": "10.0.0.0/24"}]}}\'\n')),(0,n.yg)("p",{parentName:"li"},(0,n.yg)("strong",{parentName:"p"},"Create default BGPConfiguration"),"\nUse the following sample command to create a default BGPConfiguration. Add your CIDR blocks, covering the cluster IPs to be advertised, in the ",(0,n.yg)("inlineCode",{parentName:"p"},"serviceClusterIPs")," field, for example:"),(0,n.yg)("pre",{parentName:"li"},(0,n.yg)("code",{parentName:"pre",className:"language-bash"},"calicoctl create -f - <<EOF\napiVersion: projectcalico.org/v3\nkind: BGPConfiguration\nmetadata:\n name: default\nspec:\n serviceClusterIPs:\n - cidr: 10.96.0.0/16\n - cidr: fd00:1234::/112\nEOF\n")),(0,n.yg)("p",{parentName:"li"},"For help see, ",(0,n.yg)("a",{parentName:"p",href:"/calico/3.26/reference/resources/bgpconfig"},"BGP configuration resource"),"."))),(0,n.yg)("admonition",{type:"note"},(0,n.yg)("p",{parentName:"admonition"},"In earlier versions of Calico, and for IPv4 only, service cluster IP advertisement was configured via the environment variable CALICO_ADVERTISE_CLUSTER_IPS.\nThat environment variable takes precedence over any serviceClusterIPs configured in the default BGPConfiguration. We recommend replacing the\ndeprecated CALICO_ADVERTISE_CLUSTER_IPS with BGPConfiguration.")),(0,n.yg)("h3",{id:"advertise-service-external-ip-addresses"},"Advertise service external IP addresses"),(0,n.yg)("ol",null,(0,n.yg)("li",{parentName:"ol"},(0,n.yg)("p",{parentName:"li"},"Identify the external IP ranges of all services that you want to advertise outside of the Calico cluster.")),(0,n.yg)("li",{parentName:"ol"},(0,n.yg)("p",{parentName:"li"},"Check to see if you have a default BGPConfiguration."),(0,n.yg)("pre",{parentName:"li"},(0,n.yg)("code",{parentName:"pre",className:"language-bash"},"calicoctl get bgpconfig default\n"))),(0,n.yg)("li",{parentName:"ol"},(0,n.yg)("p",{parentName:"li"},"Based on above results, update or create a BGPConfiguration."),(0,n.yg)("p",{parentName:"li"},(0,n.yg)("strong",{parentName:"p"},"Update default BGPConfiguration"),"\nPatch the BGPConfiguration using the following command, adding your own service external IP CIDRs:"),(0,n.yg)("pre",{parentName:"li"},(0,n.yg)("code",{parentName:"pre",className:"language-bash"},'calicoctl patch bgpconfig default --patch \\\n \'{"spec": {"serviceExternalIPs": [{"cidr": "x.x.x.x"}, {"cidr": "y.y.y.y"}]}}\'\n')),(0,n.yg)("p",{parentName:"li"},(0,n.yg)("strong",{parentName:"p"},"Create default BGPConfiguration"),"\nUse the following sample command to create a default BGPConfiguration. Add your CIDR blocks for external IPs to be advertised in the ",(0,n.yg)("inlineCode",{parentName:"p"},"serviceExternalIPs")," field."),(0,n.yg)("pre",{parentName:"li"},(0,n.yg)("code",{parentName:"pre",className:"language-bash"},"calicoctl create -f - <<EOF\napiVersion: projectcalico.org/v3\nkind: BGPConfiguration\nmetadata:\n name: default\nspec:\n serviceExternalIPs:\n - cidr: x.x.x.x/16\n - cidr: y.y.y.y/32\nEOF\n")),(0,n.yg)("p",{parentName:"li"},"For help see, ",(0,n.yg)("a",{parentName:"p",href:"/calico/3.26/reference/resources/bgpconfig"},"BGP configuration resource"),"."))),(0,n.yg)("h3",{id:"advertise-service-load-balancer-ip-addresses"},"Advertise service load balancer IP addresses"),(0,n.yg)("p",null,"The following steps will configure Calico to advertise Service ",(0,n.yg)("inlineCode",{parentName:"p"},"status.LoadBalancer.Ingress.IP")," addresses."),(0,n.yg)("ol",null,(0,n.yg)("li",{parentName:"ol"},(0,n.yg)("p",{parentName:"li"},"Identify the IP ranges to be used for Service LoadBalancer address allocation.")),(0,n.yg)("li",{parentName:"ol"},(0,n.yg)("p",{parentName:"li"},"Check to see if you have a default BGPConfiguration."),(0,n.yg)("pre",{parentName:"li"},(0,n.yg)("code",{parentName:"pre",className:"language-bash"},"calicoctl get bgpconfig default\n"))),(0,n.yg)("li",{parentName:"ol"},(0,n.yg)("p",{parentName:"li"},"Based on above results, update or create a BGPConfiguration."),(0,n.yg)("p",{parentName:"li"},(0,n.yg)("strong",{parentName:"p"},"Update default BGPConfiguration"),"\nPatch the BGPConfiguration using the following command, adding your own service load balancer IP CIDRs:"),(0,n.yg)("pre",{parentName:"li"},(0,n.yg)("code",{parentName:"pre",className:"language-bash"},'calicoctl patch bgpconfig default --patch \'{"spec": {"serviceLoadBalancerIPs": [{"cidr": "x.x.x.x/16"}]}}\'\n')),(0,n.yg)("p",{parentName:"li"},(0,n.yg)("strong",{parentName:"p"},"Create default BGPConfiguration"),"\nUse the following sample command to create a default BGPConfiguration. Add your CIDR blocks for load balancer IPs to be advertised in the ",(0,n.yg)("inlineCode",{parentName:"p"},"serviceLoadBalancerIPs")," field."),(0,n.yg)("pre",{parentName:"li"},(0,n.yg)("code",{parentName:"pre",className:"language-bash"},"calicoctl create -f - <<EOF\napiVersion: projectcalico.org/v3\nkind: BGPConfiguration\nmetadata:\n name: default\nspec:\n serviceLoadBalancerIPs:\n - cidr: x.x.x.x/16\nEOF\n")),(0,n.yg)("p",{parentName:"li"},"For help see, ",(0,n.yg)("a",{parentName:"p",href:"/calico/3.26/reference/resources/bgpconfig"},"BGP configuration resource"),"."))),(0,n.yg)("p",null,"Service LoadBalancer address allocation is outside the current scope of Calico, but can be implemented with an external
1controller.\nYou can build your own, or use a third-party implementation like the MetalLB project."),(0,n.yg)("p",null,"To install the MetalLB controller for allocating addresses, perform the following steps."),(0,n.yg)("ol",null,(0,n.yg)("li",{parentName:"ol"},(0,n.yg)("p",{parentName:"li"},"Follow ",(0,n.yg)("a",{parentName:"p",href:"https://metallb.universe.tf/installation/#installation-by-manifest"},"the MetalLB documentation")," to install the ",(0,n.yg)("inlineCode",{parentName:"p"},"metallb-system/controller")," resources."),(0,n.yg)("p",{parentName:"li"},"However, do not install the ",(0,n.yg)("inlineCode",{parentName:"p"},"metallb-system/speaker")," component. The speaker component also attempts to establish BGP sessions on the node, and will conflict with Calico.")),(0,n.yg)("li",{parentName:"ol"},(0,n.yg)("p",{parentName:"li"},"Configure MetalLB to provision addresses by creating the following IPAddressPool, replacing ",(0,n.yg)("inlineCode",{parentName:"p"},"x.x.x.x/16")," with the CIDR given to Calico in the steps above. Please note IPAddressPool requires Metallb ",(0,n.yg)("inlineCode",{parentName:"p"},"0.13+"),"."),(0,n.yg)("pre",{parentName:"li"},(0,n.yg)("code",{parentName:"pre",className:"language-bash"},"kubectl create -f - <<EOF\nkind: IPAddressPool\nmetadata:\n name: default\n namespace: metallb-system\nspec:\n addresses:\n - x.x.x.x/16\nEOF\n")))),(0,n.yg)("h3",{id:"exclude-certain-nodes-from-advertisement"},"Exclude certain nodes from advertisement"),(0,n.yg)("p",null,"In some cases, you may want to exclude certain nodes from advertising service addresses. For example, control plane nodes that do not host any services themselves."),(0,n.yg)("p",null,"To remove a node from service advertisement, apply the label ",(0,n.yg)("inlineCode",{parentName:"p"},"node.kubernetes.io/exclude-from-external-load-balancers=true"),"."),(0,n.yg)("p",null,"For example, to exclude the node ",(0,n.yg)("inlineCode",{parentName:"p"},"control-plane-01")," from service advertisement, you can run the following command:"),(0,n.yg)("pre",null,(0,n.yg)("code",{parentName:"pre",className:"language-bash"},"kubectl label node control-plane-01 node.kubernetes.io/exclude-from-external-load-balancers=true\n")),(0,n.yg)("h2",{id:"tutorial"},"Tutorial"),(0,n.yg)("p",null,"For a tutorial on how service advertisement works with Calico, see the blog ",(0,n.yg)("a",{parentName:"p",href:"https://www.projectcalico.org/kubernetes-service-ip-route-advertisement/"},"Kubernetes Service IP Route Advertisement"),"."),(0,n.yg)("h2",{id:"additional-resources"},"Additional resources"),(0,n.yg)("p",null,"Other topics on creating network policy for Kubernetes services:"),(0,n.yg)("ul",null,(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("a",{parentName:"li",href:"/calico/3.26/network-policy/services/services-cluster-ips"},"Apply policy to services exposed externally as cluster IPs")),(0,n.yg)("li",{parentName:"ul"},(0,n.yg)("a",{parentName:"li",href:"/calico/3.26/network-policy/services/kubernetes-node-ports"},"Apply policy to Kubernetes node ports"))))}u.isMDXComponent=!0}}]);
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.