Kubernetes 정책, 고급 튜토리얼
Kubernetes NetworkPolicy API로 레이블과 포트를 기준으로 파드에 적용되는 ingress/egress 정책(Kubernetes 1.8.0부터 지원)을 표현할 수 있어요. 이 가이드는 Kubernetes NetworkPolicy를 사용해 더 복잡한 네트워크 정책을 정의하는 방법을 다뤄요. 전체 ingress 차단부터 DNS 허용, nginx 접근 허용까지 단계별로 따라 해 보세요.
출처: 문서
본문
Kubernetes NetworkPolicy API는 사용자가 레이블과 포트를 기준으로 Kubernetes 파드에 적용되는 ingress/egress 정책(Kubernetes 1.8.0부터 지원)을 표현할 수 있게 해 줘요.
이 가이드는 Kubernetes NetworkPolicy를 사용해서 더 복잡한 네트워크 정책을 정의하는 방법을 설명해요.
요구 사항
- 동작하는 Kubernetes 클러스터와 kubectl로 접근할 수 있는 환경
- Kubernetes 노드가 퍼블릭 인터넷에 연결돼 있어야 해요
- Kubernetes NetworkPolicy에 대해 이미 알고 있어야 해요
튜토리얼 흐름
- 네임스페이스와 Nginx 서비스 만들기
- 모든 ingress 트래픽 차단
- Nginx로의 ingress 트래픽 허용
- 모든 egress 트래픽 차단
- kube-dns로의 egress 트래픽 허용
- 네임스페이스 정리
1. 네임스페이스와 nginx 서비스 만들기
이 가이드에서는 새 네임스페이스를 사용해요. 다음 명령으로 네임스페이스와, 포트 80에서 대기하는 평범한 nginx 서비스를 만들어요.
kubectl create ns advanced-policy-demo
kubectl create deployment --namespace=advanced-policy-demo nginx --image=nginx
kubectl expose --namespace=advanced-policy-demo deployment nginx --port=80
접근 확인 - ingress/egress 모두 허용 상태
kubectl로 Kubernetes 클러스터에 접근할 수 있는 다른 셸 세션을 열고, 정책 접근 테스트용 busybox 파드를 만들어요. 이 파드는 이 튜토리얼 전반에서 정책 접근을 테스트하는 데 계속 사용돼요.
kubectl run --namespace=advanced-policy-demo access --rm -ti --image busybox /bin/sh
아래처럼 access 파드 안에 셸 세션이 열려야 해요.
Waiting for pod advanced-policy-demo/access-472357175-y0m47 to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
/ #
이제 busybox "access" 파드 안에서 다음 명령을 실행해 nginx 서비스 접근을 테스트해요.
wget -q --timeout=5 nginx -O -
nginx 웰컴 페이지의 HTML이 반환되어야 해요.
busybox "access" 파드 안에서 이어서 다음 명령을 실행해 google.com 접근을 테스트해요.
wget -q --timeout=5 google.com -O -
google.com 홈 페이지의 HTML이 반환되어야 해요.
2. 모든 ingress 트래픽 차단
기본적으로 모든 ingress 트래픽을 차단하는 정책을 배포해서 네임스페이스에 ingress 격리를 활성화해요.
kubectl create -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: advanced-policy-demo
spec:
podSelector:
matchLabels: {}
policyTypes:
- Ingress
EOF
접근 확인 - 모든 ingress 차단, 모든 egress 허용
이제 네임스페이스의 모든 파드가 선택되기 때문에, 정책이 명시적으로 허용하지 않는 ingress 트래픽은 모두 거부돼요.
네임스페이스의 "access" 파드로 넘어가서 nginx 서비스에 접근을 시도하면 실제로 그런지 확인할 수 있어요.
wget -q --timeout=5 nginx -O -
다음이 반환되어야 해요:
wget: download timed out
이어서 google.com에 접근해 보세요.
wget -q --timeout=5 google.com -O -
다음이 반환되어야 해요:
<!doctype html><html itemscope="" item....
nginx 서비스로의 ingress 접근은 차단되지만, 외부 인터넷으로 나가는 egress 접근은 여전히 허용된다는 걸 알 수 있어요.
3. Nginx로의 ingress 트래픽 허용
다음을 실행해서 advanced-policy-demo 네임스페이스 안의 어떤 파드에서든 nginx 파드로 향하는 트래픽을 허용하는 NetworkPolicy를 만들어요.
kubectl create -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: access-nginx
namespace: advanced-policy-demo
spec:
podSelector:
matchLabels:
app: nginx
ingress:
- from:
- podSelector:
matchLabels: {}
EOF
접근 확인 - nginx ingress 허용
이제 nginx로 향하는 ingress 트래픽이 허용돼요. 네임스페이스의 "access" 파드로 넘어가서 nginx 서비스에 접근을 시도하면 실제로 그런지 확인할 수 있어요.
wget -q --timeout=5 nginx -O -
다음이 반환되어야 해요:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>...
정책을 만든 후에는 nginx Service에 접근할 수 있어요.
4. 모든 egress 트래픽 차단
기본적으로 모든 egress 트래픽을 차단하는 정책을 배포해서 네임스페이스에 egress 격리를 활성화해요.
kubectl create -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: advanced-policy-demo
spec:
podSelector:
matchLabels: {}
policyTypes:
- Egress
EOF
접근 확인 - 모든 egress 차단
이제 정책이 명시적으로 허용하지 않는 ingress/egress 트래픽은 모두 거부돼요.
네임스페이스의 "access" 파드로 넘어가서 nginx를 nslookup하거나 google.com을 wget해 보면 실제로 그런지 확인할 수 있어요.
nslookup nginx
다음과 비슷한 결과가 반환되어야 해요.
Server: 10.96.0.10
Address 1: 10.96.0.10
nslookup: can't resolve 'nginx'
이어서 google.com에 접근해 보세요.
wget -q --timeout=5 google.com -O -
다음이 반환되어야 해요:
wget: bad address 'google.com'
SECONDARY:
nslookup명령은 타임아웃까지 1분 이상 걸릴 수 있어요.
5. DNS egress 트래픽 허용
다음을 실행해서 kube-system 네임스페이스에 name: kube-system 레이블을 붙이고, advanced-policy-demo 네임스페이스의 어떤 파드에서든 kube-system 네임스페이스로 향하는 DNS egress 트래픽을 허용하는 NetworkPolicy를 만들어요.
kubectl label namespace kube-system name=kube-system
kubectl create -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-access
namespace: advanced-policy-demo
spec:
podSelector:
matchLabels: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
EOF
접근 확인 - DNS 접근 허용
이제 DNS로 향하는 egress 트래픽이 허용돼요.
네임스페이스의 "access" 파드로 넘어가서 nginx와 google.com 조회를 시도하면 실제로 그런지 확인할 수 있어요.
nslookup nginx
다음과 비슷한 결과가 반환되어야 해요.
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
이어서 google.com을 조회해 보세요.
nslookup google.com
다음과 비슷한 결과가 반환되어야 해요.
Name: google.com
Address 1: 2607:f8b0:4005:807::200e sfo07s16-in-x0e.1e100.net
Address 2: 216.58.195.78 sfo07s16-in-f14.1e100.net
DNS egress 트래픽은 이제 동작하지만, advanced-policy-demo 네임스페이스의 모든 파드에서 나가는 나머지 egress 트래픽은 여전히 차단돼요. 그래서 wget 호출이 만들어내는 HTTP egress 트래픽은 여전히 실패해요.
6. nginx로의 egress 트래픽 허용
다음을 실행해서 advanced-policy-demo 네임스페이스의 어떤 파드에서든, 같은 네임스페이스 안에서 app: nginx 레이블과 일치하는 파드로 향하는 egress 트래픽을 허용하는 NetworkPolicy를 만들어요.
kubectl create -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-to-advance-policy-ns
namespace: advanced-policy-demo
spec:
podSelector:
matchLabels: {}
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: nginx
EOF
접근 확인 - nginx로의 egress 접근 허용
네임스페이스의 "access" 파드로 넘어가서 nginx에 접근을 시도하면 실제로 그런지 확인할 수 있어요.
wget -q --timeout=5 nginx -O -
nginx 웰컴 페이지의 HTML이 반환되어야 해요.
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>...
이어서 google.com 홈 페이지를 가져와 보세요.
wget -q --timeout=5 google.com -O -
다음이 반환되어야 해요:
wget: download timed out
google.com 접근이 타임아웃되는 이유는, DNS 조회는 되지만 advanced-policy-demo 네임스페이스 안에서 app: nginx 레이블과 일치하는 파드 외에는 egress 접근이 전혀 허용되지 않기 때문이에요.
7. 네임스페이스 정리
advanced policy demo 네임스페이스를 삭제하면 이 튜토리얼을 마무리 정리할 수 있어요.
kubectl delete ns advanced-policy-demo
더 알아보기 (Learn more)
네임스페이스 단위의 기본 차단 정책은 Kubernetes NetworkPolicy의 기본기예요. ingress 차단과 egress 차단을 단계별로 허용해 가면서 정책 조합의 동작을 몸으로 익혀 보세요. 더 넓은 기능이 필요하면 Calico의 고급 정책 리소스를 활용할 수 있어요.