Today I Learned

[쿠버네티스 인 액션] 12. 쿠버네티스 API 서버 보안 본문

쿠버네티스

[쿠버네티스 인 액션] 12. 쿠버네티스 API 서버 보안

하이라이터 2023. 2. 2. 20:37
728x90

12장에서 다루는 내용

  • 인증에 대한 이해
  • 서비스어카운트란 무엇이며 사용하는 이유
  • 역할 기반 엑세스 제어(RBAC) 플러그인 이해
  • 롤과 롤바인딩 사용
  • 클러스터롤과 클러스터롤바인딩 사용
  • 디폴트 롤과 바인딩 이해

12.1 인증 이해

  • API 서버로 요청 -> 인증 플러그인 목록 -> 사용자 이름, ID, 클라이언트 그룹을 반환 -> 다음 인가 단계 진행
  • 인증 플러그인은 다음 방법을 사용해 클라이언트의 아이덴티티를 얻는다.
    • 클라이언트의 인증서
    • HTTP 헤더로 전달된 인증 토큰
    • 기본 HTTP 인증
    • 기타

12.1.1 사용자와 그룹

  • 인증 플러그인은 인증된 사용자의 이름과 그룹을 반환한다. 이를 통해 사용자의 작업 권한을 확인한다.

사용자

  • API 서버에 접속하는 클라이언트는 두종류로 나뉜다.
    • 실제 사람(사용자)
    • 파드(파드 내부에서 실행되는 애플리케이션)
  • 사용자는 싱글 사인 온(SSO, Single Sign On)과 같은 외부 시스템에 의해 관리된다.
  • 파드는 서비스 어카운트(service account)라는 메커니즘을 사용하며, 클러스터에 서비스어카운트 리소스로 생성되고 저장된다.

그룹

  • 그룹은 한 번에 여러 사용자에게 권한을 부여하는 데 사용된다.
  • 내장된(built-in) 그룹은 특별한 의미를 갖는다.
    • system:unauthenticated 그룹은 어떤 인증 플러그인에서도 클라이언트를 인증할 수 없는 요청에 사용된다.
    • system:authenticated 그룹은 성공적으로 인증된 사용자에게 자동으로 할당된다.
    • system:serviceaccounts 그룹은 시스템의 모든 서비스어카운트를 포함한다.
    • system:serviceaccounts:<namespace>는 특정 네임스페이스의 모든 서비스어카운트를 포함한다.

12.1.2 서비스어카운트 소개

  • 모든 파드는 파드에서 실행중인 애플리케이션의 아이덴티티를 나타내는 서비스어카운트와 연계되어 있다.
  • 시크릿 볼륨으로 각 컨테이너의 파일 시스템에 마운트된 토큰 파일은 서비스어카운트의 인증 토큰을 가지고 있다.
  • 애플리케이션이 이 토큰을 사용해 API 서버에 접속하면 인증 플러그인이 서비스어카운트를 인증하고 사용자 이름을 API 서버 코어로 전달한다.
system:serviceaccount:<namespace>:<service account name>
  • API 서버는 설정된 인가 플러그인에 사용자 이름을 전달하며, 인가 플러그인은 애플리케이션이 수행하려는 작업의 권한을 확인한다.

 

서비스어카운트 리소스

  • 서비스어카운트는 파드, 시크릿, 컨피그맵 등과 같은 리소스이며 개별 네임스페이스로 범위가 지정된다.
  • 각 네임스페이스마다 default 서비스어카운트가 자동으로 생성된다.

  • 각 파드는 하나의 서비스와 연계되지만 여러 파드가 같은 서비스어카운트를 사용할 수 있다.

 

서비스어카운트가 인가와 어떻게 밀접하게 연계되어 있는지 이해하기

  • 파드 매니페스트에 서비스어카운트의 이름을 지정해 파드에 서비스어카운트를 할당할 수 있다.
  • 명시적으로 할당하지 않으면 default 서비스어카운트를 사용한다.
  • 파드에 서로 다른 서비스어카운틀를 할당하면 각 파드가 엑세스할 수 있는 리소스를 제어할 수 있다.
  • API 서버는 클러스터 관리자가 구성한 시스템 전체의 인가 플러그인에서 요청된 작업의 권한에 대한 정보를 얻는다.

12.1.3 서비스어카운트 생성

  • default 서비스어카운트를 사용하지 않고 별도로 생성하는 이유는 클러스터 보안 때문이다.
  • 클러스터의 메타데이터를 읽을 필요가 없는 파드, 리소스의 메타데이터를 검색해야 하는 파드, 오브젝트를 수정해야 하는 파드 등 각 파드의 역할에 따라 서비스어카운트를 선택해야 한다.

서비스어카운트 생성

  • 사용자 정의 토큰 시크릿이 생성돼, 서비스 어카운트와 연결되어 있음을 알 수 있다.
  • secret 명령어로 시크릿의 데이터를 보면 default 서비스 어카운트의 토큰과 동일한 항목이 포함되어 있음을 알 수 있다.

 

서비스어카운트의 마운트 가능한 시크릿 이해

  • kubectl describe을 사용해 서비스어카운트를 검사하면 토큰이 Mountable secrets 목록에 표시된다.
  • 기본적으로 파드는 원하는 모든 시크릿을 마운트할 수 있지만, 파드가 마운트 가능한 시크릿(Mountable secrets) 목록에 있는 시크릿만 마운트하도록 파드의 서비스 어카운트를 설정할 수 있다.
  • 이 기능을 사용하려면 서비스어카운트가 다음 어노테이션을 포함하고 있어야 한다.
kubernates.io/enforce-mountable-secret="true".

 

서비스어카운트의 이미지 풀 시크릿 이해

  • 서비스어카운트는 이미지 풀 시크릿(Image Pull Secret) 목록도 포함할 수 있다.
  • 이미지 풀 시크릿은 프라이빗 이미지 리포지터리에서 컨테이너 이미지를 가져오는 데 필요한 자격증명을 갖고 있는 시크릿이다.

  • 서비스어카운트를 사용해 모든 파드에 특정 이미지 풀 시크릿을 자동으로 추가한다.

12.1.4 파드에 서비스어카운트 할당

  • 추가 서비스어카운트를 만든 후에는 파드 정의의 spec.service.AccountName 필드에서 서비스어카운트 이름을 설정해야 한다.

 

사용자 정의 서비스어카운트를 사용하는 파드 생성

  • 새로 생성한 foo 서비스어카운트를 사용하도록 파드를 수정헀다.
  • 사용자 정의 서비스어카운트의 토큰이 두 개의 컨테이너에 마운트됐는지 확인하기 위해 다음과 같이 토큰의 내용을 출력할 수 있다.

 

API 서버와 통신하기 위해 사용자 정의 서비스어카운트 토큰 사용

  • 이 토큰을 사용해 서버와 통신할 수 있는지 살펴보자. 앰배서더 컨테이너는 서버와 통신할 때 토큰을 사용하므로 localhost:8001에서 수신하는 앰배서더 컨터에너로 토큰을 테스트할 수 있다.

  • 서버에서 적절한 응답을 받았으며, 사용자 정의 서비스어카운트로 파드를 나열할 수 있음을 의미한다.
  • 이는 클러스터가 RBAC 인가 플러그인을 사용하지 않거나, 8장에서 제시한 지침에 따라 모든 서비스어카운트에 모든 권한을 부여했기 때문일 수 있다.

12.2 역할 기반 엑세스 제어로 클러스터 보안

  • 쿠버네티스 1.8.0 버전에서 RBAC 인가 플러그인이 GA(General Availability)로 승격됐으며 이제 많은 클러스터에서 기본적으로 활성화되어 있다.
  • RBAC는 권한이 없는 사용자가 클러스터 상태를 보거나 수정하지 못하게 한다.
  • 디폴트 서비스어카운트는 추가 권한을 부여하지 않는 한 클러스터 상태를 볼 수 없으며 어떤 식으로든 수정할 수 없다.


12.2.1 RBAC 인가 플러그인 소개

  • 쿠버네티스 API 서버는 인가 플러그인을 사용해 액션을 요청하는 사용자가 액션을 수행할 수 있는지 점검하도록 설정할 수 있다.
  • 사용자는 서버에 HTTP 요청을 보내 액션을 수행하며, 요청에 자격증명을 포함시켜 자신을 인증한다.

 

액션 이해하기

  • REST 클라이언트는 GET, POST, PUT, DELETE 및 기타 유형의 HTTP 요청을 특정 REST 리소스를 나타내는 특정 URL 경로로 보낸다.
  • 쿠버네티스에서 이러한 리소스에는 파드, 서비스, 시크릿 등이 있다.
    • 파드 가져오기 (GET)
    • 서비스 생성하기 (CREATE)
    • 서비스 업데이트 (UPDATE)
    • 기타 등등
  • API 서버 내에서 실행되는 RBAC와 같은 인가 플러그인은 클라이언트가 요청한 자원에서 요청한 동사를 수행할 수 있는지 판별한다.

  • 전체 리소스 유형에 보안 권한을 적용하는 것 외에도 RBAC 규칙은 특정 리소스 인스턴스에도 적용할 수 있다.
  • 리소스가 아닌 URL 경로에도 권한을 적용할 수 있는데, 이는 API 서버가 노출하는 모든 경로가 리소스를 매핑하는 것은 아니기 때문이다.

 

RBAC 플러그인 이해

  • RBAC 인가 플러그인은 사용자가 액션을 수행할 수 있는지 여부를 결정하는 핵심 요소로 사용자 롤(user role)를 사용한다.
  • 주체(사람, 서비스어카운트, 그룹)는 하나 이상의 롤과 연계돼 있으며 각 롤은 특정 리소스에 특정 동사를 수행할 수 있다.
  • 사용자에게 여러 롤이 있는 경우 롤에서 허용하는 모든 작업을 수행할 수있다.

12.2.2 RBAC 리소스 소개

  • RBAC 인가 규칙은 네 개의 리소스로 구성되며 두 개의 그룹으로 분류할 수있다.
    • 롤(Role)과 클러스터롤(ClusterRole) : 리소스에 수행할 수 있는 동사를 지정한다.
    • 롤바인딩(RoleBinding)과 클러스터롤바인딩(ClusterRoleBinding) : 위의 롤을 특정 사용자, 그룹, 또는 서비스어카운트에 바인딩한다.
  • 롤은 수행할 수 있는 작업을 정의하고, 바인딩은 누가 이를 수행할 수 있는지를 정의한다.

  • 롤과 롤바인딩은 네임스페이스가 지정된 리소스이고 클러스터롤과 클러스터롤바인딩은 네임스페이스를 지정하지 않는 클러스터 수준의 리소스이다.
  • 하나의 네임스페이스에 여러 롤바인딩이 존재할 수 있으며, 여러 클러스터롤바인딩과 클러스터롤을 만들 수 있다.
  • 롤바인딩 네임스페이스가 지정됐더라도 네임스페이스가 지정되지 않은 클러스터롤을 참조할 수 있다.

 

실습을 위한 설정

  • 먼저 클러스터에 RBAC가 활성화되어 있는지 확인해야한다. 쿠버네티스 버전이 최소 1.6 이상이어야하고, 인가 플러그인으로 RBAC 플러그인만 구성되어 있는지 확인하자.

  • RBAC가 비활성화되어있다면 다음 명령을 실행해 다시 RBAC를 활성화할 수 있다.
$kubectl delete clusterrolebinding permissive-binding
  • 네임스페이스별로 보안이 어떻게 작동하지는지 확인하기 위해 서로 다른 네임스페이스에서 두 개의 파드를 실행한다.
  • kubectl-proxy 이미지를 기반으로 컨테이너를 하나 실행하고 kubectl exec를 사용해 해당 컨테이너 내부에서 curl을 실행한다.
  • 프록시가 인증과 HTTPS를 처리해주므로, API 서버 보안의 인가 측면에 집중할 수있다.

 

네임스페이스 생성과 파드 실행

  • 네임스페이스 foo에 파드 하나를 만들고, 다른 하나는 네임스페이스 bar에 만든다.

  • 터미널을 두 개 열고 kubectl exec를 사용해 각 파드 내에서 셸을 실행한다.

  • 다른 터미널도 똑같이 하되, bar 네임스페이스를 사용한다.

 

파드에서 서비스 목록 나열하기

  • RBAC가 활성화되어 있는 상태에서 파드가 클러스터 상태 정보를 읽을 수 없다는 것을 확인하기 위해 curl을 사용해 foo 네임스페이스의 서비스를 나열한다.

  • 파드가 동일한 네임스페이스에서 실행되고 있음에도 API 서버는 서비스어카운트가 foo 네임스페이스의 서비스를 나열할 수 없다고 응답했다.
  • 서비스어카운트의 기본권한으로는 리소스를 나열하거나 수정할 수 없으며, 작업을 허용하기 위해 먼저 롤 리소스를 만들어야 한다.
728x90
Comments