보안 개요


Google Kubernetes Engine(GKE)은 워크로드를 보호하는 데 유용하고 다양한 방법을 제공합니다. GKE에서 워크로드를 보호하려면 컨테이너 이미지 콘텐츠, 컨테이너 런타임, 클러스터 네트워크, 클러스터 API 서버에 대한 액세스 등 여러 스택 레이어가 필요합니다.

클러스터와 워크로드를 보호하려면 계층화된 접근 방식을 취하는 것이 가장 좋습니다. 사용자와 애플리케이션에 제공되는 액세스 수준에 최소 권한 원칙을 적용할 수 있습니다. 레이어마다 조직이 워크로드를 안전하게 배포하고 유지하는 데 적절한 수준의 유연성과 보안의 절충점이 다를 수 있습니다. 예를 들어 일부 보안 설정은 너무 제약이 커서 상당한 리팩터링 없이는 특정 유형의 애플리케이션이나 사용 사례가 작동하지 않을 수 있습니다.

이 문서는 인프라의 각 레이어를 간단히 설명하고 필요에 가장 적합하게 보안 기능을 구성하는 방법을 보여 줍니다.

인증 및 승인

Kubernetes는 두 가지 인증 유형을 지원합니다.

  1. 사용자 계정은 Kubernetes가 알고 있지만 관리하지 않는 계정입니다. 예를 들어 kubectl을 사용하여 사용자 계정을 만들거나 삭제할 수 없습니다.
  2. 서비스 계정은 Kubernetes가 만들고 관리하지만 포드 등 Kubernetes가 만든 항목에서만 사용할 수 있는 계정입니다.

GKE 클러스터에서 Kubernetes 사용자 계정은 Google Cloud에서 관리되며 다음 두 가지 유형 중 하나일 수 있습니다.

  1. Google 계정
  2. Google Cloud 서비스 계정

인증 후 Kubernetes 리소스를 만들거나 읽거나 업데이트하거나 삭제할 수 있도록 이러한 ID를 승인해야 합니다.

Kubernetes 서비스 계정과 Google Cloud 서비스 계정은 이름은 비슷하지만 서로 다른 항목입니다. Kubernetes 서비스 계정은 계정이 정의되는 클러스터의 일부이며 일반적으로 이 클러스터 내에서 사용됩니다. 반면 Google Cloud 서비스 계정은 Google Cloud 프로젝트의 일부이며 클러스터 내에서나 Google Cloud 프로젝트 클러스터 자체뿐만 아니라 Identity and Access Management(IAM)를 사용하는 모든 Google Cloud 리소스에게 권한을 쉽게 부여할 수 있습니다. 이렇게 하면 Google Cloud 서비스 계정이 Kubernetes 서비스 계정보다 더 강력해집니다. 최소 권한의 보안 원칙을 따르기 위해 관련 권한이 필요한 경우에만 Google Cloud 서비스 계정을 사용해야 합니다.

클러스터 수준 또는 Kubernetes 네임스페이스 안에서 Kubernetes 리소스에 대한 보다 상세한 액세스를 구성하려면 역할 기반 액세스 제어(RBAC)를 사용하세요. RBAC를 사용하면 사용자와 서비스 계정의 액세스를 허용하는 작업과 리소스를 정의하는 상세한 정책을 만들 수 있습니다. RBAC로 Google 계정, Google Cloud 서비스 계정, Kubernetes 서비스 계정의 액세스를 제어할 수 있습니다. GKE의 인증 및 승인 전략을 더 단순화하고 간소화하려면 Kubernetes RBAC와 IAM이 신뢰할 수 있는 소스가 되도록 기존 속성 기반 액세스 제어를 중지해야 합니다.

추가 정보:

제어 영역 보안

GKE에서 Kubernetes 제어 영역 구성요소는 Google에서 관리하고 유지합니다. 제어 영역 구성요소는 API 서버, 스케줄러, 컨트롤러 관리자 및 Kubernetes 구성이 유지되는 etcd 데이터베이스를 비롯한 Kubernetes 제어 영역을 실행하는 소프트웨어를 호스팅합니다.

기본적으로 제어 영역 구성요소는 공개 IP 주소를 사용합니다. 제어 영역에 비공개 IP 주소를 할당하고 공개 IP 주소에서 액세스할 수 없도록 하는 승인된 네트워크비공개 클러스터를 사용하여 Kubernetes API 서버를 보호할 수 있습니다.

IAM을 ID 공급업체로 사용하여 Google Kubernetes Engine에서 클러스터 인증을 처리할 수 있습니다. 인증에 대한 자세한 내용은 Kubernetes API 서버에 인증을 참조하세요.

제어 영역을 보호하는 데 유용한 또 다른 방법은 정기적으로 사용자 인증 정보를 순환하는 것입니다. 사용자 인증 정보 순환이 시작되면 SSL 인증서와 클러스터 인증 기관이 순환됩니다. 이 프로세스는 GKE에 의해 자동화되며 제어 영역 IP 주소가 순환되도록 합니다.

추가 정보:

노드 보안

GKE는 Google Cloud 프로젝트에서 실행 중인 Compute Engine 인스턴스에 워크로드를 배포합니다. 이러한 인스턴스는 노드로 GKE 클러스터에 연결됩니다. 다음 섹션에서는 Google Cloud에서 사용할 수 있는 노드 수준 보안 기능을 활용하는 방법을 설명합니다.

Container-Optimized OS

기본적으로 GKE 노드는 Google의 Container-Optimized OS를 Kubernetes와 구성요소가 실행되는 운영체제로 사용합니다. Container-Optimized OS는 GKE 클러스터의 보안을 강화하기 위해 다음을 포함한 몇 가지 고급 기능을 구현합니다.

  • 잠긴 방화벽
  • 가능한 경우 읽기 전용 파일 시스템
  • 제한된 사용자 계정 및 루트 로그인 사용 중지

GKE Autopilot 노드는 항상 Container-Optimized OS를 운영체제로 사용합니다.

노드 업그레이드

권장사항은 정기적으로 OS를 패치하는 것입니다. 때때로 컨테이너 런타임, Kubernetes 자체 또는 노드 운영 체제의 보안 문제로 인해 노드를 긴급히 업그레이드해야 하는 경우가 있습니다. 노드를 업그레이드하면 노드의 소프트웨어가 최신 버전으로 업그레이드됩니다.

GKE 클러스터는 자동 업그레이드를 지원합니다. Autopilot 클러스터에서는 자동 업그레이드가 항상 사용 설정됩니다. Standard 클러스터의 노드를 수동으로 업그레이드할 수도 있습니다.

신뢰할 수 없는 워크로드로부터 노드 보호

알 수 없거나 신뢰할 수 없는 워크로드를 실행하는 클러스터의 경우, 포드에서 실행되는 신뢰할 수 없는 워크로드에서 노드의 운영 체제를 보호하는 것이 좋습니다.

예를 들어 SaaS(Software-as-a-Service) 제공 업체와 같은 멀티 테넌트 클러스터 는 사용자가 제출한 알 수 없는 코드를 실행하는 경우가 많습니다. 보안 조사는 기본적인 노드 제공 사항보다 더 강력한 워크로드 격리가 필요할 수 있는 또 다른 애플리케이션입니다.

클러스터의 GKE Sandbox를 사용 설정하여 노드의 샌드박스에서 신뢰할 수 없는 워크로드를 격리할 수 있습니다. GKE Sandbox는 오픈소스 프로젝트인 gVisor를 사용하여 빌드되었습니다.

인스턴스 메타데이터 보안

GKE는 기본 Compute Engine 인스턴스의 인스턴스 메타데이터를 사용하여 노드를 부트스트랩하고 제어 영역에 연결하는 데 사용되는 사용자 인증 정보와 구성을 노드에 제공합니다. 이 메타데이터에는 노드의 포드가 액세스할 필요가 없는 민감한 정보(예: 노드의 서비스 계정 키)가 포함됩니다.

GKE용 워크로드 아이덴티티 제휴를 사용하여 민감한 인스턴스 메타데이터 경로를 잠글 수 있습니다. GKE용 워크로드 아이덴티티 제휴는 클러스터에서 GKE 메타데이터 서버를 사용 설정하여 요청을 kube-env와 같은 민감한 필드로 필터링합니다.

GKE용 워크로드 아이덴티티 제휴는 항상 Autopilot 클러스터에서 사용 설정됩니다. Standard 클러스터에서는 GKE용 워크로드 아이덴티티 제휴를 수동으로 사용 설정하지 않는 한 포드가 인스턴스 메타데이터에 액세스할 수 있습니다.

네트워크 보안

GKE에서 실행되는 대부분의 워크로드는 클러스터 내부나 외부에서 실행될 수 있는 다른 서비스와 통신해야 합니다. 몇 가지 다른 방법을 사용하여 클러스터와 포드를 통과할 수 있는 트래픽을 제어할 수 있습니다.

포드 간 통신 제한

기본적으로 클러스터의 모든 포드는 포드 IP 주소를 통해 네트워크에서 도달할 수 있습니다. 마찬가지로 이그레스 트래픽은 클러스터가 배포된 VPC 내의 액세스 가능한 모든 주소로의 아웃바운드 연결을 기본적으로 허용합니다.

클러스터 관리자와 사용자는 네트워크 정책을 사용하여 네임스페이스의 포드와의 수신 및 송신 연결을 잠글 수 있습니다. 기본적으로 정의된 네트워크 정책이 없으면 모든 인그레스 및 이그레스 트래픽이 모든 포드를 드나들 수 있습니다. 네트워크 정책을 통해 태그를 사용하여 포드를 통과하는 트래픽을 정의할 수 있습니다.

네임스페이스에서 네트워크 정책이 적용되면 구성된 라벨과 일치하지 않는 포드를 드나드는 모든 트래픽이 삭제됩니다. 클러스터 및 네임스페이스를 만드는 과정에서 모든 포드의 인그레스 및 이그레스 트래픽 기본 거부를 적용하여 클러스터에 추가되는 모든 새 워크로드가 필요한 트래픽을 명시적으로 승인하도록 할 수 있습니다.

추가 정보:

부하 분산 트래픽 필터링

네트워크 부하 분산기를 사용하여 Kubernetes 포드의 부하를 분산하려면 포드의 라벨과 일치하는 LoadBalancer 유형의 서비스를 만들어야 합니다. 서비스가 생성되면 Kubernetes 포드의 포트에 매핑되는 외부 공개 IP가 생성됩니다. IP 주소를 기준으로 필터링하는 kube-proxy를 통해 승인된 트래픽이 노드 수준에서 필터링됩니다.

이 필터링을 구성하려면 서비스 객체의 loadBalancerSourceRanges 구성을 사용하면 됩니다. 이 구성 매개변수를 사용하면 서비스에 대한 액세스를 허용할 CIDR 범위 목록을 제공할 수 있습니다. loadBalancerSourceRanges를 구성하지 않으면 모든 주소가 외부 IP를 통해 서비스에 액세스할 수 있습니다.

서비스에 대한 외부 액세스가 필요하지 않으면 내부 부하 분산기를 사용하는 것이 좋습니다. 또한 내부 부하 분산기는 VPC 내부로부터 들어오는 트래픽을 필터링해야 할 때 loadBalancerSourceRanges를 적용합니다.

자세한 내용은 내부 부하 분산 튜토리얼을 참조하세요.

워크로드 보안

사용자는 Kubernetes를 통해 컨테이너 기반 워크로드를 신속하게 프로비저닝, 확장, 업데이트할 수 있습니다. 이 섹션에서는 실행 중인 컨테이너가 같은 클러스터의 다른 컨테이너, 컨테이너가 실행될 수 있는 노드, 사용자 프로젝트에서 사용 설정된 Google Cloud 서비스에 미치는 영향을 제한하도록 관리자와 사용자가 사용할 수 있는 방법을 설명합니다.

포드 컨테이너 프로세스 권한 제한

컨테이너식 프로세스의 권한 제한은 클러스터 전체 보안에 중요합니다. GKE Autopilot 클러스터는 Autopilot 보안 기능에 설명된 대로 항상 특정 권한을 제한합니다.

GKE를 사용하면 포드와 컨테이너 모두에서 보안 컨텍스트를 통해 보안 관련 옵션을 설정할 수 있습니다. 이러한 설정을 통해 변경할 수 있는 프로세스 보안 설정은 다음과 같습니다.

  • 실행할 사용자와 그룹
  • 사용할 수 있는 Linux 기능
  • 권한 상승 기능

포드 또는 컨테이너 수준이 아닌 클러스터 수준에서 이러한 제한사항을 적용하려면 PodSecurityAdmission 컨트롤러를 사용합니다. 클러스터 관리자는 PodSecurityAdmission을 사용하여 클러스터 또는 네임스페이스의 모든 포드가 포드 보안 표준의 사전 정의된 정책을 준수하도록 할 수 있습니다. 게이트키퍼를 사용하여 클러스터 수준에서 커스텀 포드 보안 정책을 설정할 수도 있습니다.

GKE 노드 기본 운영체제인 Container-Optimized OS 및 Ubuntu 모두 Kubernetes에서 시작된 모든 컨테이너에 기본 Docker AppArmor 보안 정책을 적용합니다. GitHub에서 프로필 템플릿을 확인할 수 있습니다. 무엇보다 이 프로필은 컨테이너에 대해 다음과 같은 기능을 거부합니다.

  • /proc/에서 직접 파일 쓰기
  • 프로세스 ID 디렉터리(/proc/<number>)에 없는 파일에 쓰기
  • /proc/sys/kernel/shm* 이외의 /proc/sys에 있는 파일에 쓰기
  • 파일 시스템 마운트

추가 정보:

포드에 Google Cloud 리소스에 대한 액세스 권한 부여

컨테이너와 포드가 Google Cloud의 다른 리소스에 액세스해야 할 수도 있습니다. 액세스 방법에는 다음 세 가지가 있습니다.

포드가 Google Cloud 리소스에 액세스하도록 승인하는 가장 안전한 방법은 GKE용 워크로드 아이덴티티 제휴를 사용하는 것입니다. GKE용 워크로드 아이덴티티 제휴를 통해 Kubernetes 서비스 계정을 IAM 서비스 계정으로 실행할 수 있습니다. Kubernetes 서비스 계정으로 실행되는 Pod는 IAM 서비스 계정의 권한을 가집니다.

GKE용 워크로드 아이덴티티 제휴는 GKE Sandbox에서 사용할 수 있습니다.

노드 서비스 계정

표준 클러스터에서는 포드가 노드의 Compute Engine 가상 머신(VM)에서 사용하는 서비스 계정의 사용자 인증 정보를 사용하여 Google Cloud를 인증할 수도 있습니다.

GKE Sandbox는 Compute Engine 메타데이터 서버에 대한 액세스를 차단하므로 GKE Sandbox에서는 이 방법을 사용할 수 없습니다.

서비스 계정 키를 사용하여 애플리케이션에 Google Cloud 리소스의 사용자 인증 정보를 부여할 수 있습니다. 이 방법은 계정 키를 안전하게 관리하기 어렵기 때문에 권장되지 않습니다.

이 방법을 선택하면 애플리케이션에 최소 필수 권한이 있도록 각 애플리케이션에 대해 커스텀 IAM 서비스 계정을 사용합니다. 페어링된 애플리케이션이 성공적으로 작동하는 데 필요한 최소 IAM 역할을 각 서비스 계정에 부여합니다. 서비스 계정을 애플리케이션별로 유지하면 손상이 발생할 경우, 다른 애플리케이션에 영향을 주지 않고 액세스 권한을 보다 쉽게 취소할 수 있습니다. 서비스 계정에 올바른 IAM 역할을 할당하면 JSON 서비스 계정 키를 만든 후 Kubernetes 보안 비밀을 사용하여 해당 키를 포드에 마운트할 수 있습니다.

Binary Authorization 사용

Binary Authorization은 클라우드에서 실행되는 애플리케이션에 소프트웨어 공급망 보안을 제공하는 Google Cloud 서비스입니다. Binary Authorization은 Artifact Registry 또는 다른 컨테이너 이미지 레지스트리에서 GKE에 배포하는 이미지에서 작동합니다.

Binary Authorization을 시행하면 애플리케이션을 프로덕션 환경에 배포하기 전에 소프트웨어의 품질과 무결성을 보호하는 내부 프로세스가 성공적으로 완료되었는지 확인할 수 있습니다. Binary Authorization을 사용 설정하여 클러스터를 만드는 방법은 Binary Authorization 문서클러스터 만들기를 참조하세요.

Binary Authorization 지속적 검증(CV)을 사용하면 포드와 연결된 컨테이너 이미지가 진화하는 내부 프로세스를 준수하는지 확인하기 위해 정기적으로 모니터링되도록 할 수 있습니다.

감사 로깅

감사 로깅은 관리자가 GKE 환경에서 발생하는 이벤트를 보관, 쿼리, 처리하고 알릴 수 있는 방법을 제공합니다. 관리자는 로깅된 정보를 사용하여 포렌식 분석 또는 실시간 알림을 수행하거나 다양한 GKE 클러스터 사용 방법과 사용자를 분류할 수 있습니다.

기본적으로 GKE는 관리자 활동 로그를 로깅합니다. 원하는 경우, 검사하려는 작업 유형에 따라 데이터 액세스 이벤트를 로깅할 수도 있습니다.

추가 정보:

보안 조치 기본 제공

GKE는 클러스터의 시스템 객체에 수행할 수 있는 작업에 특정 제한을 적용합니다. 워크로드 패치 적용과 같은 작업을 수행하면 GKE Warden이라는 허용 웹훅이 제한된 작업 집합을 기준으로 요청을 검증하고 요청을 허용할지 여부를 결정합니다.

Autopilot 클러스터 보안 조치

Autopilot 클러스터는 Google의 전문 지식과 업계 권장사항에 따라 여러 보안 설정을 적용합니다. 자세한 내용은 Autopilot의 보안 조치를 참조하세요.

표준 클러스터 보안 조치

표준 클러스터는 기본적으로 Autopilot 클러스터보다 더 많이 허용됩니다. GKE Standard 클러스터에는 다음과 같은 보안 설정이 있습니다.

  • kube-system 네임스페이스의 워크로드와 같이 GKE 관리 시스템 워크로드에 사용되는 ServiceAccount는 업데이트할 수 없습니다.
  • cluster-admin 기본 ClusterRole을 system:anonymous, system:unauthenticated 또는 system:authenticated 그룹에 결합할 수 없습니다.