안녕하세요, 베스핀글로벌 SRE 안은경 님이 작성해 주신 ‘클러스터의 네트워크 정책, Ingress와 Egress’에 대해 알아보도록 하겠습니다.
궁금한 부분이 있으시면 댓글을 달아주세요:)
쿠버네티스의 Network Policy (1)
Network Policy
– 클러스터 내부에서 Pod 간 통신할 경우 트래픽 규칙을 지정합니다.
– label selector를 이용하여 특정 Pod에 네트워크 정책을 적용합니다.
– 화이트리스트 방식을 사용하여, 네임스페이스 별 통신을 막거나 특정 Pod 간의 통신만 허용할 수 있습니다.
- default-allow : 하나도 설정된 것이 없을 경우, 모든 트래픽은 열려있습니다.
- default-deny : 네트워크 정책이 1개라도 설정될 경우, 해당 정책 이외의 나머지 트래픽은 전부 막힙니다.
– 생성 시 네임스페이스 별로 생성해야 합니다.
- Ingress(수신) : 인바운드 방향의 트래픽 규칙을 설정합니다.
- Egress(송신) : 아웃바운드 방향의 트래픽 규칙을 설정합니다.
Network Policy 문법 예시
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-networkpolicy
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- {}
egress:
- {}
- namespace : 네트워크 정책이 적용될 네임스페이스 지정
- podSelector : 네트워크 정책을 적용할 Pod를 라벨셀렉터로 선택
- {} : 특정 라벨을 지정하지 않은 모든 Pod
- policyTypes : 네트워크 정책을 부여할 트래픽 종류 지정
- ingress : 인바운드 트래픽 허용 규칙 지정
- – {} : 인바운드로 들어오는 모든 트래픽 허용
- egress : 아웃바운드 트래픽 허용 규칙 지정
- – {} : 아웃바운드로 들어오는 모든 트래픽 허용
Network Policy 생성 예시
1. Ingress
1) 외부 트래픽 차단
– 전체 인바운드 트래픽을 차단하여 외부 트래픽이 들어올 수 없게 Private zone으로 생성합니다.
– Client용 Pod를 먼저 생성합니다.
kubectl run client --image nginx
# pod/client created
vim privatezone.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: privatezone
namespace: default
spec:
podSelector: {}
ingress: []
- ingress: [] : 빈 리스트로, 0개의 정책을 허용한다는 뜻입니다. 모든 인바운드 트래픽을 막는 설정입니다.
2) Web용 Pod 허용하는 정책
– 전체 트래픽을 막아두고, Web용 Pod의 80번 포트만 허용합니다.
- 네트워크 적용 대상 : run=web 라벨을 가진 Pod
- 접근 허용 소스 : 모든 인바운드 트래픽 허용
- 접근 허용 포트 : 80번 포트만 허용
vim web80.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web80
namespace: default
spec:
podSelector:
matchLabels:
run: web
ingress:
- from:
- podSelector: {}
ports:
- protocol: TCP
port: 80
- podSelector : run=web 라벨이 적용된 Pod에 대해서 정책을 허용한다는 의미입니다.
- Ingress[0].from[0].podSelector : 트래픽이 열려있다는 것을 의미합니다.
- ingress[0].ports : 80번 포트만 허용한다는 것을 의미합니다.
3) 특정 서버와 통신하는 app용 정책
– 외부 전체로 노출시키지 않고, 특정 서버와 통신하는 정책입니다.
- 네트워크 적용 대상 : run=app 라벨을 가진 Pod
- 접근 허용 소스 : run = web 라벨을 가진 Pod만 허용
- 접근 허용 포트 : 전체 포트 허용
vim webapp.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: webapp
namespace: default
spec:
podSelector:
matchLabels:
run: app
ingress:
- from:
- podSelector: {}
matchLabels:
run: web
4) DB 접근 허용 정책
– 모든 서비스와 통신하지 않고, 특정 white-list에 포함된 서버와의 연결을 허용합니다.
- 네트워크 적용 대상 : run=db 라벨을 가진 Pod
- 접근 허용 소스 : db-accessable=true 라벨을 가진 Pod만 허용
- 접근 허용 포트 : 3306번 포트 (MySQL)
vim dballow.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: dballow
namespace: default
spec:
podSelector:
matchLabels:
run: db
ingress:
- from:
- podSelector: {}
matchLabels:
db-accessable: "true"
ports:
- protocol: TCP
port: 80
2. Egress
1) 특정 네임스페이스의 아웃바운드 차단
– 개발용 네임스페이스 내에서만 서비스를 개발하고, 운영용 네임스페이스에는 접근을 차단할 때, 특정 네임스페이스의 아웃바운드를 전부 막습니다.
- 네트워크 적용 대상 : dev 네임스페이스의 모든 Pod
- 접근 허용 소스 : dev 네임스페이스에 존재하는 모든 Pod 접근 허용
- 접근 허용 포트 : 전체 포트 접근 허용
vim onlydev.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: onlydev
namespace: default
spec:
podSelector:
egress:
- to:
- podSelector: {}
2) Metadata API 접근 차단
– 경우에 따라, 보안을 위해 AWS의 서비스 중 하나인 EC2 인스턴스 메타데이터를 차단합니다.
vim nometadata.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: nometadata
namespace: default
spec:
podSelector: {}
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
expect:
- 169.254.169.254/32
3. AND, OR를 활용한 정책 설정
1) AND 조건
– from 하위의 podSelector에 2개를 선언할 경우, 2개의 조건이 AND로 설정됩니다.
vim and.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: and
namespace: default
spec:
podSelector: {}
matchLabels:
run: web
ingress:
- from:
- podSelector:
matchLabels:
shape: star
- podSelector:
matchLabels:
color: blue
- 모양이 star 이고, 색상이 blue인 Pod만 선택합니다.
2) OR 조건
– 각각의 from에 선언할 경우, OR로 설정됩니다.
vim or.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: or
namespace: default
spec:
podSelector: {}
matchLabels:
run: web
ingress:
- from:
- podSelector:
matchLabels:
shape: star
- from:
- podSelector:
matchLabels:
color: blue
- 모양이 star 이거나, 색상이 blue인 Pod를 모두 선택합니다.
감사합니다:)
Written by 안 은경 / Eunkyung An
Cloud Engineer