Kubernetes 정책을 사용한 팟(Pod) 간의 트래픽 제어
Virtual Private Cloud
Kubernetes 정책을 사용하여 클러스터에 있는 팟(Pod) 간의 네트워크 트래픽을 제어하고 하나의 네임스페이스 내에서, 또는 네임스페이스 간에 앱 마이크로서비스를 서로 격리할 수 있습니다.
적용 레벨: 작업자 노드 호스트 엔드포인트
기본 동작: 클러스터에는 기본적으로 Kubernetes 네트워크 정책이 없습니다. 기본적으로 모든 팟(Pod)은 클러스터 내의 다른 모든 팟(Pod)에 액세스할 수 있습니다. 또한 모든 팟(Pod)은 팟(Pod) 네트워크에서 노출된 모든 서비스(예: 메트릭 서비스, 클러스터 DNS, API 서버 또는 수동으로 클러스터에 작성하는 서비스)에 액세스할 수 있습니다.
유스 케이스: Kubernetes 네트워크 정책은 팟(Pod)이 다른 팟(Pod) 및 외부 엔드포인트와 통신할 수 있는 방법을 지정합니다. 프로토콜, 포트 및 소스 또는 대상 IP 주소에 따라 수신 및 발신 네트워크 트래픽을 모두 허용하거나 차단할 수 있습니다. 팟(Pod) 및 네임스페이스 레이블에 따라 트래픽을 필터링할 수도 있습니다. Kubernetes 정책은 적용 시 자동으로 Calico 네트워크 정책으로 변환됩니다. 클러스터의 Calico 네트워크 플러그인은 작업자 노드에서 Linux Iptables 규칙을 설정하여 이러한 정책을 적용합니다. Iptables 규칙은 대상으로 지정된 리소스에 전달되도록 네트워크 트래픽이 충족해야 하는 특성을 정의하기 위해 작업자 노드에 대한 방화벽의 역할을 합니다.
대부분 또는 모든 팟(Pod)이 특정 팟(Pod) 또는 서비스에 액세스할 필요가 없고 팟(Pod)이 기본적으로 해당 팟(Pod) 또는 서비스에 액세스할 수 없도록 하려면 해당 팟(Pod) 또는 서비스에 대한 Ingress 트래픽을 차단하는 Kubernetes 네트워크 정책을 작성할 수 있습니다. 예를 들어, 팟(Pod)은 CoreDNS 팟(Pod)의 메트릭 엔드포인트에 액세스할 수 있습니다. 불필요한 액세스를 차단하기 위해 다음과
같은 정책을 적용할 수 있으며, 이 경우 팟(Pod)이 CoreDNS 기능에 액세스할 수 있도록 TCP 및 UDP 포트 53으로의 모든 유입을 허용합니다. 하지만 coredns-metrics-policy: allow
레이블이 있는 네임스페이스의 팟(Pod) 또는 서비스나 kube-system
레이블이 있는 coredns-metrics-policy: allow
네임스페이스의 팟(Pod)을 제외한 CoreDNS 팟(Pod)에서 메트릭을 수집하려는 시도와 같은 다른 모든 유입을 차단합니다.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: coredns-metrics
namespace: kube-system
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
coredns-metrics-policy: allow
- podSelector:
matchLabels:
coredns-metrics-policy: allow
- ports:
- port: 53
protocol: TCP
- port: 53
protocol: UDP
podSelector:
matchLabels:
k8s-app: kube-dns
policyTypes:
- Ingress
Kubernetes 의 네트워크 정책이 pod-to-pod 트래픽을 제어하는 방법에 대한 자세한 정보와 정책의 예는 Kubernetes 문서를 참조하십시오.
네임스페이스 내의 앱 서비스 격리
다음 시나리오에서는 하나의 네임스페이스 내에서 앱 마이크로서비스 간에 트래픽을 관리하는 방법을 보여줍니다.
Accounts 팀은 하나의 네임스페이스에 여러 앱 서비스를 배치하지만, 공용 네트워크를 통해 마이크로서비스 간에 필요한 통신만 허용하려면 격리가 필요합니다. 앱 Srv1
의 경우, 팀에는 프론트 엔드, 백엔드 및 데이터베이스 서비스가 있습니다. 이들은 각 서비스의 레이블을 app: Srv1
레이블 및 tier: frontend
, tier: backend
또는 tier: db
레이블로 지정합니다.
Accounts 팀은 프론트 엔드에서 백엔드로의 트래픽과 백엔드에서 데이터베이스로의 트래픽을 허용하고자 합니다. 이들은 자체 네트워크 정책의 레이블을 사용하여 마이크로서비스 간에 허용되는 트래픽 플로우를 지정합니다.
우선 이들은 프론트 엔드에서 백엔드로의 트래픽을 허용하는 Kubernetes 네트워크 정책을 작성합니다.
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: backend-allow
spec:
podSelector:
matchLabels:
app: Srv1
tier: backend
ingress:
- from:
- podSelector:
matchLabels:
app: Srv1
Tier: frontend
정책이 해당 팟(Pod)에만 적용되도록 spec.podSelector.matchLabels
섹션에는 Srv1 백엔드 서비스에 대한 레이블이 나열됩니다. 해당 팟(Pod)에서의 ingress만 허용되도록 spec.ingress.from.podSelector.matchLabels
섹션에는 Srv1 프론트 엔드 서비스에 대한 레이블이 나열됩니다.
그리고 이들은 백엔드에서 데이터베이스로의 트래픽을 허용하는 유사한 Kubernetes 네트워크 정책을 작성합니다.
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: db-allow
spec:
podSelector:
matchLabels:
app: Srv1
tier: db
ingress:
- from:
- podSelector:
matchLabels:
app: Srv1
Tier: backend
정책이 해당 팟(Pod)에만 적용되도록 spec.podSelector.matchLabels
섹션에는 Srv1 데이터베이스 서비스에 대한 레이블이 나열됩니다. 해당 팟(Pod)에서의 ingress만 허용되도록 spec.ingress.from.podSelector.matchLabels
섹션에는 Srv1 백엔드 서비스에 대한 레이블이 나열됩니다.
트래픽은 이제 프론트 엔드에서 백엔드로, 그리고 백엔드에서 데이터베이스로 이동할 수 있습니다. 데이터베이스는 백엔드에 응답할 수 있으며 백엔드는 프론트엔드에 응답할 수 있지만, 역방향 트래픽 연결은 설정될 수 없습니다.
네임스페이스 간의 앱 서비스 격리
다음 시나리오에서는 다중 네임스페이스에서 앱 마이크로서비스 간에 트래픽을 관리하는 방법을 보여줍니다.
서로 다른 하위 팀이 소유한 서비스는 서로 소통해야 하지만, 서비스는 동일한 클러스터 내의 다른 네임스페이스에 배치됩니다. Accounts 팀은 Accounts 네임스페이스의 앱 Srv1에 대해 프론트 엔드, 백엔드 및 데이터베이스 서비스를 배치합니다. Finance 팀은 Finance 네임스페이스의 앱 Srv2에 대해 프론트 엔드, 백엔드 및 데이터베이스 서비스를 배치합니다. 두 팀은 모두 각 서비스의 레이블을 app: Srv1
또는 app: Srv2
레이블과 tier: frontend
, tier: backend
또는 tier: db
레이블로 지정합니다. 또한 이들은 usage: accounts
또는 usage: finance
레이블로 네임스페이스의 레이블을 지정합니다.
Finance 팀의 Srv2는 Accounts 팀의 Srv1 백엔드에서 정보를 호출해야 합니다. 따라서 Accounts 팀은 Finance 네임스페이스로부터 Accounts 네임스페이스의 Srv1 백엔드로의 모든 트래픽을 허용하는 레이블을 사용하는 Kubernetes 네트워크 정책을 작성합니다. 또한 팀에서는 해당 포트를 통한 액세스만 격리하기 위해 포트 3111도 지정합니다.
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
Namespace: accounts
name: accounts-allow
spec:
podSelector:
matchLabels:
app: Srv1
Tier: backend
ingress:
- from:
- NamespaceSelector:
matchLabels:
usage: finance
ports:
port: 3111
정책이 해당 팟(Pod)에만 적용되도록 spec.podSelector.matchLabels
섹션에는 Srv1 백엔드 서비스에 대한 레이블이 나열됩니다. 해당 네임스페이스에 있는 서비스_에서의_ ingress만 허용되도록 spec.ingress.from.NamespaceSelector.matchLabels
섹션에는 Finance 네임스페이스에 대한 레이블이 나열됩니다.
이제 트래픽은 finance 마이크로서비스에서 accounts Srv1 백엔드로 이동할 수 있습니다. accounts Srv1 백엔드는 finance 마이크로서비스에 응답할 수 있지만 역방향 트래픽 연결은 설정할 수 없습니다.
이 예제에서는 Finance 네임스페이스의 모든 마이크로서비스에서의 모든 트래픽이 허용됩니다. podSelector
및 namespaceSelector
를 결합할 수 없으므로 사용자는 다른 네임스페이스의 특정 앱 팟(Pod)에서의 트래픽을 허용할 수 없습니다.
버전 1.28 이상에서 실행되는 클러스터가 있는 VPC에 대한 필수 정책 규칙
버전 1.27 이하에서는 VPC 클러스터가 Container Registry 프라이빗 클라우드 서비스 엔드포인트를 통해 IBM Cloud Container Registry 이미지를 가져옵니다. 버전 1.28 이상에서는 이 네트워크 경로가 업데이트되어 이미지가 비공개 서비스 엔드포인트 대신 VPE 게이트웨이를 통해 가져오도록 합니다. 이 변경 사항은 VPC의 모든 클러스터에 영향을 미치며, VPC에서 단일 클러스터를 1.28 버전으로 만들거나 업데이트하면 버전이나 유형에 관계없이 해당 VPC의 모든 클러스터의 네트워크 경로가 업데이트됩니다. 자세한 정보는 VPC 클러스터에 대한 네트워킹 변경사항 을 참조하십시오.
VPC에 버전 1.28 이상을 실행하는 클러스터가 있고 Calico 정책을 사용하여 클러스터 작업자로부터의 아웃바운드 연결을 제한하는 경우 다음 정책 규칙을 추가하여 VPE Gateway for Registry에 대한 연결을 허용해야 합니다. 이 정책은 VPC의 각 구역에 대해 작성되어야 하며 구역에 대한 전체 VPC 주소 접두부 범위를 대상 CIDR로 지정해야 합니다. VPC의 각 구역에 대한 VPC 주소 접두부 범위를 찾으려면
ibmcloud is vpc-address-prefixes <vpc_name_or_id>
를 실행하십시오.
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: allow-vpe-gateway-registry
spec:
egress:
- action: Allow
destination:
nets:
- <entire-vpc-address-prefix-range> # example: 10.245.0.0/16
ports:
- 443
- 4443
protocol: TCP
source: {}
order: 500
selector: ibm.role == 'worker_private'
types:
- Egress