PageSourceSearch

https://inspektor-gadget.io/assets/js/95ac7c90.8ab06b09.js

js inspektor-gadget.io collected 2026-10-02 04:01:16 UTC 12,835 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkig_website=self.webpackChunkig_website||[]).push([[8504],{16029:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"gadgets/advise_networkpolicy","title":"advise networkpolicy","description":"The advise networkpolicy gadget monitors the network activity in the specified namespaces","source":"@site/versioned_docs/version-v0.55.0/gadgets/advise_networkpolicy.mdx","sourceDirName":"gadgets","slug":"/gadgets/advise_networkpolicy","permalink":"/docs/v0.55.0/gadgets/advise_networkpolicy","draft":false,"unlisted":false,"editUrl":"https://github.com/inspektor-gadget/inspektor-gadget/edit/main/versioned_docs/version-v0.55.0/gadgets/advise_networkpolicy.mdx","tags":[],"version":"v0.55.0","sidebarPosition":0,"frontMatter":{"title":"advise networkpolicy","sidebar_position":0},"sidebar":"mainSidebar","previous":{"title":"Gadgets","permalink":"/docs/v0.55.0/gadgets/"},"next":{"title":"advise_seccomp","permalink":"/docs/v0.55.0/gadgets/advise_seccomp"}}');var i=t(74848),s=t(28453);t(49489),t(7227);const o={title:"advise networkpolicy",sidebar_position:0},a=void 0,l={},c=[{value:"Requirements",id:"requirements",level:2},{value:"Getting started",id:"getting-started",level:2},{value:"Flags",id:"flags",level:2},{value:"Guide",id:"guide",level:2},{value:"Limitations",id:"limitations",level:2}];function d(e){const n={code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"The advise networkpolicy gadget monitors the network activity in the specified namespaces\nand records a summary of TCP and UDP traffic. This is then used to generate Kubernetes\nnetwork policies."}),"\n",(0,i.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Minimum Kernel Version : *5.4"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"*This is the minimal kernel version we have tried for this Gadget, however it's possible that it works with earlier versions."}),"\n",(0,i.jsx)(n.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"$ kubectl gadget run ghcr.io/inspektor-gadget/gadget/advise_networkpolicy:v0.55.0\n"})}),"\n",(0,i.jsx)(n.h2,{id:"flags",children:"Flags"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"--policy-format"}),": Output format for generated policies.","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"k8s"})," (default): ",(0,i.jsx)(n.code,{children:"networking.k8s.io/v1"})," ",(0,i.jsx)(n.code,{children:"NetworkPolicy"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"cilium"}),": ",(0,i.jsx)(n.code,{children:"cilium.io/v2"})," ",(0,i.jsx)(n.code,{children:"CiliumNetworkPolicy"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"guide",children:"Guide"}),"\n",(0,i.jsx)(n.p,{children:"First, we need to create an nginx deployment which can respond to our test requests."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"$ kubectl create service nodeport nginx --tcp=80:80\nservice/nginx created\n$ kubectl create deployment nginx --image=nginx\ndeployment.apps/nginx created\n"})}),"\n",(0,i.jsx)(n.p,{children:"Then, start the advise_networkpolicy gadget in another terminal."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"$ kubectl gadget run advise_networkpolicy:v0.55.0\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Now we can deploy our client pod, send a request to our nginx deployment and ",(0,i.jsx)(n.code,{children:"1.1.1.1"})," and then quit."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"$ kubectl run --rm -ti --image busybox test-pod\nIf you don't see a command prompt, try pressing enter.\n/ # wget nginx\nConnecting to nginx (10.105.129.249:80)\nsaving to 'index.html'\nindex.html           100% |********************************|   615  0:00:00 ETA\n'index.html' saved\n/ # wget 1.1.1.1\nConnecting to 1.1.1.1 (1.1.1.1:80)\nConnecting to 1.1.1.1 (1.1.1.1:443)\nwget: note: TLS certificate validation not implemented\nConnecting to one.one.one.one (1.1.1.1:443)\nwget: can't open 'index.html': File exists\n/ # exit\nSession ended, resume using 'kubectl attach test-pod -c test-pod -i -t' command when the pod is running\npod \"test-pod\" deleted\n"})}),"\n",(0,i.jsx)(n.p,{children:"Let's switch back to the gadget terminal, stop our gadget. The policy will then be printed:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ kubectl gadget run advise_networkpolicy:v0.55.0\n...\n^C\napiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  creationTimestamp: null\n  name: nginx-network\n  namespace: default\nspec:\n  ingress:\n  - from:\n    - podSelector:\n        matchLabels:\n          run: test-pod\n    ports:\n    - port: 80\n      protocol: TCP\n  podSelector:\n    matchLabels:\n      app: nginx\n  policyTypes:\n  - Ingress\n  - Egress\n---\napiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  creationTimestamp: null\n  name: test-pod-network\n  namespace: default\nspec:\n  egress:\n  - ports:\n    - port: 80\n      protocol: TCP\n    to:\n    - ipBlock:\n        cidr: 1.1.1.1/32\n  - ports:\n    - port: 80\n      protocol: TCP\n    to:\n    - podSelector:\n        matchLabels:\n          app: nginx\n  - ports:\n    - port: 443\n      protocol: TCP\n    to:\n    - ipBlock:\n        cidr: 1.1.1.1/32\n  - ports:\n    - port: 53\n      protocol: UDP\n    to:\n    - namespaceSelector:\n        matchLabels:\n          kubernetes.io/metadata.name: kube-system\n      podSelector:\n        matchLabels:\n          k8s-app: kube-dns\n          kubernetes.io/cluster-service: "true"\n          kubernetes.io/name: CoreDNS\n  podSelector:\n    matchLabels:\n      run: test-pod\n  policyTypes:\n  - Ingress\n  - Egress\n'})}),"\n",(0,i.jsxs)(n.p,{children:["To generate Cilium policies instead, run the gadget with\n",(0,i.jsx)(n.code,{children:"--policy-format cilium"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"$ kubectl gadget run advise_networkpolicy:v0.55.0 --p
1olicy-format cilium\n"})}),"\n",(0,i.jsx)(n.p,{children:"Finally, clean the system:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ kubectl delete deployment nginx\ndeployment.apps "nginx" deleted\n$ kubectl delete service nginx\nservice "nginx" deleted\n'})}),"\n",(0,i.jsx)(n.h2,{id:"limitations",children:"Limitations"}),"\n",(0,i.jsx)(n.p,{children:"The gadget ignores the following non-identity pod labels when generating policy\nselectors:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"controller-revision-hash"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"pod-template-generation"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"pod-template-hash"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"topology.kubernetes.io/region"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"topology.kubernetes.io/zone"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"failure-domain.beta.kubernetes.io/region"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"failure-domain.beta.kubernetes.io/zone"})}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},7227:(e,n,t)=>{t.d(n,{A:()=>o});t(96540);var r=t(34164);const i={tabItem:"tabItem_Ymn6"};var s=t(74848);function o(e){let{children:n,hidden:t,className:o}=e;return(0,s.jsx)("div",{role:"tabpanel",className:(0,r.A)(i.tabItem,o),hidden:t,children:n})}},49489:(e,n,t)=>{t.d(n,{A:()=>y});var r=t(96540),i=t(34164),s=t(24245),o=t(56347),a=t(36494),l=t(62814),c=t(45167),d=t(69900);function u(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> 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(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??function(e){return u(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:i}}=e;return{value:n,label:t,attributes:r,default:i}}))}(t);return function(e){const n=(0,c.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function h(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function g(e){let{queryString:n=!1,groupId:t}=e;const i=(0,o.W6)(),s=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new 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 t??null}({queryString:n,groupId:t});return[(0,l.aZ)(s),(0,r.useCallback)((e=>{if(!s)return;const n=new URLSearchParams(i.location.search);n.set(s,e),i.replace({...i.location,search:n.toString()})}),[s,i])]}function m(e){const{defaultValue:n,queryString:t=!1,groupId:i}=e,s=p(e),[o,l]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!h({value:n,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:s}))),[c,u]=g({queryString:t,groupId:i}),[m,b]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[i,s]=(0,d.Dv)(t);return[i,(0,r.useCallback)((e=>{t&&s.set(e)}),[t,s])]}({groupId:i}),v=(()=>{const e=c??m;return h({value:e,tabValues:s})?e:null})();(0,a.A)((()=>{v&&l(v)}),[v]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!h({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),b(e)}),[u,b,s]),tabValues:s}}var b=t(11062);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=t(74848);function f(e){let{className:n,block:t,selectedValue:r,selectValue:o,tabValues:a}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.a_)(),d=e=>{const n=e.currentTarget,t=l.indexOf(n),i=a[t].value;i!==r&&(c(n),o(i))},u=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=l.indexOf(e.currentTarget)+1;n=l[t]??l[0];break}case"ArrowLeft":{const t=l.indexOf(e.currentTarget)-1;n=l[t]??l[l.length-1];break}}n?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.A)("tabs",{"tabs--block":t},n),children:a.map((e=>{let{value:n,label:t,attributes:s}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>
1l.push(e),onKeyDown:u,onClick:d,...s,className:(0,i.A)("tabs__item",v.tabItem,s?.className,{"tabs__item--active":r===n}),children:t??n},n)}))})}function k(e){let{lazy:n,children:t,selectedValue:s}=e;const o=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=o.find((e=>e.props.value===s));return e?(0,r.cloneElement)(e,{className:(0,i.A)("margin-top--md",e.props.className)}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:o.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==s})))})}function j(e){const n=m(e);return(0,x.jsxs)("div",{className:(0,i.A)("tabs-container",v.tabList),children:[(0,x.jsx)(f,{...n,...e}),(0,x.jsx)(k,{...n,...e})]})}function y(e){const n=(0,b.A)();return(0,x.jsx)(j,{...e,children:u(e.children)},String(n))}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var r=t(96540);const i={},s=r.createContext(i);function o(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(s.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.