PageSourceSearch

https://archive-ce-3-18.netlify.app/assets/js/a3cd29eb.d4a07d91.js

js archive-ce-3-18.netlify.app collected 2026-10-03 10:29:40 UTC 36,278 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunktigera_docs=self.webpackChunktigera_docs||[]).push([["12851"],{51849:function(e,n,s){s.d(n,{ZP:()=>l,d$:()=>i});var r=s(72459),t=s(36870);let i=[];function o(e){let n={a:"a",li:"li",p:"p",ul:"ul",...(0,t.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"The eBPF data plane mode has several advantages over standard Linux networking pipeline mode:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"It scales to higher throughput."}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"It uses less CPU per GBit."}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"It has native support for Kubernetes services (without needing kube-proxy) that:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Reduces first packet latency for packets to services."}),"\n",(0,r.jsx)(n.li,{children:"Preserves external client source IP addresses all the way to the pod."}),"\n",(0,r.jsx)(n.li,{children:"Supports DSR (Direct Server Return) for more efficient service routing."}),"\n",(0,r.jsx)(n.li,{children:"Uses less CPU than kube-proxy to keep the data plane in sync."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["To learn more and see performance metrics from our test environment, see the blog, ",(0,r.jsx)(n.a,{href:"https://www.projectcalico.org/introducing-the-calico-ebpf-dataplane/",children:"Introducing the Calico eBPF data plane"}),"."]})]})}function l(e={}){let{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},97286:function(e,n,s){s.r(n),s.d(n,{frontMatter:()=>c,default:()=>x,toc:()=>u,metadata:()=>r,assets:()=>h,contentTitle:()=>d});var r=JSON.parse('{"id":"operations/ebpf/install","title":"Install in eBPF mode","description":"Install Calico in eBPF mode.","source":"@site/calico_versioned_docs/version-3.28/operations/ebpf/install.mdx","sourceDirName":"operations/ebpf","slug":"/operations/ebpf/install","permalink":"/calico/3.28/operations/ebpf/install","draft":false,"unlisted":false,"editUrl":"https://github.com/tigera/docs/edit/main/calico_versioned_docs/version-3.28/operations/ebpf/install.mdx","tags":[],"version":"3.28","frontMatter":{"description":"Install Calico in eBPF mode."},"sidebar":"calicoSidebar","previous":{"title":"Enable the eBPF data plane","permalink":"/calico/3.28/operations/ebpf/enabling-ebpf"},"next":{"title":"Troubleshoot eBPF mode","permalink":"/calico/3.28/operations/ebpf/troubleshoot-ebpf"}}'),t=s(72459),i=s(36870),o=s(51849),l=s(82771),a=s(537);let c={description:"Install Calico in eBPF mode."},d="Install in eBPF mode",h={},u=[{value:"Big picture",id:"big-picture",level:2},{value:"Value",id:"value",level:2},...o.d$,{value:"Concepts",id:"concepts",level:2},{value:"eBPF",id:"ebpf",level:3},{value:"Before you begin",id:"before-you-begin",level:2},{value:"Supported",id:"supported",level:3},{value:"Not supported",id:"not-supported",level:3},{value:"Performance",id:"performance",level:3},{value:"How to",id:"how-to",level:2},{value:"Create a suitable cluster",id:"create-a-suitable-cluster",level:3},{value:"Create kubernetes-service-endpoint config map",id:"create-kubernetes-service-endpoint-config-map",level:3},{value:"Install the Tigera Operator",id:"install-the-tigera-operator",level:3},{value:"Create the Config Map",id:"create-the-config-map",level:3},{value:"Tweak and apply installation Custom Resources",id:"tweak-and-apply-installation-custom-resources",level:3},{value:"Monitor the progress of the installation",id:"monitor-the-progress-of-the-installation",level:3},{value:"Disable <code>kube-proxy</code> (or avoid conflicts)",id:"disable-kube-proxy-or-avoid-conflicts",level:3},{value:"Next steps",id:"next-steps",level:2}];function p(e){let n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"install-in-ebpf-mode",children:"Install in eBPF mode"})}),"\n","\n","\n",(0,t.jsx)(n.h2,{id:"big-picture",children:"Big picture"}),"\n",(0,t.jsx)(n.p,{children:"Install the eBPF data plane during the initial installation of Calico."}),"\n",(0,t.jsx)(n.h2,{id:"value",children:"Value"}),"\n",(0,t.jsx)(o.ZP,{}),"\n",(0,t.jsx)(n.h2,{id:"concepts",children:"Concepts"}),"\n",(0,t.jsx)(n.h3,{id:"ebpf",children:"eBPF"}),"\n",(0,t.jsx)(n.p,{children:'eBPF (or "extended Berkeley Packet Filter"), is a technology that allows safe mini programs to be attached to various\nlow-level hooks in the Linux kernel. eBPF has a wide variety of uses, including networking, security, and tracing.\nYou\u2019ll see a lot of non-networking projects leveraging eBPF, but for Calico our focus is on networking,\nand in particular, pushing the networking c
1apabilities of the latest Linux kernels to the limit.'}),"\n",(0,t.jsx)(n.h2,{id:"before-you-begin",children:"Before you begin"}),"\n",(0,t.jsx)(n.h3,{id:"supported",children:"Supported"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"x86-64"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"arm64 (little-endian)"}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Kubernetes datastore driver."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Distributions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Generic or kubeadm"}),"\n",(0,t.jsx)(n.li,{children:"kOps"}),"\n",(0,t.jsx)(n.li,{children:"OpenShift"}),"\n",(0,t.jsx)(n.li,{children:"EKS"}),"\n",(0,t.jsx)(n.li,{children:"AKS"}),"\n",(0,t.jsx)(n.li,{children:"MKE"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Linux distribution/kernel:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Ubuntu 20.04."}),"\n",(0,t.jsx)(n.li,{children:"Red Hat v8.2 with Linux kernel v4.18.0-193 or above (Red Hat have backported the required features to that build)."}),"\n",(0,t.jsxs)(n.li,{children:["Another ",(0,t.jsx)(n.a,{href:"/calico/3.28/getting-started/kubernetes/requirements",children:"supported distribution"})," with Linux kernel v5.3 or above."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"An underlying network fabric that allows VXLAN traffic between hosts. In eBPF mode, VXLAN is used to forward Kubernetes NodePort traffic."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"IPv6"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Limitations:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"IPIP is not supported (Calico iptables does not support it either). VXLAN is the recommended overlay for eBPF mode."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To enable IPv6 in eBPF mode, see ",(0,t.jsx)(n.a,{href:"/calico/3.28/networking/ipam/ipv6",children:"Configure dual stack or IPv6 only"}),". You may be able to run with non-Calico IPAM. eks-cni is known to work."]}),"\n",(0,t.jsx)(n.h3,{id:"not-supported",children:"Not supported"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Other processor architectures."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"etcd datastore driver.  The etcd datastore driver doesn't support watching Kubernetes services, which is required for some features in eBPF mode."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Distributions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"GKE. This is because of an incompatibility with the GKE CNI plugin."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["RKE: eBPF mode cannot be enabled at install time because RKE doesn't provide\na stable address for the API server. However, by following ",(0,t.jsx)(n.a,{href:"/calico/3.28/operations/ebpf/enabling-ebpf",children:"these instructions"}),",\nit can be enabled as a post-install step."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Clusters with some eBPF nodes and some standard data plane and/or Windows nodes."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Floating IPs."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"SCTP (either for policy or services)."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Log"})," action in policy rules."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Tagged VLAN devices."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"performance",children:"Performance"}),"\n",(0,t.jsx)(n.p,{children:"For best pod-to-pod performance, we recommend using an underlying network that doesn't require Calico to use an overlay. For example:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"A cluster within a single AWS subnet."}),"\n",(0,t.jsx)(n.li,{children:"A cluster using a compatible cloud provider's CNI (such as the AWS VPC CNI plugin)."}),"\n",(0,t.jsx)(n.li,{children:"An on-prem cluster with BGP peering configured."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"If you must use an overlay, we recommend that you use VXLAN, not IPIP. VXLAN has better performance than IPIP in\neBPF mode due to various kernel optimisations."}),"\n",(0,t.jsx)(n.h2,{id:"how-to",children:"How to"}),"\n",(0,t.jsx)(n.p,{children:"To install in eBPF mode, we recommend using the Tigera Operator to install Calico so these instructions\nuse the operator. Installing Calico normally consists of the following stages, which are covered by the\nmain installation guides:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Create a cluster suitable to run Calico."}),"\n",(0,t.jsx)(n.li,{children:"Install the Tigera Operator (possibly via a Helm chart), and the associated Custom Resource Definitions."}),"\n",(0,t.jsx)(n.li,{children:"Apply a set of Custom Resources to tell the operator what to install."}),"\n",(0,t.jsx)(n.li,{children:"Wait for the operator to provision all the associated resources and report back via its status resource."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"To install directly in eBPF is very similar; this guide explains the differences:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"#create-a-suitable-cluster",children:"Create a cluster"})," suitable to run Calico ",(0,t.jsx)(n.strong,{children:"with the added requirement that the nodes must use a recent\nenough kernel"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"#create-kubernetes-service-endpoint-config-map",children:(0,t.jsx)(n.strong,{children:'Create a config map with the "real" address of the API server.'})})," This allows the operator to install Calico\nwith a direct connection to the API server so that it can take over from ",(0,t.jsx)(n.code,{children:"kube-proxy"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"#install-the-tigera-operator",children:"Install the Tigera Operator"})," (possibly via a Helm chart), and the associated Custom Resource Definitions."]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsxs)(n.strong,{children:[(0,t.jsx)(n.a,{href:"#tweak-and-apply-installation-custom-resources",children:"Download and tweak the installation Custom Resource"})," to tell the operator to use eBPF mode."]})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"#tweak-and-apply-installation-custom-resources",children:"Apply a set of Custom Resources"})," to tell the operator what to install."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"#monitor-the-progress-of-the-installation",children:"Wait for the operator to provision all the associated resources and report back via its status resource"}),"."]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#disable-kube-proxy-or-avoid-conflicts",children:"Disable kube-proxy or avoid conflicts."})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"These steps are explained in more detail below."}),"\n",(0,t.jsx)(n.h3,{id:"create-a-suitable-cluster",children:"Create a suitable cluster"}),"\n",(0,t.jsxs)(n.p,{children:["The basic requirement for eBPF mode is to have a recent-enough kernel (see ",(0,t.jsx)(n.a,{href:"#supported",children:"above"}),")."]}),"\n",(0,t.jsx)(n.p,{children:"Select the appropriate tab below for distribution-s
1pecific instructions:"}),"\n",(0,t.jsxs)(l.Z,{children:[(0,t.jsxs)(a.Z,{label:"Generic or kubeadm",value:"Generic or kubeadm-0",children:[(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"kubeadm"})," supports a number of base OSes; as long as the base OS chosen (such as Ubuntu 20.04) meets the kernel\nrequirements, ",(0,t.jsx)(n.code,{children:"kubeadm"}),"-provisioned clusters are supported."]}),(0,t.jsxs)(n.p,{children:["Since ",(0,t.jsx)(n.code,{children:"kube-proxy"})," is not required in eBPF mode, you must disable ",(0,t.jsx)(n.code,{children:"kube-proxy"})," at install time. With ",(0,t.jsx)(n.code,{children:"kubeadm"}),"\nyou can do that by passing the ",(0,t.jsx)(n.code,{children:" --skip-phases=addon/kube-proxy"})," flag to ",(0,t.jsx)(n.code,{children:"kubeadm init"}),":"]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubeadm init --skip-phases=addon/kube-proxy\n"})})]}),(0,t.jsxs)(a.Z,{label:"kOps",value:"kOps-1",children:[(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"kops"})," supports a number of base OSes; as long as the base OS chosen (such as Ubuntu 20.04 or RHEL 8.2) meets the kernel\nrequirements, ",(0,t.jsx)(n.code,{children:"kops"}),"-provisioned clusters are supported."]}),(0,t.jsxs)(n.p,{children:["Since ",(0,t.jsx)(n.code,{children:"kube-proxy"})," is not required in eBPF mode, you must disable ",(0,t.jsx)(n.code,{children:"kube-proxy"})," at install time. With ",(0,t.jsx)(n.code,{children:"kops"})," you\ncan do that by setting the following in your ",(0,t.jsx)(n.code,{children:"kops"})," configuration:"]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"kubeProxy:\n  enabled: false\n"})})]}),(0,t.jsx)(a.Z,{label:"OpenShift",value:"OpenShift-2",children:(0,t.jsx)(n.p,{children:"OpenShift supports a number of base OSes; as long as the base OS chosen has a recent enough kernel, OpenShift clusters are\nfully supported. Since Red Hat have backported the eBPF features required by Calico the Red Hat kernel\nversion required is lower than the mainline: v4.18.0-193 or above."})}),(0,t.jsxs)(a.Z,{label:"AKS",value:"AKS-3",children:[(0,t.jsx)(n.p,{children:"Azure Kubernetes Service (AKS) supports a number of base OSes. The most recent Ubuntu 18.04 image has a recent enough\nkernel to use with eBPF mode."}),(0,t.jsxs)(n.p,{children:["AKS does not support disabling ",(0,t.jsx)(n.code,{children:"kube-proxy"})," so it's necessary to tell Calico not to try to clean up\n",(0,t.jsx)(n.code,{children:"kube-proxy"}),"'s iptables rules at a later stage."]})]}),(0,t.jsx)(a.Z,{label:"EKS",value:"EKS-4",children:(0,t.jsx)(n.p,{children:"Amazon's Elastic Kubernetes Service (EKS) supports a number of base OSes for nodes. At the time of writing, the\ndefault kernel used by Amazon Linux is recent enough to run eBPF mode, as is the Bottlerocket kernel. The Ubuntu\n18.04 image did not have a recent-enough kernel (but that may have changed by the time you read this)."})}),(0,t.jsxs)(a.Z,{label:"MKE",value:"MKE-5",children:[(0,t.jsx)(n.p,{children:"The eBPF data plane is supported on MKE with any Linux operating system that meets the minimum kernel requirements."}),(0,t.jsxs)(n.p,{children:["Since ",(0,t.jsx)(n.code,{children:"kube-proxy"})," is not required in eBPF mode, you must disable ",(0,t.jsx)(n.code,{children:"kube-proxy"})," at install time. With ",(0,t.jsx)(n.code,{children:"MKE"})," you\ncan do that by setting ",(0,t.jsx)(n.code,{children:"--kube-proxy-mode=disabled"})," and ",(0,t.jsx)(n.code,{children:"--kube-default-drop-masq-bits"})," when installing the cluster."]}),(0,t.jsxs)(n.p,{children:["More details can be found in ",(0,t.jsx)(n.a,{href:"https://docs.mirantis.com/mke/current/install/predeployment/configure-networking/cluster-service-networking-options.html",children:"the MKE documentation"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"create-kubernetes-service-endpoint-config-map",children:"Create kubernetes-service-endpoint config map"}),"\n",(0,t.jsxs)(n.p,{children:["In eBPF mode, Calico takes over from ",(0,t.jsx)(n.code,{children:"kube-proxy"}),". This means that, like ",(0,t.jsx)(n.code,{children:"kube-proxy"}),", it needs to be able\nto reach the API server ",(0,t.jsx)(n.em,{children:"directly"})," rather than by using the API server's ",(0,t.jsx)(n.code,{children:"ClusterIP"}),". To tell Calico how\nto reach the API server we create a ",(0,t.jsx)(n.code,{children:"ConfigMap"})," with the API server's \"real\" address. In this guide we do that before\ninstalling the Tigera Operator. That means that the operator itself can also use the direct connection and hence\nit doesn't require ",(0,t.jsx)(n.code,{children:"kube-proxy"})," to be running."]}),"\n",(0,t.jsxs)(n.p,{children:['The tabs below explain how to find the "real" address of the API server for a range of distributions.\n',(0,t.jsx)(n.strong,{children:"Note:"})," In all cases it's important that the address used is stable even if your API server is restarted or\nscaled up/d
1own. If you have multiple API servers, with DNS or other load balancing in front it's important to use\nthe address of the load balancer. This prevents Calico from being disconnected if the API servers IP changes."]}),"\n",(0,t.jsxs)(l.Z,{children:[(0,t.jsxs)(a.Z,{label:"Generic or kubeadm",value:"Generic or kubeadm-6",children:[(0,t.jsxs)(n.p,{children:["If you created a cluster manually (for example by using ",(0,t.jsx)(n.code,{children:"kubeadm"}),") then the right address to use depends on whether you\nopted for a high-availability cluster with multiple API servers or a simple one-node API server."]}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"If you opted to set up a high availability cluster then you should use the address of the load balancer that you\nused in front of your API servers. As noted in the Kubernetes documentation, a load balancer is required for a\nHA set-up but the precise type of load balancer is not specified."}),"\n",(0,t.jsxs)(n.li,{children:["If you opted for a single control plane node then you can use the address of the control plane node itself. However,\nit's important that you use a ",(0,t.jsx)(n.em,{children:"stable"})," address for that node such as a dedicated DNS record, or a static IP address.\nIf you use a dynamic IP address (such as an EC2 private IP) then the address may change when the node is restarted\ncausing Calico to lose connectivity to the API server."]}),"\n"]})]}),(0,t.jsx)(a.Z,{label:"kOps",value:"kOps-7",children:(0,t.jsxs)(n.p,{children:["When using ",(0,t.jsx)(n.code,{children:"kops"}),", ",(0,t.jsx)(n.code,{children:"kops"})," typically sets up a load balancer of some sort in front of the API server. You should use\nthe FQDN and port of the API load balancer: ",(0,t.jsx)(n.code,{children:"api.internal.<clustername>"}),"."]})}),(0,t.jsx)(a.Z,{label:"OpenShift",value:"OpenShift-8",children:(0,t.jsxs)(n.p,{children:["OpenShift requires various DNS records to be created for the cluster; one of these is exactly what we need:\n",(0,t.jsx)(n.code,{children:"api.<cluster_name>.<base_domain>"})," should point to the API server or to the load balancer in front of the\nAPI server. Use that (filling in the ",(0,t.jsx)(n.code,{children:"<cluster_name>"})," and ",(0,t.jsx)(n.code,{children:"<base_domain>"})," as appropriate for your cluster) for the\n",(0,t.jsx)(n.code,{children:"KUBERNETES_SERVICE_HOST"})," below. Openshift uses 6443 for the ",(0,t.jsx)(n.code,{children:"KUBERNETES_SERVICE_PORT"}),"."]})}),(0,t.jsxs)(a.Z,{label:"AKS",value:"AKS-9",children:[(0,t.jsx)(n.p,{children:"For AKS clusters, you should use the FQDN of your API server. This can be found by running the following command:"}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl cluster-info\n"})}),(0,t.jsx)(n.p,{children:"which should give output similar to the following:"}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Kubernetes master is running at https://mycalicocl-calicodemorg-03a087-36558dbb.hcp.canadaeast.azmk8s.io:443\n"})}),(0,t.jsxs)(n.p,{children:["In this example, you would use ",(0,t.jsx)(n.code,{children:"mycalicocl-calicodemorg-03a087-36558dbb.hcp.canadaeast.azmk8s.io"})," for\n",(0,t.jsx)(n.code,{children:"KUBERNETES_SERVICE_HOST"})," and ",(0,t.jsx)(n.code,{children:"443"})," for ",(0,t.jsx)(n.code,{children:"KUBERNETES_SERVICE_PORT"})," when creating the config map."]})]}),(0,t.jsxs)(a.Z,{label:"EKS",value:"EKS-10",children:[(0,t.jsx)(n.p,{children:"For an EKS cluster, it's important to use the domain name of the EKS-provided load balancer that is in front of the API\nserver. This can be found by running the following command:"}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl cluster-info\n"})}),(0,t.jsx)(n.p,{children:"which should give output similar to the following:"}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Kubernetes master is running at https://60F939227672BC3D5A1B3EC9744B2B21.gr7.us-west-2.eks.amazonaws.com\n...\n"})}),(0,t.jsxs)(n.p,{children:["In this example, you would use ",(0,t.jsx)(n.code,{children:"60F939227672BC3D5A1B3EC9744B2B21.gr7.us-west-2.eks.amazonaws.com"})," for\n",(0,t.jsx)(n.code,{children:"KUBERNETES_SERVICE_HOST"})," and ",(0,t.jsx)(n.code,{children:"443"})," for ",(0,t.jsx)(n.code,{children:"KUBERNETES_SERVICE_PORT"})," when creating the config map."]})]}),(0,t.jsx)(a.Z,{label:"MKE",value:"MKE-11",children:(0,t.jsxs)(n.p,{children:["MKE runs a reverse proxy in each node which can be used to reach the api-server. ",(0,t.jsx)(n.code,{children:"KUBERNETES_SERVICE_HOST"})," must be set to\n",(0,t.jsx)(n.code,{children:"proxy.local"})," and ",(0,t.jsx)(n.code,{children:"KUBERNETES_SERVICE_PORT"})," must be set to ",(0,t.jsx)(n.code,{children:"6444"}),"."]})})]}),"\n",(0,t.jsx)(n.h3,{id:"install-the-tigera-operator",children:"Install the Tigera Operator"}),"\n",(0,t.jsx)(n.p,{children:"Follow the steps in the main install for your platform that installs the Tigera Operator, without applying the custom-resources.yaml (you will update this file in a later step in this doc)."}
1),"\n",(0,t.jsx)(n.p,{children:"For clusters in AWS, such as kOps and EKS, you must also patch the tigera-operator deployment with DNS config so the operator can resolve the apiserver DNS.\nAWS DNS server's address is 169.254.169.253."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'kubectl patch deployment -n tigera-operator tigera-operator -p \'{"spec":{"template":{"spec":{"dnsConfig":{"nameservers":["169.254.169.253"]}}}}}\'\n'})}),"\n",(0,t.jsx)(n.h3,{id:"create-the-config-map",children:"Create the Config Map"}),"\n",(0,t.jsxs)(n.p,{children:["Create the following config map in the ",(0,t.jsx)(n.code,{children:"tigera-operator"})," namespace using the host and port determined above:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'kubectl apply -f - <<EOF\nkind: ConfigMap\napiVersion: v1\nmetadata:\n  name: kubernetes-services-endpoint\n  namespace: tigera-operator\ndata:\n  KUBERNETES_SERVICE_HOST: "<API server host>"\n  KUBERNETES_SERVICE_PORT: "<API server port>"\nEOF\n'})}),"\n",(0,t.jsx)(n.h3,{id:"tweak-and-apply-installation-custom-resources",children:"Tweak and apply installation Custom Resources"}),"\n",(0,t.jsxs)(n.p,{children:["When the main install guide tells you to apply the ",(0,t.jsx)(n.code,{children:"custom-resources.yaml"}),", typically by running ",(0,t.jsx)(n.code,{children:"kubectl create"})," with\nthe URL of the file directly, you should instead download the file, so that you can edit it:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:" curl -o custom-resources.yaml https://raw.githubusercontent.com/projectcalico/calico/v3.28.5/manifests/custom-resources.yaml\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Edit the file in your editor of choice and find the ",(0,t.jsx)(n.code,{children:"Installation"})," resource, which should be at the top of the file.\nTo enable eBPF mode, we need to add a new ",(0,t.jsx)(n.code,{children:"calicoNetwork"})," section inside the ",(0,t.jsx)(n.code,{children:"spec"})," of the Installation resource,\nincluding the ",(0,t.jsx)(n.code,{children:"linuxDataplane"})," field. For EKS Bottlerocket OS only, you should also add the ",(0,t.jsx)(n.code,{children:"flexVolumePath"})," setting\nas shown below."]}),"\n",(0,t.jsx)(n.p,{children:"For example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"# This section includes base Calico installation configuration.\n\napiVersion: operator.tigera.io/v1\nkind: Installation\nmetadata:\n  name: default\nspec:\n   # Added calicoNetwork section with linuxDataplane field\n  calicoNetwork:\n    linuxDataplane: BPF\n\n   # EKS with Bottlerocket as node image only:\n   # flexVolumePath: /var/lib/kubelet/plugins\n\n   # Install Calico Open Source\n   variant: Calico\n\n# This section configures the Calico API server.\n\napiVersion: operator.tigera.io/v1\nkind: APIServer \nmetadata: \n  name: default \nspec: {}  \n"})}),"\n",(0,t.jsx)(n.p,{children:"Then apply the edited file:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl create -f custom-resources.yaml\n"})}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsx)(n.p,{children:"If you already created the custom resources, you can switch your cluster over to eBPF mode by updating the\ninstallation resource. The operator will automatically roll out the change."}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'kubectl patch installation.operator.tigera.io default --type merge -p \'{"spec":{"calicoNetwork":{"linuxDataplane":"BPF", "hostPorts":null}}}\'\n'})})]}),"\n",(0,t.jsx)(n.h3,{id:"monitor-the-progress-of-the-installation",children:"Monitor the progress of the installation"}),"\n",(0,t.jsx)(n.p,{children:"You can monitor progress of the installation with the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"watch kubectl get tigerastatus\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"disable-kube-proxy-or-avoid-conflicts",children:["Disable ",(0,t.jsx)(n.code,{children:"kube-proxy"})," (or avoid conflicts)"]}),"\n",(0,t.jsxs)(n.p,{children:["In eBPF mode, to avoid conflicts with ",(0,t.jsx)(n.code,{children:"kube-proxy"})," it's necessary to either disable ",(0,t.jsx)(n.code,{children:"kube-proxy"})," or to configure\nCalico not to clean up ",(0,t.jsx)(n.code,{children:"kube-proxy"}),"'s iptables rules. If you didn't disable ",(0,t.jsx)(n.code,{children:"kube-proxy"})," when starting\nyour cluster then follow the steps below to avoid conflicts:"]}),"\n",(0,t.jsxs)(l.Z,{children:[(0,t.jsxs)(a.Z,{label:"Generic or kubeadm",value:"Generic or kubeadm-10",children:[(0,t.jsxs)(n.p,{children:["For a cluster that runs ",(0,t.jsx)(n.code,{children:"kube-proxy"})," in a ",(0,t.jsx)(n.code,{children:"DaemonSet"})," (such as a ",(0,t.jsx)(n.code,{children:"kubeadm"}),"-created cluster), you can disable\n",(0,t.jsx)(n.code,{children:"kube-proxy"}),", reversibly, by adding a node selector to ",(0,t.jsx)(n.code,{children:"kube-proxy"}),"'s ",(0,t.jsx)(n.code,{children:"DaemonSet"})," that matches no nodes, for example:"]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'kubectl patch ds -n kube-system kube-proxy -p \'{"spec":{"template":{"spec":{"nodeSelector":{"non-calico": "true"}}}}}\'\n'})}),(0,t.jsxs)(n.p,{children:["Then, should you want to start ",(0,t.jsx)(n.code,{children:"kube-proxy"})," again, you can simply remove the node selector."]})]}),(0,t.jsxs)(a.Z,{label:"kOps",value:"kOps-12",children:[(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"kops"})," allows ",(0,t.jsx)(n.code,{children:"kube-proxy"})," to be disabled by setting"]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"kubeProxy:\n  enabled: false\n"})}),(0,t.jsxs)(n.p,{children:["in its configuration. You will need to do ",(0,t.jsx)(n.code,{children:"kops update cluster"})," to roll out the change."]})]}),(0,t.jsxs)(a.Z,{label:"OpenShift",value:"OpenShift-13",children:[(0,t.jsxs)(n.p,{children:["In OpenShift, you can disable ",(0,t.jsx)(n.code,{children:"kube-proxy"})," as follows:"]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'kubectl patch networks.operator.openshift.io cluster --type merge -p \'{"spec":{"deployKubeProxy": false}}\'\n'})}),(0,t.jsx)(n.p,{children:"If you need to re-enable it later:"}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'kubectl patch networks.operator.openshift.io cluster --type merge -p \'{"spec":{"deployKubeProxy": true}}\'\n'})})]}),(0,t.jsxs)(a.Z,{label:"AKS",value:"AKS-14",children:[(0,t.jsxs)(n.p,{children:["AKS with Azure CNI does not allow ",(0,t.jsx)(n.code,{children:"kube-proxy"})," to be disabled, ",(0,t.jsx)(n.code,{children:"kube-proxy"})," is deployed by the add-on manager, which will reconcile\naway any manual changes made to its configuration. To ensure ",(0,t.jsx)(n.code,{children:"kube-proxy"})," and Calico don't fight, set\nthe Felix configuration parameter ",(0,t.jsx)(n.code,{children:"bpfKubeProxyIptablesCleanupEnabled"})," to false. This can be done with\n",(0,t.jsx)(n.code,{children:"kubectl"})," as follows:"]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'kubectl patch felixconfiguration default --type merge --patch=\'{"spec": {"bpfKubeProxyIptablesCleanupEnabled": false}}\'\n'})})]}),(0,t.jsxs)(a.Z,{label:"EKS",value:"EKS-15",children:[(0,t.jsxs)(n.p,{children:["In EKS, you can disable ",(0,t.jsx)(n.code,{children:"kube-proxy"}),", reversibly, by adding a node selector that doesn't match and nodes to\n",(0,t.jsx)(n.code,{children:"kube-proxy"}),"'s ",(0,t.jsx)(n.code,{children:"DaemonSet"}),", for example:"]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'kubectl patch ds -n kube-system kube-proxy -p \'{"spec":{"template":{"spec":{"nodeSelector":{"non-calico": "true"}}}}}\'\n'})}),(0,t.jsxs)(n.p,{children:["Then, should you want to start ",(0,t.jsx)(n.code,{children:"kube-proxy"})," again, you can simply remove the node selector."]})]})]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"If you are running kube-proxy in IPVS mode, switch to iptables mode before disabling."})}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Recommended"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/calico/3.28/operations/ebpf/use-cases-ebpf",children:"Learn more about eBPF"})}),"\n"]})]})}function x(e={}){let{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},537:function(e,n,s){s.d(n,{Z:()=>i});var r=s(72459);s(84449);var t=s(16053);function i({children:e,hidden:n,className:s}){return(0,r.jsx)("div",{role:"tabpanel",className:(0,t.Z)("tabItem_RI6z",s),hidden:n,children:e})}},82771:function(e,n,s){s.d(n,{Z:()=>f});var r=s(72459),t=s(84449),i=s(16053),o=s(99658),l=s(50660),a=s(94992),c=s(1120),d=s(71333),h=s(39723);function u(e){return t.Children.toArray(e).filter(e=>"\n"!==e).map(e=>{if(!e||(0,t.isValidElement)(e)&&function(e){let{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw Error(`Docusaurus error: Bad <Tabs>
1 child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)})?.filter(Boolean)??[]}function p({value:e,tabValues:n}){return n.some(n=>n.value===e)}var x=s(96236);function b({className:e,block:n,selectedValue:s,selectValue:t,tabValues:l}){let a=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.o5)(),d=e=>{let n=e.currentTarget,r=l[a.indexOf(n)].value;r!==s&&(c(n),t(r))},h=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{let s=a.indexOf(e.currentTarget)+1;n=a[s]??a[0];break}case"ArrowLeft":{let s=a.indexOf(e.currentTarget)-1;n=a[s]??a[a.length-1]}}n?.focus()};return(0,r.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},e),children:l.map(({value:e,label:n,attributes:t})=>(0,r.jsx)("li",{role:"tab",tabIndex:s===e?0:-1,"aria-selected":s===e,ref:e=>{a.push(e)},onKeyDown:h,onClick:d,...t,className:(0,i.Z)("tabs__item","tabItem_lXX2",t?.className,{"tabs__item--active":s===e}),children:n??e},e))})}function m({lazy:e,children:n,selectedValue:s}){let o=(Array.isArray(n)?n:[n]).filter(Boolean);if(e){let e=o.find(e=>e.props.value===s);return e?(0,t.cloneElement)(e,{className:(0,i.Z)("margin-top--md",e.props.className)}):null}return(0,r.jsx)("div",{className:"margin-top--md",children:o.map((e,n)=>(0,t.cloneElement)(e,{key:n,hidden:e.props.value!==s}))})}function j(e){let n=function(e){let{defaultValue:n,queryString:s=!1,groupId:r}=e,i=function(e){let{values:n,children:s}=e;return(0,t.useMemo)(()=>{let e=n??u(s).map(({props:{value:e,label:n,attributes:s,default:r}})=>({value:e,label:n,attributes:s,default:r})),r=(0,d.lx)(e,(e,n)=>e.value===n.value);if(r.length>0)throw Error(`Docusaurus error: Duplicate values "${r.map(e=>e.value).join(", ")}" found in <Tabs>. Every value needs to be unique.`);return e},[n,s])}(e),[o,x]=(0,t.useState)(()=>(function({defaultValue:e,tabValues:n}){if(0===n.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!p({value:e,tabValues:n}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}let s=n.find(e=>e.default)??n[0];if(!s)throw Error("Unexpected error: 0 tabValues");return s.value})({defaultValue:n,tabValues:i})),[b,m]=function({queryString:e=!1,groupId:n}){let s=(0,l.k6)(),r=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,c._X)(r),(0,t.useCallback)(e=>{if(!r)return;let n=new URLSearchParams(s.location.search);n.set(r,e),s.replace({...s.location,search:n.toString()})},[r,s])]}({queryString:s,groupId:r}),[j,f]=function({groupId:e}){let n=e?`docusaurus.tab.${e}`:null,[s,r]=(0,h.Nk)(n);return[s,(0,t.useCallback)(e=>{n&&r.set(e)},[n,r])]}({groupId:r}),g=(()=>{let e=b??j;return p({value:e,tabValues:i})?e:null})();return(0,a.Z)(()=>{g&&x(g)},[g]),{selectedValue:o,selectValue:(0,t.useCallback)(e=>{if(!p({value:e,tabValues:i}))throw Error(`Can't select invalid tab value=${e}`);x(e),m(e),f(e)},[m,f,i]),tabValues:i}}(e);return(0,r.jsxs)("div",{className:(0,i.Z)("tabs-container","tabList_Qk4j"),children:[(0,r.jsx)(b,{...n,...e}),(0,r.jsx)(m,{...n,...e})]})}function f(e){let n=(0,x.Z)();return(0,r.jsx)(j,{...e,children:u(e.children)},String(n))}},36870:function(e,n,s){s.d(n,{Z:()=>l,a:()=>o});var r=s(84449);let t={},i=r.createContext(t);function o(e){let n=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(i.Provider,{value:n},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.