LabHub

쿠버네티스 네트워크 — 진짜 클러스터에서 · 정책이 실제로 막는 것 · 실습

정책이 실제로 막는 것을 본다

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 두 줄, 그리고 기본 허용에서 허용 목록으로 바뀌는 지점을 설명하세요.

참고

단계 8개

  1. 기본값은 전부 허용이다
  2. 하나만 붙여도 방식이 바뀐다
  3. 받는 쪽에 붙인다
  4. 네임스페이스 단위로 허용한다
  5. egress 를 막았더니 이름이 안 풀린다
  6. DNS 만 열어 되살린다
  7. 출처만 고르면 절반이다
  8. 무엇을 배웠나