Calico 네트워크 정책 시작하기
Calico 네트워크 정책으로 첫 NetworkPolicy를 작성하는 방법을 다뤄요. Kubernetes NetworkPolicy를 확장하는 풍부한 규칙 기능을 직접 써보는 샘플 정책들이 모여 있어요. 네임스페이스 정책과 글로벌 정책의 차이, order 필드를 활용한 정책 순서 제어까지 익힐 수 있어요.
출처: 문서
본문
전체 그림
Calico 네트워크 정책의 규칙으로 허용하거나 거부할 네트워크 트래픽을 강제해요.
가치
Kubernetes 네트워크 정책 확장
Calico 네트워크 정책은 Kubernetes보다 풍부한 정책 기능을 제공해요. 정책 순서/우선순위, deny 규칙, 더 유연한 매치 규칙이 대표적이에요. Kubernetes 네트워크 정책이 파드에만 적용되는 것과 달리, Calico 네트워크 정책은 파드, VM, 호스트 인터페이스 등 여러 엔드포인트 타입에 적용할 수 있어요. 나아가 Istio 서비스 메시와 함께 사용하면, Calico 네트워크 정책은 애플리케이션 레이어 5-7 매치 조건과 암호학적 신원(cryptographic identity)을 활용한 보안을 지원해요.
한 번 작성, 어디서나 동작
지금 어떤 클라우드 공급자를 쓰든, Calico 네트워크 정책을 도입하면 정책을 한 번만 작성하면 되고 이식 가능해요. 다른 클라우드 공급자로 이동해도 Calico 네트워크 정책을 다시 쓸 필요가 없어요. 클라우드 공급자 락인(lock-in)을 피하는 핵심 기능이에요.
Kubernetes 네트워크 정책과 매끄럽게 동작
Calico 네트워크 정책은 Kubernetes 네트워크 정책과 함께 쓸 수도 있고, 단독으로 쓸 수도 있어요. 예를 들어 개발자에게 자기 마이크로서비스의 Kubernetes 네트워크 정책 정의를 맡기고, 개발자가 덮어쓸 수 없는 더 넓고 상위 수준의 접근 제어는 보안이나 운영(Ops) 팀만 Calico 네트워크 정책을 정의하도록 할 수 있죠.
개념
엔드포인트
Calico 네트워크 정책은 엔드포인트에 적용돼요. Kubernetes에서 각 파드는 Calico 엔드포인트예요. 다만 Calico는 다른 종류의 엔드포인트도 지원해요. Calico 엔드포인트에는 두 유형이 있어요: 워크로드 엔드포인트(Kubernetes 파드나 OpenStack VM 같은 것)와 호스트 엔드포인트(호스트의 인터페이스 또는 인터페이스 그룹)예요.
네임스페이스 정책과 글로벌 네트워크 정책
Calico 네트워크 정책은 네임스페이스 리소스로, 그 네임스페이스 안의 파드/컨테이너/VM에 적용돼요.
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-tcp-6379
namespace: production
Calico 글로벌 네트워크 정책은 네임스페이스가 없는(non-namespaced) 리소스로, 네임스페이스와 독립적으로 어떤 엔드포인트(파드, VM, 호스트 인터페이스)에든 적용할 수 있어요.
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: allow-tcp-port-6379
글로벌 네트워크 정책은 kind: GlobalNetworkPolicy를 사용하므로 kind: NetworkPolicy와 별도로 묶여요. 예를 들어 글로벌 네트워크 정책은 calicoctl get networkpolicy의 결과에 나오지 않고, calicoctl get globalnetworkpolicy로 조회해요.
kubectl vs calicoctl
Calico 네트워크 정책과 Calico 글로벌 네트워크 정책은 calicoctl로 적용해요. 문법은 Kubernetes와 비슷하지만 몇 가지 차이가 있어요. 도움이 필요하면 calicoctl 사용자 참조를 보세요.
Ingress와 egress
각 네트워크 정책 규칙은 ingress 또는 egress 트래픽에 적용돼요. 엔드포인트(파드, VM, 호스트 인터페이스)의 관점에서 ingress는 엔드포인트로 들어오는 트래픽이고 egress는 엔드포인트에서 나가는 트래픽이에요. Calico 네트워크 정책에서는 ingress와 egress 규칙을 독립적으로 만들 수 있어요(egress만, ingress만, 또는 둘 다).
types 필드로 정책이 ingress, egress, 둘 다 중 무엇에 적용될지 지정할 수 있어요. types 필드를 쓰지 않으면 Calico는 다음 기본값을 사용해요.
| Ingress 규칙 존재? | Egress 규칙 존재? | 값 |
|---|---|---|
| No | No | Ingress |
| Yes | No | Ingress |
| No | Yes | Egress |
| Yes | Yes | Ingress, Egress |
네트워크 트래픽 동작: deny와 allow
Kubernetes 네트워크 정책 명세는 다음 동작을 정의해요:
- 파드에 적용되는 네트워크 정책이 없으면, 그 파드로/부터의 모든 트래픽이 허용돼요.
- ingress 규칙을 담은 네트워크 정책이 하나 이상 파드에 적용되면, 그 정책들이 명시적으로 허용한 ingress 트래픽만 허용돼요.
- egress 규칙을 담은 네트워크 정책이 하나 이상 파드에 적용되면, 그 정책들이 명시적으로 허용한 egress 트래픽만 허용돼요.
Kubernetes와의 호환성을 위해 Calico 네트워크 정책도 Kubernetes 파드에 대해서는 같은 동작을 따라가요. 다른 엔드포인트 타입(VM, 호스트 인터페이스)에 대해서는 Calico 네트워크 정책이 기본 거부(default deny)예요. 즉 네트워크 정책이 엔드포인트에 전혀 적용되지 않더라도, 네트워크 정책이 명시적으로 허용한 트래픽만 허용돼요.
시작하기 전에
calicoctl을 사용하려면 먼저 설치하고 구성해야 해요. calicoctl은 기본 데이터스토어로 etcd를 사용하지만, 많은 Calico 설치 매니페스트는 Kubernetes를 데이터스토어로 구성해요. calicoctl 구성 방법은 다음 링크에서 더 볼 수 있어요:
방법
- 네임스페이스 안 엔드포인트로/부터의 트래픽 제어
- 네임스페이스와 독립적으로 엔드포인트로/부터의 트래픽 제어
- IP 주소나 CIDR 범위로 엔드포인트로/부터의 트래픽 제어
- 특정 순서로 네트워크 정책 적용
- 특정 트래픽에 대한 로그 생성
네임스페이스 안 엔드포인트로/부터의 트래픽 제어
다음 예시에서 namespace: production의 레이블 color: red 엔드포인트로의 ingress 트래픽은, 같은 네임스페이스에서 color: blue인 파드에서 오고 포트 6379로 향할 때만 허용돼요.
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-tcp-6379
namespace: production
spec:
selector: color == 'red'
ingress:
- action: Allow
protocol: TCP
source:
selector: color == 'blue'
destination:
ports:
- 6379
다른 네임스페이스의 엔드포인트에서 오는 ingress 트래픽을 허용하려면 정책 규칙에 namespaceSelector를 사용해요. namespaceSelector는 네임스페이스에 적용된 레이블 기준으로 네임스페이스를 매칭해요. 다음 예시에서는 shape == circle에 매칭되는 네임스페이스의 엔드포인트에서 오는 ingress 트래픽이 허용돼요.
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-tcp-6379
namespace: production
spec:
selector: color == 'red'
ingress:
- action: Allow
protocol: TCP
source:
selector: color == 'blue'
namespaceSelector: shape == 'circle'
destination:
ports:
- 6379
네임스페이스와 독립적으로 엔드포인트로/부터의 트래픽 제어
다음 Calico 네트워크 정책은 앞선 예시와 비슷하지만 kind: GlobalNetworkPolicy를 사용해서 네임스페이스와 무관하게 모든 엔드포인트에 적용돼요.
다음 예시에서 레이블 color: red인 모든 파드로 들어오는 TCP 트래픽은, color: blue인 파드에서 오면 거부돼요.
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: deny-blue
spec:
selector: color == 'red'
ingress:
- action: Deny
protocol: TCP
source:
selector: color == 'blue'
kind: NetworkPolicy와 마찬가지로, 정책 규칙의 namespaceSelector로 특정 네임스페이스의 엔드포인트에서 오는 ingress 트래픽을 허용하거나 거부할 수 있어요:
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: deny-circle-blue
spec:
selector: color == 'red'
ingress:
- action: Deny
protocol: TCP
source:
selector: color == 'blue'
namespaceSelector: shape == 'circle'
IP 주소나 CIDR 범위로 엔드포인트로/부터의 트래픽 제어
네트워크 정책에서 셀렉터 대신 CIDR 표기의 IP 블록을 지정해 어떤 트래픽을 허용할지 정의할 수도 있어요.
다음 예시에서 레이블 color: red인 파드에서 나가는 트래픽은, 1.2.3.4/24 CIDR 블록 안의 IP 주소로 갈 때 허용돼요.
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-egress-external
namespace: production
spec:
selector: color == 'red'
types:
- Egress
egress:
- action: Allow
destination:
nets:
- 1.2.3.0/24
특정 순서로 네트워크 정책 적용
네트워크 정책 적용 순서를 제어하려면 order 필드를 사용할 수 있어요(값이 낮을수록 먼저 적용). 같은 엔드포인트에 적용될 수 있는 action: allow와 action: deny 규칙이 함께 들어 있다면 정책 order 정의가 특히 중요해요.
다음 예시에서 정책 allow-cluster-internal-ingress(order: 10)는 정책 drop-other-ingress(order: 20)보다 먼저 적용돼요.
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: drop-other-ingress
spec:
order: 20
#...deny policy rules here...
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: allow-cluster-internal-ingress
spec:
order: 10
#...allow policy rules here...
특정 트래픽에 대한 로그 생성
다음 예시에서 애플리케이션으로 들어오는 TCP 트래픽은 거부되고, 각 연결 시도가 syslog에 기록돼요.
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: allow-tcp-6379
namespace: production
spec:
selector: role == 'database'
types:
- Ingress
- Egress
ingress:
- action: Log
protocol: TCP
source:
selector: role == 'frontend'
- action: Deny
protocol: TCP
source:
selector: role == 'frontend'
기존 연결(established connections)에 대한 정책 만들기
정책은 새 연결에 즉시 적용돼요. 하지만 이미 열려 있는 기존 연결에는, 정책 변경이 연결이 다시 수립된 이후에야 반영돼요. 즉 진행 중인 세션은 다시 시작되기 전까지 정책 변경을 즉시 반영하지 않을 수 있어요.
추가 리소스
- 추가 Calico 네트워크 정책 기능은 Calico 네트워크 정책과 Calico 글로벌 네트워크 정책을 참고하세요
- 정책에서 IP 주소나 CIDR 대신 쓸 수 있는 대안은 Network sets를 참고하세요
- calicoctl 명령줄 도구의 세부 내용은 calicoctl 사용자 참조를 참고하세요
더 알아보기 (Learn more)
정책을 네임스페이스 단위에서 글로벌 단위로 확장하기 전에 리소스 참조 문서로 필드 구성을 먼저 확인해 보세요. IP/CIDR 기반 규칙이 늘어나기 전에 NetworkSet으로 관리하는 편이 유지보수에 유리해요.