클러스터 보안 강화

Kubernetes에서의 개발 속도로 인해 종종 새로운 보안 기능을 사용하게 됩니다. 이 페이지에서는 Google Kubernetes Engine 클러스터를 강화하기 위한 최신 가이드를 구현하는 방법을 안내합니다. 보안 항목에 대한 일반적인 개요는 보안 개요를 읽어보세요.

Kubernetes 웹 UI(대시보드) 사용 중지

GKE에서 실행할 때는 Kubernetes 웹 UI(대시보드)를 사용 중지해야 합니다.

Kubernetes 웹 UI(대시보드)는 상위 권한의 Kubernetes 서비스 계정으로 지원됩니다. Cloud Console에서 대부분의 동일 기능을 제공하므로 이러한 권한이 필요하지 않습니다.

Kubernetes 웹 UI를 사용 중지하려면 다음을 수행하세요.

gcloud container clusters update [CLUSTER_NAME] \
    --update-addons=KubernetesDashboard=DISABLED

ABAC 사용 중지

ABAC(속성 기반 액세스 제어)를 사용 중지하고, 대신 GKE에서 RBAC(역할 기반 액세스 제어)를 사용해야 합니다.

Kubernetes에서 RBAC는 클러스터 및 네임스페이스 수준에서 리소스에 대한 권한을 부여하기 위해 사용됩니다. RBAC를 사용하면 권한 집합이 포함된 규칙을 사용하여 역할을 정의할 수 있습니다. RBAC는 중요한 보안 이점이 있으며, Kubernetes에서 현재 안정화되어 있으므로, 이제는 ABAC를 사용 중지해야 합니다.

아직 ABAC를 사용하는 경우에는 먼저 RBAC 사용을 위한 선행 조건을 참조하세요. 클러스터를 이전 버전에서 업그레이드했고, ABAC를 사용하는 경우에는 액세스 제어 구성을 업데이트해야 합니다.

gcloud container clusters update [CLUSTER_NAME] \
    --no-enable-legacy-authorization

위의 권장 사항에 따라 새 클러스터를 만들려면 다음을 사용하세요.

gcloud container clusters create [CLUSTER_NAME] \
    --no-enable-legacy-authorization

네트워크 정책으로 포드 간 트래픽 제한

기본적으로 클러스터에 있는 모든 포드는 서로 통신할 수 있습니다. 작업 부하의 필요에 따라 포드 간 통신을 제어해야 합니다.

클러스터 내에서 공격자의 측면 이동을 더 어렵게 만들기 위해 Kubernetes의 네트워크 정책을 사용할 수 있습니다. 또한 Kubernetes 네트워크 정책 API를 사용해서 포드 수준의 방화벽 규칙을 만들 수 있습니다. 이러한 방화벽 규칙은 클러스터 내에서 서로 액세스할 수 있는 포드 및 서비스를 결정합니다.

새 클러스터를 만들 때 네트워크 정책을 적용하려면 --enable-network-policy 플래그를 지정합니다.

gcloud container clusters create [CLUSTER_NAME] \
    --zone=[COMPUTE_ZONE] \
    --enable-network-policy

네트워크 정책을 사용 설정한 후에는 정책을 실제로 정의해야 합니다. 이것은 정확한 토폴로지에 따라 달라지므로, 여기에서는 특정 권장 사항을 제공할 수 없습니다. 하지만 Kubernetes 문서에는 간단한 nginx 배포를 위한 훌륭한 연습이 포함되어 있습니다.

GKE에서의 네트워크 정책에 대해 자세히 알아보려면 클러스터 네트워크 정책 설정을 참조하세요.

NetworkPolicy와 PodSecurityPolicy 함께 사용

NetworkPolicy를 사용 중이며 PodSecurityPolicy의 적용을 받는 Pod가 있는 경우 PodSecurityPolicy를 사용할 권한이 있는 RBAC Role 또는 ClusterRole을 만듭니다. 그런 다음 Pod의 서비스 계정에 역할 또는 Role 또는 ClusterRole을 바인딩합니다. 이 경우 사용자 계정에 권한을 부여하는 것만으로는 충분하지 않습니다. 자세한 내용은 정책 승인을 참조하세요.

노드에 최소 권한 서비스 계정 사용

각 GKE 노드에는 IAM 서비스 계정이 연결되어 있습니다. 기본적으로 노드에는 Compute Engine 기본 서비스 계정이 제공되며, 이는 Cloud Console의 IAM 섹션으로 이동하여 찾을 수 있습니다. 이 계정은 기본적으로 넓은 액세스 범위를 포함하기 때문에, 다양한 애플리케이션에 유용하지만, Kubernetes Engine 클러스터를 실행하는 데 필요한 것보다 많은 권한을 포함합니다. Compute Engine 기본 서비스 계정을 사용하는 대신 GKE 클러스터를 실행하는 데 필요한 최소 권한만 있는 서비스 계정을 만들어서 사용해야 합니다.

GKE에는 최소한 monitoring.viewer, monitoring.metricWriter, logging.logWriter 역할이 포함된 서비스 계정이 필요합니다. 모니터링 역할로깅 역할에 대해 자세히 알아보세요.

다음 명령어는 GKE를 작동하는 데 필요한 최소 권한으로 IAM 서비스 계정을 만듭니다.

gcloud iam service-accounts create [SA_NAME] \
    --display-name=[SA_NAME]

gcloud projects add-iam-policy-binding [PROJECT_ID] \
    --member "serviceAccount:[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com" \
    --role roles/logging.logWriter

gcloud projects add-iam-policy-binding [PROJECT_ID] \
    --member "serviceAccount:[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com" \
    --role roles/monitoring.metricWriter

gcloud projects add-iam-policy-binding [PROJECT_ID] \
    --member "serviceAccount:[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com" \
    --role roles/monitoring.viewer

또한 Google Container Registry에서 비공개 이미지를 사용할 때는 이에 대한 액세스 권한을 부여해야 합니다.

gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member "serviceAccount:[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com" \
  --role roles/storage.objectViewer

다른 사용자가 이 서비스 계정으로 새 클러스터 또는 노드 풀을 만들 수 있도록 하려면 이 서비스 계정에 서비스 계정 사용자 역할을 부여해야 합니다.

gcloud iam service-accounts add-iam-policy-binding \
  [SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com \
  --member=user:[USER] \
  --role=roles/iam.serviceAccountUser

클러스터가 이미 있으면 이제 이 새로운 서비스 계정으로 새로운 노드 풀을 만들 수 있습니다.

gcloud container node-pools create [NODE_POOL] \
  --service-account=[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com" \
  --cluster=[CLUSTER_NAME]

GKE 클러스터에 다른 Google Cloud 서비스에 대한 액세스 권한이 필요하면, 추가 서비스 계정을 만들고, Kubernetes 보안 비밀에 해당 비공개 키를 저장하여 서비스 계정에 대한 액세스 권한을 작업 부하에 부여해야 합니다. 자세한 내용은 서비스 계정으로 Google Cloud Platform 인증을 참조하세요.

노드 서비스 계정 범위 축소

커스텀 서비스 계정을 사용하지 않으려는 경우의 다른 대안은 기본 노드 서비스 계정의 권한을 축소하는 것입니다.

기본적으로 노드 서비스 계정에는 액세스 범위가 포함됩니다. 액세스 범위는 인스턴스에 권한을 지정하는 기존 방법입니다. IAM 역할 이전에는 액세스 범위가 서비스 계정에 권한을 부여하기 위한 유일한 방법이었습니다.

노드에 대해 개별적인 서비스 계정을 만드는 경우가 아니라면, 권한 상승 공격 가능성을 줄이기 위해 노드 서비스 계정의 범위를 제한해야 합니다. 이렇게 하면 클러스터를 실행하는 데 필요한 것 이상의 권한이 기본 서비스 계정에 포함되지 않도록 보장할 수 있습니다. 기본 범위가 제한되더라도, 클러스터를 실행하는 데 필요한 최소 범위를 넘는 권한 범위가 포함될 수 있습니다.

GKE에서 노드의 기본 범위는 devstorage.read_only, logging.write, monitoring, service.management.readonly, servicecontrol, trace.append입니다. 범위를 설정할 때는 gke-default로 지정됩니다. Google Container Registry에서 비공개 이미지에 액세스하는 경우 필요한 최소 범위는 logging.write, monitoring, devstorage.read_only뿐입니다.

커스텀 범위로 클러스터를 만들려면 --scopes 옵션을 사용하세요.

gcloud container clusters create [CLUSTER_NAME] \
    --scopes=[CUSTOM_SCOPES]

커스텀 서비스 계정에 범위를 지정하지 않으면 gke-default가 사용됩니다. 커스텀 서비스 계정을 지정할 경우 cloud-platformuserinfo.email이 사용됩니다.

gcloud 구성에 container/new_scopes_behavior true가 포함된 경우, 이 동작은 모든 Kubernetes 버전에 대해 이미 사용 설정되어 있습니다. 해당 환경의 기본값을 설정하려면 다음을 사용하세요.

gcloud config set container/new_scopes_behavior true

모든 범위의 권한에 대해 자세히 알아보려면 Google 범위를 참조하세요.

클라이언트 인증 방법 제한

Kubernetes API 서버에 인증하는 방법은 몇 가지가 있습니다. GKE에서 지원되는 방법은 OpenID 연결 토큰, x509 클라이언트 인증서, 정적 암호입니다. OpenID 연결 토큰 방법의 경우 GKE는 Kubernetes 구성을 설정하고, 액세스 토큰을 가져오고, 이를 최신 상태로 유지하는 방식으로 gcloud를 통해 인증을 관리합니다.

다른 인증 방법인 x509 인증서와 정적 암호는 클러스터를 손상시킬 수 있는 다양한 공격 범위가 노출됩니다. 이러한 다른 방법을 사용할 경우에는 사용자가 새 클러스터를 만들 때 사용자 인증 정보가 생성됩니다. 애플리케이션에 이러한 인증 방법이 사용되지 않는 한 이를 사용 중지해야 합니다. OpenID 인증 방법을 사용하고, 클러스터의 클라이언트 인증서 및 정적 암호 인증 방법은 사용 중지해야 합니다.

클라이언트 인증서 및 정적 암호는 container.clusters.getCredentials 권한이 있는 사용자만 검색할 수 있습니다. roles/container.admin, roles/owner, roles/editor 역할 모두 이 권한이 포함되므로, 이러한 역할은 현명하게 사용해야 합니다. GKE IAM 역할에 대해 자세히 읽어보세요.

클라이언트 인증서를 사용한 인증 사용 중지

인증서 인증의 경우, 클라이언트는 API 서버가 지정된 인증 기관에 확인하는 인증서를 제공합니다. GKE에서 클라이언트 인증서는 클러스터 루트 인증 기관에 의해 서명됩니다.

ABAC의 경우 클라이언트 인증서는 기본적으로 API 서버에 인증할 수 있습니다. 하지만 RBAC가 사용 설정된 경우에는 클라이언트 인증서에 권한이 부여되어 있어야 합니다. RBAC가 사용 설정되고 ABAC가 사용 중지된 클러스터에 이러한 인증서가 포함되더라도, 이러한 인증서는 실제로 쓸모가 없습니다.

클라이언트 인증서를 생성하지 않고 클러스터를 만들려면 --no-issue-client-certificate 플래그를 사용하세요.

gcloud container clusters create [CLUSTER_NAME] \
    --no-issue-client-certificate

현재까지는 기존 클러스터에서 클라이언트 인증서를 삭제할 수 있는 방법이 없습니다.

정적 암호를 사용한 인증 사용 중지

정적 암호는 API 서버가 검증하는 사용자 이름과 암호의 조합입니다. GKE에서 정적 암호는 기본적으로 사용자 이름 'admin'에 대해 생성됩니다.

정적 암호를 생성하지 않고 클러스터를 만들려면 --no-enable-basic-auth 옵션을 사용하세요.

gcloud container clusters create [CLUSTER_NAME] \
    --no-enable-basic-auth

기존 클러스터를 업데이트하고 정적 암호를 삭제하려면 다음을 사용하세요.

gcloud container clusters update [CLUSTER_NAME] \
    --no-enable-basic-auth

노드 메타데이터 보호

Kubernetes에 대한 일부 실제 공격은 노드의 사용자 인증 정보를 추출하기 위해 VM 메타데이터 서버에 액세스합니다.

위에 설명된 대로 최소 권한의 서비스 계정을 사용하는 것이 이러한 공격을 완화하기 위한 첫 번째 단계입니다. 다음 단계는 작업 부하가 노드를 가장하지 못하도록 방지하는 것입니다. 클러스터에서 실행되는 작업 부하로부터 민감한 시스템 메타데이터를 보호하기 위해서는 이전의 메타데이터 서버 API를 사용 중지하고 메타데이터 은닉을 사용해야 합니다.

자세한 내용은 클러스터 메타데이터 보호를 참조하세요.

자동으로 노드 업그레이드

보안 향상을 위한 가장 간단한 방법 중 하나는 Kubernetes 버전을 최신 상태로 유지하는 것입니다. Kubernetes에는 새로운 보안 기능과 보안 패치가 자주 제공됩니다.

Google Kubernetes Engine에서 마스터는 자동으로 패치 및 업그레이드되지만, 노드는 사용자가 직접 관리해야 합니다. 노드 풀에 필요한 업그레이드 및 보안 패치를 자동으로 받을 수 있도록 노드 자동 업그레이드를 사용 설정해야 합니다.

자세한 내용은 노드 자동 업그레이드를 참조하세요.

노드 자동 업그레이드를 사용 설정하지 않으려면, Kubernetes Engine 보안 게시판에서 보안 패치 정보를 신중하게 확인해야 합니다.

포드 보안 정책을 사용하여 포드 권한 제한(베타)

기본적으로 Kubernetes에서 포드는 필요한 것 이상의 기능으로 작동될 수 있습니다. 해당 작업 부하에 필요한 정도로만 포드 기능을 제한해야 합니다.

Kubernetes는 필요한 최소 기능만으로 포드 실행을 제한하기 위한 방법을 제공합니다. 포드 보안 정책을 사용하면 포드에 대한 스마트 기본값을 설정하고, 시스템 전체에서 사용 설정하려는 제어 방법을 적용할 수 있습니다. 이러한 정책은 애플리케이션의 요구에 맞게 정의해야 합니다. 이를 위해서는 restricted-psp.yaml 예제 정책을 좋은 출발점으로 사용할 수 있습니다.

Pod 보안 정책에 대해 자세히 알아 보려면 PodSecurityPolicies 사용을 참조하세요.

클러스터에서 네트워크 정책과 Pod 보안 정책을 모두 사용하는 경우 네트워크 정책과 Pod 보안 정책 함께 사용을 참조하세요.

클러스터 탐색 RBAC 권한 제한

기본적으로 Kubernetes는 CustomResourceDefinitions의 항목을 포함한 클러스터의 API 정보에 대한 광범위한 액세스 권한을 부여하는 방임적인 discovery ClusterRoleBindings 집합으로 클러스터를 부트스트랩합니다.

사용자는 system:discoverysystem:basic-user ClusterRoleBindings의 대상에 포함된 system:authenticated 그룹이 유효한 Google 사용자 인증 정보(예를 들어 Gmail 사용자)가 있는 모든 사람을 포함한 누구나 포함할 수 있으며 GKE의 클러스터에 대한 유의미한 수준의 보안을 반영하지 않는다는 점을 알아야 합니다.

클러스터의 탐색 API를 강화하고자 하는 경우 다음 중 하나 또는 여러 가지를 고려해야 합니다.

  • 승인된 네트워크를 구성하여 설정된 IP 범위에 대한 액세스를 제한
  • 비공개 클러스터를 설정하여 VPC 액세스 제한
  • 기본 system:discoverysystem:basic-user ClusterRoleBindings의 대상 선별. 예를 들어 system:(un)authenticated 액세스를 허용하는 Kubernetes 기본값 대신 system:serviceaccounts 그룹 및 다른 알려진 사용자 및 그룹 액세스만 허용하는 것을 고려

다음 단계

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

Kubernetes Engine 문서