Basic policy demo

    To run this demo, you will need a with Windows 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.

    note

    Windows Server 1809 (build older than 17763.1432) do not support direct server return. This means that policy support is limited to only pod IP addresses.

    • bash
    • PowerShell

    Create pods on Linux nodes

    First, create a client (busybox) and server (nginx) pod on the Linux nodes:

    Create pods on Window nodes

    Next, we’ll create a client (powershell) and server (porter) pod on the Windows nodes. First the create the powershell pod.

    Basic policy demo - 图2note

    The powershell and porter pod manifests below use images based on . If you are using a more recent Windows Server version, update the manifests to use a that matches your Windows Server version.

    1. kubectl apply -f - <<EOF
    2. apiVersion: v1
    3. kind: Pod
    4. metadata:
    5. name: pwsh
    6. namespace: calico-demo
    7. labels:
    8. app: pwsh
    9. spec:
    10. containers:
    11. - name: pwsh
    12. image: mcr.microsoft.com/windows/servercore:1809
    13. args:
    14. - powershell.exe
    15. - -Command
    16. - "Start-Sleep 360000"
    17. imagePullPolicy: IfNotPresent
    18. nodeSelector:
    19. kubernetes.io/os: windows
    20. EOF

    Next, we’ll create the porter server pod:

    1. kubectl apply -f - <<EOF
    2. apiVersion: v1
    3. kind: Pod
    4. metadata:
    5. name: porter
    6. namespace: calico-demo
    7. labels:
    8. app: porter
    9. spec:
    10. containers:
    11. - name: porter
    12. image: calico/porter:1809
    13. ports:
    14. - containerPort: 80
    15. env:
    16. - name: SERVE_PORT_80
    17. value: This is a Calico for Windows demo.
    18. imagePullPolicy: IfNotPresent
    19. nodeSelector:
    20. kubernetes.io/os: windows
    21. EOF

    Now that client and server pods are running on both Linux and Windows nodes, let’s verify that client pods on Linux nodes can reach server pods on Windows nodes. First, we will need the porter pod IP:

    1. kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}'

    Then we can exec into the busybox pod and try reaching the porter pod on port 80:

    1. kubectl exec -n calico-demo busybox -- nc -vz <porter_ip> 80

    To combine both of the above steps:

    1. kubectl exec -n calico-demo busybox -- nc -vz $(kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}') 80

    If the connection from the busybox pod to the porter pod succeeds, we will get output similar to the following:

    1. 192.168.40.166 (192.168.40.166:80) open

    Now let’s verify that the powershell pod can reach the nginx pod:

    1. 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

    If the connection succeeds, we will get output similar to:

    1. StatusCode : 200
    2. StatusDescription : OK
    3. Content : <!DOCTYPE html>
    4. <html>
    5. <head>
    6. <title>Welcome to nginx!</title>
    7. <style>
    8. body {
    9. width: 35em;
    10. margin: 0 auto;
    11. font-family: Tahoma, Verdana, Arial, sans-serif;
    12. }
    13. </style>
    14. <...
    15. ...

    Finally, let’s verify that the powershell pod can reach the porter pod:

    1. 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

    If that succeeds, we will see something like:

    1. StatusCode : 200
    2. StatusDescription : OK
    3. Content : This is a Calico for Windows demo.
    4. RawContent : HTTP/1.1 200 OK
    5. Content-Length: 49
    6. Content-Type: text/plain; charset=utf-8
    7. Date: Fri, 21 Aug 2020 22:45:46 GMT
    8. This is a Calico for Windows demo.
    9. Forms :
    10. Headers : {[Content-Length, 49], [Content-Type, text/plain;
    11. charset=utf-8], [Date, Fri, 21 Aug 2020 22:45:46 GMT]}
    12. Images : {}
    13. InputFields : {}
    14. ParsedHtml :
    15. RawContentLength : 49

    Apply policy to the Windows client pod

    Now let’s apply a basic network policy that allows only the busybox pod to reach the porter pod.

    1. calicoctl apply -f - <<EOF
    2. apiVersion: projectcalico.org/v3
    3. kind: NetworkPolicy
    4. metadata:
    5. name: allow-busybox
    6. namespace: calico-demo
    7. spec:
    8. selector: app == 'porter'
    9. types:
    10. ingress:
    11. - action: Allow
    12. protocol: TCP
    13. source:
    14. selector: app == 'busybox'
    15. EOF

    However, the powershell pod will not able to reach the porter pod:

    1. 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

    The request times out with a message like:

    1. Invoke-WebRequest : The operation has timed out.
    2. At line:1 char:1
    3. + Invoke-WebRequest -Uri http://192.168.40.166 -UseBasicParsing -Timeou ...
    4. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    5. + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:Htt
    6. pWebRequest) [Invoke-WebRequest], WebException
    7. + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShe
    8. ll.Commands.InvokeWebRequestCommand
    9. command terminated with exit code 1

    Wrap up

    In this demo we’ve brought up pods on Linux and Windows nodes, verified basic pod connectivity, and tried a basic network policy to isolate pod to pod traffic. Finally, we can clean up all of our demo resources:

    1. kubectl delete ns calico-demo

    To run the commands in this demo you need the Windows version of kubectl installed and add it to the system path. Install kubectl and move the kubectl binary to c:\k.

    Add c:\k to the system path

    1. Open a PowerShell window as Administrator

      1. $env:Path += ";C:\k"
    2. Close all PowerShell windows.

    Create pods on Linux nodes

    First, create a client (busybox) and server (nginx) pod on the Linux nodes.

    1. apiVersion: v1
    2. kind: Namespace
    3. metadata:
    4. name: calico-demo
    5. ---
    6. apiVersion: v1
    7. kind: Pod
    8. metadata:
    9. labels:
    10. app: busybox
    11. name: busybox
    12. namespace: calico-demo
    13. spec:
    14. containers:
    15. - args:
    16. - /bin/sh
    17. - -c
    18. - sleep 360000
    19. image: busybox:1.28
    20. imagePullPolicy: Always
    21. name: busybox
    22. nodeSelector:
    23. beta.kubernetes.io/os: linux
    24. ---
    25. apiVersion: v1
    26. kind: Pod
    27. metadata:
    28. labels:
    29. app: nginx
    30. name: nginx
    31. namespace: calico-demo
    32. spec:
    33. containers:
    34. - name: nginx
    35. image: nginx:1.8
    36. ports:
    37. - containerPort: 80
    38. nodeSelector:
    39. beta.kubernetes.io/os: linux

    Apply the policy-demo-linux.yaml file to the Kubernetes cluster

    1. Open a PowerShell window.
    2. Use kubectl to apply the policy-demo-linux.yaml configuration.
    1. kubectl apply -f policy-demo-linux.yaml

    Create pods on Window nodes

    Next, we’ll create a client (pwsh) and server (porter) pod on the Windows nodes.

    note

    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.

    Create the policy-demo-windows.yaml using your favorite editor on Windows

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: pwsh
    5. namespace: calico-demo
    6. labels:
    7. app: pwsh
    8. spec:
    9. containers:
    10. - name: pwsh
    11. image: mcr.microsoft.com/windows/servercore:1809
    12. args:
    13. - powershell.exe
    14. - -Command
    15. - 'Start-Sleep 360000'
    16. imagePullPolicy: IfNotPresent
    17. nodeSelector:
    18. kubernetes.io/os: windows
    19. ---
    20. apiVersion: v1
    21. kind: Pod
    22. name: porter
    23. namespace: calico-demo
    24. app: porter
    25. spec:
    26. containers:
    27. - name: porter
    28. image: calico/porter:1809
    29. ports:
    30. - containerPort: 80
    31. env:
    32. - name: SERVE_PORT_80
    33. value: This is a Calico for Windows demo.
    34. imagePullPolicy: IfNotPresent
    35. nodeSelector:
    36. kubernetes.io/os: windows
    1. Open a PowerShell window.
    2. Use kubectl to apply the policy-demo-windows.yaml configuration
    1. kubectl apply -f policy-demo-windows.yaml

    Verify four pods have been created and are running

    Basic policy demo - 图4note

    Launching the Windows pods is going to take some time depending on your network download speed.

    1. Open a PowerShell window.
    2. Using kubectl to list the pods in the calico-demo namespace.
    1. kubectl get pods --namespace calico-demo

    You should see something like the below

    1. NAME READY STATUS RESTARTS AGE
    2. busybox 1/1 Running 0 4m14s
    3. nginx 1/1 Running 0 4m14s
    4. porter 0/1 ContainerCreating 0 74s
    5. pwsh 0/1 ContainerCreating 0 2m9s

    Repeat the command every few minutes until the output shows all 4 pods in the Running state.

    1. NAME READY STATUS RESTARTS AGE
    2. busybox 1/1 Running 0 7m24s
    3. nginx 1/1 Running 0 7m24s
    4. porter 1/1 Running 0 4m24s
    5. pwsh 1/1 Running 0 5m19s

    Check connectivity between pods on Linux and Windows nodes

    Now that client and server pods are running on both Linux and Windows nodes, let’s verify that client pods on Linux nodes can reach server pods on Windows nodes.

    1. Open a PowerShell window.

    2. Log into the busybox pod and try reaching the porter pod on port 80. Replace the ‘<porter_ip>’ tag with the IP address returned from the previous command.

      1. kubectl exec --namespace calico-demo busybox -- nc -vz <porter_ip> 80

      note

      You can also combine both of the above steps:

      1. kubectl exec --namespace calico-demo busybox -- nc -vz $(kubectl get pod porter --namespace calico-demo -o 'jsonpath={.status.podIP}') 80

      If the connection from the busybox pod to the porter pod succeeds, you will get output similar to the following:

      1. 192.168.40.166 (192.168.40.166:80) open

      Basic policy demo - 图6note

      The IP addresses returned will vary depending on your environment setup.

    3. Now you can verify that the pwsh pod can reach the nginx pod:

      1. 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

      If the connection succeeds, you will see output similar to:

      1. StatusCode : 200
      2. StatusDescription : OK
      3. Content : <!DOCTYPE html>
      4. <html>
      5. <head>
      6. <title>Welcome to nginx!</title>
      7. <style>
      8. body {
      9. width: 35em;
      10. margin: 0 auto;
      11. font-family: Tahoma, Verdana, Arial, sans-serif;
      12. }
      13. </style>
      14. <...
    4. Verify that the pwsh pod can reach the porter pod:

      1. 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

      If that succeeds, you will see something like:

      1. StatusCode : 200
      2. StatusDescription : OK
      3. Content : This is a Calico for Windows demo.
      4. RawContent : HTTP/1.1 200 OK
      5. Content-Length: 49
      6. Content-Type: text/plain; charset=utf-8
      7. Date: Fri, 21 Aug 2020 22:45:46 GMT
      8. This is a Calico for Windows demo.
      9. Forms :
      10. Headers : {[Content-Length, 49], [Content-Type, text/plain;
      11. charset=utf-8], [Date, Fri, 21 Aug 2020 22:45:46 GMT]}
      12. Images : {}
      13. InputFields : {}
      14. Links : {}
      15. ParsedHtml :
      16. RawContentLength : 49

    You have now verified that communication is possible between all pods in the application.

    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.

    To achieve this you will apply a basic network policy which allows only the busybox pod to reach the porter pod.

    1. apiVersion: networking.k8s.io/v1
    2. kind: NetworkPolicy
    3. metadata:
    4. name: allow-busybox
    5. namespace: calico-demo
    6. spec:
    7. podSelector:
    8. matchLabels:
    9. app: porter
    10. policyTypes:
    11. - Ingress
    12. ingress:
    13. - from:
    14. - podSelector:
    15. matchLabels:
    16. app: busybox
    17. ports:
    18. - protocol: TCP
    19. port: 80

    Apply the network-policy.yaml file

    1. Open a PowerShell window.
    2. Use kubectl to apply the network-policy.yaml file.
    1. kubectl apply -f network-policy.yaml

    Verify the policy is in effect

    With the policy in place, the busybox pod should still be able to reach the porter pod:

    note

    We will be using the combined command line from earlier in this chapter.

    1. kubectl exec --namespace calico-demo busybox -- nc -vz $(kubectl get po porter -n calico-demo -o 'jsonpath={.status.podIP}') 80

    However, the pwsh pod will not able to reach the porter pod:

    Wrap up

    In this demo we’ve configured pods on Linux and Windows nodes, verified basic pod connectivity, and tried a basic network policy to isolate pod to pod traffic. As the final step you can clean up all of the demo resources:

    1. Open a PowerShell window.