LabHub
배우기 러닝패스 코스

Kubernetes運用実務

デフォルト拒否から始めるポリシー設計

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

네임스페이스의 통신 기본값을 거부로 뒤집고, 필요한 경로만 라벨로 골라 여는 정책 세트를 직접 작성합니다.

왜 중요한가

NetworkPolicy 에서 가장 많이 틀리는 것은 문법이 아니라 방향과 결합 방식입니다. 정책은 트래픽을 보내는 쪽이 아니라 받는 쪽에 붙습니다. web 에서 api 로 가는 통신을 허용하려면 정책의 podSelector 가 api 여야 하고, web 은 ingress.from 안에 등장합니다. 또 from 배열의 항목끼리는 OR 이고 한 항목 안의 namespaceSelectorpodSelector 는 AND 입니다. 하이픈 위치 하나로 "특정 네임스페이스의 특정 파드"가 "그 네임스페이스의 모든 파드 또는 아무 데나 있는 그 파드"로 바뀝니다. 그리고 이그레스를 막을 때는 DNS 예외를 반드시 짝으로 넣으세요. 실제 프로덕션에서 기본 거부만 먼저 넣었다가 이름 해석이 죽어 전체 서비스가 연쇄로 멈춘 사례가 반복해서 보고됩니다. 이 랩의 클러스터는 파드 간 실제 패킷이 흐르지 않으므로 채점은 정책 오브젝트의 내용과 셀렉터 의미로 이루어집니다. 문법과 사고방식을 여기서 굳히고, 실제 차단 확인은 CNI 가 있는 환경에서 하면 됩니다.

단계

  1. 네임스페이스 netpol-lab 을 만들고 /opt/lab/fixtures/k8s/workloads.yaml 을 그 안에 적용하세요. 결과로 web, api, db 세 파드가 각각 자기 이름과 같은 app 라벨을 갖고, api 파드는 추가로 tier=backend 라벨을 가져야 합니다.
  2. netpol-lab 에 NetworkPolicy default-deny-ingress 를 만드세요. podSelector 는 빈 객체 {} 이고 policyTypesIngress 하나만이며 ingress 규칙은 하나도 없어야 합니다.
  3. NetworkPolicy allow-web-to-api 를 만드세요. podSelector.matchLabels.appapi, ingress[0].from[0]podSelector.matchLabels.app: web 하나만 갖습니다(같은 항목에 namespaceSelector 를 넣지 마세요). 허용 포트는 TCP 8080 입니다.
  4. NetworkPolicy default-deny-egress 를 만드세요. policyTypesEgress 하나만입니다. 이어서 allow-dns-egress 를 만들되 egress[0].to[0].namespaceSelector.matchLabelskubernetes.io/metadata.name: kube-system 을 쓰고, egress[0].ports 에는 포트 53UDP 와 TCP 두 항목으로 넣으세요.
  5. 네임스페이스 monitoring 을 만들고 라벨 purpose=monitoring 을 붙이세요. 그다음 netpol-lab 에 NetworkPolicy allow-from-monitoring 을 만드세요. podSelector.matchLabels.appapi, ingress[0].from[0].namespaceSelector.matchLabels.purposemonitoring, 허용 포트는 9090 입니다.
  6. NetworkPolicy allow-office-cidr 을 만드세요. podSelector.matchLabels.appweb 이고, ingress[0].from[0].ipBlock.cidr10.0.0.0/16, except10.0.5.0/24 하나입니다.
  7. NetworkPolicy api-full 을 만드세요. podSelector.matchLabels.appapi, policyTypesIngressEgress 둘 다입니다. ingress[0].from 에는 항목이 2개 이상(예: web 파드와 monitoring 네임스페이스) 들어가야 하고, egress[0].to[0]podSelector.matchLabels.app: db, 허용 포트는 5432 입니다.
  8. /root/ops/netpol/out/policy-map.json 을 만드세요. 최상위 키는 web, api, db 세 개이고 각 값은 그 파드를 고르는 정책 이름의 배열입니다. 빈 셀렉터를 가진 정책은 세 파드 모두에 들어가야 하고, allow-web-to-apiapi 에만 들어가야 합니다(web 이나 db 에 넣으면 안 됩니다). allow-office-cidrweb 에, api-fullapi 에 들어갑니다. 최종적으로 netpol-lab 의 NetworkPolicy 는 6개 이상이어야 합니다.

참고

실습용 네임스페이스와 라벨 붙은 파드 만들기

네임스페이스 netpol-lab 을 만들고 /opt/lab/fixtures/k8s/workloads.yaml 을 그 안에 적용하세요. 결과로 web, api, db 세 파드가 각각 자기 이름과 같은 app 라벨을 갖고, api 파드는 추가로 tier=backend 라벨을 가져야 합니다.

정책은 라벨로만 대상을 고릅니다. 픽스처에 세 파드가 준비돼 있으니 그대로 올리되, 어느 네임스페이스에 올리는지를 확인하세요.

인그레스 기본 거부 정책 만들기

netpol-lab 에 NetworkPolicy default-deny-ingress 를 만드세요. podSelector 는 빈 객체 {} 이고 policyTypesIngress 하나만이며 ingress 규칙은 하나도 없어야 합니다.

네임스페이스 전체를 고르는 셀렉터는 비어 있는 셀렉터입니다. 전부 거부한다는 뜻은 허용 규칙을 하나도 쓰지 않는 것입니다.

web 에서 api 로 가는 포트만 열기

NetworkPolicy allow-web-to-api 를 만드세요. podSelector.matchLabels.appapi, ingress[0].from[0]podSelector.matchLabels.app: web 하나만 갖습니다(같은 항목에 namespaceSelector 를 넣지 마세요). 허용 포트는 TCP 8080 입니다.

정책은 보내는 쪽이 아니라 받는 쪽에 붙습니다. 같은 네임스페이스 안이므로 상대를 고를 때 네임스페이스 셀렉터를 섞지 마세요.

이그레스 기본 거부와 DNS 예외

NetworkPolicy default-deny-egress 를 만드세요. policyTypesEgress 하나만입니다. 이어서 allow-dns-egress 를 만들되 egress[0].to[0].namespaceSelector.matchLabelskubernetes.io/metadata.name: kube-system 을 쓰고, egress[0].ports 에는 포트 53UDP 와 TCP 두 항목으로 넣으세요.

이그레스를 막으면 이름 해석부터 죽습니다. DNS 는 UDP 만으로 끝나지 않는다는 점과, 대상 네임스페이스를 고르는 표준 라벨이 무엇인지 확인하세요.

다른 네임스페이스에서 오는 트래픽 허용하기

네임스페이스 monitoring 을 만들고 라벨 purpose=monitoring 을 붙이세요. 그다음 netpol-lab 에 NetworkPolicy allow-from-monitoring 을 만드세요. podSelector.matchLabels.appapi, ingress[0].from[0].namespaceSelector.matchLabels.purposemonitoring, 허용 포트는 9090 입니다.

네임스페이스를 고르려면 그 네임스페이스에 라벨이 실제로 붙어 있어야 합니다. 셀렉터가 고를 대상이 없으면 정책은 아무 의미가 없습니다.

IP 대역 허용과 예외 지정하기

NetworkPolicy allow-office-cidr 을 만드세요. podSelector.matchLabels.appweb 이고, ingress[0].from[0].ipBlock.cidr10.0.0.0/16, except10.0.5.0/24 하나입니다.

ipBlock 은 넓게 열고 좁게 빼는 방식으로 씁니다. 제외 대역은 반드시 허용 대역 안에 들어 있어야 합니다.

인그레스와 이그레스를 한 정책에 담기

NetworkPolicy api-full 을 만드세요. podSelector.matchLabels.appapi, policyTypesIngressEgress 둘 다입니다. ingress[0].from 에는 항목이 2개 이상(예: web 파드와 monitoring 네임스페이스) 들어가야 하고, egress[0].to[0]podSelector.matchLabels.app: db, 허용 포트는 5432 입니다.

from 배열의 항목끼리는 OR 입니다. 두 종류의 출처를 허용하려면 항목을 두 개로 나누세요. 나가는 쪽은 데이터베이스 포트만 열립니다.

파드별 적용 정책 지도 만들기

/root/ops/netpol/out/policy-map.json 을 만드세요. 최상위 키는 web, api, db 세 개이고 각 값은 그 파드를 고르는 정책 이름의 배열입니다. 빈 셀렉터를 가진 정책은 세 파드 모두에 들어가야 하고, allow-web-to-apiapi 에만 들어가야 합니다(web 이나 db 에 넣으면 안 됩니다). allow-office-cidrweb 에, api-fullapi 에 들어갑니다. 최종적으로 netpol-lab 의 NetworkPolicy 는 6개 이상이어야 합니다.

빈 셀렉터를 가진 정책은 모든 파드에 적용됩니다. 정책이 고르는 것은 받는 쪽이라는 점을 지도에 반영하세요.