본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

기본 정책 데모

원문 보기 위키 갱신

Calico for Windows 클러스터에서 기본적인 파드 간 연결성과 네트워크 정책 적용을 보여 주는 데모예요. Linux 노드와 Windows 노드에 클라이언트·서버 파드를 만들고, 파드 간 연결을 확인한 다음, 기본 네트워크 정책을 적용해 파드 트래픽을 격리해 봐요. bash와 PowerShell 두 가지 탭으로 절차가 나뉘어 있으니 본인 환경에 맞는 탭을 따라가면 돼요.

출처: 문서

본문

사전 준비

이 데모를 실행하려면 Windows Server 1809(build 17763.1432, 2020년 8월 업데이트 이상)가 설치된 Calico for Windows 클러스터가 필요해요. 더 최신 버전의 Windows Server도 데모 매니페스트를 살짝 바꾸면 사용할 수 있어요. 구체적으로는 Windows 이미지의 버전 태그, 예를 들어 servercore:1809 대신 servercore:ltsc2022 같은 식으로요.

SECONDARY: Windows Server 1809(build 17763.1432보다 오래된)는 direct server return을 지원하지 않아요. 즉 정책 지원이 파드 IP 주소로만 제한된다는 뜻이에요.

Tab: bash

Linux 노드에 파드 만들기

먼저 Linux 노드에 클라이언트(busybox)와 서버(nginx) 파드를 만들어요:

kubectl apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
  name: calico-demo

---

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: busybox
  name: busybox
  namespace: calico-demo
spec:
  containers:
  - args:
    - /bin/sh
    - -c
    - sleep 360000
    image: busybox:1.28
    imagePullPolicy: Always
    name: busybox
  nodeSelector:
    kubernetes.io/os: linux

---

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: calico-demo
spec:
  containers:
  - name: nginx
    image: nginx:1.8
    ports:
    - containerPort: 80
  nodeSelector:
    kubernetes.io/os: linux
EOF

Windows 노드에 파드 만들기

다음으로 Windows 노드에 클라이언트(powershell)와 서버(porter) 파드를 만들 거예요. 먼저 powershell 파드를 만들어요.

SECONDARY: 아래의 powershell과 porter 파드 매니페스트는 mcr.microsoft.com/windows/servercore:1809 기반 이미지를 사용해요. 더 최신 Windows Server 버전을 사용한다면, 사용 중인 Windows Server 버전에 맞는 servercore 이미지로 매니페스트를 업데이트하세요.

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: pwsh
  namespace: calico-demo
  labels:
    app: pwsh
spec:
  containers:
  - name: pwsh
    image: mcr.microsoft.com/windows/servercore:1809
    args:
    - powershell.exe
    - -Command
    - "Start-Sleep 360000"
    imagePullPolicy: IfNotPresent
  nodeSelector:
    kubernetes.io/os: windows
EOF

다음으로 porter 서버 파드를 만들어요:

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: porter
  namespace: calico-demo
  labels:
    app: porter
spec:
  containers:
  - name: porter
    image: calico/porter:1809
    ports:
    - containerPort: 80
    env:
    - name: SERVE_PORT_80
      value: This is a Calico for Windows demo.
    imagePullPolicy: IfNotPresent
  nodeSelector:
    kubernetes.io/os: windows
EOF

Linux 노드와 Windows 노드의 파드 간 연결 확인하기

이제 Linux와 Windows 노드 양쪽에서 클라이언트·서버 파드가 실행 중이니, Linux 노드의 클라이언트 파드가 Windows 노드의 서버 파드에 도달할 수 있는지 확인해 볼게요. 먼저 porter 파드 IP가 필요해요:

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

그다음 busybox 파드로 접속해서 porter 파드의 80 포트에 도달해 봐요:

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

위 두 단계를 한 번에 합치면:

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

busybox 파드에서 porter 파드로의 연결이 성공하면 다음과 비슷한 출력이 나와요:

192.168.40.166 (192.168.40.166:80) open

이제 powershell 파드가 nginx 파드에 도달할 수 있는지 확인해 봐요:

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

연결이 성공하면 다음과 비슷한 출력이 나와요:

StatusCode        : 200
StatusDescription : OK
Content           : <!DOCTYPE html>
                    <html>
                    <head>
                    <title>Welcome to nginx!</title>
                    <style>
                        body {
                            width: 35em;
                            margin: 0 auto;
                            font-family: Tahoma, Verdana, Arial, sans-serif;
                        }
                    </style>
                    <...
...

마지막으로 powershell 파드가 porter 파드에 도달할 수 있는지 확인해 봐요:

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

성공하면 다음과 같은 내용이 보여요:

StatusCode        : 200
StatusDescription : OK
Content           : This is a Calico for Windows demo.
RawContent        : HTTP/1.1 200 OK
                    Content-Length: 49
                    Content-Type: text/plain; charset=utf-8
                    Date: Fri, 21 Aug 2020 22:45:46 GMT

                    This is a Calico for Windows demo.
Forms             :
Headers           : {[Content-Length, 49], [Content-Type, text/plain;
                    charset=utf-8], [Date, Fri, 21 Aug 2020 22:45:46 GMT]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        :
RawContentLength  : 49

Windows 클라이언트 파드에 정책 적용하기

이제 busybox 파드만 porter 파드에 도달할 수 있도록 허용하는 기본 네트워크 정책을 적용해 볼게요.

kubectl apply -f - <<EOF
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-busybox
  namespace: calico-demo
spec:
  selector: app == 'porter'
  types:
  - Ingress
  ingress:
  - action: Allow
    protocol: TCP
    source:
      selector: app == 'busybox'
EOF

정책이 적용되면 busybox 파드는 여전히 porter 파드에 도달할 수 있어요:

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

하지만 powershell 파드는 porter 파드에 도달할 수 없어요:

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

요청이 다음과 같은 메시지와 함께 시간 초과돼요:

Invoke-WebRequest : The operation has timed out.
At line:1 char:1
+ Invoke-WebRequest -Uri http://192.168.40.166 -UseBasicParsing -Timeou ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:Htt
   pWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShe
   ll.Commands.InvokeWebRequestCommand

command terminated with exit code 1

마무리

이 데모에서는 Linux와 Windows 노드에 파드를 띄우고, 기본 파드 연결성을 확인하고, 파드 간 트래픽을 격리하는 기본 네트워크 정책을 적용해 봤어요. 마지막으로 데모 리소스를 모두 정리할 수 있어요:

kubectl delete ns calico-demo

Tab: PowerShell

Windows에 kubectl 설치하기

이 데모의 명령어를 실행하려면 Windows용 kubectl이 설치되어 있고 시스템 경로에 추가되어 있어야 해요. kubectl을 설치하고 kubectl 바이너리를 c:\k로 옮기세요.

c:\k를 시스템 경로에 추가하기

  1. 관리자 권한으로 PowerShell 창을 열어요

    $env:Path += ";C:\k"
    
  2. 모든 PowerShell 창을 닫아요.

Linux 노드에 파드 만들기

먼저 Linux 노드에 클라이언트(busybox)와 서버(nginx) 파드를 만들어요.

Windows에서 선호하는 편집기로 policy-demo-linux.yaml 파일 만들기

apiVersion: v1
kind: Namespace
metadata:
  name: calico-demo

---
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: busybox
  name: busybox
  namespace: calico-demo
spec:
  containers:
    - args:
        - /bin/sh
        - -c
        - sleep 360000
      image: busybox:1.28
      imagePullPolicy: Always
      name: busybox
  nodeSelector:
    kubernetes.io/os: linux

---
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: calico-demo
spec:
  containers:
    - name: nginx
      image: nginx:1.8
      ports:
        - containerPort: 80
  nodeSelector:
    kubernetes.io/os: linux

policy-demo-linux.yaml 파일을 Kubernetes 클러스터에 적용하기

  1. PowerShell 창을 열어요.
  2. kubectl로 policy-demo-linux.yaml 구성을 적용해요.
kubectl apply -f policy-demo-linux.yaml

Windows 노드에 파드 만들기

다음으로 Windows 노드에 클라이언트(pwsh)와 서버(porter) 파드를 만들 거예요.

SECONDARY: 아래의 pwsh와 porter 파드 매니페스트는 mcr.microsoft.com/windows/servercore:1809 기반 이미지를 사용해요. 더 최신 Windows Server 버전을 사용한다면, 사용 중인 Windows Server 버전에 맞는 servercore 이미지로 매니페스트를 업데이트하세요.

Windows에서 선호하는 편집기로 policy-demo-windows.yaml 만들기

apiVersion: v1
kind: Pod
metadata:
  name: pwsh
  namespace: calico-demo
  labels:
    app: pwsh
spec:
  containers:
    - name: pwsh
      image: mcr.microsoft.com/windows/servercore:1809
      args:
        - powershell.exe
        - -Command
        - 'Start-Sleep 360000'
      imagePullPolicy: IfNotPresent
  nodeSelector:
    kubernetes.io/os: windows
---
apiVersion: v1
kind: Pod
metadata:
  name: porter
  namespace: calico-demo
  labels:
    app: porter
spec:
  containers:
    - name: porter
      image: calico/porter:1809
      ports:
        - containerPort: 80
      env:
        - name: SERVE_PORT_80
          value: This is a Calico for Windows demo.
      imagePullPolicy: IfNotPresent
  nodeSelector:
    kubernetes.io/os: windows

policy-demo-windows.yaml 파일을 Kubernetes 클러스터에 적용하기

  1. PowerShell 창을 열어요.
  2. kubectl로 policy-demo-windows.yaml 구성을 적용해요
kubectl apply -f policy-demo-windows.yaml

네 개의 파드가 만들어지고 실행 중인지 확인하기

SECONDARY: Windows 파드를 띄우는 시간은 네트워크 다운로드 속도에 따라 다소 걸릴 수 있어요.

  1. PowerShell 창을 열어요.
  2. kubectl로 calico-demo 네임스페이스의 파드를 나열해요.
kubectl get pods --namespace calico-demo

아래와 비슷한 결과가 보일 거예요

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

4개 파드가 모두 Running 상태로 표시될 때까지 몇 분마다 명령을 반복하세요.

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

Linux 노드와 Windows 노드의 파드 간 연결 확인하기

이제 Linux와 Windows 노드 양쪽에서 클라이언트·서버 파드가 실행 중이니, Linux 노드의 클라이언트 파드가 Windows 노드의 서버 파드에 도달할 수 있는지 확인해 볼게요.

  1. PowerShell 창을 열어요.

  2. kubectl로 porter 파드의 IP 주소를 알아내요:

    kubectl get pod porter --namespace calico-demo -o 'jsonpath={.status.podIP}'
    
  3. busybox 파드에 접속해서 porter 파드의 80 포트에 도달해 보세요. <porter_ip> 자리에는 이전 명령이 반환한 IP 주소를 넣으세요.

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

    SECONDARY: 위 두 단계를 합칠 수도 있어요:

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

    busybox 파드에서 porter 파드로의 연결이 성공하면 다음과 비슷한 출력이 나와요:

    192.168.40.166 (192.168.40.166:80) open
    

    SECONDARY: 반환되는 IP 주소는 환경 설정에 따라 달라져요.

  4. 이제 pwsh 파드가 nginx 파드에 도달할 수 있는지 확인할 수 있어요:

    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
    

    연결이 성공하면 다음과 비슷한 출력이 보여요:

    StatusCode        : 200
    StatusDescription : OK
    Content           : <!DOCTYPE html>
                        <html>
                        <head>
                        <title>Welcome to nginx!</title>
                        <style>
                            body {
                                width: 35em;
                                margin: 0 auto;
                                font-family: Tahoma, Verdana, Arial, sans-serif;
                            }
                        </style>
                        <...
    
  5. pwsh 파드가 porter 파드에 도달할 수 있는지 확인해요:

    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
    

    성공하면 다음과 같은 내용이 보여요:

    StatusCode        : 200
    StatusDescription : OK
    Content           : This is a Calico for Windows demo.
    RawContent        : HTTP/1.1 200 OK
                        Content-Length: 49
                        Content-Type: text/plain; charset=utf-8
                        Date: Fri, 21 Aug 2020 22:45:46 GMT
    
                        This is a Calico for Windows demo.
    Forms             :
    Headers           : {[Content-Length, 49], [Content-Type, text/plain;
                        charset=utf-8], [Date, Fri, 21 Aug 2020 22:45:46 GMT]}
    Images            : {}
    InputFields       : {}
    Links             : {}
    ParsedHtml        :
    RawContentLength  : 49
    
    

이제 애플리케이션의 모든 파드 사이에 통신이 가능하다는 걸 확인했어요.

Windows 클라이언트 파드에 정책 적용하기

실제 배포 환경에서는 서로 통신해야 하는 파드만 실제로 통신이 허용되도록 만들고 싶을 거예요.

이를 위해 busybox 파드만 porter 파드에 도달할 수 있도록 허용하는 기본 네트워크 정책을 적용할 거예요.

Windows에서 선호하는 편집기로 network-policy.yaml 파일 만들기

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-busybox
  namespace: calico-demo
spec:
  podSelector:
    matchLabels:
      app: porter
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: busybox
      ports:
        - protocol: TCP
          port: 80

network-policy.yaml 파일 적용하기

  1. PowerShell 창을 열어요.
  2. kubectl로 network-policy.yaml 파일을 적용해요.
kubectl apply -f network-policy.yaml

정책이 적용되었는지 확인하기

정책이 적용되면 busybox 파드는 여전히 porter 파드에 도달할 수 있어요:

SECONDARY: 이 장의 앞에서 다룬 합쳐진 명령줄을 사용할 거예요.

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

하지만 pwsh 파드는 porter 파드에 도달할 수 없어요:

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

요청이 다음과 같은 메시지와 함께 시간 초과돼요:

Invoke-WebRequest : The operation has timed out.
At line:1 char:1
+ Invoke-WebRequest -Uri http://192.168.40.166 -UseBasicParsing -Timeout ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:Htt
pWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
command terminated with exit code 1

마무리

이 데모에서는 Linux와 Windows 노드에 파드를 구성하고, 기본 파드 연결성을 확인하고, 파드 간 트래픽을 격리하는 기본 네트워크 정책을 적용해 봤어요. 마지막 단계로 데모 리소스를 모두 정리할 수 있어요:

  1. PowerShell 창을 열어요.
kubectl delete namespace calico-demo

더 알아보기 (Learn more)

이 데모의 핵심은 Calico 정책(projectcalico.org/v3 NetworkPolicy)이 Linux 파드에서 Windows 파드로 향하는 트래픽까지 똑같이 제어한다는 점이에요. 정책 적용 후에는 허용된 클라이언트(busybox)는 연결이 유지되고 허용되지 않은 클라이언트(pwsh)는 타임아웃되는 걸 직접 확인할 수 있죠. Windows Server 1809 이전 빌드는 direct server return 미지원 때문에 정책이 파드 IP에만 동작한다는 제약도 기억하세요.