GKE (Google Cloud Study Jam) : Google Kubernetes Engine으로 설계하기: 프로덕션 -1

LEE EUI JOO·2023년 7월 27일
0

GCP

목록 보기
4/7

1. Google Cloud IAM

Google Cloud IAM 액세스 제어에 대해 살펴볼텐데 Cloud IAM 액세스 제어가 구성되는 방법에 대해 알아보고 또한 Cloud IAM 정책 및 역할을 사용하여 제어하는 방법도 알아볼 것이다.

Cloud IAM 액세스 제어에는 누가, 무엇을, 무엇 이라는 세 가지 요소가 정의된다.

  • 누가는 요청하는 사람의 신원

  • 무엇을은 부여된 권한 집합

  • 무엇은 이 정책이 적용되는 리소스

Cloud IAM에서는 구성원에게 액세스 권한을 부여하며 Cloud IAM은 클라우드 ID에 대해 사용자를 인증한다.

Google 계정, G Suite 도메인 계정 및 GCP 서비스 계정을 관리하는 서비스로서의 클라우드 ID를 잊지말고 이러한 ID를 그룹으로 모을 수 있다는 사실과 그리고 그룹 자체는 자체 권한을 가질 수 있다

➡️ AWS 의 IAM 이랑 거의 동일하다고 볼 수 있을 것 같다.

만약 어떤 회사에서 Active Directory를 사용하거나 ELD 앱 서버가 있는 경우에는 어떻게 할까?

GCDS로 알려진 Google 클라우드 디렉토리 동기화를 구성하여 디렉토리 서비스의 데이터를 Google 도메인과 단방향 동기화 작업할 수 있다.

여기서 단방향 동기화 작업이란 Google 사용자, 그룹 및 공유 연락처가 디렉토리 서비스의 Maxie 정보와 동기화되고 렉터리 서비스의 데이터는 수정되지 않는다.

Cloud IAM을 사용하여 구성원에게 권한을 부여하고 특정 리소스에 대해 특정 작업을 수행할 수 있도록 한다.

GCB 권한은 일반적인 사용자 흐름에 따라 역할로 그룹화되는데 구성원에게 권한을 개별적으로 할당할 수 없는 대신 구성원에게 역할이 할당된다.

GCP 리소스에 대한 모든 작업은 API 호출을 사용하여 수행되며 권한을 사용하여 액세스를 제어한다.

작업을 수행하려는 구성원에게 API 호출에 필요한 권한이 없으면 거부되는 격이다.

예시를 잠깐 보자면, 컴퓨팅 뷰어라는 역할이 있고 이를 통해 컴퓨팅 엔진 리소스에 대한 다양한 종류의 정보를 가져올 수 있다.

이 역할은 compute.instance.get 과 같은 이름을 가진 많은 권한으로 구성된다.

이러한 이름은 GCP 서비스의 약칭, 일종의 GCP 리소스 및 동사로 구성되는 것은 짐작해 볼 수 있다.

GCP 관리자(Root 계정을 말하는 것 같다)는 example@gmail.com 이라는 회원에게 이 역할을 부여할 수 있으며 GCP 프로젝트 수준에서 구성원이 프로젝트의 모든 컴퓨팅 엔진 리소스를 검사할 수 있다.

이제 전체 Cloud IAM 스토리를 함께 살펴보자.

GCP에 수행하려는 리소스에 대해 수행하려는 작업에 대한 권한을 요청할 때마다 Cloud IAM 은 사용자를 인증하고 필요한 정보가 있는지 확인한다.

클라우드 IAM 정책은 바인딩 목록이며 각 바인딩에서 구성원 집합은 하나 이상의 역할에 바인딩된다.

그러면 IAM 정책을 특정 리소스, 프로젝트, 프로젝트 폴더 또는 전체 조직에 연결할 수 있다.

GCP 리소스는 조직에서 시작하여 계층적으로 구성되는데 조직 내에서 여러 프로젝트 등을 포함하는 여러 폴더를 가질 수 있고 조직 수준에 연결된 IAM 정책은 자동으로 모든 폴더, 모든 프로젝트, 모든 관련 리소스에 대한 액세스 권한을 갖는다.

이러한 방식으로 조직 계층 내의 모든 수준에서 액세스 제어를 설정할 수 있고 각 IAM 정책에 가장 적합한 수준을 선택한다.

GCP 조직 계층의 상위 수준에 적용된 Cloud IAM 정책은 해당 계층 아래의 리소스에 상속된다.

예를 들어 조직 수준에서 적용되는 정책은 모든 프로젝트에 적용되고 해당 프로젝트의 모든 리소스에 적용된다.

정책을 설계할 때 염두에 두어야 할 핵심 요소는 계층 구조의 상위 수준에서 권한을 부여한 다음 아래에서 제거할 방법이 없다.

일반적으로 더 높은 수준에서 적용하는 정책은 매우 적은 수의 권한을 부여해야 한다.

그리고 낮은 수준에서 적용하는 정책은 필요한 사람에게만 추가 권한을 부여해야 한다.


2. IAM 역할 유형

Cloud IAM 에는 기본(Basic), 사전 정의(Pre-Defined), 커스텀(Custom) 의 세 가지 역할 유형이 있다.

2-1. 기본 역할

기본 역할은 Cloud IAM이 도입되기 전에 존재했지만 여전히 Cloud IAM과 함께 사용할 수 있다.

이러한 역할을 사용하여 사용자에게 프로젝트 내의 모든 Google Cloud 리소스에 대한 전역 프로젝트 수준 액세스 권한을 부여할 수 있으며 세 가지 기본 역할이 있다.

  • 뷰어(Viewer) 역할

    • 전체 프로젝트에서 기존 리소스 또는 데이터 보기와 같은 읽기 전용 작업을 허용
  • 편집자(Editor) 역할

    • 모든 뷰어 권한 외에도 편집자 역할은 기존 리소스를 수정할 수 있음
  • 소유자(Owner) 역할

    • 모든 편집자 권한이 있으며 역할 및 권한을 관리하고 프로젝트에 대한 결제를 설정할 수 있는 권한도 있음

이러한 역할은 App Engine, Compute Engine, Cloud Storage와 같은 모든 리소스에 액세스할 수 있다.

기본 역할은 매우 광범위하기 때문에 우리는 최소 권한의 원칙, 즉 사용자가 작업을 수행하는 데 필요한 최소한의 권한 집합을 부여받아야 한다.

기본 역할을 사용하는 경우 최소권한 원칙을 준수하지 않을 수 있으며 운영자 실수 및 노출이 발생될 수 있다.


2-2. 사전 정의 역할

GKE는 Kubernetes Engine 리소스에 대한 세분화된 액세스를 제공하는 몇 가지 사전 정의된 Cloud IAM 역할을 제공한다.

GKE 뷰어 역할은 감사에 필요할 수 있는 읽기 전용 액세스 권한을 부여한다.

일반적으로 사용되는 이 역할을 통해 클러스터를 볼 수 있지만 역할 기반 액세스 제어는 클러스터 내에서 수행할 수 있는 작업을 결정한다.

GKE 개발자 역할은 클러스터 내의 모든 리소스에 대한 모든 권한을 부여하기 때문에 개발자 및 출시 엔지니어에게 적합하다.

GKE 관리자 역할은 클러스터 및 클러스터 내부의 Kubernetes Engine 리소스에 대한 전체 액세스 권한을 부여한다.

만약에 프로젝트 소유자이고 시스템 관리자 및 대기 중인 엔지니어라면 GKE 클러스터 관리자 역할은 클러스터를 생성, 삭제, 업데이트, 확인하는 데 사용되지만 Kubernetes 리소스에 대한 액세스 권한은 제공하지 않는다.

이러한 모든 역할은 클러스터 수준이 아닌 프로젝트 수준에서 정의된다는 것을 짐작할 수 있다.


2-3. 커스텀 역할

기본 역할 및 GKE 사전 정의된 역할이 너무 관대하거나 가정이 비즈니스 사례에 맞지 않는 경우, 보다 세분화된 제어로 사용자 지정 역할을 만들 수 있다.

사용자 지정 역할을 만들려면 해당 역할을 구성할 각각의 개별 권한을 지정해야 한다.

예를 들어 관리에만 사용할 특정 사용자 계정을 생성해야 한다고 가정한다면 특정 GKE 클러스터 내에서 실행되지만 Google Cloud 리소스를 볼 수 있는 액세스 권한이 없어야 하는 소프트웨어같은 클러스터에 인증하는 데 필요한 권한만 있는 사용자 지정 IAM 역할을 생성할 수 있다.


3. RBAC (Role Based Access Control)

RBAC는 사용자 계정 권한을 관리하기 위한 세분화된 도구를 제공하는 기본 Kubernetes 보안 기능이다.

GKE 환경에서 RBAC는 클러스터 내 Kubernetes 리소스에 대한 제어를 제공하여 Cloud IAM 보안을 확장하고 GKE 및 클러스터 수준에서 액세스를 제어할 수 있도록 Cloud IAM 에서 직접 제공하는 제어 기능이다.

Kubernetes 역할 기반 액세스 제어에는 주제, 리소스 및 동사의 세 가지 주요 요소가 있다.

Kubernetes RBAC를 사용하면 어떤 작업(동사)을 어떤 개체, 리소스, 누구, 주제에 대해 실행할 수 있는지 정의할 수 있다.

  • 주체

    • Kubernetes API에 요청할 수 있는 사용자 또는 프로세스 집합
  • 리소스

    • 포드, 배포, 서비스 또는 PersistentVolume과 같은 Kubernetes API 개체 집합
  • 동사

    • get, watch, create 및 describe와 같은 리소스에 대해 수행할 수 있는 일련의 작업

이러한 세 가지 요소는 두 가지 유형의 RBAC API 객체인 RoleRoleBinding을 생성하여 연결할 수 있다.

RoleAPI 리소스와 동사를 연결하며 RoleBinding역할을 주제에 연결한다.

또한, 역할 및 RoleBinding은 클러스터 또는 네임스페이스 수준에서 적용할 수 있다.

사용자에게 특정 Kubernetes 네임스페이스에 대한 액세스 권한을 부여해야 하는 경우 Kubernetes RBAC가 유용하다.

사용자를 주체로 추가하고 적절한 권한으로 역할을 구성한 다음 개체에 바인딩할 수 있으며 이 경우 클러스터의 네임스페이스이다.

Kubernetes에는 두 가지 유형의 역할이 있는데 앞에서 언급한 RoleClusterRole 이다.

RBAC 역할네임스페이스 수준에서 정의되RBAC ClusterRole클러스터 수준에서 정의된다.

상위 개념은 Cluster Role 인 듯하다.

위의 매니페스트는 네임스페이스 수준에서 RBAC 역할을 정의한다.

여기서는 ClusterRole이 아닌 역할 유형이 정의되며 역할이 해당 네임스페이스에 적용되도록 default 네임스페이스가 지정되었고 역할에 대해 단일 네임스페이스만 정의할 수 있다.

규칙에서 apiGgroups는 비어 있는 것으로 정의되어 역할이 핵심 API 그룹에 적용됨을 나타낸다.

리소스는 포드로 지정되며 동사 get, list 및 watch가 할당되었다.

이렇게 세 개의 동사를 Role에 넣으면 Role을 가진 주체에게 Pod의 상태를 검사할 수 있는 권한이 부여 되는데 항상 get, list 및 watch를 함께 할당하는 것이 일반적이다.

규칙은 순전히 부가적이며, '거부' 규칙은 없으며 지정된 리소스에 대해 사용자에게 동사를 부여하는 규칙이 없으면 해당 사용자는 작업을 수행할 수 없는 방식이다.

다음으로 ClusterRole이 정의된 매니페스트 파일을 살펴보자.

ClusterRole은 클러스터 수준에서 권한을 부여하기 떄문에 네임스페이스를 지정할 필요가 없다.

API 그룹은 역할 생성 시 정의한 것과 동일하게 정의하며 리소스는 노드 및 스토리지 클래스와 같은 클러스터 범위이거나 포드 및 디플로이먼트와 같은 네임스페이스 리소스일 수 있다.

다음으로 Role 또는 ClusterRole에서 다루는 리소스 및 동사를 지정하는 규칙 집합의 몇 가지 예시를 살펴보자.

  • 왼쪽 상단

    • 모든 Pod 리소스에 대한 가져오기, 나열 및 감시 작업을 지정하는 기본 할당
  • 왼쪽 하단

    • Pod 로그에 대한 액세스를 지정하기 위해 리소스 목록에 하위 리소스인 'logs'가 추가됐으며 get, list 및 watch 동사의 조합은 표준 읽기 전용 동사이다.
  • 우측 상단

    • 범위를 리소스의 특정 인스턴스로 제한하기 위해 리소스 이름을 지정하고 패치 및 업데이트로 지정된 동사를 지정했으며 이들은 또한 일반적으로 하나의 단위로 취급되어 함께 적용되는 동사 그룹이다.

    • get, update, delete 및 patch와 같은 동사만 명명된 리소스에 사용할 수 있다.

  • 오른쪽 하단

    • 리소스가 아닌 끝점에 대해 get 및 post 작업을 지정하는 방법을 보여주며, 이 형태의 규칙은 ClusterRoles에 고유하다.

4. 역할 연결

다음은 다양한 주제 유형을 참조하는 방법에 대한 몇 가지 예시이다.

왼쪽 상단부터 작업하면 사용자와 그룹을 지정하는 예가 표시됐으며, 왼쪽 하단에는 ServiceAccount 이름이 'default' 이고 네임스페이스가 'kube-system'으로 지정된 ServiceAccount 주제의 예가 있다.

Google groups 에는 Kubernetes RBAC 권한을 할당할 수 없으며 Cloud IAM 권한은 Google 그룹에만 할당할 수 있다.

그러나 Kubernetes는 그룹도 지원하므로 Kubernetes RBAC 권한을 Kubernetes 그룹에 할당할 수 있다.

이 예에서 관리자가 '개발자'라는 그룹을 생성한 것을 볼 수 있고 오른쪽 열에는 더 많은 그룹 유형이 있다.

이 예시에는 모든 네임스페이스의 모든 서비스 계정이 포함되며, 이것은 시스템 그룹이므로 GKE 환경에서 RBAC에 사용할 수 있다.

오른쪽 중간 예시에는 QA 네임스페이스의 서비스 계정만 포함되어 있고, 오른쪽 하단의 예에는 모든 인증된 사용자가 포함된다.

이제 ClusterRole을 정의했으므로 RoleBindings 및 ClusterRoleBindings를 해당 역할에 연결할 수 있다.

먼저 RoleBinding을 연결해 보자.

네임스페이스를 정의한 다음 주체(subjects)를 정의하는데 Kubernetes에서 주체 종류는 사용자, 그룹 또는 서비스 계정일 수 있다.

주체 이름은 대소문자를 구분하며 GKE의 RBAC를 사용하여 액세스를 제어할 수 있는 계정 유형은 Google 계정, GCP 서비스 계정 또는 Kubernetes 서비스 계정이며 이메일 주소를 사용하여 식별된다.

역할 종류와 역할 이름을 정의하여 roleRef를 사용하여 주체 및 RoleBinding에 역할을 바인딩한다.

RoleBinding은 역할 또는 ClusterRole을 참조할 수 있으며 ClusterRole이 RoleBinding에 바인딩된 경우 전체 클러스터가 아니라 RoleBinding에 대해 정의된 특정 네임스페이스의 리소스에 대한 권한만 부여 된다.

여기선 ClusterRole이 정의되는데, ClusterRole은 클러스터 수준에서 권한을 부여하므로 네임스페이스를 지정할 필요가 없으며 ApiGroups는 Role 생성 시 정의한 것과 동일하게 정의한다.

리소스는 노드 및 스토리지 클래스와 같은 클러스터 범위이거나 포드 및 디플로이먼트와 같은 네임스페이스 안의 리소스일 수 있다.

ClusterRoleBinding은 항상 클러스터 전체 범위를 갖기 때문에 네임스페이스는 언급되지 않으며, ClusterRoleBinding은 역할이 아닌 ClusterRole만 참조할 수 있다.

Kubernetes RBAC를 사용하면 네임스페이스 수준과 클러스터 수준 모두에서 사용자 및 그룹을 사용하는 사람과 서비스 계정을 사용하는 컨테이너에 대한 세분화된 권한을 관리할 수 있다.

리소스 및 동사는 Roles 또는 ClusterRoles를 사용하여 바인딩되며 역할 및 ClusterRole은 RoleBinding 또는 ClusterRoleBinding을 사용하여 주체에 바인딩된다.

다양한 ClusterRole 및 ClusterRoleBinding도 RBAC 시스템 내에서 사전 정의될 수 있다.

사전 정의된 정보들은 아래 Kubernetes Docs에 자세히 설명되어 있다.

https://kubernetes.io/docs/reference/access-authn-authz/rbac/

역할 및 ClusterRole을 생성할 때 리소스가 네임스페이스와 연결되어 있는지 또는 클러스터 수준에서 정의되어 있는지 여부를 고려해야 한다.

kubectl api-resources 명령을 사용하여 'NameSpaced' 리소스와 그렇지 않은 리소스를 나열할 수 있으므로 일반적으로 클러스터 수준 리소스는 ClusterRole을 사용하여 관리해야 하며 NameSpaced 리소스는 역할을 사용하여 관리해야 한다.

그러나 여러 네임스페이스에서 RBAC 권한을 정의해야 하는 경우 ClusterRole을 사용해야 한다.


5. Control Plane Security

GKE에서 API 서버, etcd 데이터베이스, 컨트롤러 관리자와 같은 모든 제어 영역 구성요소는 Google에서 관리한다.

각 클러스터에는 자체 루트 인증 기관(줄여서 'CA')이 있는데 내부 Google 서비스는 이 CA의 루트 키를 관리한다.

컨트롤 플레인과 클러스터의 노드 간의 보안 통신은 CA에서 발급한 인증서에서 제공하는 Root Trust Share에 의존한다.

GKE는 별도의 클러스터별 CA를 사용하여 클러스터 내의 etcd 데이터베이스에 대한 인증서를 제공하는데 이 기능을 켜기 위해 아무 것도 할 필요가 없으며 구글에서 자동 설정된다.

이는 클러스터에서 실행 중인 서비스와 클러스터 작동을 유지하는 데이터베이스 간에 공유 신뢰가 필요하지 않음을 의미하기 때문에 유용하다.

Kubernetes API 서버와 노드의 기본 Kubernetes 에이전트인 kubelets은 서로 통신할 때 보안 네트워크 통신 프로토콜(TLS 및 SSH)을 사용하는데 이러한 프로토콜을 지원하기 위해 클러스터의 루트 CA에서 발급한 인증서를 사용한다.

개별 클러스터마다 별도의 CA가 사용되기 때문에 한 클러스터의 손상된 CA를 사용하여 다른 클러스터를 손상시킬 수 없는건 당연하다

Kubernetes 클러스터의 새 노드가 생성되면 생성의 일부로 노드에 공유 암호가 주입이 되고 그런 다음 이 시크릿은 kubelet에서 인증서 서명 요청을 클러스터 루트 CA에 제출하는 데 사용된다.

이런 식으로 노드가 생성될 때 클라이언트 인증서를 얻을 수 있고 갱신 또는 교체가 필요할 때 새 인증서를 얻을 수 있다.

Kubelets는 이러한 클라이언트 인증서를 사용하여 API 서버와 안전하게 통신하는 방식이다.

이 시크릿은 메타데이터 은닉이 활성화되지 않은 경우 파드 및 확장된 컨테이너에서 액세스할 수 있다.

클러스터의 보안 태세를 개선하고 자격 증명을 손상시키는 잠재적인 보안 위반의 영향을 제한하려면 이러한 자격 증명을 주기적으로 교체하는 것이 중요하는데 이것은 Trade-Off이다.

클러스터가 고가치 자산을 관리하는 경우 자격 증명을 자주 교체하는 것이 좋다.

하지만 교체할 때는 클러스터의 kube-APIserver를 잠시 사용할 수 없기 때문에 조직의 보안 정책에 적합한 절충안을 만들어야 한다.

다음 실습 중에 API 서버 및 클라이언트에서 사용하는 자격 증명을 수동으로 교체하는 방법을 배울 예정인데 Google에서 전적으로 관리하기 때문에 GKE에서 etcd 인증서는 수동으로 순환할 수 없다.


교체 프로세스

이 프로세스는 기존 IP 주소(10.1.1.1)와 함께 클러스터 컨트롤 플레인에 대한 새 IP 주소(10.1.1.2_를 생성하는 것으로 시작되며 새 자격 증명이 컨트롤 플레인에 발급된다.

Pod는 계속 실행되지만 API 서버는 이 기간 동안 사용할 수 없다.

제어 영역이 재구성되면 새 IP와 사용자 인증 정보를 사용하도록 GKE에서 노드를 자동으로 업데이트하며 이로 인해 GKE도 노드 버전을 지원되는 가장 가까운 버전으로 자동 업그레이드된다.

노드가 다시 생성되기 때문에 컨트롤러 없이 실행 중인 모든 포드는 사용할 수 없게 된다.

클러스터 외부의 모든 API 클라이언트도 새 자격 증명을 사용하도록 업데이트해야 한다.

클러스터 컨트롤 플레인이 새 IP 주소 및 새 자격 증명 제공을 시작하고 이전 IP 주소 및 이전 자격 증명을 제거하려면 주소 순환을 완료해야 한다.

순환을 수동으로 완료하지 않으면 GKE가 7일 후에 순환을 자동으로 완료시킨다.

사용자 인증 정보 순환을 시작하려면 'start-credential-rotation' gcloud 명령어를 실행하여 새 사용자 인증 정보를 만들고 이 사용자 인증 정보를 제어 영역에 발급한다.

순환을 완료하려면 새 사용자 인증 정보로만 제공하도록 제어 영역을 구성하는 'complete-credential-rotation' gcloud 명령어를 실행하면 된다.

클러스터의 IP 주소를 순환할 수도 있으며 컨트롤 플레인 IP 주소가 변경될 때 인증서를 갱신해야 하지만 위에 표시된 것과 같이 다른 명령을 사용하기 때문에 기본적으로 동일한 프로세스를 거친다.

포드는 노드 구성에 사용되는 노드 시크릿과 같이 실행 중인 노드의 메타데이터에 액세스할 수 있다.

Pod가 손상되면 의도하지 않은 방식으로 사용될 가능성이 있기 때문에 노출을 방지하기 위해 취할 수 있는 몇 가지 조치가 있다.

  • 최소한의 권한으로 노드에 대한 Cloud IAM 서비스 계정을 항상 구성

    • Node VM 자체에서 사용하는 Cloud IAM 서비스 계정
    • 서비스 계정, 컴퓨팅 인스턴스 관리자 역할 또는 사용자 지정 역할을 통해 'compute.instances.get' 권한을 사용하지 않는 것
    • 이 권한을 생략하면 역할 소유자가 이러한 노드에 대해 Compute Engine API를 직접 호출하여 GKE 노드에서 메타데이터를 가져오는 것을 차단한다.
  • 수행해야 하는 두 번째 단계는 레거시 메타데이터 API 비활성화

    • /0.1/ 및 /v1beta1/을 사용하는 Compute Engine API 엔드포인트는 메타데이터 쿼리를 지원함

    • /v1/ API는 메타데이터 검색을 제한한다.

    • GKE 버전 1.12부터 레거시 Compute Engine 메타데이터 엔드포인트는 기본적으로 사용 중지되며 이전 버전에서는 새 클러스터를 만들거나 기존 클러스터에 새 노드 풀을 추가해야만 비활성화할 수 있음

  • 메타데이터 숨김을 활성화

    • 기본적으로 포드가 노드의 메타데이터에 액세스하지 못하도록 하는 방화벽

    • kube-env(kubelet 자격 증명 포함) 및 가상 머신의 인스턴스 ID 토큰에 대한 액세스를 제한하여 이를 수행

    • 이는 향후 더 나은 보안 개선 사항이 개발됨에 따라 더 이상 사용되지 않는 임시 솔루션임


6. Pod Security

기본적으로 사용자는 권한 승격을 허용하고 호스트 파일 시스템 및 호스트 네트워크에 액세스할 수 있는 포드 내부에 컨테이너를 배포할 수 있다.

이러한 기능은 편리한 경우도 있지만 보안 관점에서 바람직하지 않은 경우도 있을 수 있기 때문에 securiy context를 사용하여 Pod의 컨테이너가 수행할 수 있는 작업에 대한 제한을 정의할 수 있으며 특정 보안 수단을 사용하도록 강제할 수도 있다.

보안 컨텍스트는 Pod 사양에 정의된 보안 설정 집합이다.

Pod 내부의 securityContext 정의는 첫 번째 프로세스가 사용자 ID 1,000으로 실행되도록 지정하고 Pod의 모든 컨테이너 및 그룹 ID 2,000은 Pod의 모든 컨테이너와 연결된다.

이는 컨테이너에 대한 특정 사용자 및 그룹 컨텍스트를 제공하며 이 컨텍스트에서 가장 중요한 점은 1,000이 0이 아니라는 것!

Linux 시스템에서 0은 권한이 있는 루트 사용자의 사용자 ID 이며 컨테이너 내부에서 실행되는 코드에서 루트 권한을 제거하면 손상 시 수행할 수 있는 작업이 제한된다.

포드 수준에서 보안 컨텍스트를 정의하면 포드의 모든 컨테이너에 적용되며 Pod 정의에서 보안 컨텍스트를 사용하면 호스트 네임스페이스 사용에 대한 많은 제어를 실행할 수 있다.

네트워킹, 파일 시스템 및 볼륨 유형, 권한이 있는 컨테이너를 실행할 수 있는지 여부 및 컨테이너의 코드가 루트 권한으로 에스컬레이션될 수 있는지 여부같은 제어를 실행할 수 있고 다른 보안 설정을 제어할 수도 있다.

예를 들어 Seccomp를 활성화하여 컨테이너에서 실행 중인 코드가 알고 있는 시스템 호출을 수행하지 못하도록 차단할 수 있고 합법적으로 만들어서는 안 되는 경우 보안 프로필을 사용하여 개별 프로그램의 작업을 제한하는 AppArmor를 활성화할 수 있다.

또한, 프로세스에 일부 권한만 부여하여 일부 Linux 기능에 대한 액세스를 제한할 수도 있다.

만약, 수십 또는 수백 개의 Pod가 있는 경우 어떻게 제어해야 할까?

각 개별 포드에서 보안 컨텍스트를 직접 구성하는 것은 많은 작업이 될 수 있기 때문에 보안 구성을 별도로 정의하고 관리한 다음 이를 필요로 하는 포드에 적용하는 것이 더 쉬울 수 있다.

PodSecurityPolicies를 정의하여 재사용 가능한 보안 컨텍스트를 만들고 각 Pod 정의에서 해당 세부 정보를 지정하고 관리할 필요 없이 PodSecurityPolicies를 여러 Pod에 적용할 수 있다.

PodSecurityPolicy 는 각각의 개체와 허용 컨트롤러로 구성되는데 PodSecurityPolicy 개체는 제한 사항, 요구 사항 및 기본값의 집합이며 동일한 정책에 정의되어 있다.

Pod 내부의 보안 컨텍스트로 사용되며 동일한 보안 기능을 제어하는데 사용할 수 있다.

Pod가 클러스터에 허용되려면 PodSecurityPolicy에 정의된 모든 보안 조건을 충족해야 한다.

이러한 규칙은 Pod가 생성되거나 업데이트될 때만 적용된다.

PodSecurityPolicy 컨트롤러는 하나 이상의 보안 정책에 대해 포드 생성 또는 업데이트 요청을 확인하거나 수정하는 승인 컨트롤러이다.

앞부분에서 특정 작업을 수행하기 위한 요청이 인증되고 승인되어야 한다는 것을 배웠지만 허용 제어라고 하는 추가 단계가 있다.

유효성을 검사하거나 변경하지 않는 허용 컨트롤러는 요청의 유효성만 검사한다.

변경 허용 컨트롤러는 필요한 경우 요청을 수정할 수 있으며 요청의 유효성을 검사할 수도 있다.

요청은 여러 컨트롤러를 통해 전달될 수 있으며 어느 시점에서 요청이 실패하면 전체 요청이 즉시 거부되고 최종 사용자에게 오류를 공지한다.

PodSecurityPolicy 승인 컨트롤러는 포드의 생성 및 수정에 대해 작동하며 요청된 보안 컨텍스트 및 사용 가능한 PodSecurityPolicies를 기반으로 포드를 승인해야 하는지 여부를 결정한다.

이러한 정책은 Pod 생성 또는 업데이트 중에 적용되지만 보안 컨텍스트는 컨테이너 런타임에 의해 적용된다.


7. Pod Security Policy 적용

PodSecurityPolicy를 정의한 후에는 권한을 부여해야 하며 그렇지 않으면 포드가 생성되지 않는다.

Kubernetes RBAC 를 사용하여 정책을 승인할 수 있는데 위의 예시에서 ClusterRole은 'demo-psp'라는 PodSecurityPolicy를 사용할 수 있도록 허용한다.

다음으로 RoleBinding을 정의하여 이전 ClusterRole을 사용자 또는 그룹에 바인딩한다.

위의 예시에서는 RoleBinding에 대한 두 개의 주제가 있는데 'demo' 네임스페이스 내의 모든 서비스 계정을 포함하는 그룹과 'demo' 네임스페이스의 특정 서비스 계정이다.

RoleBinding은 디플로이먼트, ReplicaSet 또는 기타 템플릿 컨트롤러일 수 있는 포드 생성자에게 권한을 부여하거나 생성된 포드 서비스 계정에 권한을 부여할 수 있다.

정책에 대한 컨트롤러 액세스 권한을 부여하면 해당 정책에 의해 생성된 모든 Pod에 대한 액세스 권한이 부여된다.

따라서 정책을 승인하는 기본 방법은 Pod의 서비스 계정에 대한 액세스 권한을 부여하는 것이다.

PodSecurityPolicy 컨트롤러가 없으면 PodSecurityPolicy는 아무 의미가 없으므로 정책을 정의하고 PodSecurityPolicy 컨트롤러를 활성화하려면 둘 다 필요하다.

정책을 정의하기 전에 PodSecurityPolicy 컨트롤러를 활성화하면 아무 것도 배포할 수 없도록 한것이나 다름없다.

GKE에서 PodSecurityPolicy 컨트롤러는 기본적으로 사용 중지되어 있으며 PodSecurityPolicies를 사용하기로 선택한 경우 먼저 이를 정의한 다음 여기에 표시된 상위의 gcloud 명령어로 컨트롤러를 사용 설정하면 된다.

GKE에서, 특히 GKE 클러스터에서 최신 버전의 Kubernetes를 실행하도록 선택한 경우 Kubernetes에서 추가 보안 조치를 취할 수 있으며 이러한 조치 중 다수는 기본적으로 활성화된다.

예를 들어 노드에 Google의 컨테이너 최적화 OS를 사용하는 GKE의 기본 정책은 노드 보안을 향상시킨다는 장점이 있다.

범용 Linux 배포와 달리 Container-Optimized OS는 최소 읽기 전용 파일 시스템을 구현하고 시스템 무결성 검사를 수행하며 방화벽, 감사 로깅 및 자동 업데이트를 구현하기 때문이다.

자동 노드 업그레이드를 활성화하여 모든 노드를 최신 버전의 Kubernetes로 업데이트할 수 있다.

외부 IP 주소가 없는 노드를 포함하는 비공개 클러스터를 실행하도록 선택할 수 있거나 공개적으로 연결할 수 있는 엔드포인트가 없는 프라이빗 클러스터에 대해 클러스터 제어 플레인을 실행하도록 선택할 수도 있다.

기본적으로 비공개 클러스터는 Google Cloud IP 주소가 클러스터 제어 영역 엔드포인트에 액세스하는 것을 허용하지 않지만 승인된 네트워크에서 비공개 클러스터를 사용하면 선택한 특정 IP 주소 범위에서만 클러스터 제어 평면에 도달할 수 있다.

클러스터의 VPC 네트워크에 있는 노드는 여전히 제어 영역에 액세스할 수 있으며 이를 관리하는 Google의 내부 프로덕션 작업도 마찬가지이다.

민감한 구성 정보를 ConfigMaps에 저장하는 대신 암호화된 비밀을 활용하여 저장하는 것을 잊지 말고 또한, 가능하면 개인이 아닌 그룹에 권한을 부여하자.

이는 Google 그룹에 역할을 부여할 수 있는 Cloud IAM과 Kubernetes 그룹에 역할을 바인딩할 수 있는 Kubernetes RBAC 모두에 적용된다.

여러 위치에서 'Pat'이라는 관리자에게 권한을 부여한 후 Pat이 회사를 떠난다고 가정해보자.

이제 Pat이 권한을 갖고 있는 모든 위치를 추적하고 제거해야 하는데 이는 지루하고 오류가 발생하기 쉽상이다.

항상 사용자가 아닌 그룹에 권한을 부여하는 모범 사례를 따랐다면 Pat을 관리자 그룹에서 제외하는 것만으로 Pat의 액세스 권한을 제거할 수 있다는 편리성이 있다.

쿠버 대시보드는 이용하지 말자

Kubernetes 대시보드는 Kubernetes의 기존 추가 기능인데 원래는 관리자가 클러스터를 관리할 수 있는 편리한 웹 기반 방법을 제공하기 위한 것이었다.

과거에 Kubernetes 대시보드는 기본적으로 권한이 높은 Kubernetes 서비스 계정의 지원을 받았지만 종종 인터넷에서 액세스할 수 있는 상태로 유지되었으며 이는 심각한 문제였다.

기본 구성은 원격 공격에 취약할 수 있는 인터페이스를 노출시켰기 때문에 GKE는 이러한 위험을 줄이기 위한 조치를 취했다.

Kubernetes 버전 1.7 이상을 실행하는 GKE 클러스터는 Kubernetes 대시보드 관리자 액세스 권한을 부여하지 않고 Kubernetes 버전 1.10 이상에서 실행되는 GKE 클러스터는 기본적으로 Kubernetes 대시보드를 완전히 사용 중지했다.

Kubernetes 대시보드를 사용하는 대신 이 전문 분야에서 해왔던 것처럼 Cloud Console의 기본 제공 GKE 대시보드 또는 kubectl 명령어를 대신 사용하도록 하자.


8. Cloud IAM 및 포드 보안 승인으로 Google Kubernetes Engine 보호 실습

  • Cloud IAM을 사용하여 GKE 액세스 제어

  • Pod 보안 정책을 만들고 사용하여 Pod 생성을 제어

  • IP 주소 및 자격 증명 순환 수행

8-1. Cloud IAM 역할을 사용하여 프로젝트의 모든 GKE 클러스터에 대한 관리 액세스 권한 부여

  • 첫 번째 사용자로 Google Cloud Console에 로그인
  1. 평소와 같이 제공된 사용자 이름 1 로 시크릿 창에서 Google Cloud Console에 로그인 (두 사용자 이름 모두 동일한 암호)

  2. Google Cloud Console 제목 표시줄에서 Cloud Shell 활성화 ( Cloud Shell 아이콘)를 클릭

  • 두 번째 사용자로 로그인하고 Google Cloud Console 탐색
  1. 시크릿 창에서 다른 탭 열기

  2. console.cloud.google.com 으로 이동

  3. 화면 오른쪽 상단 모서리에 있는 사용자 아이콘을 클릭한 다음 계정 추가를 클릭

  4. 제공된 사용자 이름 2 로 Google Cloud Console에 로그인

참고: 사용자 이름 2 Google Cloud Console 탭 에 있는지 확인
사용자 이름 2 로 로그인한 상태에서 탐색 메뉴 ( 탐색 메뉴 아이콘) 에서 Kubernetes Engine > 클러스터 를 클릭

페이지 상단에서 랩 프로젝트 ID가 선택되어 있는지 확인

클러스터 생성 옵션이 비활성화되어 있음

사용자 이름 2는 현재 프로젝트에 대한 액세스 권한이 있지만
뷰어 역할만 소유하여 프로젝트의 모든 리소스를 볼 수 있지만 읽기 전용이다.
  • 사용자 이름 2에 GKE Admin Cloud IAM 역할 부여

사용자 이름 2가 기본 역할을 사용하여 GKE 클러스터를 만들고 워크로드를 배포하여 이 프로젝트에서 모든 GKE 클러스터를 관리하고 해당 클러스터 내의 리소스를 관리할 수 있는 사용자 권한을 사용자에게 부여하도록 허용한다.

사용자 이름 1 계정에는 프로젝트 소유자 권한이 있으며 해당 계정을 사용하여 사용자 이름 2 에 추가 권한을 부여할 것이다.

  1. 사용자 이름 1 Google Cloud Console 탭 으로 다시 전환
참고: 사용자 이름 1 Google Cloud Console 탭 에 있는지 확인
  1. 탐색 메뉴 ( 탐색 메뉴 아이콘) 에서 IAM 및 관리자 > IAM 을 클릭

  2. IAM 콘솔 에서 Username 2 에 해당하는 행을 찾은 다음 해당 행의 오른쪽 끝에 있는 연필 아이콘을 클릭하여 해당 사용자의 권한을 편집

  3. 사용자 이름 2 에는 현재 프로젝트 내의 모든 리소스에 대한 읽기 액세스 권한을 제공하는 뷰어 역할이 있으며 다른 역할 추가를 클릭하여 역할에 대한 다른 드롭다운 선택 항목을 추가

  4. 역할 선택 드롭다운 상자 에서 Kubernetes Engine > Kubernetes Engine 클러스터 관리자를 선택 후 저장

참고: 이제 사용자 이름 2는 프로젝트의 모든 GKE 클러스터를 관리하고
해당 클러스터 내의 리소스를 관리할 수 있는 액세스 권한을 가진다.

이 액세스 수준이 조직에 너무 광범위하면 Kubernetes 역할 기반 액세스 제어를 사용하여
GKE 클러스터 내에서 사용자 권한을 제한할 수 있다.
  • 사용자 이름 2의 액세스 테스트
  1. 사용자 이름 2 Google Cloud Console 탭 으로 다시 전환

  2. 사용자 이름 2 로 로그인한 상태에서 탐색 메뉴 ( 탐색 메뉴 아이콘) 에서 Kubernetes Engine > 클러스터 를 클릭

  3. 이제 클러스터 생성 옵션이 활성화된 것을 볼 수 있다.

  4. 만들기를 클릭하여 GKE 클러스터 만들기를 시작합니다.

  • 표준에 대한 구성 옵션 선택

  • 클러스터 이름을 standard-cluster-1 로 설정

  • 리전이 아닌 영역 클러스터 선택

  • us-central1-a 영역을 선택

  • 다른 모든 값은 기본값으로 두고 만들기를 클릭

클러스터가 프로비저닝을 시작하지만 곧 실패하는데 사용자 이름 2에는 여전히 클러스터를 배포하는 데 필요한 일부 권한이 없다.

이는 GKE가 노드에 Google Cloud Compute Engine 인스턴스를 활용하기 때문입니다.

GKE 클러스터를 배포하려면 사용자에게 Compute Engine 기본 서비스 계정에 대한 iam.serviceAccountUser 역할도 할당되어야 한다.

  • ServiceAccountUser IAM 역할을 사용자 이름 2에 부여

이제 사용자 이름 2가 GKE 클러스터를 성공적으로 배포할 수 있도록 IAM을 사용하여 사용자 이름 2에 iam.serviceAccountUser 역할을 부여해야 한다.

  1. 사용자 이름 1 Google Cloud Console 탭 으로 다시 전환

  2. 탐색 메뉴 ( 탐색 메뉴 아이콘) 에서 IAM & admin > 서비스 계정을 클릭

  3. IAM 콘솔 에서 Compute Engine 기본 서비스 계정 에 해당하는 행을 클릭하여 선택

  4. 권한을 클릭하여 권한 정보 패널을 열어 권한 페이지에서 액세스 권한 부여 를 클릭

  5. 새 주체 상자에 사용자 이름 2 의 사용자 이름을 입력

  6. 역할 선택 상자 에서 서비스 계정 > 서비스 계정 사용자(Service Account User)가 선택되어 있는지 확인하고 저장

  • 사용자 이름 2가 GKE 클러스터를 만들 수 있는지 확인
  1. 사용자 이름 2 Google Cloud Console 탭 으로 다시 전환

  2. 사용자 이름 2 로 로그인한 상태에서 탐색 메뉴 (탐색 메뉴 아이콘) 에서 Kubernetes Engine > 클러스터 를 클릭

  • 표준에 대한 구성 옵션 선택

  • 클러스터 이름을 standard-cluster-1 로 설정

  • 리전이 아닌 영역 클러스터가 선택되었는지 확인

  • us-central1-a 영역을 선택

  • 다른 모든 값은 기본값으로 두고 만들기를 클릭


8-2. 작업 2. 포드 보안 승인 정의 및 사용

GKE 클러스터에 연결

export my_zone=us-central1-a
export my_cluster=standard-cluster-1

source <(kubectl completion bash)

gcloud container clusters get-credentials $my_cluster --zone $my_zone

PodSecurity를 사용하여 Pod 보안 표준 적용

PodSecurity 승인 컨트롤러를 사용하려면 특정 모드에서 특정 네임스페이스에 특정 Pod 보안 표준을 적용해야 한다.

  • 클러스터에 네임스페이스를 생성
kubectl create ns baseline-ns
kubectl create ns restricted-ns
  • baseline-ns: 허용 워크로드의 경우

  • limited-ns: 고도로 제한된 워크로드용

레이블을 사용하여 보안 정책 적용

Pod 보안 표준을 적용

  • baseline: 경고 모드에서 기준선-ns에 적용

  • limited: 강제 모드에서 limited-ns에 적용

 kubectl label --overwrite ns baseline-ns pod-security.kubernetes.io/warn=baseline
 kubectl label --overwrite ns restricted-ns pod-security.kubernetes.io/enforce=restricted

이러한 명령은 다음 결과를 얻는다.

  • 기준(baseline) 정책을 위반하는 baseline-ns 네임스페이스의 워크로드가 허용되며 클라이언트는 경고 메시지를 표시
  • 제한된(limited) 정책을 위반하는 limited-ns 네임스페이스의 워크로드는 거부되고 GKE는 감사 로그에 항목을 추가

레이블이 추가되었는지 확인하면

$  kubectl get ns --show-labels
NAME              STATUS   AGE     LABELS
baseline-ns       Active   47s     kubernetes.io/metadata.name=baseline-ns,pod-security.kubernetes.io/warn=baseline
default           Active   5m24s   kubernetes.io/metadata.name=default
gmp-public        Active   4m41s   addonmanager.kubernetes.io/mode=Reconcile,kubernetes.io/metadata.name=gmp-public
gmp-system        Active   4m41s   addonmanager.kubernetes.io/mode=Reconcile,kubernetes.io/metadata.name=gmp-system
kube-node-lease   Active   5m24s   kubernetes.io/metadata.name=kube-node-lease
kube-public       Active   5m24s   kubernetes.io/metadata.name=kube-public
kube-system       Active   5m24s   kubernetes.io/metadata.name=kube-system
restricted-ns     Active   46s     kubernetes.io/metadata.name=restricted-ns,pod-security.kubernetes.io/enforce=restricted

구성된 정책 테스트

PodSecurity 승인 컨트롤러가 의도한 대로 작동하는지 확인하려면 기준 및 제한된 정책을 위반하는 워크로드를 두 네임스페이스 모두에 배포한다.

다음 예제 매니페스트는 권한 에스컬레이션을 허용하는 nginx 컨테이너를 배포하는 매니페스트 파일이다.

$ nano psa-workload.yaml
student_03_8f64b7958f47@cloudshell:~ (qwiklabs-gcp-00-99785c58bd47)$ cat psa-workload.yaml 
 apiVersion: v1
 kind: Pod
 metadata:
   name: nginx
   labels:
     app: nginx
 spec:
   containers:
   - name: nginx
     image: nginx
     securityContext:
       privileged: true

### 기준선 정책은 Pod가 네임스페이스에 배포되도록 허용

$  kubectl apply -f psa-workload.yaml --namespace=baseline-ns
Warning: would violate PodSecurity "baseline:latest": privileged (container "nginx" must not set securityContext.privileged=true)
pod/nginx created
student_03_8f64b7958f47@cloudshell:~ (qwiklabs-gcp-00-99785c58bd47)$  kubectl get pods --namespace=baseline-ns -l=app=nginx
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          18s

### 포드는 네임스페이스에 배포되지 않으며 감사 항목이 로그에 추가됨

$  kubectl apply -f psa-workload.yaml --namespace=restricted-ns
Error from server (Forbidden): error when creating "psa-workload.yaml": pods "nginx" is forbidden: violates PodSecurity "restricted:latest": privileged (container "nginx" must not set securityContext.privileged=true), allowPrivilegeEscalation != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")

감사 로그에서 정책 위반 보기

  • 탐색 메뉴 ( 탐색 메뉴 아이콘) 에서 로깅 > 로그 탐색기를 클릭
  • 쿼리 필드 에서 다음을 지정
 resource.type="k8s_cluster"
 protoPayload.response.reason="Forbidden"
 protoPayload.resourceName="core/v1/namespaces/restricted-ns/pods/nginx"

  • 쿼리 실행을 클릭하고 쿼리 결과 섹션에서 금지된 로그 항목을 확장


8-3. IP 주소 및 자격 증명 교체

클러스터에서 IP 및 자격 증명 순환을 수행하는데 자격 증명 수명을 줄이기 위해 정기적으로 수행하는 것이 안전한 방법이다.

서빙 IP와 사용자 인증 정보를 회전하는 별도의 명령이 있지만 사용자 인증 정보를 회전하면 IP도 추가로 회전한다.

gcloud container clusters update $my_cluster --zone $my_zone --start-credential-rotation

-> Y(yes)

Cloud Shell에서 명령이 완료되면 클러스터는 각 노드를 업데이트하는 프로세스를 시작하는데 15분 정도 걸릴 수 있다.

또한 이 프로세스는 현재 사용자의 kubeconfig 항목을 자동으로 업데이트하며 이제 클러스터 마스터는 원래 주소 외에 새 IP 주소를 일시적으로 제공한다.

  • 자격 증명 및 IP 순환 작업을 완료하려면 다음 명령을 실행
gcloud container clusters update $my_cluster --zone $my_zone --complete-credential-rotation

이렇게 하면 순환 프로세스가 완료되고 원래 클러스터 IP 주소가 제거된다.

  • ❗️ 자격 증명 교체가 완료되지 않고 오류 메시지가 반환되면 아래 명령을 실행
gcloud container clusters upgrade $my_cluster     --node-pool=default-pool   --zone $my_zone

-> Y(yes)
  • 클러스터가 성공적으로 업그레이드된 후 다음 명령을 다시 실행
gcloud container clusters update $my_cluster --zone $my_zone --complete-credential-rotation

9. Google Kubernetes Engine으로 역할 기반 액세스 제어 구현실습

이번엔 GKE 클러스터 내에 네임스페이스를 만든 다음역할 기반 액세스 제어(RBAC)를 사용하여 관리자가 아닌 사용자가 특정 네임스페이스에서 Pod를 사용할 수 있도록 허용해보자.

  • 사용자가 클러스터 리소스에 대한 액세스를 제어할 수 있도록 네임스페이스 생성

  • 네임스페이스 내에서 액세스를 제어하는 역할 및 RoleBinding 생성


9-1. 사용자가 클러스터 리소스에 액세스할 수 있도록 네임스페이스 생성

사용자 계정 1 과 사용자 계정 2 콘솔에 로그인하여 Cloud Shell 활성화

  • GKE 클러스터에 연결
export my_zone=us-central1-a
export my_cluster=standard-cluster-1

source <(kubectl completion bash)

gcloud container clusters get-credentials $my_cluster --zone $my_zone

git clone https://github.com/GoogleCloudPlatform/training-data-analyst

ln -s ~/training-data-analyst/courses/ak8s/v1.1 ~/ak8s

cd ~/ak8s/RBAC/
  • Namespace 생성
$ cat my-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: production

$ kubectl apply -f my-namespace.yaml

$ kubectl get namespaces
NAME             STATUS    AGE
default          Active    6m
kube-node-lease  Active    6m
kube-public      Active    6m
kube-system      Active    6m
production       Active    4s

$ kubectl describe namespaces production
Name:         production
Labels:       
Annotations:  
Status:       Active
Resource Quotas
 Name:                       gke-resource-quotas
 Resource                    Used  Hard
 --------                    ---   ---
 count/ingresses.extensions  0     100
 count/jobs.batch            0     5k
 pods                        0     1500
 services                    0     500
No LimitRange resource.
  • Namespace 에 리소스 생성
$ cat my-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80

$ kubectl apply -f ./my-pod.yaml --namespace=production

$ kubectl get pods --namespace=production
NAME      READY     STATUS    RESTARTS   AGE
nginx     1/1       Running   0          20s

9-2. 역할 및 RoleBinding 정보

이 작업에서는 샘플 사용자 지정 역할을 만든 다음 Username 2 에게 프로덕션 네임스페이스의 편집자 역할을 부여하는 RoleBinding을 만든다.

역할은 pod-reader-role.yaml제공된 파일에 정의되어 있으며 pod-reader이 매니페스트는 네임스페이스 의 포드 객체에 대한 생성, 가져오기, 나열 및 감시 권한을 제공하는 라는 production 역할을 정의할 수 있으며 이 역할은 포드를 삭제할 수 없다.

$ cat pod-reader-role.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: production
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["create", "get", "list", "watch"]
  • 사용자 지정 역할 생성

역할을 생성하려면 계정에 할당되는 역할에 부여된 권한이 있어야 합니다. 클러스터 관리자의 경우 다음 RoleBinding을 생성하여 자신의 사용자 계정에 클러스터 관리자 역할을 부여하면 이 작업을 쉽게 수행할 수 있습니다.

사용자 이름 1 계정에 클러스터 관리자 권한을 부여하려면 다음 명령을 실행하여 사용자 이름 1 계정 [USERNAME_1_EMAIL]의 이메일 주소로 바꾼다

$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user [USERNAME_1_EMAIL]

$ kubectl apply -f pod-reader-role.yaml

$ kubectl get roles --namespace production
NAME           AGE 
Pod-reader 		3m
  • 역할 바인딩 만들기

역할은 권한을 할당하는 데 사용되지만 그 자체로는 아무 작업도 수행하지 않으며 역할은 RoleBinding에서 수행되는 사용자 및 개체에 바인딩되어야 한다.

username2-editor-binding.yaml 매니페스트 파일은 이전에 생성한 역할 에 대한 두 번째 랩 사용자에 대해 호출된 RoleBinding을 생성한다.

해당 역할 username2-editorpod-reader은 Pod를 만들고 볼 수 있지만 삭제할 수는 없다.

$ cat username2-editor-binding.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: username2-editor
  namespace: production
subjects:
- kind: User
  name: [USERNAME_2_EMAIL] ### 사용자이름 2 의 메일주소로 바꿔야함
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

$ export USER2=[USERNAME_2_EMAIL]

$ sed -i "s/\[USERNAME_2_EMAIL\]/${USER2}/" username2-editor-binding.yaml

나중에 이 RoleBinding 을 적용할 것이다.

  • 액세스 테스트

이제 Username 2가 Manifest 파일(production-pod.yaml)을 사용하여 Pod를 생성하기 위해 Username 2를 사용하여 프로덕션 네임스페이스에서 Pod를 생성할 수 있는지 여부를 테스트한다.

이 매니페스트는 단일 nginx 컨테이너로 간단한 포드를 배포하는 매니페스트 파일이다.

$ cat production-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: production-pod
  labels:
    name: production-pod
  namespace: production
spec:
  containers:
  - name: production-pod
    image: nginx
    ports:
    - containerPort: 8080
  1. 사용자 이름 2 Google Cloud Console 탭 으로 다시 전환
  2. 사용자 이름 2 용 Cloud Shell에서 다음 명령을 입력하여 영역 및 클러스터 이름에 대한 환경 변수를 설정
$ export my_zone=us-central1-a
$ export my_cluster=standard-cluster-1

$ source <(kubectl completion bash)

$ gcloud container clusters get-credentials $my_cluster --zone $my_zone

$ git clone https://github.com/GoogleCloudPlatform/training-data-analyst

$ ln -s ~/training-data-analyst/courses/ak8s/v1.1 ~/ak8s

$ cd ~/ak8s/RBAC/

$ kubectl get namespaces
NAME             STATUS    AGE
default          Active    29m
kube-node-lease  Active    29m
kube-public      Active    29m
kube-system      Active    29m
production       Active    23m

Cloud Shell에서 다음 명령을 실행하여 production이라는 네임스페이스에 리소스를 생성

$ kubectl apply -f ./production-pod.yaml

사용자 이름 2에 포드를 생성할 수 있는 올바른 권한이 없음을 나타내는 오류가 발생된다.

사용자 이름 2는 아직 해당 계정에 다른 역할을 바인딩하지 않았기 때문에 이 시점에서는 뷰어 권한만 가진다 이제 롤바인딩을 통해 바꿔볼 것이다.

  1. 사용자 이름 1 Google Cloud Console 탭 으로 다시 전환
  2. Username 1 의 Cloud Shell에서 다음 명령을 실행하여 Username 2에게 production 네임스페이스 에서 포드를 생성할 수 있는 권한을 포함하는 역할(pod-leader)을 부여하는 RoleBinding을 생성한다.
$ kubectl apply -f username2-editor-binding.yaml

$ kubectl get rolebinding --namespace production
NAME               AGE
username2-editor   23s
  1. 사용자 이름 2 Google Cloud Console 탭 으로 다시 전환
  2. 사용자 이름 2 용 Cloud Shell에서 다음 명령을 실행하여 production이라는 네임스페이스에 리소스를 생성
  3. production-pod 삭제를 시도하여 pod-reader 역할에서 부여한 특정 RBAC 권한만 사용자 이름 2 에 적용되는지 확인
$ kubectl apply -f ./production-pod.yaml

$ kubectl get pods --namespace production
NAME               READY     STATUS    RESTARTS   AGE
nginx              1/1       Running   0          16m
production-pod     1/1       Running   0          20s

$ kubectl delete pod production-pod --namespace production
### 사용자 이름 2에 포드에 대한 삭제 권한이 없기 때문에 실패

profile
무럭무럭 자라볼까

0개의 댓글