역할 기반 액세스 제어를 사용한 클러스터의 작업 승인


이 페이지에서는 Kubernetes에서 기본 제공되는 역할 기반 액세스 제어(RBAC) 메커니즘을 사용하여 Google Kubernetes Engine(GKE) 클러스터의 리소스에 대한 작업을 승인하는 방법을 보여줍니다.

RBAC는 Kubernetes의 핵심 보안 기능으로, 이를 통해 사용자와 워크로드가 클러스터의 리소스에 수행할 수 있는 작업을 관리하는 세분화된 권한을 만들 수 있습니다. 플랫폼 관리자는 RBAC 역할을 만들고 이러한 역할을 서비스 계정 또는 그룹과 같은 인증된 사용자인 주체에 결합합니다. Kubernetes RBAC는 기본적으로 사용 설정되어 있습니다.

시작하기 전에

시작하기 전에 다음 태스크를 수행했는지 확인합니다.

  • Google Kubernetes Engine API를 사용 설정합니다.
  • Google Kubernetes Engine API 사용 설정
  • 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치한 경우 gcloud components update를 실행하여 최신 버전을 가져옵니다.

Identity and Access Management와 상호작용

Identity and Access Management(IAM) Kubernetes RBAC를 모두 사용하여 GKE 클러스터에 대한 액세스를 제어할 수 있습니다.

  • IAM은 Kubernetes에 국한되지 않습니다. 다양한 Google Cloud 제품의 ID 관리 기능을 제공하며 주로 Google Cloud 프로젝트 수준에서 작동합니다.

  • Kubernetes RBAC는 Kubernetes의 핵심 구성요소로, 클러스터에 속한 객체 또는 객체 유형에 대한 역할(권한 집합)을 만들고 부여할 수 있습니다.

  • 작업을 승인하기 위해 GKE는 먼저 RBAC 정책을 확인합니다. RBAC 정책이 없으면 GKE가 IAM 권한을 확인합니다.

GKE에서는 IAM과 Kubernetes RBAC가 서로 연동하여 사용자의 작업 수행을 승인합니다. 사용자는 둘 중 하나의 도구에서만 충분한 권한을 가지고 있으면 됩니다. 기본적으로 Google Cloud 사용자에게는 Kubernetes RBAC RoleBindings가 없으므로 GKE 클러스터를 준비하는 과정에서 이는 중요 부분을 차지합니다.

Google Cloud 계정을 통해 사용자를 승인하려면 먼저 이 계정으로 인증하도록 클라이언트를 올바르게 구성해야 합니다. 예를 들어 kubectl을 사용하는 경우 승인이 필요한 명령어를 실행하기 전에 Google Cloud를 인증하도록 kubectl 명령어를 구성해야 합니다.

거의 모든 경우에 IAM 대신 Kubernetes RBAC를 사용할 수 있습니다. GKE 사용자는 적어도 클러스터가 포함된 프로젝트의 container.clusters.get IAM 권한을 필요로 합니다. 이 권한은 container.clusterViewer 역할과 더 높은 권한을 가진 다른 역할에 포함되어 있습니다. 사용자가 프로젝트의 클러스터에 인증하려면 container.clusters.get 권한이 필요하지만 이 권한은 이 클러스터 내에서 작업 수행을 승인하지 않습니다. 그러면 IAM 또는 Kubernetes RBAC에서 승인을 제공할 수 있습니다.

권한 정의 및 할당

ClusterRoleRole 객체에서 RBAC 규칙을 정의한 후 다음과 같이 해당 규칙을 ClusterRoleBindingRoleBinding 객체와 함께 할당할 수 있습니다.

  • ClusterRole: RoleBinding 또는 ClusterRoleBinding을 사용하여 사용자 또는 그룹에 할당할 수 있는 리소스 및 허용 작업의 클러스터 수준 그룹화입니다.
  • 역할: RoleBinding을 사용하여 사용자 또는 사용자 그룹에 할당할 수 있는 리소스 및 허용 작업의 네임스페이스가 있는 그룹화입니다.
  • ClusterRoleBinding: 클러스터에 포함된 모든 네임스페이스의 사용자 또는 그룹에 ClusterRole을 할당합니다.
  • RoleBinding: 특정 네임스페이스 내의 사용자 또는 그룹에 Role 또는 ClusterRole을 할당합니다.

RoleBinding을 사용하여 사용자 또는 그룹에 ClusterRole을 할당하면 해당 사용자 및 그룹이 RoleBinding에 지정된 네임스페이스의 리소스에만 액세스할 수 있습니다. 사용자 또는 그룹이 모든 네임스페이스의 리소스에 액세스하도록 하려면 ClusterRoleBinding을 대신 사용하세요.

Role 또는 ClusterRole을 사용하여 권한 정의

Role 또는 ClusterRole 객체 내에 권한을 정의합니다. Role은 단일 네임스페이스에 포함된 리소스에 대한 액세스를 정의하고, ClusterRole은 전체 클러스터의 리소스에 대한 액세스를 정의합니다.

Role과 ClusterRole의 구문은 동일합니다. 각 항목에는 규칙이 적용되는 리소스 및 해당 역할에 허용되는 작업을 정의하는 rules 섹션이 포함되어 있습니다. 예를 들어 다음 Role은 accounting 네임스페이스의 모든 Pod에 대한 읽기 액세스 권한(get, watch, list)을 부여합니다.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: accounting
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

허용되는 전체 필드 목록은 RoleClusterRole API 문서를 참조하세요.

RoleClusterRole 비교

ClusterRole에서 부여하는 권한은 전체 클러스터에 적용되므로 ClusterRole을 사용하면 Role을 사용할 때보다 더욱 다양한 리소스에 대한 액세스를 제어할 수 있습니다. 예를 들면 다음과 같습니다.

  • 노드와 같은 클러스터 범위의 리소스
  • /healthz와 같은 리소스 이외의 REST 엔드포인트
  • 모든 네임스페이스 간의 네임스페이스로 지정된 리소스(예: 네임스페이스에 관계없이 전체 클러스터 간 모든 Pod)

RoleBinding 또는 ClusterRoleBinding을 사용하여 역할 할당

Role 또는 ClusterRole을 만든 후 RoleBinding 또는 ClusterRoleBinding을 만들어 사용자나 사용자 그룹에 할당합니다. 사용자 및 그룹을 subjects라 하며 다음과 같은 유형일 수 있습니다.

주체 유형 kind name
Google Cloud 사용자 계정 User Google Cloud에 등록된 이메일 주소
Kubernetes 서비스 계정 ServiceAccount 클러스터의 Kubernetes ServiceAccount 객체 이름
IAM 서비스 계정 User 자동으로 생성된 IAM 서비스 계정 이메일 주소
확인된 도메인의 Google 그룹 주소 Group gke-security-groups 그룹의 구성원인 Google Workspace 그룹의 이메일 주소입니다. RBAC용 Google 그룹스를 설정하는 방법은 RBAC용 Google 그룹스 구성을 참조하세요.

다음 RoleBinding은 사용자, Kubernetes 서비스 계정, IAM 서비스 계정, Google 그룹에 pod-reader 역할을 부여합니다.

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: pod-reader-binding
  namespace: accounting
subjects:
# Google Cloud user account
- kind: User
  name: janedoe@example.com
# Kubernetes service account
- kind: ServiceAccount
  name: johndoe
# IAM service account
- kind: User
  name: test-account@test-project.iam.gserviceaccount.com
# Google Group
- kind: Group
  name: accounting-group@example.com
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

kubectl을 사용하여 API 액세스 확인

kubectl은 API 승인 레이어를 빠르게 쿼리할 수 있는 auth can-i 하위 명령어를 제공합니다. 플랫폼 관리자는 사용자가 수행할 수 있는 작업을 확인하기 위해 사용자를 가장해야 할 수 있습니다. 개발자는 auth can-i을 사용하고 추가 --as 플래그를 전달할 수 있습니다.

--as 플래그 없이 kubectl auth can-i 명령어를 실행하면 Identity and Access Management(IAM)가 승인을 수행합니다. 반면에 --as 플래그를 추가하면 Kubernetes RBAC는 승인을 수행합니다. 따라서 RBAC에 필요한 RoleRoleBinding 객체를 만들어야 합니다.

자세한 내용은 API 액세스 확인을 참조하세요.

API 사용 및 예시

Kubernetes API를 사용하여 RBAC에 필요한 Role, ClusterRole, RoleBinding, ClusterRoleBinding 객체를 만드는 방법에 대한 자세한 내용은 Kubernetes 문서의 역할 기반 액세스 제어 승인 사용을 참조하세요.

문제해결과 디버깅

RBAC 문제를 디버깅하기 위해 기본적으로 모든 클러스터에서 사용 설정되는 관리자 활동 감사 로그를 사용합니다. 권한이 부족하여 리소스 또는 작업에 대한 액세스가 거부되면 API 서버는 RBAC DENY 오류와 함께 사용자의 암시적/명시적 그룹 멤버십과 같은 추가 정보를 로깅합니다. RBAC용 Google 그룹스를 사용하는 경우 로그 메시지에 google groups가 표시됩니다.

제한사항

다음 섹션에서는 Kubernetes RBAC 및 IAM을 사용할 때 간과하기 쉬운 상호작용을 설명합니다.

기본 검색 역할

클러스터는 기본 ClusterRole 및 ClusterRoleBinding 집합과 함께 생성됩니다. 유효한 사용자 인증 정보로 수행된 요청은 system:authenticated 그룹에 배치되고, 다른 모든 요청은 system:unauthenticated에 배치됩니다.

system:basic-user ClusterRole이 있는 사용자는 SelfSubjectAccessReviews가 클러스터에서 권한을 테스트하도록 허용할 수 있습니다. system:discovery 역할이 있는 사용자는 검색 API를 읽을 수 있습니다. 이 API는 클러스터에 추가된 CustomResourceDefinitions에 대한 정보를 표시합니다.

익명 사용자(system:unauthenticated)는 대신 /healthz/version API에 대한 읽기 전용 액세스 권한을 부여하는 system:public-info-viewer ClusterRole을 받습니다.

system:discovery ClusterRole에서 허용되는 API 엔드포인트를 확인하려면 다음 명령어를 실행합니다.

kubectl get clusterroles system:discovery -o yaml

Google Cloud VM 인스턴스에서 서비스 계정의 금지됨 오류

VM 인스턴스에 userinfo-email 범위가 없으면 다음과 같은 오류가 발생할 수 있습니다.

Error from server (Forbidden): error when creating ... "role-name" is forbidden: attempt to grant extra privileges:...

예를 들어 VM에 cloud-platform 범위는 있지만 userinfo-email 범위가 없다고 가정해 보겠습니다. VM이 액세스 토큰을 가져오면 Google Cloud는 이 토큰을 cloud-platform 범위와 연결합니다. Kubernetes API 서버가 액세스 토큰과 연결된 ID를 Google Cloud에 요청하면 서비스 계정의 이메일이 아닌 서비스 계정의 고유 ID가 수신됩니다.

성공적으로 인증하려면 userinfo-email 범위로 새 VM을 만들거나 고유 ID를 사용하는 새 역할 결합을 만듭니다.

userinfo-email 범위로 새 VM 인스턴스를 만들려면 다음 명령어를 실행합니다.

gcloud compute instances create INSTANCE_NAME \
    --service-account SERVICE_ACCOUNT_EMAIL \
    --scopes userinfo-email

기존 VM에 서비스 계정의 고유 ID를 사용하는 새 역할 결합을 만들려면 다음 단계를 따르세요.

  1. 서비스 계정의 고유 ID를 확인합니다.

    gcloud iam service-accounts describe SERVICE_ACCOUNT_EMAIL
    

    예를 들어 다음 출력은 my-iam-account@somedomain.com 서비스 계정의 uniqueId를 표시합니다.

    displayName: Some Domain IAM service account
    email: my-iam-account@somedomain.com
    etag: BwWWja0YfJA
    name: projects/project-name/serviceAccounts/my-iam-account@somedomain.com
    oauth2ClientId: '123456789012345678901'
    projectId: project-name
    uniqueId: '123456789012345678901'
    
  2. 서비스 계정의 uniqueId를 사용하여 역할 결합을 만듭니다.

    kubectl create clusterrolebinding CLUSTERROLEBINDING_NAME \
        --clusterrole cluster-admin \
        --user UNIQUE_ID
    

역할과 역할 바인딩을 만들거나 업데이트할 수 있는 권한

Kubernetes에서는 다음 조건을 충족하는 경우에만 특정 권한이 있는 역할이나 역할 바인딩을 만들거나 업데이트할 수 있습니다.

  • 역할 만들기 또는 업데이트: 역할에 부여할 권한과 동일한 권한이 이미 있어야 합니다. 또는 역할에서 escalate 동사를 수행하도록 승인을 받아야 합니다.
  • 역할 바인딩 만들기 또는 업데이트: 바인딩된 역할에 부여된 동일한 권한이 있어야 하며 이 권한의 범위는 역할 바인딩과 동일한 범위여야 합니다. 또는 참조된 역할에서 bind 동사를 수행하도록 승인을 받아야 합니다.

역할에서 부여하는 권한이 원래 RBAC 대신 IAM 정책을 사용하여 부여된 경우 역할이나 역할 바인딩 요청이 실패할 수 있습니다. 예를 들어 IAM 권한 container.pods.*container.roles.create가 부여된 사용자의 다음 역할 만들기 요청을 살펴보겠습니다.

kubectl create role allowed-to-view-pods --resource pods --verb list,get

사용자에게 IAM을 사용하는 권한만 부여된 경우 다음 오류가 발생할 수 있습니다.

Error from server (Forbidden): clusterroles.rbac.authorization.k8s.io "allowed-to-view-pods" is forbidden:
user "caller@example.com" (groups=["system:authenticated"]) is attempting to grant RBAC permissions not currently held:
{APIGroups:[""], Resources:["pods"], Verbs:["list" "get"]}

이러한 제한을 완화하려면 IAM 대신 RBAC를 사용하여 호출자에게 역할에서 권한을 부여합니다.

또는 RBAC 또는 IAM을 사용하여 호출자에게 escalate 동사, bind 동사 또는 둘 다 부여할 수 있습니다. 하지만 호출자는 모든 역할에 모든 권한을 부여할 수 있으므로 GKE에서 이 방법을 사용하지 않는 것이 좋습니다.

다음 단계