[{"data":1,"prerenderedAt":1498},["ShallowReactive",2],{"learn-doc-\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking\u002Fservices":3,"learn-doc-topic-\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking":363,"lessons-\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking":401,"sidebar-course-\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking":1443,"i-lucide:chevron-down":1456,"i-lucide:search":1459,"i-lucide:sun":1461,"i-lucide:moon":1463,"i-lucide:menu":1465,"i-lucide:panel-left":1467,"i-lucide:chevron-right":1469,"i-lucide:arrow-right":1471,"i-lucide:corner-down-right":1473,"i-lucide:mail":1475,"i-simple-icons:x":1477,"i-simple-icons:linkedin":1479,"i-simple-icons:dribbble":1481,"i-simple-icons:github":1483,"sidebar-quiz-\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking":1485,"i-lucide:network":1486,"i-lucide:circle-check-big":1488,"i-lucide:printer":1490,"i-lucide:graduation-cap":1492,"i-lucide:book-marked":1494,"i-lucide:notebook-pen":1496},{"id":4,"title":5,"access":6,"body":7,"description":353,"extension":354,"lang":355,"meta":356,"navigation":357,"order":52,"partial":358,"path":359,"seo":360,"stem":361,"__hash__":362},"lessons\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking\u002F01.services.md","Services","free",{"type":8,"value":9,"toc":346},"minimark",[10,14,18,26,31,39,156,163,169,173,242,248,252,259,262,276,280,289,292,296,303,339,342],[11,12,5],"h1",{"id":13},"services",[15,16,17],"p",{},"A pod IP is an unstable identifier. Pods are rescheduled, replaced on deploy, and\nscaled in and out. Anything that hard-codes a pod IP breaks on the first restart.",[15,19,20,21,25],{},"A ",[22,23,24],"strong",{},"Service"," is a stable name and virtual IP in front of a changing set of pods.",[27,28,30],"h2",{"id":29},"how-the-selector-works","How the selector works",[15,32,33,34,38],{},"A Service does not reference pods directly. It declares a label selector, and a\ncontroller keeps a matching ",[35,36,37],"code",{},"EndpointSlice"," up to date:",[40,41,46],"pre",{"className":42,"code":43,"language":44,"meta":45,"style":45},"language-yaml shiki shiki-themes github-dark-dimmed github-dark-dimmed","apiVersion: v1\nkind: Service\nmetadata:\n  name: payments\nspec:\n  selector:\n    app: payments\n  ports:\n    - port: 80\n      targetPort: 8080\n","yaml","",[35,47,48,65,76,85,96,104,112,122,130,145],{"__ignoreMap":45},[49,50,53,57,61],"span",{"class":51,"line":52},"line",1,[49,54,56],{"class":55},"sza-u","apiVersion",[49,58,60],{"class":59},"sM9_K",": ",[49,62,64],{"class":63},"szYpP","v1\n",[49,66,68,71,73],{"class":51,"line":67},2,[49,69,70],{"class":55},"kind",[49,72,60],{"class":59},[49,74,75],{"class":63},"Service\n",[49,77,79,82],{"class":51,"line":78},3,[49,80,81],{"class":55},"metadata",[49,83,84],{"class":59},":\n",[49,86,88,91,93],{"class":51,"line":87},4,[49,89,90],{"class":55},"  name",[49,92,60],{"class":59},[49,94,95],{"class":63},"payments\n",[49,97,99,102],{"class":51,"line":98},5,[49,100,101],{"class":55},"spec",[49,103,84],{"class":59},[49,105,107,110],{"class":51,"line":106},6,[49,108,109],{"class":55},"  selector",[49,111,84],{"class":59},[49,113,115,118,120],{"class":51,"line":114},7,[49,116,117],{"class":55},"    app",[49,119,60],{"class":59},[49,121,95],{"class":63},[49,123,125,128],{"class":51,"line":124},8,[49,126,127],{"class":55},"  ports",[49,129,84],{"class":59},[49,131,133,136,139,141],{"class":51,"line":132},9,[49,134,135],{"class":59},"    - ",[49,137,138],{"class":55},"port",[49,140,60],{"class":59},[49,142,144],{"class":143},"sQdni","80\n",[49,146,148,151,153],{"class":51,"line":147},10,[49,149,150],{"class":55},"      targetPort",[49,152,60],{"class":59},[49,154,155],{"class":143},"8080\n",[15,157,158,159,162],{},"Any pod carrying ",[35,160,161],{},"app: payments"," and passing its readiness probe is added to the\nendpoint list. Any pod that fails readiness is removed. This is the reconciliation\nmodel again: the Service is a declaration, the endpoint list is reality, and a\ncontroller closes the gap.",[164,165,166],"note",{},[15,167,168],{},"A Service with a selector that matches nothing is not an error. It is an empty\nendpoint list, and connections to it fail with connection refused rather than a\nclear message. This is the single most common \"my Service is broken\" cause.",[27,170,172],{"id":171},"the-three-types","The three types",[174,175,176,192],"table",{},[177,178,179],"thead",{},[180,181,182,186,189],"tr",{},[183,184,185],"th",{},"Type",[183,187,188],{},"Allocates",[183,190,191],{},"Reachable from",[193,194,195,209,226],"tbody",{},[180,196,197,203,206],{},[198,199,200],"td",{},[35,201,202],{},"ClusterIP",[198,204,205],{},"A virtual IP inside the cluster",[198,207,208],{},"Inside the cluster only",[180,210,211,216,223],{},[198,212,213],{},[35,214,215],{},"NodePort",[198,217,218,219,222],{},"A ClusterIP ",[22,220,221],{},"plus"," the same port on every node",[198,224,225],{},"Anything that can reach a node",[180,227,228,233,239],{},[198,229,230],{},[35,231,232],{},"LoadBalancer",[198,234,235,236,238],{},"A NodePort ",[22,237,221],{}," an external load balancer",[198,240,241],{},"The internet, via the cloud provider",[15,243,244,245,247],{},"The types are cumulative, not alternatives. A ",[35,246,232],{}," Service still has a\nClusterIP and still has a node port — the cloud controller simply provisions an\nexternal balancer that points at those node ports.",[27,249,251],{"id":250},"what-clusterip-really-is","What ClusterIP really is",[15,253,254,255,258],{},"The ClusterIP is not assigned to any interface. Nothing answers ARP for it. It\nexists only as a set of rules in each node's kernel — iptables or IPVS entries\ninstalled by ",[35,256,257],{},"kube-proxy"," — that rewrite the destination address to a real pod IP\nas the packet leaves.",[15,260,261],{},"That has a practical consequence worth internalising:",[263,264,265],"warning",{},[15,266,267,268,271,272,275],{},"You cannot ",[35,269,270],{},"ping"," a ClusterIP. There is no host to answer ICMP — only DNAT rules\nfor the ports the Service declares. A failed ping proves nothing about whether\nthe Service works. Test with ",[35,273,274],{},"curl"," against a declared port instead.",[27,277,279],{"id":278},"load-balancing-granularity","Load balancing granularity",[15,281,282,284,285,288],{},[35,283,257],{}," picks an endpoint per ",[22,286,287],{},"connection",", not per request. For HTTP\u002F1.1\nwith connection reuse, and especially for HTTP\u002F2 and gRPC where a single long-lived\nconnection carries every request, this means traffic pins to one pod.",[15,290,291],{},"This is why gRPC services behind a plain ClusterIP often show badly skewed load.\nThe fix is client-side load balancing, a proxy that understands HTTP\u002F2, or a\nservice mesh — not a different Service type.",[27,293,295],{"id":294},"headless-services","Headless Services",[15,297,298,299,302],{},"Setting ",[35,300,301],{},"clusterIP: None"," disables the virtual IP entirely. DNS then returns the\npod IPs directly, one A record per ready endpoint:",[40,304,306],{"className":42,"code":305,"language":44,"meta":45,"style":45},"spec:\n  clusterIP: None\n  selector:\n    app: cassandra\n",[35,307,308,314,324,330],{"__ignoreMap":45},[49,309,310,312],{"class":51,"line":52},[49,311,101],{"class":55},[49,313,84],{"class":59},[49,315,316,319,321],{"class":51,"line":67},[49,317,318],{"class":55},"  clusterIP",[49,320,60],{"class":59},[49,322,323],{"class":63},"None\n",[49,325,326,328],{"class":51,"line":78},[49,327,109],{"class":55},[49,329,84],{"class":59},[49,331,332,334,336],{"class":51,"line":87},[49,333,117],{"class":55},[49,335,60],{"class":59},[49,337,338],{"class":63},"cassandra\n",[15,340,341],{},"This is what StatefulSets use. When each replica is individually addressable and\nidentity matters — database members, brokers, anything with a quorum — you want\nthe caller to see the real topology rather than a single virtual IP hiding it.",[343,344,345],"style",{},"html pre.shiki code .sza-u, html code.shiki .sza-u{--shiki-default:#8DDB8C;--shiki-dark:#8DDB8C}html pre.shiki code .sM9_K, html code.shiki .sM9_K{--shiki-default:#ADBAC7;--shiki-dark:#ADBAC7}html pre.shiki code .szYpP, html code.shiki .szYpP{--shiki-default:#96D0FF;--shiki-dark:#96D0FF}html pre.shiki code .sQdni, html code.shiki .sQdni{--shiki-default:#6CB6FF;--shiki-dark:#6CB6FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":45,"searchDepth":78,"depth":78,"links":347},[348,349,350,351,352],{"id":29,"depth":67,"text":30},{"id":171,"depth":67,"text":172},{"id":250,"depth":67,"text":251},{"id":278,"depth":67,"text":279},{"id":294,"depth":67,"text":295},"ClusterIP, NodePort and LoadBalancer, and what each one actually allocates.","md","en",{},true,false,"\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking\u002Fservices",{"title":5,"description":353},"learn\u002Fen\u002Fcourses\u002Fnetworking\u002F01.services","6w0dHzL6jKSzV2gpGWIKGGQgiq8FUOgmMB__4BLHel8",{"id":364,"title":365,"access":6,"body":366,"description":370,"draft":358,"estimatedMinutes":371,"extension":354,"featured":357,"icon":372,"lang":355,"level":373,"meta":374,"navigation":357,"order":67,"path":375,"prerequisites":376,"resources":378,"seo":389,"sku":390,"stem":391,"subjects":392,"summary":394,"tags":395,"updated":399,"__hash__":400},"courses\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking\u002Findex.md","Kubernetes Networking",{"type":8,"value":367,"toc":368},[],{"title":45,"searchDepth":78,"depth":78,"links":369},[],"Services, Ingress and network policy — how a packet actually reaches a pod.",45,"lucide:network","intermediate",{},"\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking",[377],"\u002Flearn\u002Fen\u002Fkubernetes\u002Fpods",[379,383],{"label":380,"file":381,"access":6,"size":382},"Service types cheat sheet","k8s-service-types.pdf","180 KB",{"label":384,"file":385,"access":386,"sku":387,"size":388},"NetworkPolicy recipe pack","k8s-network-policies.pdf","premium","res-k8s-netpol","640 KB",{"title":365,"description":370},null,"learn\u002Fen\u002Fcourses\u002Fnetworking\u002Findex",[393],"kubernetes","Kubernetes networking rests on one rule: every pod gets its own IP and can\nreach every other pod without NAT. Everything above that — Services, Ingress,\nNetworkPolicy — exists because pod IPs are not stable and not exposed.\nServices give you a stable virtual IP and load balancing. Ingress puts an\nHTTP router in front of Services so many hostnames share one entry point.\nNetworkPolicy takes the default-allow flat network and narrows it down. Get\nthose three roles clear and the failure modes stop being mysterious.\n",[396,13,397,398],"networking","ingress","cni","2026-08-06","GumIppvDWYP1scgT_rOvScFGIQ-Wqs-Uax-NJtxnUbU",[402,636,1068],{"id":4,"title":5,"access":6,"body":403,"description":353,"extension":354,"lang":355,"meta":634,"navigation":357,"order":52,"partial":358,"path":359,"seo":635,"stem":361,"__hash__":362},{"type":8,"value":404,"toc":627},[405,407,409,413,415,419,497,501,505,507,555,559,561,565,567,575,577,583,585,587,591,623,625],[11,406,5],{"id":13},[15,408,17],{},[15,410,20,411,25],{},[22,412,24],{},[27,414,30],{"id":29},[15,416,33,417,38],{},[35,418,37],{},[40,420,421],{"className":42,"code":43,"language":44,"meta":45,"style":45},[35,422,423,431,439,445,453,459,465,473,479,489],{"__ignoreMap":45},[49,424,425,427,429],{"class":51,"line":52},[49,426,56],{"class":55},[49,428,60],{"class":59},[49,430,64],{"class":63},[49,432,433,435,437],{"class":51,"line":67},[49,434,70],{"class":55},[49,436,60],{"class":59},[49,438,75],{"class":63},[49,440,441,443],{"class":51,"line":78},[49,442,81],{"class":55},[49,444,84],{"class":59},[49,446,447,449,451],{"class":51,"line":87},[49,448,90],{"class":55},[49,450,60],{"class":59},[49,452,95],{"class":63},[49,454,455,457],{"class":51,"line":98},[49,456,101],{"class":55},[49,458,84],{"class":59},[49,460,461,463],{"class":51,"line":106},[49,462,109],{"class":55},[49,464,84],{"class":59},[49,466,467,469,471],{"class":51,"line":114},[49,468,117],{"class":55},[49,470,60],{"class":59},[49,472,95],{"class":63},[49,474,475,477],{"class":51,"line":124},[49,476,127],{"class":55},[49,478,84],{"class":59},[49,480,481,483,485,487],{"class":51,"line":132},[49,482,135],{"class":59},[49,484,138],{"class":55},[49,486,60],{"class":59},[49,488,144],{"class":143},[49,490,491,493,495],{"class":51,"line":147},[49,492,150],{"class":55},[49,494,60],{"class":59},[49,496,155],{"class":143},[15,498,158,499,162],{},[35,500,161],{},[164,502,503],{},[15,504,168],{},[27,506,172],{"id":171},[174,508,509,519],{},[177,510,511],{},[180,512,513,515,517],{},[183,514,185],{},[183,516,188],{},[183,518,191],{},[193,520,521,531,543],{},[180,522,523,527,529],{},[198,524,525],{},[35,526,202],{},[198,528,205],{},[198,530,208],{},[180,532,533,537,541],{},[198,534,535],{},[35,536,215],{},[198,538,218,539,222],{},[22,540,221],{},[198,542,225],{},[180,544,545,549,553],{},[198,546,547],{},[35,548,232],{},[198,550,235,551,238],{},[22,552,221],{},[198,554,241],{},[15,556,244,557,247],{},[35,558,232],{},[27,560,251],{"id":250},[15,562,254,563,258],{},[35,564,257],{},[15,566,261],{},[263,568,569],{},[15,570,267,571,271,573,275],{},[35,572,270],{},[35,574,274],{},[27,576,279],{"id":278},[15,578,579,284,581,288],{},[35,580,257],{},[22,582,287],{},[15,584,291],{},[27,586,295],{"id":294},[15,588,298,589,302],{},[35,590,301],{},[40,592,593],{"className":42,"code":305,"language":44,"meta":45,"style":45},[35,594,595,601,609,615],{"__ignoreMap":45},[49,596,597,599],{"class":51,"line":52},[49,598,101],{"class":55},[49,600,84],{"class":59},[49,602,603,605,607],{"class":51,"line":67},[49,604,318],{"class":55},[49,606,60],{"class":59},[49,608,323],{"class":63},[49,610,611,613],{"class":51,"line":78},[49,612,109],{"class":55},[49,614,84],{"class":59},[49,616,617,619,621],{"class":51,"line":87},[49,618,117],{"class":55},[49,620,60],{"class":59},[49,622,338],{"class":63},[15,624,341],{},[343,626,345],{},{"title":45,"searchDepth":78,"depth":78,"links":628},[629,630,631,632,633],{"id":29,"depth":67,"text":30},{"id":171,"depth":67,"text":172},{"id":250,"depth":67,"text":251},{"id":278,"depth":67,"text":279},{"id":294,"depth":67,"text":295},{},{"title":5,"description":353},{"id":637,"title":638,"access":6,"body":639,"description":1062,"extension":354,"lang":355,"meta":1063,"navigation":357,"order":67,"partial":358,"path":1064,"seo":1065,"stem":1066,"__hash__":1067},"lessons\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking\u002F02.ingress.md","Ingress",{"type":8,"value":640,"toc":1055},[641,643,648,652,659,672,676,894,900,904,952,977,982,986,1030,1037,1043,1047,1050,1053],[11,642,638],{"id":397},[15,644,20,645,647],{},[35,646,232],{}," Service gives you one external IP per Service. Thirty services\nmeans thirty load balancers and thirty bills. Ingress exists to collapse that into\none entry point that routes by hostname and path.",[27,649,651],{"id":650},"the-resource-is-only-a-declaration","The resource is only a declaration",[15,653,654,655,658],{},"This is the part that catches people out. An Ingress object is inert. It describes\nrouting rules; it does not implement them. Without an ",[22,656,657],{},"ingress controller"," running\nin the cluster — ingress-nginx, Traefik, HAProxy, a cloud-native one — creating an\nIngress does exactly nothing.",[263,660,661],{},[15,662,663,664,667,668,671],{},"An Ingress with no controller stays in a permanent pending state with no address,\nand produces no events explaining why. If ",[35,665,666],{},"kubectl get ingress"," shows an empty\n",[35,669,670],{},"ADDRESS"," column and nothing is logged, check whether a controller is installed\nbefore debugging the rules.",[27,673,675],{"id":674},"a-minimal-rule-set","A minimal rule set",[40,677,679],{"className":42,"code":678,"language":44,"meta":45,"style":45},"apiVersion: networking.k8s.io\u002Fv1\nkind: Ingress\nmetadata:\n  name: storefront\nspec:\n  ingressClassName: nginx\n  rules:\n    - host: shop.example.com\n      http:\n        paths:\n          - path: \u002Fapi\n            pathType: Prefix\n            backend:\n              service:\n                name: api\n                port:\n                  number: 80\n          - path: \u002F\n            pathType: Prefix\n            backend:\n              service:\n                name: web\n                port:\n                  number: 80\n",[35,680,681,690,699,705,714,720,730,737,749,756,763,777,788,796,804,815,823,833,845,854,861,868,878,885],{"__ignoreMap":45},[49,682,683,685,687],{"class":51,"line":52},[49,684,56],{"class":55},[49,686,60],{"class":59},[49,688,689],{"class":63},"networking.k8s.io\u002Fv1\n",[49,691,692,694,696],{"class":51,"line":67},[49,693,70],{"class":55},[49,695,60],{"class":59},[49,697,698],{"class":63},"Ingress\n",[49,700,701,703],{"class":51,"line":78},[49,702,81],{"class":55},[49,704,84],{"class":59},[49,706,707,709,711],{"class":51,"line":87},[49,708,90],{"class":55},[49,710,60],{"class":59},[49,712,713],{"class":63},"storefront\n",[49,715,716,718],{"class":51,"line":98},[49,717,101],{"class":55},[49,719,84],{"class":59},[49,721,722,725,727],{"class":51,"line":106},[49,723,724],{"class":55},"  ingressClassName",[49,726,60],{"class":59},[49,728,729],{"class":63},"nginx\n",[49,731,732,735],{"class":51,"line":114},[49,733,734],{"class":55},"  rules",[49,736,84],{"class":59},[49,738,739,741,744,746],{"class":51,"line":124},[49,740,135],{"class":59},[49,742,743],{"class":55},"host",[49,745,60],{"class":59},[49,747,748],{"class":63},"shop.example.com\n",[49,750,751,754],{"class":51,"line":132},[49,752,753],{"class":55},"      http",[49,755,84],{"class":59},[49,757,758,761],{"class":51,"line":147},[49,759,760],{"class":55},"        paths",[49,762,84],{"class":59},[49,764,766,769,772,774],{"class":51,"line":765},11,[49,767,768],{"class":59},"          - ",[49,770,771],{"class":55},"path",[49,773,60],{"class":59},[49,775,776],{"class":63},"\u002Fapi\n",[49,778,780,783,785],{"class":51,"line":779},12,[49,781,782],{"class":55},"            pathType",[49,784,60],{"class":59},[49,786,787],{"class":63},"Prefix\n",[49,789,791,794],{"class":51,"line":790},13,[49,792,793],{"class":55},"            backend",[49,795,84],{"class":59},[49,797,799,802],{"class":51,"line":798},14,[49,800,801],{"class":55},"              service",[49,803,84],{"class":59},[49,805,807,810,812],{"class":51,"line":806},15,[49,808,809],{"class":55},"                name",[49,811,60],{"class":59},[49,813,814],{"class":63},"api\n",[49,816,818,821],{"class":51,"line":817},16,[49,819,820],{"class":55},"                port",[49,822,84],{"class":59},[49,824,826,829,831],{"class":51,"line":825},17,[49,827,828],{"class":55},"                  number",[49,830,60],{"class":59},[49,832,144],{"class":143},[49,834,836,838,840,842],{"class":51,"line":835},18,[49,837,768],{"class":59},[49,839,771],{"class":55},[49,841,60],{"class":59},[49,843,844],{"class":63},"\u002F\n",[49,846,848,850,852],{"class":51,"line":847},19,[49,849,782],{"class":55},[49,851,60],{"class":59},[49,853,787],{"class":63},[49,855,857,859],{"class":51,"line":856},20,[49,858,793],{"class":55},[49,860,84],{"class":59},[49,862,864,866],{"class":51,"line":863},21,[49,865,801],{"class":55},[49,867,84],{"class":59},[49,869,871,873,875],{"class":51,"line":870},22,[49,872,809],{"class":55},[49,874,60],{"class":59},[49,876,877],{"class":63},"web\n",[49,879,881,883],{"class":51,"line":880},23,[49,882,820],{"class":55},[49,884,84],{"class":59},[49,886,888,890,892],{"class":51,"line":887},24,[49,889,828],{"class":55},[49,891,60],{"class":59},[49,893,144],{"class":143},[15,895,896,899],{},[35,897,898],{},"ingressClassName"," decides which controller claims this object. With two controllers\ninstalled and no class set, either both claim it or neither does — both outcomes are\nconfusing to debug.",[27,901,903],{"id":902},"pathtype-matters-more-than-it-looks","pathType matters more than it looks",[174,905,906,916],{},[177,907,908],{},[180,909,910,913],{},[183,911,912],{},"Value",[183,914,915],{},"Matches",[193,917,918,928,942],{},[180,919,920,925],{},[198,921,922],{},[35,923,924],{},"Exact",[198,926,927],{},"The path string exactly, case-sensitive",[180,929,930,935],{},[198,931,932],{},[35,933,934],{},"Prefix",[198,936,937,938,941],{},"Split on ",[35,939,940],{},"\u002F",", element by element",[180,943,944,949],{},[198,945,946],{},[35,947,948],{},"ImplementationSpecific",[198,950,951],{},"Whatever the controller decides",[15,953,954,956,957,961,962,965,966,968,969,972,973,976],{},[35,955,934],{}," compares path ",[958,959,960],"em",{},"elements",", not characters. ",[35,963,964],{},"\u002Fapi"," matches ",[35,967,964],{}," and\n",[35,970,971],{},"\u002Fapi\u002Forders",", but not ",[35,974,975],{},"\u002Fapiary",". That distinction surprises people expecting a\nplain string prefix.",[15,978,979,981],{},[35,980,948],{}," is where portability quietly dies — an ingress-nginx regex\npath will not survive a move to a different controller.",[27,983,985],{"id":984},"tls","TLS",[40,987,989],{"className":42,"code":988,"language":44,"meta":45,"style":45},"spec:\n  tls:\n    - hosts:\n        - shop.example.com\n      secretName: shop-tls\n",[35,990,991,997,1004,1013,1020],{"__ignoreMap":45},[49,992,993,995],{"class":51,"line":52},[49,994,101],{"class":55},[49,996,84],{"class":59},[49,998,999,1002],{"class":51,"line":67},[49,1000,1001],{"class":55},"  tls",[49,1003,84],{"class":59},[49,1005,1006,1008,1011],{"class":51,"line":78},[49,1007,135],{"class":59},[49,1009,1010],{"class":55},"hosts",[49,1012,84],{"class":59},[49,1014,1015,1018],{"class":51,"line":87},[49,1016,1017],{"class":59},"        - ",[49,1019,748],{"class":63},[49,1021,1022,1025,1027],{"class":51,"line":98},[49,1023,1024],{"class":55},"      secretName",[49,1026,60],{"class":59},[49,1028,1029],{"class":63},"shop-tls\n",[15,1031,1032,1033,1036],{},"The Secret must be type ",[35,1034,1035],{},"kubernetes.io\u002Ftls",", must live in the same namespace as the\nIngress, and must already exist. A missing Secret does not block the Ingress from\nbeing created — it just serves the controller's default self-signed certificate,\nwhich looks like a certificate problem rather than a missing-object problem.",[1038,1039,1040],"tip",{},[15,1041,1042],{},"In practice you rarely create these by hand. cert-manager watches Ingress objects\nand issues certificates automatically from an ACME issuer such as Let's Encrypt.",[27,1044,1046],{"id":1045},"when-ingress-is-not-enough","When Ingress is not enough",[15,1048,1049],{},"Ingress only models HTTP and HTTPS. Raw TCP, UDP, gRPC routing rules and weighted\ntraffic splits all sit outside the spec, which is why every controller grew its own\nannotations — and why those annotations do not port between controllers.",[15,1051,1052],{},"The Gateway API is the successor that models these properly, with separate resources\nfor infrastructure and routing. New clusters should look at it before committing to\ncontroller-specific annotations.",[343,1054,345],{},{"title":45,"searchDepth":78,"depth":78,"links":1056},[1057,1058,1059,1060,1061],{"id":650,"depth":67,"text":651},{"id":674,"depth":67,"text":675},{"id":902,"depth":67,"text":903},{"id":984,"depth":67,"text":985},{"id":1045,"depth":67,"text":1046},"HTTP routing in front of Services, and why the resource does nothing on its own.",{},"\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking\u002Fingress",{"title":638,"description":1062},"learn\u002Fen\u002Fcourses\u002Fnetworking\u002F02.ingress","ijcTN78jYH-ktpYMTtKJTvnbYvlGui3oJDXv_cjRfNA",{"id":1069,"title":1070,"access":6,"body":1071,"description":1437,"extension":354,"lang":355,"meta":1438,"navigation":357,"order":78,"partial":358,"path":1439,"seo":1440,"stem":1441,"__hash__":1442},"lessons\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking\u002F03.network-policies.md","Network policies",{"type":8,"value":1072,"toc":1431},[1073,1076,1079,1085,1089,1096,1234,1241,1265,1269,1279,1325,1337,1341,1344,1354,1358,1361,1420,1429],[11,1074,1070],{"id":1075},"network-policies",[15,1077,1078],{},"By default, every pod in a cluster can reach every other pod, in any namespace.\nThe flat network is a deliberate simplification — and a poor security posture the\nmoment you run more than one team's workloads.",[15,1080,1081,1084],{},[35,1082,1083],{},"NetworkPolicy"," narrows it.",[27,1086,1088],{"id":1087},"selecting-turns-on-default-deny","Selecting turns on default-deny",[15,1090,1091,1092,1095],{},"A NetworkPolicy does not add rules to a permissive baseline. The moment any policy\nselects a pod, that pod switches to default-deny ",[22,1093,1094],{},"for the directions the policy\nmentions",", and only the listed rules are permitted.",[40,1097,1099],{"className":42,"code":1098,"language":44,"meta":45,"style":45},"apiVersion: networking.k8s.io\u002Fv1\nkind: NetworkPolicy\nmetadata:\n  name: payments-ingress\nspec:\n  podSelector:\n    matchLabels:\n      app: payments\n  policyTypes: [Ingress]\n  ingress:\n    - from:\n        - podSelector:\n            matchLabels:\n              app: checkout\n      ports:\n        - port: 8080\n",[35,1100,1101,1109,1118,1124,1133,1139,1146,1153,1162,1175,1182,1191,1200,1207,1217,1224],{"__ignoreMap":45},[49,1102,1103,1105,1107],{"class":51,"line":52},[49,1104,56],{"class":55},[49,1106,60],{"class":59},[49,1108,689],{"class":63},[49,1110,1111,1113,1115],{"class":51,"line":67},[49,1112,70],{"class":55},[49,1114,60],{"class":59},[49,1116,1117],{"class":63},"NetworkPolicy\n",[49,1119,1120,1122],{"class":51,"line":78},[49,1121,81],{"class":55},[49,1123,84],{"class":59},[49,1125,1126,1128,1130],{"class":51,"line":87},[49,1127,90],{"class":55},[49,1129,60],{"class":59},[49,1131,1132],{"class":63},"payments-ingress\n",[49,1134,1135,1137],{"class":51,"line":98},[49,1136,101],{"class":55},[49,1138,84],{"class":59},[49,1140,1141,1144],{"class":51,"line":106},[49,1142,1143],{"class":55},"  podSelector",[49,1145,84],{"class":59},[49,1147,1148,1151],{"class":51,"line":114},[49,1149,1150],{"class":55},"    matchLabels",[49,1152,84],{"class":59},[49,1154,1155,1158,1160],{"class":51,"line":124},[49,1156,1157],{"class":55},"      app",[49,1159,60],{"class":59},[49,1161,95],{"class":63},[49,1163,1164,1167,1170,1172],{"class":51,"line":132},[49,1165,1166],{"class":55},"  policyTypes",[49,1168,1169],{"class":59},": [",[49,1171,638],{"class":63},[49,1173,1174],{"class":59},"]\n",[49,1176,1177,1180],{"class":51,"line":147},[49,1178,1179],{"class":55},"  ingress",[49,1181,84],{"class":59},[49,1183,1184,1186,1189],{"class":51,"line":765},[49,1185,135],{"class":59},[49,1187,1188],{"class":55},"from",[49,1190,84],{"class":59},[49,1192,1193,1195,1198],{"class":51,"line":779},[49,1194,1017],{"class":59},[49,1196,1197],{"class":55},"podSelector",[49,1199,84],{"class":59},[49,1201,1202,1205],{"class":51,"line":790},[49,1203,1204],{"class":55},"            matchLabels",[49,1206,84],{"class":59},[49,1208,1209,1212,1214],{"class":51,"line":798},[49,1210,1211],{"class":55},"              app",[49,1213,60],{"class":59},[49,1215,1216],{"class":63},"checkout\n",[49,1218,1219,1222],{"class":51,"line":806},[49,1220,1221],{"class":55},"      ports",[49,1223,84],{"class":59},[49,1225,1226,1228,1230,1232],{"class":51,"line":817},[49,1227,1017],{"class":59},[49,1229,138],{"class":55},[49,1231,60],{"class":59},[49,1233,155],{"class":143},[15,1235,1236,1237,1240],{},"Payments now accepts traffic from checkout on 8080 and nothing else. Egress is\nuntouched, because ",[35,1238,1239],{},"policyTypes"," does not list it.",[263,1242,1243],{},[15,1244,1245,1246,1249,1250,1252,1253,1256,1257,1260,1261,1264],{},"Listing ",[35,1247,1248],{},"Egress"," in ",[35,1251,1239],{}," with an empty ",[35,1254,1255],{},"egress"," block denies ",[958,1258,1259],{},"all","\noutbound traffic — including DNS to ",[35,1262,1263],{},"kube-dns",". Name resolution stops, so every\noutbound connection fails with a resolution error rather than a connection error,\nand the policy looks unrelated to the symptom. Always allow UDP and TCP 53 to the\nDNS namespace when you start restricting egress.",[27,1266,1268],{"id":1267},"namespace-selectors-need-labels","Namespace selectors need labels",[15,1270,1271,1274,1275,1278],{},[35,1272,1273],{},"namespaceSelector"," matches on namespace labels, not names. Namespaces have no\nuseful labels by default beyond ",[35,1276,1277],{},"kubernetes.io\u002Fmetadata.name",", which the control\nplane sets automatically:",[40,1280,1282],{"className":42,"code":1281,"language":44,"meta":45,"style":45},"ingress:\n  - from:\n      - namespaceSelector:\n          matchLabels:\n            kubernetes.io\u002Fmetadata.name: monitoring\n",[35,1283,1284,1290,1299,1308,1315],{"__ignoreMap":45},[49,1285,1286,1288],{"class":51,"line":52},[49,1287,397],{"class":55},[49,1289,84],{"class":59},[49,1291,1292,1295,1297],{"class":51,"line":67},[49,1293,1294],{"class":59},"  - ",[49,1296,1188],{"class":55},[49,1298,84],{"class":59},[49,1300,1301,1304,1306],{"class":51,"line":78},[49,1302,1303],{"class":59},"      - ",[49,1305,1273],{"class":55},[49,1307,84],{"class":59},[49,1309,1310,1313],{"class":51,"line":87},[49,1311,1312],{"class":55},"          matchLabels",[49,1314,84],{"class":59},[49,1316,1317,1320,1322],{"class":51,"line":98},[49,1318,1319],{"class":55},"            kubernetes.io\u002Fmetadata.name",[49,1321,60],{"class":59},[49,1323,1324],{"class":63},"monitoring\n",[15,1326,1327,1328,1330,1331,1333,1334,1336],{},"Combining ",[35,1329,1273],{}," and ",[35,1332,1197],{}," in a single ",[35,1335,1188],{}," entry is an AND.\nListing them as two entries is an OR. One character of YAML indentation separates\n\"Prometheus pods in the monitoring namespace\" from \"anything in monitoring, plus\nPrometheus pods anywhere\".",[27,1338,1340],{"id":1339},"the-cni-has-to-implement-it","The CNI has to implement it",[15,1342,1343],{},"Like Ingress, the object is only a declaration. Calico, Cilium and Antrea enforce\npolicies. Flannel, on its own, does not.",[1345,1346,1347],"danger",{},[15,1348,1349,1350,1353],{},"Applying NetworkPolicy on a CNI that ignores it produces no error and no warning.\n",[35,1351,1352],{},"kubectl get networkpolicy"," lists the object, the API accepted it, and traffic\nflows exactly as before. A policy you believe is enforced but is not is worse than\nno policy — verify by actually attempting a connection that should be denied.",[27,1355,1357],{"id":1356},"a-sensible-starting-point","A sensible starting point",[15,1359,1360],{},"Deny everything inbound in a namespace, then open specific paths:",[40,1362,1364],{"className":42,"code":1363,"language":44,"meta":45,"style":45},"apiVersion: networking.k8s.io\u002Fv1\nkind: NetworkPolicy\nmetadata:\n  name: default-deny-ingress\nspec:\n  podSelector: {}\n  policyTypes: [Ingress]\n",[35,1365,1366,1374,1382,1388,1397,1403,1410],{"__ignoreMap":45},[49,1367,1368,1370,1372],{"class":51,"line":52},[49,1369,56],{"class":55},[49,1371,60],{"class":59},[49,1373,689],{"class":63},[49,1375,1376,1378,1380],{"class":51,"line":67},[49,1377,70],{"class":55},[49,1379,60],{"class":59},[49,1381,1117],{"class":63},[49,1383,1384,1386],{"class":51,"line":78},[49,1385,81],{"class":55},[49,1387,84],{"class":59},[49,1389,1390,1392,1394],{"class":51,"line":87},[49,1391,90],{"class":55},[49,1393,60],{"class":59},[49,1395,1396],{"class":63},"default-deny-ingress\n",[49,1398,1399,1401],{"class":51,"line":98},[49,1400,101],{"class":55},[49,1402,84],{"class":59},[49,1404,1405,1407],{"class":51,"line":106},[49,1406,1143],{"class":55},[49,1408,1409],{"class":59},": {}\n",[49,1411,1412,1414,1416,1418],{"class":51,"line":114},[49,1413,1166],{"class":55},[49,1415,1169],{"class":59},[49,1417,638],{"class":63},[49,1419,1174],{"class":59},[15,1421,1422,1423,1425,1426,1428],{},"An empty ",[35,1424,1197],{}," selects every pod in the namespace. With no ",[35,1427,397],{}," rules,\nnothing is allowed in. Layer permissive policies on top per service — policies are\nadditive, so any rule that allows traffic wins over the baseline denial.",[343,1430,345],{},{"title":45,"searchDepth":78,"depth":78,"links":1432},[1433,1434,1435,1436],{"id":1087,"depth":67,"text":1088},{"id":1267,"depth":67,"text":1268},{"id":1339,"depth":67,"text":1340},{"id":1356,"depth":67,"text":1357},"Narrowing a default-allow flat network, and the traps in doing it.",{},"\u002Flearn\u002Fen\u002Fcourses\u002Fnetworking\u002Fnetwork-policies",{"title":1070,"description":1437},"learn\u002Fen\u002Fcourses\u002Fnetworking\u002F03.network-policies","6JfTFK0E4FUQ3up_YPMrK33esdPME_tZFDmROIyTNDw",{"id":364,"title":365,"access":6,"body":1444,"description":370,"draft":358,"estimatedMinutes":371,"extension":354,"featured":357,"icon":372,"lang":355,"level":373,"meta":1448,"navigation":357,"order":67,"path":375,"prerequisites":1449,"resources":1450,"seo":1453,"sku":390,"stem":391,"subjects":1454,"summary":394,"tags":1455,"updated":399,"__hash__":400},{"type":8,"value":1445,"toc":1446},[],{"title":45,"searchDepth":78,"depth":78,"links":1447},[],{},[377],[1451,1452],{"label":380,"file":381,"access":6,"size":382},{"label":384,"file":385,"access":386,"sku":387,"size":388},{"title":365,"description":370},[393],[396,13,397,398],{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1458},0,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m6 9l6 6l6-6\"\u002F>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1460},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"\u002F>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"\u002F>\u003C\u002Fg>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1462},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"\u002F>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"\u002F>\u003C\u002Fg>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1464},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"\u002F>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1466},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5h16M4 12h16M4 19h16\"\u002F>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1468},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"\u002F>\u003Cpath d=\"M9 3v18\"\u002F>\u003C\u002Fg>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1470},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m9 18l6-6l-6-6\"\u002F>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1472},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1474},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m15 10l5 5l-5 5\"\u002F>\u003Cpath d=\"M4 4v7a4 4 0 0 0 4 4h12\"\u002F>\u003C\u002Fg>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1476},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m22 7l-8.991 5.727a2 2 0 0 1-2.009 0L2 7\"\u002F>\u003Crect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"\u002F>\u003C\u002Fg>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1478},"\u003Cpath fill=\"currentColor\" d=\"M14.234 10.162L22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299l-.929-1.329L3.076 1.56h3.182l5.965 8.532l.929 1.329l7.754 11.09h-3.182z\"\u002F>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1480,"hidden":357},"\u003Cpath fill=\"currentColor\" d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037c-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85c3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065a2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z\"\u002F>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1482},"\u003Cpath fill=\"currentColor\" d=\"M12 24C5.385 24 0 18.615 0 12S5.385 0 12 0s12 5.385 12 12s-5.385 12-12 12m10.12-10.358c-.35-.11-3.17-.953-6.384-.438c1.34 3.684 1.887 6.684 1.992 7.308a10.28 10.28 0 0 0 4.395-6.87zm-6.115 7.808c-.153-.9-.75-4.032-2.19-7.77l-.066.02c-5.79 2.015-7.86 6.025-8.04 6.4a10.16 10.16 0 0 0 6.29 2.166c1.42 0 2.77-.29 4-.814zm-11.62-2.58c.232-.4 3.045-5.055 8.332-6.765q.202-.067.405-.12q-.392-.879-.832-1.74C7.17 11.775 2.206 11.71 1.756 11.7l-.004.312c0 2.633.998 5.037 2.634 6.855zm-2.42-8.955c.46.008 4.683.026 9.477-1.248a66 66 0 0 0-3.8-5.928a10.28 10.28 0 0 0-5.676 7.17zM9.6 2.052c.282.38 2.145 2.914 3.822 6c3.645-1.365 5.19-3.44 5.373-3.702A10.2 10.2 0 0 0 12 1.764c-.825 0-1.63.1-2.4.285zm10.335 3.483c-.218.29-1.935 2.493-5.724 4.04c.24.49.47.985.68 1.486c.08.18.15.36.22.53c3.41-.43 6.8.26 7.14.33c-.02-2.42-.88-4.64-2.31-6.38z\"\u002F>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1484},"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",{"course":375},{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1487},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"6\" height=\"6\" x=\"16\" y=\"16\" rx=\"1\"\u002F>\u003Crect width=\"6\" height=\"6\" x=\"2\" y=\"16\" rx=\"1\"\u002F>\u003Crect width=\"6\" height=\"6\" x=\"9\" y=\"2\" rx=\"1\"\u002F>\u003Cpath d=\"M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3m-7-4V8\"\u002F>\u003C\u002Fg>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1489},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M21.801 10A10 10 0 1 1 17 3.335\"\u002F>\u003Cpath d=\"m9 11l3 3L22 4\"\u002F>\u003C\u002Fg>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1491},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6\"\u002F>\u003Crect width=\"12\" height=\"8\" x=\"6\" y=\"14\" rx=\"1\"\u002F>\u003C\u002Fg>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1493},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M21.42 10.922a1 1 0 0 0-.019-1.838L12.83 5.18a2 2 0 0 0-1.66 0L2.6 9.08a1 1 0 0 0 0 1.832l8.57 3.908a2 2 0 0 0 1.66 0zM22 10v6\"\u002F>\u003Cpath d=\"M6 12.5V16a6 3 0 0 0 12 0v-3.5\"\u002F>\u003C\u002Fg>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1495},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M10 2v8l3-3l3 3V2\"\u002F>\u003Cpath d=\"M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20\"\u002F>\u003C\u002Fg>",{"left":1457,"top":1457,"width":887,"height":887,"rotate":1457,"vFlip":358,"hFlip":358,"body":1497},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4M2 6h4m-4 4h4m-4 4h4m-4 4h4\"\u002F>\u003Cpath d=\"M21.378 5.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z\"\u002F>\u003C\u002Fg>",1787597895747]