네트워크 보안 - Amazon EKS

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

네트워크 보안

네트워크 보안에는 여러 패싯이 있습니다. 첫 번째는 서비스 간의 네트워크 트래픽 흐름을 제한하는 규칙의 적용을 포함합니다. 두 번째에는 전송 중 트래픽 암호화가 포함됩니다. EKS에서 이러한 보안 조치를 구현하는 메커니즘은 다양하지만 종종 다음 항목을 포함합니다.

트래픽 제어

  • 네트워크 정책

  • 보안 그룹

네트워크 암호화

  • 서비스 메시

  • 컨테이너 네트워크 인터페이스(CNIs)

  • 수신 컨트롤러 및 로드 밸런서

  • Nitro 인스턴스

  • cert-manager를 사용하는 ACM Private CA

네트워크 정책

Kubernetes 클러스터 내에서 모든 포드 간 통신은 기본적으로 허용됩니다. 이러한 유연성은 실험을 촉진하는 데 도움이 될 수 있지만 안전한 것으로 간주되지 않습니다. Kubernetes 네트워크 정책은 포드 간(종종 동부/서부 트래픽이라고 함) 및 포드와 외부 서비스 간 네트워크 트래픽을 제한하는 메커니즘을 제공합니다. Kubernetes 네트워크 정책은 OSI 모델의 계층 3 및 4에서 작동합니다. 네트워크 정책은 포드, 네임스페이스 선택기 및 레이블을 사용하여 소스 및 대상 포드를 식별하지만 IP 주소, 포트 번호, 프로토콜 또는 이들의 조합을 포함할 수도 있습니다. 네트워크 정책은 종종 수신 및 송신 규칙이라고 하는 포드에 대한 인바운드 또는 아웃바운드 연결 모두에 적용할 수 있습니다.

Amazon VPC CNI 플러그인의 기본 네트워크 정책 지원을 통해 네트워크 정책을 구현하여 kubernetes 클러스터에서 네트워크 트래픽을 보호할 수 있습니다. 이는 업스트림 Kubernetes 네트워크 정책 API와 통합되어 호환성과 Kubernetes 표준 준수를 보장합니다. 업스트림 API에서 지원하는 다양한 식별자를 사용하여 정책을 정의할 수 있습니다. 기본적으로 모든 수신 및 송신 트래픽은 포드에 허용됩니다. policyType Ingress가 있는 네트워크 정책을 지정하면 포드에 허용되는 연결만 포드 노드의 연결과 수신 규칙에서 허용하는 연결입니다. 송신 규칙에도 동일하게 적용됩니다. 여러 규칙이 정의된 경우 결정을 내릴 때 모든 규칙의 조합이 고려됩니다. 따라서 평가 순서는 정책 결과에 영향을 주지 않습니다.

중요

EKS 클러스터를 처음 프로비저닝할 때 VPC CNI 네트워크 정책 기능은 기본적으로 활성화되어 있지 않습니다. 지원되는 VPC CNI 추가 기능 버전을 배포했는지 확인하고 vpc-cni 추가 기능true에서 ENABLE_NETWORK_POLICY 플래그를 로 설정하여 이를 활성화합니다. 자세한 지침은 Amazon EKS 사용 설명서를 참조하세요.

추천

네트워크 정책 시작하기 - 최소 권한 원칙 준수

기본 거부 정책 생성

RBAC 정책과 마찬가지로 네트워크 정책에 대한 최소 권한 액세스 원칙을 따르는 것이 좋습니다. 네임스페이스에서를 사용하여 모든 인바운드 및 아웃바운드 트래픽을 제한하는 모든 거부 정책을 생성하는 것부터 시작합니다.

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny namespace: default spec: podSelector: {} policyTypes: - Ingress - Egress

default-deny

default-deny
참고

위 이미지는 Tufin의 네트워크 정책 뷰어에 의해 생성되었습니다.

DNS 쿼리를 허용하는 규칙 생성

기본 거부 모든 규칙이 적용되면 포드가 이름 확인을 위해 CoreDNS를 쿼리하도록 허용하는 규칙과 같은 추가 규칙에 대한 계층화를 시작할 수 있습니다.

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-dns-access namespace: default spec: podSelector: matchLabels: {} policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: - protocol: UDP port: 53

allow-dns-access

allow-dns-access

네임스페이스/포드 간의 트래픽 흐름을 선택적으로 허용하는 규칙을 점진적으로 추가

애플리케이션 요구 사항을 이해하고 필요에 따라 세분화된 수신 및 송신 규칙을 생성합니다. 아래 예제에서는 포트 80의 수신 트래픽을 app-one에서 로 제한하는 방법을 보여줍니다client-one. 이렇게 하면 공격 표면을 최소화하고 무단 액세스 위험을 줄일 수 있습니다.

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-ingress-app-one namespace: default spec: podSelector: matchLabels: k8s-app: app-one policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: k8s-app: client-one ports: - protocol: TCP port: 80

allow-ingress-app-one

allow-ingress-app-one

네트워크 정책 적용 모니터링

  • 네트워크 정책 편집기 사용

    • 네트워크 정책 편집기는 네트워크 흐름 로그에서 시각화, 보안 점수, 자동 생성에 도움이 됩니다.

    • 대화형 방식으로 네트워크 정책 구축

  • 감사 로그

    • EKS 클러스터의 감사 로그를 정기적으로 검토

    • 감사 로그는 네트워크 정책 변경을 포함하여 클러스터에서 수행된 작업에 대한 풍부한 정보를 제공합니다.

    • 이 정보를 사용하여 시간 경과에 따른 네트워크 정책의 변경 사항을 추적하고 무단 또는 예상치 못한 변경 사항을 감지합니다.

  • 자동 테스트

    • 프로덕션 환경을 미러링하는 테스트 환경을 생성하여 자동 테스트를 구현하고 네트워크 정책을 위반하려고 시도하는 워크로드를 주기적으로 배포합니다.

  • 지표 모니터링

    • 가 에이전트 상태 및 sdk 오류를 모니터링할 수 있도록 VPC CNI 노드 에이전트에서 prometheus 지표를 스크레이프하도록 관찰성 에이전트를 구성합니다.

  • 네트워크 정책을 정기적으로 감사

    • 네트워크 정책을 정기적으로 감사하여 현재 애플리케이션 요구 사항을 충족하는지 확인합니다. 애플리케이션이 발전함에 따라 감사를 통해 중복 수신, 송신 규칙을 제거하고 애플리케이션에 과도한 권한이 없는지 확인할 수 있습니다.

  • OPA(Open Policy Agent)를 사용하여 네트워크 정책이 존재하는지 확인

    • 애플리케이션 포드를 온보딩하기 전에 네트워크 정책이 항상 존재하는지 확인하려면 아래 표시된 것과 같은 OPA 정책을 사용합니다. 이 정책은 해당 네트워크 정책이 없는 k8s-app: sample-app 경우 레이블이 있는 k8s 포드 온보딩을 거부합니다.

package kubernetes.admission
import data.kubernetes.networkpolicies

deny[msg] {
    input.request.kind.kind == "Pod"
    pod_label_value := {v["k8s-app"] | v := input.request.object.metadata.labels}
    contains_label(pod_label_value, "sample-app")
    np_label_value := {v["k8s-app"] | v := networkpolicies[_].spec.podSelector.matchLabels}
    not contains_label(np_label_value, "sample-app")
    msg:= sprintf("The Pod %v could not be created because it is missing an associated Network Policy.", [input.request.object.metadata.name])
}
contains_label(arr, val) {
    arr[_] == val
}

문제 해결

vpc-network-policy-controller, node-agent 로그 모니터링

EKS 컨트롤 플레인 컨트롤러 관리자 로그를 활성화하여 네트워크 정책 기능을 진단합니다. 컨트롤 플레인 로그를 CloudWatch 로그 그룹으로 스트리밍하고 CloudWatch Log 인사이트를 사용하여 고급 쿼리를 수행할 수 있습니다. 로그에서 네트워크 정책으로 확인된 포드 엔드포인트 객체, 정책의 조정 상태를 확인하고 정책이 예상대로 작동하는지 디버깅할 수 있습니다.

또한 Amazon VPC CNI를 사용하면 정책 적용 로그를 수집하고 EKS 작업자 노드에서 Amazon Cloudwatch로 내보낼 수 있습니다. 활성화되면 CloudWatch Container Insights를 활용하여 네트워크 정책과 관련된 사용량에 대한 인사이트를 제공할 수 있습니다.

또한 Amazon VPC CNI는 노드의 eBPF 프로그램과 상호 작용할 수 있는 인터페이스를 제공하는 SDK를 제공합니다. SDK는가 노드에 배포될 때 설치aws-node됩니다. 노드의 /opt/cni/bin 디렉터리 아래에 설치된 SDK 바이너리를 찾을 수 있습니다. 시작 시 SDK는 eBPF 프로그램 및 맵 검사와 같은 기본 기능에 대한 지원을 제공합니다.

sudo /opt/cni/bin/aws-eks-na-cli ebpf progs

네트워크 트래픽 메타데이터 로깅

AWS VPC 흐름 로그는 수락/중단된 패킷과 함께 소스 및 대상 IP 주소 및 포트와 같이 VPC를 통해 흐르는 트래픽에 대한 메타데이터를 캡처합니다. 이 정보를 분석하여 포드를 포함한 VPC 내의 리소스 간에 의심스럽거나 비정상적인 활동을 찾을 수 있습니다. 그러나 포드의 IP 주소는 교체될 때 자주 변경되므로 흐름 로그만으로는 충분하지 않을 수 있습니다. Calico Enterprise는 포드 레이블 및 기타 메타데이터를 사용하여 흐름 로그를 확장하므로 포드 간의 트래픽 흐름을 더 쉽게 확인할 수 있습니다.

보안 그룹

EKS는 AWS VPC 보안 그룹(SGs)을 사용하여 Kubernetes 컨트롤 플레인과 클러스터의 작업자 노드 간의 트래픽을 제어합니다. 보안 그룹은 작업자 노드, 기타 VPC 리소스 및 외부 IP 주소 간의 트래픽을 제어하는 데에도 사용됩니다. EKS 클러스터(Kubernetes 버전 1.14-eks.3 이상)를 프로비저닝하면 클러스터 보안 그룹이 자동으로 생성됩니다. 이 보안 그룹은 EKS 컨트롤 플레인과 관리형 노드 그룹의 노드 간에 원활한 통신을 허용합니다. 간소화를 위해 비관리형 노드 그룹을 포함한 모든 노드 그룹에 클러스터 SG를 추가하는 것이 좋습니다.

Kubernetes 버전 1.14 및 EKS 버전 eks.3 이전에는 EKS 컨트롤 플레인 및 노드 그룹에 대해 별도의 보안 그룹이 구성되었습니다. 컨트롤 플레인 및 노드 그룹 보안 그룹에 대한 최소 및 권장 규칙은 https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html 확인할 수 있습니다. 컨트롤 플레인 보안 그룹의 최소 규칙은 작업자 노드 SG에서 인바운드로 포트 443을 허용합니다. 이 규칙은 kubelet이 Kubernetes API 서버와 통신할 수 있도록 허용합니다. 작업자 노드 SG로의 아웃바운드 트래픽을 위한 포트 10250도 포함되어 있습니다. 10250은 kubelet이 수신하는 포트입니다. 마찬가지로 최소 노드 그룹 규칙은 컨트롤 플레인 SG에서 인바운드 포트 10250과 컨트롤 플레인 SG로 아웃바운드 포트 443을 허용합니다. 마지막으로 노드 그룹 내의 노드 간 원활한 통신을 허용하는 규칙이 있습니다.

클러스터 내에서 실행되는 서비스와 RDS 데이터베이스와 같은 클러스터 외부에서 실행되는 서비스 간의 통신을 제어해야 하는 경우 포드의 보안 그룹을 고려하세요. 포드의 보안 그룹을 사용하면 포드 컬렉션에 기존 보안 그룹을 할당할 수 있습니다.

주의

포드를 생성하기 전에 존재하지 않는 보안 그룹을 참조하면 포드가 예약되지 않습니다.

SecurityGroupPolicy 객체를 생성하고 PodSelector 또는를 지정하여 보안 그룹에 할당되는 포드를 제어할 수 있습니다ServiceAccountSelector. 선택기를 로 설정{}하면에서 참조되는 SGs가 네임스페이스의 SecurityGroupPolicy 모든 포드 또는 네임스페이스의 모든 서비스 계정에 할당됩니다. 포드에 대한 보안 그룹을 구현하기 전에 모든 고려 사항을 숙지해야 합니다.

중요

포드에 SGs를 사용하는 경우 클러스터 보안 그룹에 대한 포트 53 아웃바운드를 허용하는 SGs를 생성해야 합니다. 마찬가지로 포드 보안 그룹의 포트 53 인바운드 트래픽을 수락하도록 클러스터 보안 그룹을 업데이트해야 합니다.

중요

포드에 보안 그룹을 사용할 때는 보안 그룹에 대한 제한이 계속 적용되므로 신중하게 사용하십시오.

중요

포드에 대해 구성된 모든 프로브에 대해 클러스터 보안 그룹(kubelet)의 인바운드 트래픽에 대한 규칙을 생성해야 합니다.

중요

포드의 보안 그룹은 EC2 인스턴스의 ENI 밀도를 높이기 위해 생성된 ENI 트렁킹이라는 기능을 사용합니다. 포드가 SG에 할당되면 VPC 컨트롤러는 노드 그룹의 브랜치 ENI를 포드와 연결합니다. 포드가 예약된 시점에 노드 그룹에서 사용할 수 있는 브랜치 ENIs가 충분하지 않으면 포드는 보류 상태로 유지됩니다. 인스턴스가 지원할 수 있는 브랜ENIs 수는 인스턴스 유형/계열에 따라 다릅니다. 자세한 내용은 https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#supported-instance-types 참조하십시오.

포드의 보안 그룹은 정책 데몬의 오버헤드 없이 클러스터 내부 및 외부의 네트워크 트래픽을 제어하는 AWS 네이티브 방법을 제공하지만 다른 옵션을 사용할 수 있습니다. 예를 들어 Cilium 정책 엔진을 사용하면 네트워크 정책에서 DNS 이름을 참조할 수 있습니다. Calico Enterprise에는 네트워크 정책을 AWS 보안 그룹에 매핑하는 옵션이 포함되어 있습니다. Istio와 같은 서비스 메시를 구현한 경우 송신 게이트웨이를 사용하여 네트워크 송신을 정규화된 특정 도메인 또는 IP 주소로 제한할 수 있습니다. 이 옵션에 대한 자세한 내용은 Istio에서 송신 트래픽 제어에 대한 세 부분 시리즈를 참조하십시오.

포드에 네트워크 정책과 보안 그룹을 언제 사용해야 합니까?

Kubernetes 네트워크 정책을 사용해야 하는 경우

  • pod-to-pod 트래픽 제어

    • 클러스터 내의 포드 간 네트워크 트래픽을 제어하는 데 적합(동서 트래픽)

  • IP 주소 또는 포트 수준에서 트래픽 제어(OSI 계층 3 또는 4)

포드에 AWS 보안 그룹을 사용해야 하는 경우(SGP)

  • 기존 AWS 구성 활용

    • AWS 서비스에 대한 액세스를 관리하는 복잡한 EC2 보안 그룹 세트가 이미 있고 EC2 인스턴스에서 EKS로 애플리케이션을 마이그레이션하는 경우 SGPs를 사용하면 보안 그룹 리소스를 재사용하고 포드에 적용할 수 있습니다.

  • AWS 서비스에 대한 액세스 제어

    • EKS 클러스터 내에서 실행되는 애플리케이션은 다른 AWS 서비스(RDS 데이터베이스)와 통신하려는 경우 SGPs 효율적인 메커니즘으로 사용하여 포드에서 AWS 서비스로의 트래픽을 제어합니다.

  • 포드 및 노드 트래픽 격리

    • 포드 트래픽을 나머지 노드 트래픽과 완전히 분리하려면 POD_SECURITY_GROUP_ENFORCING_MODE=strict 모드에서 SGP를 사용합니다.

포드 및 네트워크 정책에 대한 보안 그룹 사용 모범 사례

  • 계층형 보안

    • 계층화된 보안 접근 방식을 위해 SGP와 kubernetes 네트워크 정책의 조합 사용

    • SGPs 사용하여 클러스터의 일부가 아닌 AWS 서비스에 대한 네트워크 수준 액세스를 제한하는 반면, kubernetes 네트워크 정책은 클러스터 내의 포드 간 네트워크 트래픽을 제한할 수 있습니다.

  • 최소 권한의 원칙

    • 포드 또는 네임스페이스 간에 필요한 트래픽만 허용

  • 애플리케이션 세그먼트화

    • 가능하면 네트워크 정책에 따라 애플리케이션을 분할하여 애플리케이션이 손상된 경우 블래스트 반경을 줄입니다.

  • 정책을 간단하고 명확하게 유지

    • Kubernetes 네트워크 정책은 매우 세분화되고 복잡할 수 있으므로 구성 오류 위험을 줄이고 관리 오버헤드를 완화하기 위해 최대한 간단하게 유지하는 것이 가장 좋습니다.

  • 공격 표면 축소

    • 애플리케이션의 노출을 제한하여 공격 표면 최소화

중요

포드용 보안 그룹은 strict 및의 두 가지 적용 모드를 제공합니다standard. EKS 클러스터의 포드 기능에 네트워크 정책 및 보안 그룹을 모두 사용할 때는 standard 모드를 사용해야 합니다.

네트워크 보안과 관련하여 계층화된 접근 방식이 가장 효과적인 솔루션인 경우가 많습니다. kubernetes 네트워크 정책과 SGP를 함께 사용하면 EKS에서 실행되는 애플리케이션에 대한 강력한 defense-in-depth 전략을 제공할 수 있습니다.

Service Mesh 정책 적용 또는 Kubernetes 네트워크 정책

service mesh는 애플리케이션에 추가할 수 있는 전용 인프라 계층입니다. 이를 통해 자체 코드에 추가하지 않고도 관찰성, 트래픽 관리 및 보안과 같은 기능을 투명하게 추가할 수 있습니다.

서비스 메시는 OSI 모델의 계층 7(애플리케이션)에서 정책을 적용하는 반면, kubernetes 네트워크 정책은 계층 3(네트워크) 및 계층 4(전송)에서 작동합니다. 이 스페이스에는 AWS AppMesh, Istio, Linkerd 등과 같은 다양한 상품이 있습니다.

정책 적용을 위해 서비스 메시를 사용해야 하는 경우

  • 서비스 메시에 대한 기존 투자 보유

  • 트래픽 관리, 관찰성 및 보안과 같은 고급 기능 필요

    • 트래픽 제어, 로드 밸런싱, 회로 차단, 속도 제한, 제한 시간 등

    • 서비스 수행 방식에 대한 자세한 인사이트(지연 시간, 오류율, 초당 요청 수, 요청 볼륨 등)

    • mTLS와 같은 보안 기능을 위해 서비스 메시를 구현하고 활용하려는 경우

더 간단한 사용 사례를 위해 Kubernetes 네트워크 정책 선택

  • 서로 통신할 수 있는 포드 제한

  • 네트워크 정책은 서비스 메시보다 적은 리소스가 필요하므로 더 간단한 사용 사례 또는 서비스 메시를 실행하고 관리하는 오버헤드가 정당화되지 않을 수 있는 소규모 클러스터에 적합합니다.

참고

네트워크 정책과 서비스 메시를 함께 사용할 수도 있습니다. 네트워크 정책을 사용하여 포드 간에 기준 수준의 보안 및 격리를 제공한 다음 서비스 메시를 사용하여 트래픽 관리, 관찰성 및 보안과 같은 추가 기능을 추가합니다.

ThirdParty 네트워크 정책 엔진

글로벌 네트워크 정책, DNS 호스트 이름 기반 규칙 지원, 계층 7 규칙, ServiceAccount 기반 규칙, 명시적 거부/로그 작업 등과 같은 고급 정책 요구 사항이 있는 경우 타사 네트워크 정책 엔진을 고려하세요. Calico는 EKS와 잘 작동하는 Tigera의 오픈 소스 정책 엔진입니다. Calico는 전체 Kubernetes 네트워크 정책 기능 세트를 구현하는 것 외에도 Istio와 통합될 때 HTTP와 같은 계층 7 규칙에 대한 지원을 포함하여 더 풍부한 기능 세트를 갖춘 확장된 네트워크 정책을 지원합니다. Calico 정책의 범위는 네임스페이스, 포드, 서비스 계정 또는 전역으로 지정할 수 있습니다. 정책 범위가 서비스 계정으로 지정되면 수신/송신 규칙 세트를 해당 서비스 계정과 연결합니다. 적절한 RBAC 규칙을 마련하면 팀이 이러한 규칙을 재정의하지 못하도록 하여 IT 보안 전문가가 네임스페이스 관리를 안전하게 위임할 수 있습니다. Cilium의 유지 관리인 등가는 HTTP와 같은 계층 7 규칙에 대한 부분 지원을 포함하도록 네트워크 정책도 확장했습니다. 또한 Cilium은 Kubernetes 서비스/포드와 VPC 내부 또는 외부에서 실행되는 리소스 간의 트래픽을 제한하는 데 유용할 수 있는 DNS 호스트 이름을 지원합니다. 반면 Calico Enterprise에는 Kubernetes 네트워크 정책을 AWS 보안 그룹과 DNS 호스트 이름에 매핑할 수 있는 기능이 포함되어 있습니다.

일반적인 Kubernetes 네트워크 정책 목록은 https://github.com/ahmetb/kubernetes-network-policy-recipes 확인할 수 있습니다. Calico에 대한 유사한 규칙 세트는 https://docs.projectcalico.org/security/calico-network-policy 확인할 수 있습니다.

Amazon VPC CNI 네트워크 정책 엔진으로 마이그레이션

일관성을 유지하고 예기치 않은 포드 통신 동작을 방지하려면 클러스터에 네트워크 정책 엔진을 하나만 배포하는 것이 좋습니다. 3P에서 VPC CNI 네트워크 정책 엔진으로 마이그레이션하려면 VPC CNI 네트워크 정책 지원을 활성화하기 전에 기존 3P NetworkPolicy CRDs를 Kubernetes NetworkPolicy 리소스로 변환하는 것이 좋습니다. 또한 마이그레이션된 정책을 프로덕션 환경에 적용하기 전에 별도의 테스트 클러스터에서 테스트합니다. 이를 통해 포드 통신 동작의 잠재적 문제 또는 불일치를 식별하고 해결할 수 있습니다.

마이그레이션 도구

마이그레이션 프로세스를 지원하기 위해 기존 Calico/Cilium 네트워크 정책 CRD를 Kubernetes 기본 네트워크 정책으로 변환하는 K8s Network Policy Migrator라는 도구를 개발했습니다. CRDs 변환 후 VPC CNI 네트워크 정책 컨트롤러를 실행하는 새 클러스터에서 변환된 네트워크 정책을 직접 테스트할 수 있습니다. 이 도구는 마이그레이션 프로세스를 간소화하고 원활한 전환을 보장하도록 설계되었습니다.

중요

마이그레이션 도구는 네이티브 kubernetes 네트워크 정책 API와 호환되는 3P 정책만 변환합니다. 3P 플러그인에서 제공하는 고급 네트워크 정책 기능을 사용하는 경우 마이그레이션 도구는 이를 건너뛰고 보고합니다.

마이그레이션 도구는 현재 AWS VPC CNI 네트워크 정책 엔지니어링 팀에서 지원되지 않으며 최선을 다해 고객에게 제공됩니다. 이 도구를 활용하여 마이그레이션 프로세스를 용이하게 하는 것이 좋습니다. 도구에 문제나 버그가 발생하는 경우 GitHub 문제를 생성해 주시기 바랍니다. 귀하의 피드백은 매우 소중하며 서비스를 지속적으로 개선하는 데 도움이 될 것입니다.

추가 리소스

전송 중 암호화

PCI, HIPAA 또는 기타 규정을 준수해야 하는 애플리케이션은 전송 중 데이터를 암호화해야 할 수 있습니다. 오늘날 TLS는 유선의 트래픽을 암호화하기 위한 사실상의 선택입니다. TLS는 이전 SSL과 마찬가지로 암호화 프로토콜을 사용하여 네트워크를 통해 보안 통신을 제공합니다. TLS는 대칭 암호화를 사용합니다. 여기서 데이터를 암호화하는 키는 세션 시작 시 협상된 공유 보안 암호를 기반으로 생성됩니다. 다음은 Kubernetes 환경에서 데이터를 암호화하는 몇 가지 방법입니다.

Nitro 인스턴스

C5n, G4, I3en, M5dn, M5n, P3dn, R5dn 및 R5n과 같은 Nitro 인스턴스 유형 간에 교환되는 트래픽은 기본적으로 자동으로 암호화됩니다. 전송 게이트웨이 또는 로드 밸런서와 같은 중간 홉이 있는 경우 트래픽은 암호화되지 않습니다. 전송 중 암호화에 대한 자세한 내용과 기본적으로 네트워크 암호화를 지원하는 인스턴스 유형의 전체 목록은 전송 중 암호화를 참조하세요.

컨테이너 네트워크 인터페이스(CNIs)

WeaveNet은 소매 트래픽의 경우 NaCl 암호화를, 빠른 데이터 경로 트래픽의 경우 IPsec ESP를 사용하여 모든 트래픽을 자동으로 암호화하도록 구성할 수 있습니다.

서비스 메시

App Mesh, Linkerd v2, Istio와 같은 서비스 메시를 사용하여 전송 중 암호화를 구현할 수도 있습니다. AppMesh는 X.509 인증서 또는 Envoy의 보안 암호 검색 서비스(SDS)를 통해 mTLS를 지원합니다. Linkerd와 Istio 모두 mTLS를 지원합니다.

aws-app-mesh-examples GitHub 리포지토리는 Envoy 컨테이너와 함께 X.509 인증서 및 SPIRE를 SDS 공급자로 사용하여 mTLS를 구성하는 방법을 안내합니다.

App Mesh는 AWS Certificate Manager(ACM)에서 발급한 프라이빗 인증서 또는 가상 노드의 로컬 파일 시스템에 저장된 인증서를 사용한 TLS 암호화도 지원합니다.

aws-app-mesh-examples GitHub 리포지토리는 ACM에서 발급한 인증서와 Envoy 컨테이너와 함께 패키징된 인증서를 사용하여 TLS를 구성하는 방법을 안내합니다.

수신 컨트롤러 및 로드 밸런서

수신 컨트롤러는 클러스터 외부에서 발생하는 HTTP/S 트래픽을 클러스터 내에서 실행되는 서비스로 지능적으로 라우팅하는 방법입니다. 이러한 수신은 Classic Load Balancer 또는 Network Load Balancer(NLB)와 같은 계층 4 Load Balancer가 앞에 오는 경우가 많습니다. 암호화된 트래픽은 로드 밸런서, 수신 리소스 또는 포드와 같이 네트워크 내의 여러 위치에서 종료될 수 있습니다. SSL 연결을 종료하는 방법과 위치는 궁극적으로 조직의 네트워크 보안 정책에 따라 결정됩니다. 예를 들어 end-to-end 암호화가 필요한 정책이 있는 경우 포드에서 트래픽을 해독해야 합니다. 이렇게 하면 초기 핸드셰이크를 설정하는 주기를 소비해야 하므로 포드에 추가 부담이 발생합니다. 전체 SSL/TLS 처리는 CPU 집약적입니다. 따라서 유연성이 있는 경우 수신 또는 로드 밸런서에서 SSL 오프로드를 수행해 보세요.

AWS Elastic 로드 밸런서에서 암호화 사용

AWS Application Load Balancer(ALB)와 Network Load Balancer(NLB) 모두 전송 암호화(SSL 및 TLS)를 지원합니다. ALB에 대한 alb.ingress.kubernetes.io/certificate-arn 주석을 사용하면 ALB에 추가할 인증서를 지정할 수 있습니다. 주석을 생략하면 컨트롤러는 호스트 필드를 사용하여 사용 가능한 AWS Certificate Manager(ACM) 인증서와 일치시켜 필요한 인증서를 리스너에 추가하려고 시도합니다. EKS v1.15부터 아래 예제와 같이 NLB와 함께 service.beta.kubernetes.io/aws-load-balancer-ssl-cert 주석을 사용할 수 있습니다.

apiVersion: v1 kind: Service metadata: name: demo-app namespace: default labels: app: demo-app annotations: service.beta.kubernetes.io/aws-load-balancer-type: "nlb" service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "<certificate ARN>" service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443" service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http" spec: type: LoadBalancer ports: - port: 443 targetPort: 80 protocol: TCP selector: app: demo-app //--- kind: Deployment apiVersion: apps/v1 metadata: name: nginx namespace: default labels: app: demo-app spec: replicas: 1 selector: matchLabels: app: demo-app template: metadata: labels: app: demo-app spec: containers: - name: nginx image: nginx ports: - containerPort: 443 protocol: TCP - containerPort: 80 protocol: TCP

다음은 SSL/TLS 종료에 대한 추가 예제입니다.

중요

AWS LB 컨트롤러와 같은 일부 수신은 수신 사양의 일부로 대신 주석을 사용하여 SSL/TLS를 구현합니다.

cert-manager를 사용하는 ACM Private CA

인증서를 배포, 갱신 및 취소하는 인기 있는 Kubernetes 추가 기능인 ACM Private Certificate Authority(CA) 및 cert-manager를 사용하여 TLS 및 mTLS를 활성화하여 수신 시, 포드에서, 포드 간에 EKS 애플리케이션 워크로드를 보호할 수 있습니다. ACM Private CA는 자체 CA를 관리하는 데 드는 선결제 및 유지 관리 비용 없이 가용성이 높고 안전한 관리형 CA입니다. 기본 Kubernetes 인증 기관을 사용하는 경우 보안을 개선하고 ACM Private CA의 규정 준수 요구 사항을 충족할 수 있습니다. ACM Private CA는 메모리에 인코딩된 키를 저장하는 기본 CA(안전하지 않음)와 비교하여 FIPS 140-2 레벨 3 하드웨어 보안 모듈(매우 안전)에서 프라이빗 키를 보호합니다. 또한 중앙 집중식 CA를 사용하면 Kubernetes 환경 내부 및 외부에서 프라이빗 인증서에 대한 제어를 강화하고 감사 가능성을 개선할 수 있습니다.

워크로드 간 상호 TLS를 위한 단기 CA 모드

EKS의 mTLS에 ACM Private CA를 사용하는 경우 수명이 짧은 CA 모드에서 수명이 짧은 인증서를 사용하는 것이 좋습니다. 범용 CA 모드에서 수명이 짧은 인증서를 발급할 수 있지만, 수명이 짧은 CA 모드를 사용하면 새 인증서를 자주 발급해야 하는 사용 사례에 더 비용 효율적으로(일반 모드보다 약 75% 저렴) 사용할 수 있습니다. 또한 프라이빗 인증서의 유효 기간을 EKS 클러스터의 포드 수명에 맞게 조정해야 합니다. 여기에서 ACM Private CA와 그 이점에 대해 자세히 알아보세요.

ACM 설정 지침

먼저 ACM Private CA 기술 문서에 제공된 절차에 따라 Private CA를 생성합니다. Private CA가 있으면 일반 설치 지침에 따라 cert-manager를 설치합니다. cert-manager를 설치한 후 GitHub의 설정 지침에 따라 Private CA Kubernetes cert-manager 플러그인을 설치합니다. 플러그인을 사용하면 cert-manager가 ACM Private CA에서 프라이빗 인증서를 요청할 수 있습니다.

이제 Private CA와 cert-manager 및 플러그인이 설치된 EKS 클러스터가 있으므로 권한을 설정하고 발급자를 생성할 차례입니다. ACM Private CA에 대한 액세스를 허용하도록 EKS 노드 역할의 IAM 권한을 업데이트합니다. 를 프라이빗 CA<CA_ARN>의 값으로 바꿉니다.

{ "Version": "2012-10-17", "Statement": [ { "Sid": "awspcaissuer", "Action": [ "acm-pca:DescribeCertificateAuthority", "acm-pca:GetCertificate", "acm-pca:IssueCertificate" ], "Effect": "Allow", "Resource": "<CA_ARN>" } ] }

IAM 계정 또는 IRSA에 대한 서비스 역할도 사용할 수 있습니다. 전체 예제는 아래의 추가 리소스 섹션을 참조하세요.

다음 텍스트가 포함된 cluster-issuer.yaml이라는 사용자 지정 리소스 정의 파일을 생성하고 <CA_ARN><Region> 정보를 프라이빗 CA로 대체하여 Amazon EKS에서 발급자를 생성합니다.

apiVersion: awspca.cert-manager.io/v1beta1 kind: AWSPCAClusterIssuer metadata: name: demo-test-root-ca spec: arn: <CA_ARN> region: <Region>

생성한 발급자를 배포합니다.

kubectl apply -f cluster-issuer.yaml

EKS 클러스터는 Private CA에서 인증서를 요청하도록 구성되어 있습니다. 이제 cert-manager의 Certificate 리소스를 사용하여 issuerRef 필드 값을 위에서 생성한 Private CA Issuer로 변경하여 인증서를 발급할 수 있습니다. 인증서 리소스를 지정하고 요청하는 방법에 대한 자세한 내용은 cert-manager의 인증서 리소스 가이드를 참조하세요. 여기에서 예제를 참조하세요.

Istio 및 cert-manager가 포함된 ACM Private CA

EKS 클러스터에서 Istio를 실행하는 경우 Istio 컨트롤 플레인(특히 istiod)이 루트 인증 기관(CA)으로 작동하지 않도록 비활성화하고 ACM Private CA를 워크로드 간 mTLS의 루트 CA로 구성할 수 있습니다. 이 접근 방식을 사용하는 경우 ACM Private CA에서 수명이 짧은 CA 모드를 사용하는 것이 좋습니다. 자세한 내용은 이전 섹션과이 블로그 게시물을 참조하세요.

Istio에서 인증서 서명 작동 방식(기본값)

Kubernetes의 워크로드는 서비스 계정을 사용하여 식별됩니다. 서비스 계정을 지정하지 않으면 Kubernetes가 워크로드에 자동으로 할당합니다. 또한 서비스 계정은 연결된 토큰을 자동으로 탑재합니다. 이 토큰은 서비스 계정에서 워크로드가 Kubernetes API에 대해 인증하는 데 사용됩니다. 서비스 계정은 Kubernetes의 자격 증명으로 충분할 수 있지만 Istio에는 자체 자격 증명 관리 시스템과 CA가 있습니다. 워크로드가 인코딩 사이드카 프록시로 시작되면 신뢰할 수 있는 것으로 간주되고 메시의 다른 서비스와 통신할 수 있도록 Istio에서 할당된 자격 증명이 필요합니다.

Istio에서이 자격 증명을 가져오기 위해는 인증서 서명 요청(또는 CSR)이라는 요청을 Istio 컨트롤 플레인으로 istio-agent 보냅니다. 이 CSR에는 처리 전에 워크로드의 자격 증명을 확인할 수 있도록 서비스 계정 토큰이 포함되어 있습니다. 이 확인 프로세스는 등록 기관(또는 RA)과 CA의 istiod역할을 하는에서 처리합니다. RA는 확인된 CSR만 CA로 전달하도록 하는 게이트키퍼 역할을 합니다. CSR이 확인되면 CA로 전달되어 서비스 계정에 SPIFFE 자격 증명이 포함된 인증서를 발급합니다. 이 인증서를 SPIFFE 확인 가능 자격 증명 문서(또는 SVID)라고 합니다. SVID는 식별을 위해 요청 서비스에 할당되고 통신 서비스 간에 전송 중인 트래픽을 암호화합니다.

Istio 인증서 서명 요청의 기본 흐름:

Istio 인증서 서명 요청의 기본 흐름

ACM Private CA를 사용하는 Istio에서 인증서 서명 작동 방식

Istio Certificate Signing Request 에이전트(istio-csr)라는 cert-manager 추가 기능을 사용하여 Istio를 ACM Private CA와 통합할 수 있습니다. 이 에이전트를 사용하면 Istio 워크로드 및 컨트롤 플레인 구성 요소를 인증서 관리자 발급자,이 경우 ACM Private CA로 보호할 수 있습니다. istio-csr 에이전트는 수신 CSR을 검증하는 기본 구성에서 istiod가 제공하는 것과 동일한 서비스를 노출합니다. CSRs 단, 확인 후에는 요청을 인증서 관리자가 지원하는 리소스(예: 외부 CA 발급자와의 통합)로 변환합니다.

워크로드에서 CSR이 있을 때마다 istio-csr로 전달되어 ACM Private CA에 인증서를 요청합니다. istio-csr와 ACM Private CA 간의이 통신은 AWS Private CA 발급자 플러그인에 의해 활성화됩니다. Cert Manager는이 플러그인을 사용하여 ACM Private CA에서 TLS 인증서를 요청합니다. 발급자 플러그인은 ACM Private CA 서비스와 통신하여 워크로드에 대해 서명된 인증서를 요청합니다. 인증서가 서명되면 istio-csr로 반환되어 서명된 요청을 읽고 CSR을 시작한 워크로드로 반환됩니다.

istio-csr을 사용한 Istio 인증서 서명 요청 흐름

image::istio-csr-with-acm-private-ca.png[istio-csr을 사용한 Istio 인증서 서명 요청 흐름]

프라이빗 CA 설정 지침이 포함된 Istio

  1. 먼저이 섹션의 동일한 설정 지침에 따라 다음을 완료합니다.

  2. 사설 CA 생성

  3. cert-manager 설치

  4. 발급자 플러그인 설치

  5. 권한을 설정하고 발급자를 생성합니다. 발급자는 CA를 나타내며 워크로드 인증서에 서명하고 istiod 메시하는 데 사용됩니다. ACM Private CA와 통신합니다.

  6. istio-system 네임스페이스를 생성합니다. 여기에서 istiod certificate 및 기타 Istio 리소스가 배포됩니다.

  7. AWS Private CA 발급자 플러그인으로 구성된 Istio CSR을 설치합니다. 워크로드에 대한 인증서 서명 요청을 보존하여 승인 및 서명()되었는지 확인할 수 있습니다preserveCertificateRequests=true.

    helm install -n cert-manager cert-manager-istio-csr jetstack/cert-manager-istio-csr \ --set "app.certmanager.issuer.group=awspca.cert-manager.io" \ --set "app.certmanager.issuer.kind=AWSPCAClusterIssuer" \ --set "app.certmanager.issuer.name=<the-name-of-the-issuer-you-created>" \ --set "app.certmanager.preserveCertificateRequests=true" \ --set "app.server.maxCertificateDuration=48h" \ --set "app.tls.certificateDuration=24h" \ --set "app.tls.istiodCertificateDuration=24h" \ --set "app.tls.rootCAFile=/var/run/secrets/istio-csr/ca.pem" \ --set "volumeMounts[0].name=root-ca" \ --set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \ --set "volumes[0].name=root-ca" \ --set "volumes[0].secret.secretName=istio-root-ca"
  8. 를 메시cert-manager istio-csr의 인증서 공급자로 대체할 사용자 지정 구성istiod으로 Istio를 설치합니다. 이 프로세스는 Istio 연산자를 사용하여 수행할 수 있습니다.

    apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: name: istio namespace: istio-system spec: profile: "demo" hub: gcr.io/istio-release values: global: # Change certificate provider to cert-manager istio agent for istio agent caAddress: cert-manager-istio-csr.cert-manager.svc:443 components: pilot: k8s: env: # Disable istiod CA Sever functionality - name: ENABLE_CA_SERVER value: "false" overlays: - apiVersion: apps/v1 kind: Deployment name: istiod patches: # Mount istiod serving and webhook certificate from Secret mount - path: spec.template.spec.containers.[name:discovery].args[7] value: "--tlsCertFile=/etc/cert-manager/tls/tls.crt" - path: spec.template.spec.containers.[name:discovery].args[8] value: "--tlsKeyFile=/etc/cert-manager/tls/tls.key" - path: spec.template.spec.containers.[name:discovery].args[9] value: "--caCertFile=/etc/cert-manager/ca/root-cert.pem" - path: spec.template.spec.containers.[name:discovery].volumeMounts[6] value: name: cert-manager mountPath: "/etc/cert-manager/tls" readOnly: true - path: spec.template.spec.containers.[name:discovery].volumeMounts[7] value: name: ca-root-cert mountPath: "/etc/cert-manager/ca" readOnly: true - path: spec.template.spec.volumes[6] value: name: cert-manager secret: secretName: istiod-tls - path: spec.template.spec.volumes[7] value: name: ca-root-cert configMap: defaultMode: 420 name: istio-ca-root-cert
  9. 생성한 위의 사용자 지정 리소스를 배포합니다.

    istioctl operator init kubectl apply -f istio-custom-config.yaml
  10. 이제 EKS 클러스터의 메시에 워크로드를 배포하고 mTLS를 적용할 수 있습니다.

Istio 인증서 서명 요청

image::istio-csr-requests.png[Istio 인증서 서명 요청]

도구 및 리소스