LabHub
배우기 러닝패스 코스

Kubernetesネットワーク — 本物のクラスタで

ポリシーが実際に塞ぐものを見る

LabHub 에서 이어서 보기

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

이 실습은 진짜 쿠버네티스에서 돕니다

VM 안에 k3s 한 대가 실제로 떠 있고, NetworkPolicy 를 강제하는 컨트롤러가 돌고 있습니다. 그래서 정책을 붙이면 정말로 막힙니다. 채점기도 파일만 보지 않고 매번 실제로 접속을 시도해 확인합니다.

처음 뜨는 데 2분쯤 걸립니다.

목표

허용 목록 방식의 네트워크 정책을 한 겹씩 쌓고, 그 과정에서 실무에서 가장 자주 나는 사고 하나를 직접 일으켰다가 고칩니다.

왜 중요한가

쿠버네티스의 기본값은 전부 허용입니다. 어느 네임스페이스의 어느 파드든 다른 모든 파드에 닿습니다. 침입자가 웹 파드 하나를 잡으면 그 자리에서 데이터베이스가 보입니다.

그런데 정책의 동작 방식이 직관과 다릅니다. 파드에 정책이 하나도 붙지 않으면 전부 허용이고, 하나라도 붙는 순간 그 파드는 허용 목록 방식으로 바뀝니다. 그래서 "막는 정책" 을 쓰는 것이 아니라 "허용하는 정책" 을 쓰게 되고, 이 전환을 모르면 정책을 추가할수록 뜻밖의 것이 끊깁니다.

가장 흔한 사고가 5번 단계입니다. egress 를 기본 차단하는 순간 DNS 가 함께 끊깁니다. CoreDNS 로 나가는 53번 포트도 egress 이기 때문입니다. 증상은 "이름을 못 찾습니다" 라서 아무도 방금 붙인 네트워크 정책을 의심하지 않습니다.

단계

준비된 것: shop 네임스페이스에 api(app=api)와 db(app=db, nginx) 파드, 그리고 ops 네임스페이스가 있습니다. 없으면 1번에서 만듭니다.

  1. 정책이 하나도 없을 때 아무 파드에서나 db 에 닿는 것을 확인해 /root/k8snp/baseline.txt 에 저장하세요. 응답 코드 200 이 보여야 합니다.
  2. shopdefault-deny 정책을 만드세요. podSelector: {} 이고 policyTypes: [Ingress] 입니다. 그리고 이제 막힌다는 것을 /root/k8snp/deny.txt 에 기록하세요.
  3. allow-api 정책으로 app=api 파드만 db 에 닿게 하세요. 결과를 /root/k8snp/allow-pod.txt 에 저장합니다. 정책은 받는 쪽(app=db)에 붙습니다.
  4. allow-ops 정책으로 ops 네임스페이스 전체를 허용하고 /root/k8snp/namespace.txt 에 저장하세요. 네임스페이스는 kubernetes.io/metadata.name 라벨로 고릅니다.
  5. shopdeny-egress(policyTypes: [Egress], 빈 선택자) 를 붙이고 무슨 일이 생기는지 보세요. 그리고 /root/k8snp/incident.md 에 사고 보고서를 쓰세요. 원인이 DNS 라는 것, 53번 포트, CoreDNS 가 어느 네임스페이스에 있는지가 들어가야 합니다.
  6. allow-dns 정책으로 DNS 만 열어 되살리세요. 결과를 /root/k8snp/fixed.txt 에 저장합니다. UDP 와 TCP 둘 다 53번을 열어야 합니다.
  7. allow-api포트 제한(80) 을 추가하고 결과를 /root/k8snp/ports.txt 에 저장하세요.
  8. /root/k8snp/report.mdpolicies=(정책 개수)와 dns_fix_policy=allow-dns 두 줄, 그리고 기본 허용에서 허용 목록으로 바뀌는 지점을 설명하세요.

참고

기본값은 전부 허용이다

정책이 하나도 없을 때 아무 파드에서나 db 에 닿는 것을 확인해 /root/k8snp/baseline.txt 에 저장하세요. 응답 코드 200 이 보여야 합니다.

정책을 만들기 전에 지금 상태를 재 두세요. 무엇을 바꿨는지 알려면 바꾸기 전을 알아야 합니다.

하나만 붙여도 방식이 바뀐다

shopdefault-deny 정책을 만드세요. podSelector: {} 이고 policyTypes: [Ingress] 입니다. 그리고 이제 막힌다는 것을 /root/k8snp/deny.txt 에 기록하세요.

podSelector: {} 는 '이 네임스페이스의 모든 파드' 라는 뜻입니다. 규칙을 하나도 주지 않으면 '허용하는 것이 없다' 가 됩니다.

받는 쪽에 붙인다

allow-api 정책으로 app=api 파드만 db 에 닿게 하세요. 결과를 /root/k8snp/allow-pod.txt 에 저장합니다. 정책은 받는 쪽(app=db)에 붙습니다.

정책의 podSelector 는 보호받는 파드(db)를 고르고, ingress.from 이 허용할 출처(api)를 고릅니다. 방향을 반대로 쓰면 아무 일도 일어나지 않습니다.

네임스페이스 단위로 허용한다

allow-ops 정책으로 ops 네임스페이스 전체를 허용하고 /root/k8snp/namespace.txt 에 저장하세요. 네임스페이스는 kubernetes.io/metadata.name 라벨로 고릅니다.

namespaceSelectorkubernetes.io/metadata.name 라벨로 고릅니다. 쿠버네티스가 모든 네임스페이스에 자동으로 붙여 주는 라벨입니다.

egress 를 막았더니 이름이 안 풀린다

shopdeny-egress(policyTypes: [Egress], 빈 선택자) 를 붙이고 무슨 일이 생기는지 보세요. 그리고 /root/k8snp/incident.md 에 사고 보고서를 쓰세요. 원인이 DNS 라는 것, 53번 포트, CoreDNS 가 어느 네임스페이스에 있는지가 들어가야 합니다.

egress 를 기본 차단하면 CoreDNS 로 나가는 53번도 함께 막힙니다. 사고 보고서에 원인·포트·CoreDNS 의 위치를 적으세요.

DNS 만 열어 되살린다

allow-dns 정책으로 DNS 만 열어 되살리세요. 결과를 /root/k8snp/fixed.txt 에 저장합니다. UDP 와 TCP 둘 다 53번을 열어야 합니다.

to 에 kube-system 네임스페이스를 고르고 ports 에 UDP 53 과 TCP 53 을 둘 다 넣습니다.

출처만 고르면 절반이다

allow-api포트 제한(80) 을 추가하고 결과를 /root/k8snp/ports.txt 에 저장하세요.

ingress 항목에 ports 를 더합니다. 비워 두면 그 출처는 대상 파드의 모든 포트에 닿습니다.

무엇을 배웠나

/root/k8snp/report.mdpolicies=(정책 개수)와 dns_fix_policy=allow-dns 두 줄, 그리고 기본 허용에서 허용 목록으로 바뀌는 지점을 설명하세요.

policies=dns_fix_policy= 두 줄, 그리고 기본 허용이 허용 목록으로 바뀌는 지점을 설명하세요.