PageSourceSearch

https://archive-os-3-25.netlify.app/assets/js/87f1d04a.fdd62fb1.js

js archive-os-3-25.netlify.app collected 2026-10-03 10:28:46 UTC 12,973 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunktigera_docs=self.webpackChunktigera_docs||[]).push([[1362],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var o=r(67294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,o,n=function(e,t){if(null==e)return{};var r,o,n={},a=Object.keys(e);for(o=0;o<a.length;o++)r=a[o],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o<a.length;o++)r=a[o],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var i=o.createContext({}),c=function(e){var t=o.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=c(e.components);return o.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(r),f=n,h=d["".concat(i,".").concat(f)]||d[f]||u[f]||a;return r?o.createElement(h,l(l({ref:t},p),{},{components:r})):o.createElement(h,l({ref:t},p))}));function f(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,l=new Array(a);l[0]=d;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:n,l[1]=s;for(var c=2;c<a;c++)l[c]=r[c];return o.createElement.apply(null,l)}return o.createElement.apply(null,r)}d.displayName="MDXCreateElement"},50030:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var o=r(87462),n=(r(67294),r(3905));const a={description:"Restrict access to Kubernetes node ports using Calico global network policy. Follow the steps to secure the host, the node ports, and the cluster."},l="Apply Calico policy to Kubernetes node ports",s={unversionedId:"network-policy/services/kubernetes-node-ports",id:"version-3.25/network-policy/services/kubernetes-node-ports",title:"Apply Calico policy to Kubernetes node ports",description:"Restrict access to Kubernetes node ports using Calico global network policy. Follow the steps to secure the host, the node ports, and the cluster.",source:"@site/calico_versioned_docs/version-3.25/network-policy/services/kubernetes-node-ports.mdx",sourceDirName:"network-policy/services",slug:"/network-policy/services/kubernetes-node-ports",permalink:"/calico/3.25/network-policy/services/kubernetes-node-ports",draft:!1,editUrl:"https://github.com/tigera/docs/edit/main/calico_versioned_docs/version-3.25/network-policy/services/kubernetes-node-ports.mdx",tags:[],version:"3.25",frontMatter:{description:"Restrict access to Kubernetes node ports using Calico global network policy. Follow the steps to secure the host, the node ports, and the cluster."},sidebar:"calicoSidebar",previous:{title:"Policy for Kubernetes services",permalink:"/calico/3.25/network-policy/services/"},next:{title:"Apply Calico policy to services exposed externally as cluster IPs",permalink:"/calico/3.25/network-policy/services/services-cluster-ips"}},i={},c=[{value:"Big picture",id:"big-picture",level:2},{value:"Value",id:"value",level:2},{value:"Concepts",id:"concepts",level:2},{value:"Network policy with preDNAT field",id:"network-policy-with-prednat-field",level:3},{value:"Before you begin...",id:"before-you-begin",level:2},{value:"How to",id:"how-to",level:2},{value:"Allow cluster ingress traffic but deny general ingress traffic",id:"allow-cluster-ingress-traffic-but-deny-general-ingress-traffic",level:3},{value:"Allow local host egress traffic",id:"allow-local-host-egress-traffic",level:3},{value:"Create host endpoints with appropriate network policy",id:"create-host-endpoints-with-appropriate-network-policy",level:3},{value:"Allow ingress traffic to specific node ports",id:"allow-ingress-traffic-to-specific-node-ports",level:3},{value:"Additional resources",id:"additional-resources",level:2}],p={toc:c};
1function u(e){let{components:t,...r}=e;return(0,n.kt)("wrapper",(0,o.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"apply-calico-policy-to-kubernetes-node-ports"},"Apply Calico policy to Kubernetes node ports"),(0,n.kt)("h2",{id:"big-picture"},"Big picture"),(0,n.kt)("p",null,"Restrict access to node ports to specific external clients."),(0,n.kt)("h2",{id:"value"},"Value"),(0,n.kt)("p",null,"Exposing services to external clients using node ports is a standard Kubernetes feature. However, if you want to restrict access to node ports to specific external clients, you need to use Calico global network policy."),(0,n.kt)("h2",{id:"concepts"},"Concepts"),(0,n.kt)("h3",{id:"network-policy-with-prednat-field"},"Network policy with preDNAT field"),(0,n.kt)("p",null,"In a Kubernetes cluster, kube-proxy will DNAT a request to the node's port and IP address to one of the pods that backs the service. For Calico global network policy to both allow normal ingress cluster traffic and deny other general ingress traffic, it must take effect before DNAT. To do this, you simply add a ",(0,n.kt)("strong",{parentName:"p"},"preDNAT")," field to a Calico global network policy. The preDNAT field:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Applies before DNAT"),(0,n.kt)("li",{parentName:"ul"},"Applies only to ingress rules"),(0,n.kt)("li",{parentName:"ul"},"Enforces all ingress traffic through a host endpoint, regardless of destination\nThe destination can be a locally hosted pod, a pod on another node, or a process running on the host.")),(0,n.kt)("h2",{id:"before-you-begin"},"Before you begin..."),(0,n.kt)("p",null,"For services that you want to expose to external clients, configure Kubernetes services with type ",(0,n.kt)("strong",{parentName:"p"},"NodePort"),"."),(0,n.kt)("h2",{id:"how-to"},"How to"),(0,n.kt)("p",null,"To securely expose a Kubernetes service to external clients, you must implement all of the following steps."),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"#allow-cluster-ingress-traffic-but-deny-general-ingress-traffic"},"Allow cluster ingress traffic, but deny general ingress traffic")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"#allow-local-host-egress-traffic"},"Allow local host egress traffic")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"#create-host-endpoints-with-appropriate-network-policy"},"Create host endpoints with appropriate network policy")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"#allow-ingress-traffic-to-specific-node-ports"},"Allow ingress traffic to specific node ports"))),(0,n.kt)("h3",{id:"allow-cluster-ingress-traffic-but-deny-general-ingress-traffic"},"Allow cluster ingress traffic but deny general ingress traffic"),(0,n.kt)("p",null,"In the following example, we create a global network policy to allow cluster ingress traffic (",(0,n.kt)("strong",{parentName:"p"},"allow-cluster-internal-ingress"),"): for the nodes\u2019 IP addresses (",(0,n.kt)("strong",{parentName:"p"},"1.2.3.4/16"),"), and for pod IP addresses assigned by Kubernetes (",(0,n.kt)("strong",{parentName:"p"},"100.100.100.0/16"),"). By adding a preDNAT field, Calico global network policy is applied before regular DNAT on the Kubernetes cluster."),(0,n.kt)("p",null,"In this example, we use the ",(0,n.kt)("strong",{parentName:"p"},"selector: has(kubernetes-host)")," -- so the policy is applicable to any endpoint with a ",(0,n.kt)("strong",{parentName:"p"},"kubernetes-host")," label (but you can easily specify particular nodes)."),(0,n.kt)("p",null,"Finally, when you specify a preDNAT field, you must also add the ",(0,n.kt)("strong",{parentName:"p"},"applyOnForward: true")," field."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: projectcalico.org/v3\nkind: GlobalNetworkPolicy\nmetadata:\n  name: allow-cluster-internal-ingress-only\nspec:\n  order: 20\n  preDNAT: true\n  applyOnForward: true\n  ingress:\n    - action: Allow\n      source:\n        nets: [1.2.3.4/16, 100.100.100.0/16]\n    - action: Deny\n  selector: has(kubernetes-host)\n")),(0,n.kt)("h3",{id:"allow-local-host-egress-traffic"},"Allow local host egress traffic"),(0,n.kt)("p",null,"We also need a global network policy to allow egress traffic through each node's external interface. Otherwise, when we define host endpoints for those interfaces, no egress traffic will be allowed from local processes (except for traffic that is allowed by the ",(0,n.kt)("a",{parentName:"p",href:"/calico/3.25/reference/host-endpoints/failsafe"},"Failsafe rules"),"."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: projectcalico.org/v3\nkind: GlobalNetworkPolicy\nmetadata:\n  name: allow-outboun
1d-external\nspec:\n  order: 10\n  egress:\n    - action: Allow\n  selector: has(kubernetes-host)\n")),(0,n.kt)("h3",{id:"create-host-endpoints-with-appropriate-network-policy"},"Create host endpoints with appropriate network policy"),(0,n.kt)("p",null,"In this example, we assume that you have already defined Calico host endpoints with network policy that is appropriate for the cluster. (For example, you wouldn\u2019t want a host endpoint with a \u201cdefault deny all traffic to/from this host\u201d network policy because that is counter to the goal of allowing/denying specific traffic.) For help, see ",(0,n.kt)("a",{parentName:"p",href:"/calico/3.25/reference/resources/hostendpoint"},"host endpoints"),"."),(0,n.kt)("p",null,"All of our previously-defined global network policies have a selector that makes them applicable to any endpoint with a ",(0,n.kt)("strong",{parentName:"p"},"kubernetes-host label"),"; so we will include that label in our definitions. For example, for ",(0,n.kt)("strong",{parentName:"p"},"eth0")," on ",(0,n.kt)("strong",{parentName:"p"},"node1"),"."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: projectcalico.org/v3\nkind: HostEndpoint\nmetadata:\n  name: node1-eth0\n  labels:\n    kubernetes-host: ingress\nspec:\n  interfaceName: eth0\n  node: node1\n  expectedIPs:\n    - INSERT_IP_HERE\n")),(0,n.kt)("p",null,"When creating each host endpoint, replace ",(0,n.kt)("inlineCode",{parentName:"p"},"INSERT_IP_HERE")," with the IP address on eth0. The ",(0,n.kt)("inlineCode",{parentName:"p"},"expectedIPs")," field is required so that any selectors within ingress or egress rules can properly match the host endpoint."),(0,n.kt)("h3",{id:"allow-ingress-traffic-to-specific-node-ports"},"Allow ingress traffic to specific node ports"),(0,n.kt)("p",null,"Now we can allow external access to the node ports by creating a global network policy with the preDNAT field. In this example, ",(0,n.kt)("strong",{parentName:"p"},"ingress traffic is allowed")," for any host endpoint with ",(0,n.kt)("strong",{parentName:"p"},"port: 31852"),"."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-yaml"},"apiVersion: projectcalico.org/v3\nkind: GlobalNetworkPolicy\nmetadata:\n  name: allow-nodeport\nspec:\n  preDNAT: true\n  applyOnForward: true\n  order: 10\n  ingress:\n    - action: Allow\n      protocol: TCP\n      destination:\n        selector: has(kubernetes-host)\n        ports: [31852]\n  selector: has(kubernetes-host)\n")),(0,n.kt)("p",null,"To make the NodePort accessible only through particular nodes, give the nodes a particular label. For example:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-yaml"},"nodeport-external-ingress: true\n")),(0,n.kt)("p",null,"Then, use ",(0,n.kt)("strong",{parentName:"p"},"nodeport-external-ingress: true")," as the selector of the ",(0,n.kt)("strong",{parentName:"p"},"allow-nodeport")," policy, instead of ",(0,n.kt)("strong",{parentName:"p"},"has(kubernetes-host)"),"."),(0,n.kt)("h2",{id:"additional-resources"},"Additional resources"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/calico/3.25/reference/resources/globalnetworkpolicy"},"Global network policy")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"/calico/3.25/reference/resources/hostendpoint"},"Host endpoints"))))}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.