하이브리드 노드용 Kubernetes 네트워크 정책 구성하기
하이브리드 노드용 Kubernetes 네트워크 정책 구성하기 (Configure Kubernetes Network Policies for hybrid nodes)
AWS는 EKS Hybrid Nodes와 함께 CNI로 Cilium을 사용할 때 Pod 인그레스 및 이그레스 트래픽에 대한 Kubernetes 네트워크 정책(레이어 3 / 레이어 4)을 지원해요. AWS Cloud에 노드가 있는 EKS 클러스터를 실행한다면 AWS는 Kubernetes 네트워크 정책용 Amazon VPC CNI를 지원해요.
이 주제는 EKS Hybrid Nodes에서 Cilium과 Kubernetes 네트워크 정책을 구성하는 방법을 다뤄요. Kubernetes 네트워크 정책에 대한 자세한 내용은 Kubernetes 문서의 Kubernetes Network Policies를 참고하세요.
출처: 문서
본문
네트워크 정책 구성하기
고려 사항
- AWS는 Pod 인그레스 및 이그레스에 대한 업스트림 Kubernetes 네트워크 정책과 사양을 지원해요. AWS는 현재
CiliumNetworkPolicy또는CiliumClusterwideNetworkPolicy를 지원하지 않아요. policyEnforcementModeHelm 값은 기본 Cilium 정책 적용 동작을 제어하는 데 사용할 수 있어요. 기본 동작은 모든 이그레스 및 인그레스 트래픽을 허용해요. 엔드포인트가 네트워크 정책에 의해 선택되면 기본 거부(default-deny) 상태로 전환되어 명시적으로 허용된 트래픽만 허용돼요. 기본 정책 모드와 정책 적용 모드에 대한 자세한 내용은 Cilium 문서를 참고하세요.- 기존 Cilium 설치에서
policyEnforcementMode를 변경한다면 새 정책 적용 모드를 적용하려면 Cilium 에이전트 DaemonSet을 재시작해야 해요. namespaceSelector와podSelector를 사용해 일치하는 레이블이 있는 네임스페이스 및 Pod와의 트래픽을 허용하거나 거부할 수 있어요.namespaceSelector와podSelector는matchLabels또는matchExpressions와 함께 사용해 레이블을 기반으로 네임스페이스와 Pod를 선택할 수 있어요.ingress.ports와egress.ports를 사용해 포트와 프로토콜과의 트래픽을 허용하거나 거부할 수 있어요.ipBlock필드는 Pod IP 주소와의 트래픽을 선택적으로 허용하거나 거부하는 데 사용할 수 없어요(#9209). 노드 IP에ipBlock선택기를 사용하는 것은 Cilium의 베타 기능이며 AWS에서 지원하지 않아요.- Kubernetes 네트워크 정책에서 사용 가능한 필드에 대한 정보는 Kubernetes 문서의 NetworkPolicy 리소스를 참고하세요.
사전 요구 사항
- 하이브리드 노드용 CNI 구성하기의 지침에 따라 Cilium이 설치되어 있어야 해요.
- 명령줄 환경에 Helm이 설치되어 있어야 해요. Helm 설정 지침을 참고하세요.
절차
다음 절차는 샘플 마이크로서비스 애플리케이션에 네트워크 정책을 설정해, 각 컴포넌트가 애플리케이션 작동에 필요한 다른 컴포넌트와만 통신할 수 있게 해요. 이 절차는 Istio Bookinfo 샘플 마이크로서비스 애플리케이션을 사용해요.
Bookinfo 애플리케이션은 다음 관계를 가진 4개의 별도 마이크로서비스로 구성돼요.
- productpage. productpage 마이크로서비스는 details와 reviews 마이크로서비스를 호출해 페이지를 채워요.
- details. details 마이크로서비스는 책 정보를 포함해요.
- reviews. reviews 마이크로서비스는 책 리뷰를 포함해요. 또한 ratings 마이크로서비스를 호출해요.
- ratings. ratings 마이크로서비스는 책 리뷰에 함께 제공되는 책 순위 정보를 포함해요.
-
샘플 애플리케이션을 만들어요.
kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml -
애플리케이션이 성공적으로 실행되는지 확인하고 productpage 마이크로서비스의 Pod IP 주소를 기록해 두어요. 이후 단계에서 각 마이크로서비스를 쿼리하는 데 이 Pod IP 주소를 사용해요.
kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODE details-v1-766844796b-9wff2 1/1 Running 0 7s 10.86.3.7 mi-0daa253999fe92daa productpage-v1-54bb874995-lwfgg 1/1 Running 0 7s 10.86.2.193 mi-082f73826a163626e ratings-v1-5dc79b6bcd-59njm 1/1 Running 0 7s 10.86.2.232 mi-082f73826a163626e reviews-v1-598b896c9d-p2289 1/1 Running 0 7s 10.86.2.47 mi-026d6a261e355fba7 reviews-v2-556d6457d-djktc 1/1 Running 0 7s 10.86.3.58 mi-0daa253999fe92daa reviews-v3-564544b4d6-g8hh4 1/1 Running 0 7s 10.86.2.69 mi-09183e8a3d755abf6 -
네트워크 정책을 테스트하는 데 전체에서 사용할 Pod를 만들어요. Pod가
default네임스페이스에access: true레이블로 생성된다는 점에 유의하세요.kubectl run curl-pod --image=curlimages/curl -i --tty --labels=access=true --namespace=default --overrides='{"spec": { "nodeSelector": {"eks.amazonaws.com/compute-type": "hybrid"}}}' -- /bin/sh -
productpage 마이크로서비스에 대한 접근을 테스트해요. 아래 예시에서는 productpage Pod의 Pod IP 주소(
10.86.2.193)를 사용해 마이크로서비스를 쿼리해요. 이 값을 환경의 productpage Pod IP 주소로 바꾸세요.curl -s http://10.86.2.193:9080/productpage | grep -o ".*"Simple Bookstore App테스트 curl Pod에서
exit를 입력해 나가고, 다음 명령을 실행해 Pod에 다시 연결할 수 있어요.kubectl attach curl-pod -c curl-pod -i -t -
다음 단계에서 네트워크 정책의 효과를 보여주기 위해 먼저 BookInfo 마이크로서비스의 모든 트래픽을 거부하는 네트워크 정책을 만들어요. 거부 네트워크 정책을 정의하는
network-policy-deny-bookinfo.yaml이라는 파일을 만들어요.apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-bookinfo namespace: default spec: podSelector: matchExpressions: - key: app operator: In values: ["productpage", "details", "reviews", "ratings"] policyTypes: - Ingress - Egress -
거부 네트워크 정책을 클러스터에 적용해요.
kubectl apply -f network-policy-default-deny-bookinfo.yaml -
BookInfo 애플리케이션에 대한 접근을 테스트해요. 아래 예시에서는 productpage Pod의 Pod IP 주소(
10.86.2.193)를 사용해 마이크로서비스를 쿼리해요. 이 값을 환경의 productpage Pod IP 주소로 바꾸세요.curl http://10.86.2.193:9080/productpage --max-time 10curl: (28) Connection timed out after 10001 milliseconds -
productpage 네트워크 정책을 정의하는
network-policy-productpage.yaml이라는 파일을 만들어요. 정책에는 다음 규칙이 있어요.access: true레이블이 있는 Pod(이전 단계에서 만든 curl Pod)의 인그레스 트래픽을 허용.- details, reviews, ratings 마이크로서비스의 포트
9080에 대한 이그레스 TCP 트래픽을 허용. kube-system네임스페이스에서 실행되는 CoreDNS의 포트53에 대한 이그레스 TCP/UDP 트래픽을 허용.
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: productpage-policy namespace: default spec: podSelector: matchLabels: app: productpage policyTypes: - Ingress - Egress ingress: - from: - podSelector: matchLabels: access: "true" egress: - to: - podSelector: matchExpressions: - key: app operator: In values: ["details", "reviews", "ratings"] ports: - port: 9080 protocol: TCP - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: - port: 53 protocol: UDP - port: 53 protocol: TCP -
productpage 네트워크 정책을 클러스터에 적용해요.
kubectl apply -f network-policy-productpage.yaml -
curl Pod에 연결해 Bookinfo 애플리케이션에 대한 접근을 테스트해요. productpage 마이크로서비스에 대한 접근은 이제 허용되지만, 다른 마이크로서비스는 여전히 거부 네트워크 정책의 적용을 받으므로 거부돼요. 아래 예시에서는 productpage Pod의 Pod IP 주소(
10.86.2.193)를 사용해 마이크로서비스를 쿼리해요. 이 값을 환경의 productpage Pod IP 주소로 바꾸세요.kubectl attach curl-pod -c curl-pod -i -tcurl -s http://10.86.2.193:9080/productpage | grep -o ".*" Simple Bookstore Appcurl -s http://10.86.2.193:9080/api/v1/products/1 {"error": "Sorry, product details are currently unavailable for this book."}curl -s http://10.86.2.193:9080/api/v1/products/1/reviews {"error": "Sorry, product reviews are currently unavailable for this book."}curl -s http://10.86.2.193:9080/api/v1/products/1/ratings {"error": "Sorry, product ratings are currently unavailable for this book."} -
details 네트워크 정책을 정의하는
network-policy-details.yaml이라는 파일을 만들어요. 정책은 productpage 마이크로서비스의 인그레스 트래픽만 허용해요.apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: details-policy namespace: default spec: podSelector: matchLabels: app: details policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: productpage -
reviews 네트워크 정책을 정의하는
network-policy-reviews.yaml이라는 파일을 만들어요. 정책은 productpage 마이크로서비스의 인그레스 트래픽과 ratings 마이크로서비스 및 CoreDNS로 가는 이그레스 트래픽만 허용해요.apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: reviews-policy namespace: default spec: podSelector: matchLabels: app: reviews policyTypes: - Ingress - Egress ingress: - from: - podSelector: matchLabels: app: productpage egress: - to: - podSelector: matchLabels: app: ratings - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: - port: 53 protocol: UDP - port: 53 protocol: TCP -
ratings 네트워크 정책을 정의하는
network-policy-ratings.yaml이라는 파일을 만들어요. 정책은 productpage 및 reviews 마이크로서비스의 인그레스 트래픽만 허용해요.apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: ratings-policy namespace: default spec: podSelector: matchLabels: app: ratings policyTypes: - Ingress ingress: - from: - podSelector: matchExpressions: - key: app operator: In values: ["productpage", "reviews"] -
details, reviews, ratings 네트워크 정책을 클러스터에 적용해요.
kubectl apply -f network-policy-details.yaml kubectl apply -f network-policy-reviews.yaml kubectl apply -f network-policy-ratings.yaml -
curl Pod에 연결해 Bookinfo 애플리케이션에 대한 접근을 테스트해요. 아래 예시에서는 productpage Pod의 Pod IP 주소(
10.86.2.193)를 사용해 마이크로서비스를 쿼리해요. 이 값을 환경의 productpage Pod IP 주소로 바꾸세요.kubectl attach curl-pod -c curl-pod -i -tdetails 마이크로서비스를 테스트해요.
curl -s http://10.86.2.193:9080/api/v1/products/1{"id": 1, "author": "William Shakespeare", "year": 1595, "type": "paperback", "pages": 200, "publisher": "PublisherA", "language": "English", "ISBN-10": "1234567890", "ISBN-13": "123-1234567890"}reviews 마이크로서비스를 테스트해요.
curl -s http://10.86.2.193:9080/api/v1/products/1/reviews{"id": "1", "podname": "reviews-v1-598b896c9d-p2289", "clustername": "null", "reviews": [{"reviewer": "Reviewer1", "text": "An extremely entertaining play by Shakespeare. The slapstick humour is refreshing!"}, {"reviewer": "Reviewer2", "text": "Absolutely fun and entertaining. The play lacks thematic depth when compared to other plays by Shakespeare."}]}ratings 마이크로서비스를 테스트해요.
curl -s http://10.86.2.193:9080/api/v1/products/1/ratings{"id": 1, "ratings": {"Reviewer1": 5, "Reviewer2": 4}} -
이 절차에서 만든 리소스를 정리해요.
kubectl delete -f network-policy-deny-bookinfo.yaml kubectl delete -f network-policy-productpage.yaml kubectl delete -f network-policy-details.yaml kubectl delete -f network-policy-reviews.yaml kubectl delete -f network-policy-ratings.yaml kubectl delete -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/bookinfo/platform/kube/bookinfo.yaml kubectl delete pod curl-pod