기본 정책 데모
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를 시스템 경로에 추가하기
-
관리자 권한으로 PowerShell 창을 열어요
$env:Path += ";C:\k" -
모든 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 클러스터에 적용하기
- PowerShell 창을 열어요.
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 클러스터에 적용하기
- PowerShell 창을 열어요.
kubectl로policy-demo-windows.yaml구성을 적용해요
kubectl apply -f policy-demo-windows.yaml
네 개의 파드가 만들어지고 실행 중인지 확인하기
SECONDARY: Windows 파드를 띄우는 시간은 네트워크 다운로드 속도에 따라 다소 걸릴 수 있어요.
- PowerShell 창을 열어요.
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 노드의 서버 파드에 도달할 수 있는지 확인해 볼게요.
-
PowerShell 창을 열어요.
-
kubectl로 porter 파드의 IP 주소를 알아내요:kubectl get pod porter --namespace calico-demo -o 'jsonpath={.status.podIP}' -
busybox 파드에 접속해서 porter 파드의 80 포트에 도달해 보세요.
<porter_ip>자리에는 이전 명령이 반환한 IP 주소를 넣으세요.kubectl exec --namespace calico-demo busybox -- nc -vz <porter_ip> 80SECONDARY: 위 두 단계를 합칠 수도 있어요:
kubectl exec --namespace calico-demo busybox -- nc -vz $(kubectl get pod porter --namespace calico-demo -o 'jsonpath={.status.podIP}') 80busybox 파드에서 porter 파드로의 연결이 성공하면 다음과 비슷한 출력이 나와요:
192.168.40.166 (192.168.40.166:80) openSECONDARY: 반환되는 IP 주소는 환경 설정에 따라 달라져요.
-
이제 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> <... -
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 파일 적용하기
- PowerShell 창을 열어요.
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 노드에 파드를 구성하고, 기본 파드 연결성을 확인하고, 파드 간 트래픽을 격리하는 기본 네트워크 정책을 적용해 봤어요. 마지막 단계로 데모 리소스를 모두 정리할 수 있어요:
- PowerShell 창을 열어요.
kubectl delete namespace calico-demo
더 알아보기 (Learn more)
이 데모의 핵심은 Calico 정책(projectcalico.org/v3 NetworkPolicy)이 Linux 파드에서 Windows 파드로 향하는 트래픽까지 똑같이 제어한다는 점이에요. 정책 적용 후에는 허용된 클라이언트(busybox)는 연결이 유지되고 허용되지 않은 클라이언트(pwsh)는 타임아웃되는 걸 직접 확인할 수 있죠. Windows Server 1809 이전 빌드는 direct server return 미지원 때문에 정책이 파드 IP에만 동작한다는 제약도 기억하세요.