1"use strict";(self.webpackChunktigera_docs=self.webpackChunktigera_docs||[]).push([["1384"],{4292:function(e,n,o){o.r(n),o.d(n,{frontMatter:()=>a,toc:()=>p,default:()=>u,metadata:()=>t,assets:()=>d,contentTitle:()=>c});var t=JSON.parse('{"id":"getting-started/kubernetes/windows-calico/demo","title":"Basic policy demo","description":"An interactive demo to show how to apply basic network policy to pods in a Calico for Windows cluster.","source":"@site/calico_versioned_docs/version-3.28/getting-started/kubernetes/windows-calico/demo.mdx","sourceDirName":"getting-started/kubernetes/windows-calico","slug":"/getting-started/kubernetes/windows-calico/demo","permalink":"/calico/3.28/getting-started/kubernetes/windows-calico/demo","draft":false,"unlisted":false,"editUrl":"https://github.com/tigera/docs/edit/main/calico_versioned_docs/version-3.28/getting-started/kubernetes/windows-calico/demo.mdx","tags":[],"version":"3.28","frontMatter":{"description":"An interactive demo to show how to apply basic network policy to pods in a Calico for Windows cluster."},"sidebar":"calicoSidebar","previous":{"title":"Calico for Windows on a Rancher Kubernetes Engine cluster","permalink":"/calico/3.28/getting-started/kubernetes/windows-calico/rancher"},"next":{"title":"Troubleshoot Calico for Windows","permalink":"/calico/3.28/getting-started/kubernetes/windows-calico/troubleshoot"}}'),i=o(37937),s=o(17869),l=o(71018),r=o(38958);let a={description:"An interactive demo to show how to apply basic network policy to pods in a Calico for Windows cluster."},c="Basic policy demo",d={},p=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Create pods on Linux nodes",id:"create-pods-on-linux-nodes",level:2},{value:"Create pods on Window nodes",id:"create-pods-on-window-nodes",level:2},{value:"Check connectivity between pods on Linux and Windows nodes",id:"check-connectivity-between-pods-on-linux-and-windows-nodes",level:2},{value:"Apply policy to the Windows client pod",id:"apply-policy-to-the-windows-client-pod",level:2},{value:"Wrap up",id:"wrap-up",level:2},{value:"Installing kubectl on Windows",id:"installing-kubectl-on-windows",level:2},{value:"Create pods on Linux nodes",id:"create-pods-on-linux-nodes-1",level:2},{value:"Create a YAML file policy-demo-linux.yaml using your favorite editor on Windows",id:"create-a-yaml-file-policy-demo-linuxyaml-using-your-favorite-editor-on-windows",level:3},{value:"Apply the policy-demo-linux.yaml file to the Kubernetes cluster",id:"apply-the-policy-demo-linuxyaml-file-to-the-kubernetes-cluster",level:3},{value:"Create pods on Window nodes",id:"create-pods-on-window-nodes-1",level:2},{value:"Create the policy-demo-windows.yaml using your favorite editor on Windows",id:"create-the-policy-demo-windowsyaml-using-your-favorite-editor-on-windows",level:3},{value:"Apply the policy-demo-windows.yaml file to the Kubernetes cluster",id:"apply-the-policy-demo-windowsyaml-file-to-the-kubernetes-cluster",level:3},{value:"Verify four pods have been created and are running",id:"verify-four-pods-have-been-created-and-are-running",level:3},{value:"Check connectivity between pods on Linux and Windows nodes",id:"check-connectivity-between-pods-on-linux-and-windows-nodes-1",level:3},{value:"Apply policy to the Windows client pod",id:"apply-policy-to-the-windows-client-pod-1",level:2},{value:"Create the network-policy.yaml file using your favorite editor on Windows",id:"create-the-network-policyyaml-file-using-your-favorite-editor-on-windows",level:3},{value:"Apply the network-policy.yaml file",id:"apply-the-network-policyyaml-file",level:3},{value:"Verify the policy is in effect",id:"verify-the-policy-is-in-effect",level:3},{value:"Wrap up",id:"wrap-up-1",level:2}];function h(e){let n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"basic-policy-demo",children:"Basic policy demo"})}),"\n","\n",(0,i.jsx)(n.p,{children:"This guide provides a simple demo to illustrate basic pod-to-pod connectivity and the application of network policy in a Calico for Windows cluster. We will create client and server pods on Linux and Windows no
1des, verify connectivity between the pods, and then we'll apply a basic network policy to isolate pod traffic."}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.p,{children:["To run this demo, you will need a ",(0,i.jsx)(n.a,{href:"/calico/3.28/getting-started/kubernetes/windows-calico/operator",children:"Calico for Windows cluster"})," with\nWindows Server 1809 (build 17763.1432 August 2020 update or newer). More recent versions of Windows Server can be used with a change to the demo manifests, namely the version tags of the Windows images, e.g.: ",(0,i.jsx)(n.code,{children:"servercore:ltsc2022"})," instead of ",(0,i.jsx)(n.code,{children:"servercore:1809"}),"."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["Windows Server 1809 (build older than 17763.1432) do not support ",(0,i.jsx)(n.a,{href:"https://techcommunity.microsoft.com/t5/networking-blog/direct-server-return-dsr-in-a-nutshell/ba-p/693710",children:"direct server return"}),". This means that policy support is limited to only pod IP addresses."]})}),"\n",(0,i.jsxs)(l.A,{children:[(0,i.jsxs)(r.A,{label:"bash",value:"bash-0",children:[(0,i.jsx)(n.h2,{id:"create-pods-on-linux-nodes",children:"Create pods on Linux nodes"}),(0,i.jsx)(n.p,{children:"First, create a client (busybox) and server (nginx) pod on the Linux nodes:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f - <<EOF\napiVersion: v1\nkind: Namespace\nmetadata:\n name: calico-demo\n\n---\n\napiVersion: v1\nkind: Pod\nmetadata:\n labels:\n app: busybox\n name: busybox\n namespace: calico-demo\nspec:\n containers:\n - args:\n - /bin/sh\n - -c\n - sleep 360000\n image: busybox:1.28\n imagePullPolicy: Always\n name: busybox\n nodeSelector:\n kubernetes.io/os: linux\n\n---\n\napiVersion: v1\nkind: Pod\nmetadata:\n labels:\n app: nginx\n name: nginx\n namespace: calico-demo\nspec:\n containers:\n - name: nginx\n image: nginx:1.8\n ports:\n - containerPort: 80\n nodeSelector:\n kubernetes.io/os: linux\nEOF\n"})}),(0,i.jsx)(n.h2,{id:"create-pods-on-window-nodes",children:"Create pods on Window nodes"}),(0,i.jsx)(n.p,{children:"Next, we'll create a client (powershell) and server (porter) pod on the Windows nodes. First the create the powershell pod."}),(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["The powershell and porter pod manifests below use images based on ",(0,i.jsx)(n.code,{children:"mcr.microsoft.com/windows/servercore:1809"}),".\nIf you are using a more recent Windows Server version, update the manifests to use a ",(0,i.jsx)(n.a,{href:"https://hub.docker.com/_/microsoft-windows-servercore",children:"servercore image"}),"\nthat matches your Windows Server version."]})}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'kubectl apply -f - <<EOF\napiVersion: v1\nkind: Pod\nmetadata:\n name: pwsh\n namespace: calico-demo\n labels:\n app: pwsh\nspec:\n containers:\n - name: pwsh\n image: mcr.microsoft.com/windows/servercore:1809\n args:\n - powershell.exe\n - -Command\n - "Start-Sleep 360000"\n imagePullPolicy: IfNotPresent\n nodeSelector:\n kubernetes.io/os: windows\nEOF\n'})}),(0,i.jsx)(n.p,{children:"Next, we'll create the porter server pod:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f - <<EOF\napiVersion: v1\nkind: Pod\nmetadata:\n name: porter\n namespace: calico-demo\n labels:\n app: porter\nspec:\n containers:\n - name: porter\n image: calico/porter:1809\n ports:\n - containerPort: 80\n env:\n - name: SERVE_PORT_80\n value: This is a Calico for Windows demo.\n imagePullPolicy: IfNotPresent\n nodeSelector:\n kubernetes.io/os: windows\nEOF\n"})}),(0,i.jsx)(n.h2,{id:"check-connectivity-between-pods-on-linux-and-windows-nodes",children:"Check connectivity between pods on Linux and Windows nodes"}),(0,i.jsx)(n.p,{children:"Now that client and server pods are running on both Linux and Windows no
1des, let's verify that client pods\non Linux nodes can reach server pods on Windows nodes. First, we will need the porter pod IP:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}'\n"})}),(0,i.jsx)(n.p,{children:"Then we can exec into the busybox pod and try reaching the porter pod on port 80:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl exec -n calico-demo busybox -- nc -vz <porter_ip> 80\n"})}),(0,i.jsx)(n.p,{children:"To combine both of the above steps:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl exec -n calico-demo busybox -- nc -vz $(kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}') 80\n"})}),(0,i.jsx)(n.p,{children:"If the connection from the busybox pod to the porter pod succeeds, we will get output similar to the following:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"192.168.40.166 (192.168.40.166:80) open\n"})}),(0,i.jsx)(n.p,{children:"Now let's verify that the powershell pod can reach the nginx pod:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl exec -n calico-demo pwsh -- powershell Invoke-WebRequest -Uri http://$(kubectl get po nginx -n calico-demo -o 'jsonpath={.status.podIP}') -UseBasicParsing -TimeoutSec 5\n"})}),(0,i.jsx)(n.p,{children:"If the connection succeeds, we will get output similar to:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"StatusCode : 200\nStatusDescription : OK\nContent : <!DOCTYPE html>\n <html>\n <head>\n <title>Welcome to nginx!</title>\n <style>\n body {\n width: 35em;\n margin: 0 auto;\n font-family: Tahoma, Verdana, Arial, sans-serif;\n }\n </style>\n <...\n...\n"})}),(0,i.jsx)(n.p,{children:"Finally, let's verify that the powershell pod can reach the porter pod:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl exec -n calico-demo pwsh -- powershell Invoke-WebRequest -Uri http://$(kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}') -UseBasicParsing -TimeoutSec 5\n"})}),(0,i.jsx)(n.p,{children:"If that succeeds, we will see something like:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"StatusCode : 200\nStatusDescription : OK\nContent : This is a Calico for Windows demo.\nRawContent : HTTP/1.1 200 OK\n Content-Length: 49\n Content-Type: text/plain; charset=utf-8\n Date: Fri, 21 Aug 2020 22:45:46 GMT\n\n This is a Calico for Windows demo.\nForms :\nHeaders : {[Content-Length, 49], [Content-Type, text/plain;\n charset=utf-8], [Date, Fri, 21 Aug 2020 22:45:46 GMT]}\nImages : {}\nInputFields : {}\nLinks : {}\nParsedHtml :\nRawContentLength : 49\n"})}),(0,i.jsx)(n.h2,{id:"apply-policy-to-the-windows-client-pod",children:"Apply policy to the Windows client pod"}),(0,i.jsx)(n.p,{children:"Now let's apply a basic network policy that allows only the busybox pod to reach the porter pod."}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl apply -f - <<EOF\napiVersion: projectcalico.org/v3\nkind: NetworkPolicy\nmetadata:\n name: allow-busybox\n namespace: calico-demo\nspec:\n selector: app == 'porter'\n types:\n - Ingress\n ingress:\n - action: Allow\n protocol: TCP\n source:\n selector: app == 'busybox'\nEOF\n"})}),(0,i.jsx)(n.p,{children:"With the policy in place, the busybox pod should still be able to reach the porter pod:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl exec -n calico-demo busybox -- nc -vz $(kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}') 80\n"})}),(0,i.jsx)(n.p,{children:"However, the powershell pod will not able to reach the porter pod:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl exec -n calico-demo pwsh -- powershell Invoke-WebRequest -Uri http://$(kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}') -UseBasicParsing -TimeoutSec 5\n"})}),(0,i.jsx)(n.p,{children:"The request times out with a message like:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Invoke-WebRequest : The operation has timed out.\nAt line:1 char:1\n+ Invoke-WebRequest -Uri http://192.168.40.166 -UseBasicParsing -Timeou ...\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:Htt\n pWebRequest) [Invoke-WebRequest], WebException\n + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShe\n ll.Commands.InvokeWebRequestCommand\n\ncommand terminated with exit code 1\n"})}),(0,i.jsx)(n.h2,{id:"wrap-up",children:"Wrap up"}),(0,i.jsx)(n.p,{children:"In this demo we've brought up pods on Linux and Windows no
1des, verified basic pod connectivity, and tried a\nbasic network policy to isolate pod to pod traffic. Finally, we can clean up all of our demo resources:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"kubectl delete ns calico-demo\n"})})]}),(0,i.jsxs)(r.A,{label:"PowerShell",value:"PowerShell-1",children:[(0,i.jsx)(n.h2,{id:"installing-kubectl-on-windows",children:"Installing kubectl on Windows"}),(0,i.jsxs)(n.p,{children:["To run the commands in this demo you need the Windows version of kubectl installed and add it to the system path.\n",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/",children:"Install kubectl"})," and move the kubectl binary to ",(0,i.jsx)(n.strong,{children:"c:\\k"}),"."]}),(0,i.jsxs)(n.p,{children:["Add ",(0,i.jsx)(n.code,{children:"c:\\k"})," to the system path"]}),(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Open a PowerShell window as Administrator"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:'$env:Path += ";C:\\k"\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Close all PowerShell windows."}),"\n"]}),"\n"]}),(0,i.jsx)(n.h2,{id:"create-pods-on-linux-nodes-1",children:"Create pods on Linux nodes"}),(0,i.jsx)(n.p,{children:"First, create a client (busybox) and server (nginx) pod on the Linux nodes."}),(0,i.jsx)(n.h3,{id:"create-a-yaml-file-policy-demo-linuxyaml-using-your-favorite-editor-on-windows",children:"Create a YAML file policy-demo-linux.yaml using your favorite editor on Windows"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Namespace\nmetadata:\n name: calico-demo\n\n---\napiVersion: v1\nkind: Pod\nmetadata:\n labels:\n app: busybox\n name: busybox\n namespace: calico-demo\nspec:\n containers:\n - args:\n - /bin/sh\n - -c\n - sleep 360000\n image: busybox:1.28\n imagePullPolicy: Always\n name: busybox\n nodeSelector:\n kubernetes.io/os: linux\n\n---\napiVersion: v1\nkind: Pod\nmetadata:\n labels:\n app: nginx\n name: nginx\n namespace: calico-demo\nspec:\n containers:\n - name: nginx\n image: nginx:1.8\n ports:\n - containerPort: 80\n nodeSelector:\n kubernetes.io/os: linux\n"})}),(0,i.jsx)(n.h3,{id:"apply-the-policy-demo-linuxyaml-file-to-the-kubernetes-cluster",children:"Apply the policy-demo-linux.yaml file to the Kubernetes cluster"}),(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Open a PowerShell window."}),"\n",(0,i.jsxs)(n.li,{children:["Use ",(0,i.jsx)(n.code,{children:"kubectl"})," to apply the ",(0,i.jsx)(n.code,{children:"policy-demo-linux.yaml"})," configuration."]}),"\n"]}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"kubectl apply -f policy-demo-linux.yaml\n"})}),(0,i.jsx)(n.h2,{id:"create-pods-on-window-nodes-1",children:"Create pods on Window nodes"}),(0,i.jsx)(n.p,{children:"Next, we\u2019ll create a client (pwsh) and server (porter) pod on the Windows nodes."}),(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"The pwsh and porter pod manifests below use images based on mcr.microsoft.com/windows/servercore:1809. If you are using a more recent Windows Server version, update the manifests to use a servercore image that matches your Windows Server version."})}),(0,i.jsx)(n.h3,{id:"create-the-policy-demo-windowsyaml-using-your-favorite-editor-on-windows",children:"Create the policy-demo-windows.yaml using your favorite editor on Windows"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nmetadata:\n name: pwsh\n namespace: calico-demo\n labels:\n app: pwsh\nspec:\n containers:\n - name: pwsh\n image: mcr.microsoft.com/windows/servercore:1809\n args:\n - powershell.exe\n - -Command\n - 'Start-Sleep 360000'\n imagePullPolicy: IfNotPresent\n nodeSelector:\n kubernetes.io/os: windows\n---\napiVersion: v1\nkind: Pod\nmetadata:\n name: porter\n namespace: calico-demo\n labels:\n app: porter\nspec:\n containers:\n - name: porter\n image: calico/porter:1809\n ports:\n - containerPort: 80\n env:\n - name: SERVE_PORT_80\n value: This is a Calico for Windows demo.\n imagePullPolicy: IfNotPresent\n nodeSelector:\n kubernetes.io/os: windows\n"})}),(0,i.jsx)(n.h3,{id:"apply-the-policy-demo-windowsyaml-file-to-the-kubernetes-cluster",children:"Apply the policy-demo-windows.yaml file to the Kubernetes cluster"}),(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Open a PowerShell window."}),"\n",(0,i.jsxs)(n.li,{children:["Use ",(0,i.jsx)(n.code,{children:"kubectl"})," to apply the ",(0,i.jsx)(n.code,{children:"policy-demo-windows.yaml"})," configuration"]}),"\n"]}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"kubectl apply -f policy-demo-windows.yaml\n"})}),(0,i.jsx)(n.h3,{id:"verify-four-pods-have-been-created-and-are-running",children:"Verify four pods have been created and are running"}),(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Launching the Windows pods is going to take some time depending on your network download speed."})}),(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Open a PowerShell window."}),"\n",(0,i.jsxs)(n.li,{children:["Using ",(0,i.jsx)(n.code,{children:"kubectl"})," to list the pods in the ",(0,i.jsx)(n.code,{children:"calico-demo"})," namespace."]}),"\n"]}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"kubectl get pods --namespace calico-demo\n"})}),(0,i.jsx)(n.p,{children:"You should see something like the below"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-output",children:"NAME READY STATUS RESTARTS AGE\nbusybox 1/1 Running 0 4m14s\nnginx 1/1 Running 0 4m14s\nporter 0/1 ContainerCreating 0 74s\npwsh 0/1 ContainerCreating 0 2m9s\n"})}),(0,i.jsx)(n.p,{children:"Repeat the command every few minutes until the output shows all 4 pods in the Running state."}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-output",children:"NAME READY STATUS RESTARTS AGE\nbusybox 1/1 Running 0 7m24s\nnginx 1/1 Running 0 7m24s\nporter 1/1 Running 0 4m24s\npwsh 1/1 Running 0 5m19s\n"})}),(0,i.jsx)(n.h3,{id:"check-connectivity-between-pods-on-linux-and-windows-nodes-1",children:"Check connectivity between pods on Linux and Windows no
1des"}),(0,i.jsx)(n.p,{children:"Now that client and server pods are running on both Linux and Windows nodes, let\u2019s verify that client pods on Linux nodes can reach server pods on Windows nodes."}),(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Open a PowerShell window."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Using ",(0,i.jsx)(n.code,{children:"kubectl"})," to determine the porter pod IP address:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"kubectl get pod porter --namespace calico-demo -o 'jsonpath={.status.podIP}'\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Log into the busybox pod and try reaching the porter pod on port 80. Replace the ",(0,i.jsx)(n.code,{children:"<porter_ip>"})," tag with the IP address returned from the previous command."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"kubectl exec --namespace calico-demo busybox -- nc -vz <porter_ip> 80\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"You can also combine both of the above steps:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"kubectl exec --namespace calico-demo busybox -- nc -vz $(kubectl get pod porter --namespace calico-demo -o 'jsonpath={.status.podIP}') 80\n"})}),"\n",(0,i.jsx)(n.p,{children:"If the connection from the busybox pod to the porter pod succeeds, you will get output similar to the following:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"192.168.40.166 (192.168.40.166:80) open\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"The IP addresses returned will vary depending on your environment setup."})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Now you can verify that the pwsh pod can reach the nginx pod:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"kubectl exec --namespace calico-demo pwsh -- powershell Invoke-WebRequest -Uri http://$(kubectl get po nginx -n calico-demo -o 'jsonpath={.status.podIP}') -UseBasicParsing -TimeoutSec 5\n"})}),"\n",(0,i.jsx)(n.p,{children:"If the connection succeeds, you will see output similar to:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"StatusCode : 200\nStatusDescription : OK\nContent : <!DOCTYPE html>\n <html>\n <head>\n <title>Welcome to nginx!</title>\n <style>\n body {\n width: 35em;\n margin: 0 auto;\n font-family: Tahoma, Verdana, Arial, sans-serif;\n }\n </style>\n <...\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Verify that the pwsh pod can reach the porter pod:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"kubectl exec --namespace calico-demo pwsh -- powershell Invoke-WebRequest -Uri http://$(kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}') -UseBasicParsing -TimeoutSec 5\n"})}),"\n",(0,i.jsx)(n.p,{children:"If that succeeds, you will see something like:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"StatusCode : 200\nStatusDescription : OK\nContent : This is a Calico for Windows demo.\nRawContent : HTTP/1.1 200 OK\n Content-Length: 49\n Content-Type: text/plain; charset=utf-8\n Date: Fri, 21 Aug 2020 22:45:46 GMT\n\n This is a Calico for Windows demo.\nForms :\nHeaders : {[Content-Length, 49], [Content-Type, text/plain;\n charset=utf-8], [Date, Fri, 21 Aug 2020 22:45:46 GMT]}\nImages : {}\nInputFields : {}\nLinks : {}\nParsedHtml :\nRawContentLength : 49\n\n"})}),"\n"]}),"\n"]}),(0,i.jsx)(n.p,{children:"You have now verified that communication is possible between all pods in the application."}),(0,i.jsx)(n.h2,{id:"apply-policy-to-the-windows-client-pod-1",children:"Apply policy to the Windows client pod"}),(0,i.jsx)(n.p,{children:"In a real world deployment you would want to make sure only pods that are supposed to communicate with each other, are actually allowed to do so."}),(0,i.jsx)(n.p,{children:"To achieve this you will apply a basic network policy which allows only the busybox pod to reach the porter pod."}),(0,i.jsx)(n.h3,{id:"create-the-network-policyyaml-file-using-your-favorite-editor-on-windows",children:"Create the network-policy.yaml file using your favorite editor on Windows"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n name: allow-busybox\n namespace: calico-demo\nspec:\n podSelector:\n matchLabels:\n app: porter\n policyTypes:\n - Ingress\n ingress:\n - from:\n - podSelector:\n matchLabels:\n app: busybox\n ports:\n - protocol: TCP\n port: 80\n"})}),(0,i.jsx)(n.h3,{id:"apply-the-network-policyyaml-file",children:"Apply the network-policy.yaml file"}),(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Open a PowerShell window."}),"\n",(0,i.jsxs)(n.li,{children:["Use ",(0,i.jsx)(n.code,{children:"kubectl"})," to apply the network-policy.yaml file."]}),"\n"]}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"kubectl apply -f network-policy.yaml\n"})}),(0,i.jsx)(n.h3,{id:"verify-the-policy-is-in-effect",children:"Verify the policy is in effect"}),(0,i.jsx)(n.p,{children:"With the policy in place, the busybox pod should still be able to reach the porter pod:"}),(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"We will be using the combined command line from earlier in this chapter."})}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"kubectl exec --namespace calico-demo busybox -- nc -vz $(kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}') 80\n"})}),(0,i.jsx)(n.p,{children:"However, the pwsh pod will not able to reach the porter pod:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"kubectl exec --namespace calico-demo pwsh -- powershell Invoke-WebRequest -Uri http://$(kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}') -UseBasicParsing -TimeoutSec 5\n"})}),(0,i.jsx)(n.p,{children:"The request times out with a message like the below:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"Invoke-WebRequest : The operation has timed out.\nAt line:1 char:1\n+ Invoke-WebRequest -Uri http://192.168.40.166 -UseBasicParsing -Timeout ...\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:Htt\npWebRequest) [Invoke-WebRequest], WebException\n + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand\ncommand terminated with exit code 1\n"})}),(0,i.jsx)(n.h2,{id:"wrap-up-1",children:"Wrap up"}),(0,i.jsx)(n.p,{children:"In this demo we\u2019ve configured pods on Linux and Windows no
1des, verified basic pod connectivity, and tried a basic network policy to isolate pod to pod traffic.\nAs the final step you can clean up all of the demo resources:"}),(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Open a PowerShell window."}),"\n"]}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-powershell",children:"kubectl delete namespace calico-demo\n"})})]})]})]})}function u(e={}){let{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},38958:function(e,n,o){o.d(n,{A:()=>s});var t=o(37937);o(82645);var i=o(71918);function s({children:e,hidden:n,className:o}){return(0,t.jsx)("div",{role:"tabpanel",className:(0,i.A)("tabItem_lI36",o),hidden:n,children:e})}},71018:function(e,n,o){o.d(n,{A:()=>g});var t=o(37937),i=o(82645),s=o(71918),l=o(22669),r=o(52678),a=o(13526),c=o(64855),d=o(66235),p=o(77848),h=o(24947);function u(e){return i.Children.toArray(e).filter(e=>"\n"!==e).map(e=>{if(!e||(0,i.isValidElement)(e)&&function(e){let{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw Error(`Docusaurus error: Bad <Tabs> 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 m({value:e,tabValues:n}){return n.some(n=>n.value===e)}var w=o(21);function x({className:e,block:n,selectedValue:o,selectValue:i,tabValues:l}){let a=[],{blockElementScrollPositionUntilNextRender:c}=(0,r.a_)(),d=e=>{let n=e.currentTarget,t=l[a.indexOf(n)].value;t!==o&&(c(n),i(t))},p=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{let o=a.indexOf(e.currentTarget)+1;n=a[o]??a[0];break}case"ArrowLeft":{let o=a.indexOf(e.currentTarget)-1;n=a[o]??a[a.length-1]}}n?.focus()};return(0,t.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.A)("tabs",{"tabs--block":n},e),children:l.map(({value:e,label:n,attributes:i})=>(0,t.jsx)("li",{role:"tab",tabIndex:o===e?0:-1,"aria-selected":o===e,ref:e=>{a.push(e)},onKeyDown:p,onClick:d,...i,className:(0,s.A)("tabs__item","tabItem_tQpp",i?.className,{"tabs__item--active":o===e}),children:n??e},e))})}function b({lazy:e,children:n,selectedValue:o}){let l=(Array.isArray(n)?n:[n]).filter(Boolean);if(e){let e=l.find(e=>e.props.value===o);return e?(0,i.cloneElement)(e,{className:(0,s.A)("margin-top--md",e.props.className)}):null}return(0,t.jsx)("div",{className:"margin-top--md",children:l.map((e,n)=>(0,i.cloneElement)(e,{key:n,hidden:e.props.value!==o}))})}function y(e){let n=function(e){let n,{defaultValue:o,queryString:t=!1,groupId:s}=e,l=function(e){let{values:n,children:o}=e;return(0,i.useMemo)(()=>{let e=n??u(o).map(({props:{value:e,label:n,attributes:o,default:t}})=>({value:e,label:n,attributes:o,default:t})),t=(0,p.XI)(e,(e,n)=>e.value===n.value);if(t.length>0)throw Error(`Docusaurus error: Duplicate values "${t.map(e=>e.value).join(", ")}" found in <Tabs>. Every value needs to be unique.`);return e},[n,o])}(e),[r,w]=(0,i.useState)(()=>(function({defaultValue:e,tabValues:n}){if(0===n.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!m({value:e,tabValues:n}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}let o=n.find(e=>e.default)??n[0];if(!o)throw Error("Unexpected error: 0 tabValues");return o.value})({defaultValue:o,tabValues:l})),[x,b]=function({queryString:e=!1,groupId:n}){let o=(0,a.W6)(),t=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,d.aZ)(t),(0,i.useCallback)(e=>{if(!t)return;let n=new URLSearchParams(o.location.search);n.set(t,e),o.replace({...o.location,search:n.toString()})},[t,o])]}({queryString:t,groupId:s}),[y,g]=function({groupId:e}){let n=e?`docusaurus.tab.${e}`:null,[o,t]=(0,h.Dv)(n);return[o,(0,i.useCallback)(e=>{n&&t.set(e)},[n,t])]}({groupId:s}),f=m({value:n=x??y,tabValues:l})?n:null;return(0,c.A)(()=>{f&&w(f)},[f]),{selectedValue:r,selectValue:(0,i.useCallback)(e=>{if(!m({value:e,tabValues:l}))throw Error(`Can't select invalid tab value=${e}`);w(e),b(e),g(e)},[b,g,l]),tabValues:l}}(e);return(0,t.jsxs)("div",{className:(0,s.A)(l.G.tabs.container,"tabs-container","tabList_HImo"),children:[(0,t.jsx)(x,{...n,...e}),(0,t.jsx)(b,{...n,...e})]})}function g(e){let n=(0,w.A)();return(0,t.jsx)(y,{...e,children:u(e.children)},String(n))}},17869:function(e,n,o){o.d(n,{R:()=>l,x:()=>r});var t=o(82645);let i={},s=t.createContext(i);function l(e){let n=t.useContext(s);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),t.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.