본문 바로가기
MLOps/Doker & Kubernetes

Udemy CKA 강의 정리 175: Developing network policies

by 공부하는 무니 2023. 1. 20.
반응형

해당 내용은 Udemy의 Certified Kubernetes Administrator (CKA) with Practice Tests 강의를 공부한 내용입니다. 내용을 그대로 번역하기보다는, 제가 이해하기 쉬운 대로 수정한 부분들이 있습니다.

⚠️ 영어 독해가 많이 부족합니다. 틀린 내용이 있으면 알려주시면 감사하겠습니다.


이번 강의에서는 네트워크 정책에 대해 좀 더 자세히 살펴보도록 하겠습니다. 여기에 이전 강의에서 논의한 것과 동일한 웹, API, 데이터베이스 파드가 있습니다.

먼저 우리의 요구 사항을 명확히 합시다. 우리의 목표는 API 파드를 제외한 다른 파드의 액세스를 허용하지 않고 포트 3306에서만 데이터베이스 파드를 보호하는 것입니다. 따라서 웹 파드 또는 API 파드에 대해 걱정하지 않는다고 가정해 보겠습니다. 이러한 파드의 경우 모든 트래픽이 어디에서든 드나들 수 있습니다. 그러나 데이터베이스 파드를 보호하고 API 파드의 트래픽만 허용하려고 합니다. 따라서 필요한 작업에 정확히 집중할 수 있도록 다른 작업은 제쳐두도록 합시다. 따라서 API 파드 이외의 다른 소스에서 오는 트래픽을 허용하지 않기 때문에 웹 파드 또는 해당 포트에 대해 걱정할 필요가 없습니다. 그러니 그것을 제거합시다. 웹 서버가 연결되는 API 파드의 포트도 신경 쓰지 않기 때문에 잊을 수 있습니다.

논의한 바와 같이 default로 Kubernetes는 모든 파드에서 모든 대상으로의 모든 트래픽을 허용합니다.

따라서 첫 번째 단계로 데이터베이스 파드에서 들어오고 나가는 모든 것을 차단하려고 합니다. 따라서 우리는 네트워크 정책을 생성하고 이를 dp-policy라고 합시다. 첫 번째 단계는 이 네트워크 정책을 보호하려는 파드와 연결하는 것입니다. 레이블과 selector를 사용하여 이를 수행합니다. 따라서 일치하는 레이블 옵션이 있는 파드 selector 필드를 추가하고 role: db 라고 하는 DB 파드의 label을 지정하고 네트워크 정책을 데이터베이스 파드와 연결함으로써 이를 수행합니다.

아직 policyTypes을 지정하지 않았기 때문에 여전히 트래픽을 차단하지 않습니다. 따라서 네트워크 정책 정의에 지정된 policyType이 없으면 보호가 적용되지 않습니다. ingress 및 egress 트래픽을 모두 제한하고 싶기 때문에 정책 유형에 ingress 및 egress를 추가하고 파드의 모든 ingress 및 egress 트래픽을 차단해야 합니다.

그러나 포트 3306에서 데이터베이스를 쿼리하려면 API 파드가 필요합니다. 이것이 우리가 다음에 구성할 것입니다. 먼저, 요구 사항을 충족하기 위해 이 네트워크 정책 오브젝트에 어떤 유형의 정책을 정의해야 하는지 파악해야 합니다. 그래서 우리가 이전 강의에서 논의한 두 가지 유형의 정책이 있습니다. ingress와 egress입니다. 그렇다면 여기에서 ingress 또는 egress가 필요합니까, 아니면 둘 다 필요합니까?  항상 DB 파드 관점에서 이를 살펴봅니다. DB 파드 관점에서 API 파드에서 들어오는 트래픽을 허용하려고 합니다. 이것이 들어오는 것이므로 ingress입니다. API 파드는 데이터베이스 쿼리를 만들고 데이터베이스 파드는 결과를 반환합니다. 결과는 어떻습니까? 결과가 API 파드로 돌아가려면 별도의 규칙이 필요합니까? 아니요, 들어오는 트래픽을 허용하면 해당 트래픽에 대한 응답 또는 회신이 자동으로 다시 허용되기 때문입니다. 이에 대한 별도의 규정은 필요하지 않습니다. 따라서 이 경우 API 파드에서 데이터베이스 파드로의 트래픽을 허용하고 API 파드가 데이터베이스에 연결하고 쿼리를 실행하고 쿼리 결과를 검색할 수 있도록 허용하는 ingress 규칙만 있으면 됩니다.

따라서 생성할 rule 유형을 결정할 때 요청이 시작되는 방향(여기에서 직선으로 표시됨)에만 관심을 기울이면 되고 응답에 대해서는 걱정할 필요가 없습니다. 응답은 점선으로 표시됩니다.

그러나 이 규칙은 데이터베이스 파드가 API 파드에 연결하거나 API를 호출할 수 있음을 의미하지 않습니다. 예를 들어, 데이터베이스 파드가 API 파드에 대한 API 호출을 시도한다고 가정하면, 이는 이제 데이터베이스 파드에서 발생하는 egress 트래픽이고 특정 egress 규칙을 정의해야 하기 때문에 허용되지 않습니다. 그래서 둘 사이의 차이점을 알고 ingress 및 egress 규칙에 대해 명확하게 알아야 합니다.

단일 네트워크 정책은 파드가 수신되는 연결을 허용하고 외부 호출을 수행하려는 경우에  ingress 유형의 rule, egress 유형의 rule 둘 다를 가질 수 있습니다. 따라서 현재 예로 든 경우에는 ingress 정책 유형만 필요합니다.

이제 policyType을 결정했으므로 다음 단계는 해당 정책의 세부 사항을 정의하는 것입니다. ingress인 경우 여러 rule을 지정할 수 있는 ingress라는 섹션을 만듭니다. 각 rule에는 from 및 ports 필드가 있습니다. from 필드는 데이터베이스 파드에 통할 수 있는 트래픽의 원천을 정의합니다.

여기서는 파드 selector를 사용하고 이와 같이 api-pod의 레이블을 제공합니다.

ports 필드는 트래픽이 이동할 수 있는 데이터베이스 파드의 포트를 정의합니다. 이 경우 TCP 프로토콜을 사용하는 3306입니다.

이게 다 입니다. 이렇게 하면 api pod의 트래픽을 제외하고 DB 파드에 대한 모든 트래픽을 차단하는 정책이 생성됩니다.

클러스터안에서 레이블은 같지만 네임스페이스가 다른 여러 API 파드가 있는 경우엔 어떻게 될까요?

여기에는 dev, staging 및 prod 환경에 대한 서로 다른 네임스페이스가 있으며 이러한 각 환경에서 동일한 레이블이 있는 API 파드가 있습니다. 그리고 먼저 default 네임스페이스가 아닌 prod 네임스페이스에 대한 네트워크 정책을 생성하는 경우, 네트워크 정책 오브젝트 definition에 prod로 정의된 네임스페이스가 있어야 합니다.

이제 default로 네트워크 정책의 네임스페이스와 동일한 네임스페이스이면서, 레이블이 일치하는 prod 네임스페이스의 파드만 데이터베이스 파드에 도달하도록 허용합니다. 그러나 어떤 이유로 다른 네임스페이스인 staging 네임스페이스에 있는 파드가 prod 네임스페이스에 있는 데이터베이스에 도달하기를 원한다면 어떻게 될까요?

이를 위해 podSelector 속성과 함께 namespaceSelector 속성을 추가합니다. 여기에서 matchLabel을 다시 사용하여 네임스페이스에 설정된 레이블을 제공합니다. 이것이 작동하려면 먼저 네임스페이스에 이 레이블을 설정해야 합니다. 그러니 참고만 하세요.

이것이 namespaceSelector가 하는 일입니다. 데이터베이스 파드에 도달할 수 있는 네임스페이스 트래픽을 정의하는 데 도움이 됩니다.

만약 podSelector가 없고 namespaceSelector만 있으면 어떻게 될까요? 이 경우 지정된 네임스페이스 내의 모든 파드가 데이터베이스 파드에 도달할 수 있습니다. 이제 해당 namespaceSelector를 다시 prod로 변경하고 예제를 계속 진행하겠습니다.

른 사용 사례를 살펴보겠습니다. 쿠버네티스 클러스터 외부 어딘가에 백업 서버가 있고 이 서버가 데이터베이스 파드에 연결하도록 허용하고 싶다고 가정해 보겠습니다. 이제 이 백업 서버가 Kubernetes 클러스터에 배포되지 않았기 때문에 트래픽을 정의하는 데 사용하는 podSelector 와 namespaceSelector필드는 클러스터의 파드가 아니기 때문에 작동하지 않습니다. 그러나 우리는 백업 서버의 IP 주소를 알고 있으며 그 주소는 192.168.5.10입니다. 특정 IP 주소에서 발생하는 트래픽을 허용하도록 네트워크 정책을 구성할 수 있습니다.

이를 위해 ipBlock이라는 새로운 유형의 from 정의를 추가합니다. ipBlock을 사용하면 트래픽이 데이터베이스 파드에 도달하도록 허용할 수 있는 IP 주소 범위를 지정할 수 있습니다.

from 섹션과 ingress에서 지원되는 selector가 세 가지 있습니다. 레이블별로 파드를 선택하는 podSelector, 레이블별로 네임스페이스를 선택하는 namspaceSelector, IP 주소 범위를 선택하는 ipBlock selector가 입니다. 그리고 이것들은 egress의 to 섹션에도 적용할 수 있습니다.

이들은 개별 rule로 개별적으로 전달되거나 단일 rule으로 묶여서 함께 전달될 수 있습니다.

이 예에서는 from 섹션 아래에 두 개의 요소가 있습니다. 이것이 두 가지 rule입니다. 첫 번째 rule에는 podSelector와 namespaceSelector가 함께 있고, 두 번째 rule 에는 ipBlock selector가 있습니다. 이것은 OR 연산처럼 작동합니다. 이러한 기준 중 하나를 충족하는 소스의 트래픽은 통과가 허용됩니다. 그러나 첫 번째 rule에는 두 개의 selector가 있습니다. 이는 소스의 트래픽이 통과하려면 이 두 가지 기준을 모두 충족해야 함을 의미합니다. 따라서 그들은 API 파드의 일치하는 레이블이 있는 파드여야 하며 해당 파드는 prod 네임스페이스에 있어야 합니다. 따라서 AND 연산처럼 작동합니다.

이제 이와 같이 namespaceSelector 앞에 대시를 추가하여 이들을 구분한다면 어떨까요?

이제 첫번째 rule이 두 가지 별도의 rule 이 되었습니다. 즉 동일한 네임스페이스의 레이블 API 파드와 일치하는 모든 파드에서 오는 트래픽이 허용되고, 두 번째 rule과 일치하는 트래픽도 허용됨을 의미합니다. 물론 ipBlock도 있으므로 백업 서버도 허용됩니다. 이제 세 가지 별도의 rule이 있는 것이며, 거의 모든 곳의 트래픽이 DB 파드로 허용됩니다. 따라서 대시 같은 작은 변화가 큰 영향을 미칠 수 있습니다. 그러므로 요구 사항에 따라 이러한 rule을 조합하는 방법을 이해하는 것이 중요합니다.

이제 모든 것을 제거하고 default rule로 돌아가서 egress를 살펴보겠습니다.

예를 들어 백업 서버가 백업을 시작하는 대신, 백업 서버에 백업을 푸시하는 DB 파드에 에이전트가 있다고 가정해 보겠습니다.

이 경우 트래픽은 데이터베이스 파드에서 외부 백업 서버로 갑니다. 이를 위해서는 egress 규칙을 정의해야 합니다. 따라서 먼저 정책 유형에 egress를 추가한 다음 새 egress 섹션을 추가하여 정책의 세부 사항을 정의합니다.  egress 아래에 이제 from 대신에 to가 있습니다. 이것이 유일한 차이점입니다.

아래에서 우리는 다음과 같은 선택자를 사용할 수 있습니다.

파드, 네임스페이스 또는 ipBlock selector입니다. 그리고 이 경우 데이터베이스 서버가 외부에 있기 때문에 ipBlock selector를 사용하여 서버에 대한 cidr 블록을 제공합니다.

요청을 보낼 포트는 80이므로 80을 포트로 지정합니다. 따라서 이 rule은 데이터베이스 파드에서 지정된 주소의 외부 백업 서버로 가는 트래픽을 허용합니다. 

반응형

댓글