1"use strict";(self.webpackChunktigera_docs=self.webpackChunktigera_docs||[]).push([[5285],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>k});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,a,o=function(e,t){if(null==e)return{};var n,a,o={},r=Object.keys(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=p(n),k=o,m=c["".concat(s,".").concat(k)]||c[k]||d[k]||r;return n?a.createElement(m,i(i({ref:t},u),{},{components:n})):a.createElement(m,i({ref:t},u))}));function k(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var p=2;p<r;p++)i[p]=n[p];return a.createElement.apply(null,i)}return a.createElement.apply(null,n)}c.displayName="MDXCreateElement"},61621:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>k,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var a=n(87462),o=(n(67294),n(3905));const r={description:"Install Calico for Windows to enable a workload-to-workload Zero Trust model that protects modern business and legacy applications."},i="Install Calico for Windows",l={unversionedId:"getting-started/kubernetes/windows-calico/kubernetes/standard",id:"version-3.24/getting-started/kubernetes/windows-calico/kubernetes/standard",title:"Install Calico for Windows",description:"Install Calico for Windows to enable a workload-to-workload Zero Trust model that protects modern business and legacy applications.",source:"@site/calico_versioned_docs/version-3.24/getting-started/kubernetes/windows-calico/kubernetes/standard.mdx",sourceDirName:"getting-started/kubernetes/windows-calico/kubernetes",slug:"/getting-started/kubernetes/windows-calico/kubernetes/standard",permalink:"/calico/3.24/getting-started/kubernetes/windows-calico/kubernetes/standard",draft:!1,editUrl:"https://github.com/tigera/docs/edit/main/calico_versioned_docs/version-3.24/getting-started/kubernetes/windows-calico/kubernetes/standard.mdx",tags:[],version:"3.24",frontMatter:{description:"Install Calico for Windows to enable a workload-to-workload Zero Trust model that protects modern business and legacy applications."},sidebar:"calicoSidebar",previous:{title:"Requirements",permalink:"/calico/3.24/getting-started/kubernetes/windows-calico/kubernetes/requirements"},next:{title:"Install Calico for Windows on a Rancher Kubernetes Engine cluster",permalink:"/calico/3.24/getting-started/kubernetes/windows-calico/kubernetes/rancher"}},s={},p=[{value:"Big picture",id:"big-picture",level:2},{value:"Value",id:"value",level:2},{value:"Before you begin",id:"before-you-begin",level:2},{value:"How to",id:"how-to",level:2},{value:"Create a Linux cluster",id:"create-a-linux-cluster",level:3},{value:"Ensure pods run on the correct nodes",id:"ensure-pods-run-on-the-correct-nodes",level:3}
1,{value:"Prepare Windows nodes to join the Linux cluster",id:"prepare-windows-nodes-to-join-the-linux-cluster",level:3},{value:"Install Calico on Linux control and worker nodes",id:"install-calico-on-linux-control-and-worker-nodes",level:3},{value:"Install Calico and Kubernetes on Windows nodes",id:"install-calico-and-kubernetes-on-windows-nodes",level:3},{value:"Next steps",id:"next-steps",level:2}],u=(d="GeekDetails",function(e){return console.warn("Component "+d+" was not imported, exported, or provided by MDXProvider as global scope"),(0,o.kt)("div",e)});var d;const c={toc:p};function k(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"install-calico-for-windows"},"Install Calico for Windows"),(0,o.kt)("h2",{id:"big-picture"},"Big picture"),(0,o.kt)("p",null,"Install Calico for Windows on Kubernetes clusters. The standard installation for Calico for Windows requires more time and expertise to configure. If you need to get started quickly, we recommend the ",(0,o.kt)("a",{parentName:"p",href:"/calico/3.24/getting-started/kubernetes/windows-calico/quickstart"},"Quickstart"),"."),(0,o.kt)("h2",{id:"value"},"Value"),(0,o.kt)("p",null,"Extend your Kubernetes deployment to Windows environments."),(0,o.kt)("h2",{id:"before-you-begin"},"Before you begin"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Required")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},"Install and configure ",(0,o.kt)("a",{parentName:"p",href:"/calico/3.24/operations/calicoctl/"},"calicoctl"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},"Linux and Windows nodes ",(0,o.kt)("a",{parentName:"p",href:"/calico/3.24/getting-started/kubernetes/windows-calico/kubernetes/requirements"},"meet requirements"))),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},"If using Calico networking, copy the kubeconfig file (used by kubelet) to each Windows node to the file, ",(0,o.kt)("inlineCode",{parentName:"p"},"c:\\k\\config"),".")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},"Download Calico for Windows and Kubernetes binaries to each Windows nodes to prepare for install:"),(0,o.kt)("p",{parentName:"li"},"On each of your Windows nodes, download and run Calico for Windows installation scripts:"),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre"},"Invoke-WebRequest https://github.com/projectcalico/calico/releases/download/v3.24.6/install-calico-windows.ps1 -OutFile c:\\install-calico-windows.ps1\nc:\\install-calico-windows.ps1 -DownloadOnly yes -KubeVersion <your Kubernetes version>\n")),(0,o.kt)("p",{parentName:"li"},"cd into ",(0,o.kt)("inlineCode",{parentName:"p"},"C:\\CalicoWindows"),", you will see the calico-node.exe binary, install scripts, and other files."))),(0,o.kt)("h2",{id:"how-to"},"How to"),(0,o.kt)("p",null,"Because the Kubernetes and Calico control components do not run on Windows yet, a hybrid Linux/Windows cluster is required. First you create a Linux cluster for Calico components, then you join Windows nodes to the Linux cluster."),(0,o.kt)("p",null,"The geeky details of what you get by default:"),(0,o.kt)(u,{prodname:"Calico",details:"Policy:Calico,IPAM:Calico,CNI:Calico,Overlay:VXLAN,Routing:BGP,Datastore:Kubernetes",mdxType:"GeekDetails"}),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Kubernetes")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#create-a-linux-cluster"},"Create a Linux cluster")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#ensure-pods-run-on-the-correct-nodes"},"Ensure pods run on the correct nodes")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#prepare-windows-nodes-to-join-the-linux-cluster"},"Prepare Windows nodes to join the Linux cluster"))),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Calico")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#install-calico-on-linux-control-and-worker-nodes"},"Install Calico on Linux control and worker nodes")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("a",{parentName:"li",href:"#install-calico-and-kubernetes-on-windows-nodes"}
1,"Install Calico and Kubernetes on Windows nodes"))),(0,o.kt)("h3",{id:"create-a-linux-cluster"},"Create a Linux cluster"),(0,o.kt)("p",null,"There are many ways to create a Linux Kubernetes cluster. We regularly test Calico for Windows with ",(0,o.kt)("inlineCode",{parentName:"p"},"kubeadm"),"."),(0,o.kt)("h3",{id:"ensure-pods-run-on-the-correct-nodes"},"Ensure pods run on the correct nodes"),(0,o.kt)("p",null,"A primary issue of running a hybrid Kubernetes cluster is that many Kubernetes manifests do not specify a ",(0,o.kt)("strong",{parentName:"p"},"node selector")," to restrict where their pods can run. For example, ",(0,o.kt)("inlineCode",{parentName:"p"},"kubeadm")," installs ",(0,o.kt)("inlineCode",{parentName:"p"},"kube-proxy")," (Kubernetes per-host NAT daemon) using a DaemonSet that does not include a node selector. This means that the kube-proxy pod, which only supports Linux, will be scheduled to both Linux and Windows nodes. Services/pods that should run only on Linux nodes (such as the ",(0,o.kt)("inlineCode",{parentName:"p"},"kube-proxy")," DaemonSet) should be started with a node selector to avoid attempting to schedule them to Windows nodes."),(0,o.kt)("p",null,"To get around this for ",(0,o.kt)("inlineCode",{parentName:"p"},"kube-proxy"),":"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Use ",(0,o.kt)("inlineCode",{parentName:"p"},"kubectl")," to retrieve the DaemonSet."),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre"}," kubectl get ds kube-proxy -n kube-system -o yaml > kube-proxy.yaml\n"))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Modify the ",(0,o.kt)("inlineCode",{parentName:"p"},"kube-proxy.yaml")," file to include a node selector that selects only Linux nodes:"),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre",className:"language-yaml",metastring:"noValidation",noValidation:!0},"spec:\n template:\n ...\n spec:\n nodeSelector:\n beta.kubernetes.io/os: linux\n containers:\n"))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Apply the updated manifest."),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre"},"kubectl apply -f kube-proxy.yaml\n")))),(0,o.kt)("p",null,"A similar change may be needed for other Kubernetes services (such as ",(0,o.kt)("inlineCode",{parentName:"p"},"kube-dns")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"core-dns"),")."),(0,o.kt)("h3",{id:"prepare-windows-nodes-to-join-the-linux-cluster"},"Prepare Windows nodes to join the Linux cluster"),(0,o.kt)("p",null,"On each Windows node, follow the steps below to configure ",(0,o.kt)("inlineCode",{parentName:"p"},"kubelet")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"kube-proxy")," service."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 1: Configure kubelet")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"kubelet")," must be configured to use CNI networking by setting the following command line arguments, depending on the installed container runtime."),(0,o.kt)("p",null,"For Docker:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"--network-plugin=cni")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"--cni-bin-dir=<directory for CNI binaries>")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"--cni-conf-dir=<directory for CNI configuration>"))),(0,o.kt)("p",null,"For containerd:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"--container-runtime=remote")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"--container-runtime-endpoint=npipe:////.//pipe//containerd-containerd"))),(0,o.kt)("p",null,"The CNI bin and conf dir settings are required by the Calico installer to install the CNI binaries and configuration file."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Among other parameters, the containerd configuration file includes options to configure the CNI bin and conf dirs.")),(0,o.kt)("p",null,"The following kubelet settings are also important:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"--hostname-override")," can be set to $(hostname) to match Calico's default. ",(0,o.kt)("inlineCode",{parentName:"p"},"kubelet")," and Calico must agree on the host/nodename; if your network environment results in hostnames that vary over time you should set the hostname override to a static value per host and update Calico's nodename accordingly.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},(0,o.kt)("inlineCode",{parentName:"p"},"--node-ip")," should be used to explicitly set the IP that kubelet reports to the API server for the node. We recommend setting this to the host's main network adapter's IP since we've seen kubelet incorrectly use an IP assigned to a HNS bridge device rather than the host's network adapter.")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("p",{parentName:"li"},"Because of a Windows networking limitation, if using Calico IPAM, --max-pods should be set to, at most, the IPAM block size of the IP pool in use minus 4:"),(0,o.kt)("table",{parentName:"li"},(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"th"},"IP pool block size")),(0,o.kt)("th",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"th"},"Max pods")))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"/n"),(0,o.kt)("td",{parentName:"tr",align:null},"2^/32-n^ - 4")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"/24"),(0,o.kt)("td",{parentName:"tr",align:null},"252")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"/25"),(0,o.kt)("td",{parentName:"tr",align:null},"124")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"/26 (default)"),(0,o.kt)("td",{parentName:"tr",align:null},"60")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"/27"),(0,o.kt)("td",{parentName:"tr",align:null},"28")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"/28"),(0,o.kt)("td",{parentName:"tr",align:null},"12")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"/29"),(0,o.kt)("td",{parentName:"tr",align:null},"4")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"/30 or above"),(0,o.kt)("td",{parentName:"tr",align:null},"Cannot be used")))))),(0,o.kt)("p",null,"In addition, it's important that ",(0,o.kt)("inlineCode",{parentName:"p"},"kubelet")," is started after the vSwitch has been created, which happens when Calico initializes the dataplane. Otherwise, ",(0,o.kt)("inlineCode",{parentName:"p"},"kubelet")," can be disconnected for the API server when the vSwitch is created."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"AWS users"),": If using the AWS cloud provider, you should add the following argument to the ",(0,o.kt)("inlineCode",{parentName:"p"},"kubelet"),":"),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"--hostname-override=<aws instance private DNS name>")," (and set the Calico nodename variable to match). In addition, you should add ",(0,o.kt)("inlineCode",{parentName:"p"},"KubernetesCluster=<cluster-name>")," as a tag when creating your Windows instance."),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"As a quickstart"),", the Calico package includes a sample script at ",(0,o.kt)("inlineCode",{parentName:"p"},"C:\\CalicoWindows\\kubernetes\\kubelet-service.ps1")," that:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Waits for Calico to initialise the vSwitch"),(0,o.kt)("li",{parentName:"ul"},"Starts ",(0,o.kt)("inlineCode",{parentName:"li"},"kubelet")," with",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"If containerd service is running, the following flags are set:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"--container-runtime set to ",(0,o.kt)("inlineCode",{parentName:"li"},"remote")),(0,o.kt)("li",{parentName:"ul"},"--container-runtime-endpoint set to ",(0,o.kt)("inlineCode",{parentName:"li"}
1,"npipe:////.//pipe//containerd-containerd")))),(0,o.kt)("li",{parentName:"ul"},"Otherwise, the following flags are set for Docker:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"--network-plugin set to ",(0,o.kt)("inlineCode",{parentName:"li"},"cni")),(0,o.kt)("li",{parentName:"ul"},"--cni-bin-dir set to ",(0,o.kt)("inlineCode",{parentName:"li"},"c:\\k\\cni")),(0,o.kt)("li",{parentName:"ul"},"--cni-conf-dir set to ",(0,o.kt)("inlineCode",{parentName:"li"},"c:\\k\\cni\\config")),(0,o.kt)("li",{parentName:"ul"},"--pod-infra-container-image set to ",(0,o.kt)("inlineCode",{parentName:"li"},"kubeletwin/pause")))),(0,o.kt)("li",{parentName:"ul"},"--kubeconfig set to the path of node kubeconfig file"),(0,o.kt)("li",{parentName:"ul"},"--hostname-override set to match Calico's nodename"),(0,o.kt)("li",{parentName:"ul"},"--node-ip set to the IP of the default vEthernet device"),(0,o.kt)("li",{parentName:"ul"},"--cluster-dns set to the IPs of the dns name servers")))),(0,o.kt)("p",null,"See the README in the same directory for more details. Feel free to modify the script to adjust other ",(0,o.kt)("inlineCode",{parentName:"p"},"kubelet")," parameters."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"The script will pause at the first stage until Calico is installed by following the instructions in the next section.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Step 2: Configure kube-proxy")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"kube-proxy")," must be configured as follows:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"With the correct HNS network name used by the active CNI plugin. kube-proxy reads the HNS network name from an environment variable KUBE_NETWORK",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},'With default configuration, Calico uses network name "Calico"'))),(0,o.kt)("li",{parentName:"ul"},"For VXLAN, with the source VIP for the pod subnet allocated to the node. This is the IP that kube-proxy uses when it does SNAT for a NodePort. For Calico, the source VIP should be the second IP address in the subnet chosen for the host. For example, if Calico chooses an IP block 10.0.0.0/26 then the source VIP should be 10.0.0.2. The script below will automatically wait for the block to be chosen and configure kube-proxy accordingly."),(0,o.kt)("li",{parentName:"ul"},"For Calico policy to function correctly with Kubernetes services, the WinDSR feature gate must be enabled. This requires Windows Server build 17763.1432 or greater and Kubernetes v1.14 or greater. Calico will automatically enable the WinDSR feature gate if kubernetes services are managed by Calico for Windows.")),(0,o.kt)("p",null,"kube-proxy should be started via a script that waits for the Calico HNS network to be provisioned. The Calico package contains a suitable script for use with Calico networking at ",(0,o.kt)("inlineCode",{parentName:"p"},"C:\\CalicoWindows\\kubernetes\\kube-proxy-service.ps1"),". The script:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Waits for Calico to initialise the vSwitch."),(0,o.kt)("li",{parentName:"ul"},"Calculates the correct source VIP for the local subnet."),(0,o.kt)("li",{parentName:"ul"},"Starts kube-proxy with the correct feature gates and hostname to work with Calico.")),(0,o.kt)("p",null,"See the README in the same directory for more details. Feel free to modify the script to\nadjust other kube-proxy parameters."),(0,o.kt)("p",null,"The script will pause at the first stage until Calico is installed by following the instructions in the next section."),(0,o.kt)("h3",{id:"install-calico-on-linux-control-and-worker-nodes"},"Install Calico on Linux control and worker nodes"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"If using Calico BGP networking")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Disable the default Calico IP-in-IP networking (which is not compatible with Windows), by modifying the Calico manifest, and setting the ",(0,o.kt)("inlineCode",{parentName:"p"},"CALICO_IPV4POOL_IPIP"),' environment variable to "Never" before applying the manifest.'),(0,o.kt)("p",{parentName:"li"},"If you do apply the manifest with the incorrect value, changing the manifest and re-applying will have no effect. To adjust the already-created IP pool:"),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"calicoctl get ippool -o yaml > ippool.yaml\n")),(0,o.kt)("p",{parentName:"li"},"Then, modify ippool.yaml by setting the ",(0,o.kt)("inlineCode",{parentName:"p"},"ipipMode")," to ",(0,o.kt)("inlineCode",{parentName:"p"},"Never")," and then apply the updated manifest:"),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"calicoctl apply -f ippool.yaml\n")))),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"If using Calico VXLAN networking")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"}
1,"Modify VXLAN as described in ",(0,o.kt)("a",{parentName:"p",href:"/calico/3.24/getting-started/kubernetes/self-managed-onprem/config-options"},"Customize the manifests")," guide. Note the following:"),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"Windows can support only a single type of IP pool so it is important that you use only a single VXLAN IP pool in this mode."),(0,o.kt)("li",{parentName:"ul"},"Windows supports only VXLAN on port 4789 and VSID ","\u2265"," 4096. Calico's default (on Linux and Windows) is to use port 4789 and VSID 4096."))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Apply the manifest using ",(0,o.kt)("inlineCode",{parentName:"p"},"calicoctl"),", and verify that you have a single pool with ",(0,o.kt)("inlineCode",{parentName:"p"},"VXLANMODE Always"),"."),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"calicoctl get ippool -o wide\n"))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"For Linux control nodes using Calico networking, strict affinity must be set to ",(0,o.kt)("inlineCode",{parentName:"p"},"true"),".\nThis is required to prevent Linux nodes from borrowing IP addresses from Windows nodes:"),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre",className:"language-bash"},'kubectl patch ipamconfigurations default --type merge --patch=\'{"spec": {"strictAffinity": true}}\'\n')))),(0,o.kt)("h3",{id:"install-calico-and-kubernetes-on-windows-nodes"},"Install Calico and Kubernetes on Windows nodes"),(0,o.kt)("p",null,"Follow the steps below on each Windows node to install Kubernetes and Calico:"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"If using Calico BGP")),(0,o.kt)("p",null,"Install the RemoteAccess service using the following PowerShell commands:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-powershell"},"Install-WindowsFeature RemoteAccess\nInstall-WindowsFeature RSAT-RemoteAccess-PowerShell\nInstall-WindowsFeature Routing\n")),(0,o.kt)("p",null,"Then restart the computer:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-powershell"},"Restart-Computer -Force\n")),(0,o.kt)("p",null,"before running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-powershell"},"Install-RemoteAccess -VpnType RoutingOnly\n")),(0,o.kt)("p",null,"Sometimes the remote access service fails to start automatically after install. To make sure it is running, execute the following command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-powershell"},"Start-Service RemoteAccess\n")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"If using a non-Calico network plugin for networking, install and verify it now.")),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Edit the install configuration file, ",(0,o.kt)("inlineCode",{parentName:"p"},"config.ps1")," as follows:"),(0,o.kt)("table",{parentName:"li"},(0,o.kt)("thead",{parentName:"table"},(0,o.kt)("tr",{parentName:"thead"},(0,o.kt)("th",{parentName:"tr",align:null},(0,o.kt)("strong",{parentName:"th"},"Set this variable...")),(0,o.kt)("th",{parentName:"tr",align:null},"To..."))),(0,o.kt)("tbody",{parentName:"table"},(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"$env:KUBE_NETWORK"),(0,o.kt)("td",{parentName:"tr",align:null},"CNI plugin you plan to use. For Calico, set the variable to ",(0,o.kt)("inlineCode",{parentName:"td"},"Calico.*"))),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"$env:CALICO_NETWORKING_BACKEND"),(0,o.kt)("td",{parentName:"tr",align:null},(0,o.kt)("inlineCode",{parentName:"td"},"windows-bgp")," ",(0,o.kt)("inlineCode",{parentName:"td"},"vxlan")," or ",(0,o.kt)("inlineCode",{parentName:"td"},"none")," (if using a non-Calico CNI plugin).")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"$env:CNI","_"," variables"),(0,o.kt)("td",{parentName:"tr",align:null},"Location of your Kubernetes installation.")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"$env:K8S_SERVICE_CIDR"),(0,o.kt)("td",{parentName:"tr",align:null},"Your Kubernetes service cluster IP CIDR.")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"$env:CALICO_DATASTORE_TYPE"),(0,o.kt)("td",{parentName:"tr",align:null},"Calico datastore you want to use.")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"$env:KUBECONFIG"),(0,o.kt)("td",{parentName:"tr",align:null},"Location of the kubeconfig file Calico should use to access the Kubernetes API server. To set up a secure kubeconfig with the correct permissions for Calico for Windows, see ",(0,o.kt)("a",{parentName:"td",href:"/calico/3.24/getting-started/kubernetes/windows-calico/kubeconfig"},"Create a kubeconfig")," for Calico for Windows.")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"$env:ETCD","_"," parameters"),(0,o.kt)("td",{parentName:"tr",align:null},"etcd3 datastore parameters. ",(0,o.kt)("strong",{parentName:"td"},"Note"),": Because of a limitation of the Windows dataplane, a Kubernetes service ClusterIP cannot be used for the etcd endpoint (the host compartment cannot reach Kubernetes services).")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null},"$env:NODENAME"),(0,o.kt)("td",{parentName:"tr",align:null},"Hostname used by kubelet. The default uses the node's hostname. ",(0,o.kt)("strong",{parentName:"td"},"Note"),": If you are using the sample kubelet start-up script from the Calico package, kubelet is started with a hostname override that forces it to use this value.")),(0,o.kt)("tr",{parentName:"tbody"},(0,o.kt)("td",{parentName:"tr",align:null}),(0,o.kt)("td",{parentName:"tr",align:null},"For AWS to work properly, kubelet should use the node's internal domain name for the AWS integration."))))),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Run the installer."),(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"Change directory to the location that you unpacked the archive. For example:")))),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-powershell"},"cd C:\\CalicoWindows\n")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Run the install script:")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},".\\install-calico.ps1\n")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"The installer initializes the Windows vSwitch, which can cause a short connectivity outage as the networking stack
1is reconfigured. After running that command, you may need to:"),(0,o.kt)("ul",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ul"},"Reconnect to your remote desktop session."),(0,o.kt)("li",{parentName:"ul"},"Restart ",(0,o.kt)("inlineCode",{parentName:"li"},"kubelet")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"kube-proxy")," if they were already running."),(0,o.kt)("li",{parentName:"ul"},"If you haven't started ",(0,o.kt)("inlineCode",{parentName:"li"},"kubelet")," and ",(0,o.kt)("inlineCode",{parentName:"li"},"kube-proxy")," already, you should do so now. The quickstart scripts provided in the Calico package provide an easy way to do this. Calico requires ",(0,o.kt)("inlineCode",{parentName:"li"},"kubelet")," to be running to complete its per-node configuration (since Kubelet creates the Kubernetes Node resource)."))),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"After you run the installer, do not move the directory because the service registration refers to the path of the directory.")),(0,o.kt)("ol",{start:4},(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("p",{parentName:"li"},"Verify that the Calico services are running."),(0,o.kt)("pre",{parentName:"li"},(0,o.kt)("code",{parentName:"pre",className:"language-powershell"},"Get-Service -Name CalicoNode\nGet-Service -Name CalicoFelix\n")))),(0,o.kt)("h2",{id:"next-steps"},"Next steps"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/calico/3.24/getting-started/kubernetes/windows-calico/kubeconfig"},"Create a kubeconfig")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/calico/3.24/getting-started/kubernetes/windows-calico/limitations"},"Review network policy limitations in Windows"))))}k.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.