본문 바로가기

Infrastructure/Kubernetes

[CKA] Security (ClusterRole)

Security (Cluster Role)

  • 이번 장에서는 Certified Kubernetes Administrator (CKA) 을 준비하며 "Cluster Role"에 대해서 자세하게 알아보도록 한다.

Roles & Role Bindings

  • Role과 Role Binding은 네임스페이스(namespace) 범위 내에서 권한을 관리한다.
  • 네임스페이스를 지정하지 않으면 기본(default) 네임스페이스에 생성된다.
  • 특정 네임스페이스 내에서만 리소스에 대한 접근 권한을 제어한다.

Namespace와 클러스터 범위(Cluster-scoped) 리소스

  • 네임스페이스는 파드, 디플로이먼트, 서비스와 같은 리소스를 그룹화하거나 격리하는 데 사용된다.
  • 하지만 노드와 같은 일부 리소스는 클러스터 전체 범위(cluster-wide 또는 cluster-scoped)에 적용된다.
  • 클러스터 범위 리소스는 특정 네임스페이스에 연결할 수 없다.
  • 리소스는 네임스페이스 범위 또는 클러스터 범위로 분류된다.

  • 네임스페이스 범위 리소스 예시: 파드, 레플리카셋, 잡, 디플로이먼트, 서비스, 시크릿, 역할, 역할 바인딩
  • 클러스터 범위 리소스 예시: 노드, 퍼시스턴트 볼륨, 클러스터 역할, 클러스터 역할 바인딩, 인증서 서명 요청, 네임스페이스 자체
  • kubectl api-resources --namespaced 명령어를 사용하여 네임스페이스 범위 및 비네임스페이스 범위 리소스의 전체 목록을 확인할 수 있다.

Cluster Role & Cluster Role Bindings

  • 역할과 역할 바인딩은 네임스페이스 범위 리소스에 대한 사용자 권한 부여에 사용된다.
  • 클러스터 범위 리소스(예: 노드, 퍼시스턴트 볼륨)에 대한 사용자 권한 부여에는 클러스터 역할과 클러스터 역할 바인딩이 사용된다.
  • 클러스터 역할은 클러스터 범위 리소스에 대한 권한을 정의한다.

  • 예를 들어, 클러스터 관리자 역할(cluster admin role)은 클러스터 관리자에게 노드 조회, 생성, 삭제 권한을 부여한다.
  • 예를 들어, 스토리지 관리자 역할(storage admin role)은 스토리지 관리자에게 퍼시스턴트 볼륨 및 클레임 생성 권한을 부여한다.
  • 클러스터 역할 정의 파일은 종류(kind)를 클러스터 역할(cluster role)로 설정하고 규칙(rules)을 지정한다.

클러스터 역할 바인딩 (Cluster Role Binding) 생성

  • 클러스터 역할 바인딩은 사용자를 클러스터 역할에 연결한다.
  • 예: 클러스터 관리자 역할 바인딩(cluster admin role binding)은 클러스터 관리자 사용자(cluster admin user)를 클러스터 관리자 역할에 연결한다.
  • 클러스터 역할 바인딩 정의 파일은 종류를 클러스터 역할 바인딩으로 설정하고, 주제(subject)에 사용자 세부 정보를 지정하며 역할 참조(role ref)에 클러스터 역할 세부 정보를 제공한다.
  • kubectl create 명령어를 사용하여 클러스터 역할 바인딩을 생성한다.

클러스터 역할(Cluster Role)의 네임스페이스 범위 리소스 적용

  • 클러스터 역할은 클러스터 범위 리소스뿐만 아니라 네임스페이스 범위 리소스에도 사용할 수 있다.
  • 클러스터 역할을 네임스페이스 범위 리소스에 적용하면 사용자는 모든 네임스페이스에서 해당 리소스에 접근할 수 있다.
  • 역할을 사용하여 파드에 대한 접근 권한을 부여하면 사용자는 특정 네임스페이스의 파드에만 접근할 수 있다.
  • 클러스터 역할을 사용하여 파드에 대한 접근 권한을 부여하면 사용자는 클러스터 전체의 모든 파드에 접근할 수 있다.
  • 쿠버네티스 클러스터는 초기 설정 시 여러 기본 클러스터 역할을 생성한다.

Service

서비스 계정의 개념

  • 쿠버네티스에는 사용자 계정(User Account)과 서비스 계정(Service Account) 두 가지 계정이 있다.
  • 사용자 계정은 사람이 클러스터에 접근하여 관리 작업을 수행하거나 애플리케이션을 배포하는 데 사용된다.
  • 서비스 계정은 애플리케이션이 쿠버네티스 클러스터와 상호 작용하는 데 사용된다.

  • 예를 들어, Prometheus와 같은 모니터링 애플리케이션이나 Jenkins와 같은 자동화 빌드 도구가 서비스 계정을 사용하여 쿠버네티스 API에 접근한다.

서비스 계정 생성 및 사용

  • kubectl create serviceaccount <계정 이름> 명령어를 사용하여 서비스 계정을 생성한다.
  • 서비스 계정을 생성하면 자동으로 토큰(token)이 생성되며 이 토큰은 시크릿(Secret) 객체에 저장된다.
  • kubectl get serviceaccount 명령어를 사용하여 서비스 계정들을 확인한다.

  • kubectl describe secret <시크릿 이름> 명령어를 사용하여 토큰을 확인할 수 있다.

  • 애플리케이션은 이 토큰을 사용하여 쿠버네티스 API에 인증할 수 있다.
  • 외부의 애플리케이션에서 API를 사용하기위해 curl 명령어와 Authorization 헤더에 Bearer token을 사용해 API를 호출할 수 있다.

클러스터 내부 애플리케이션 서비스 계정 사용

  • 클러스터 내부에서 실행되는 애플리케이션(예: Prometheus, 사용자 정의 대시보드)은 서비스 계정 토큰을 자동으로 마운트하여 사용할 수 있다.
  • 각 네임스페이스에는 기본 서비스 계정(default service account)이 자동으로 생성된다.
  • 파드를 생성할 때 서비스 계정을 명시적으로 지정하지 않으면 기본 서비스 계정이 자동으로 마운트된다.
  • /var/run/secrets/kubernetes.io/serviceaccount 디렉터리에 토큰이 마운트된다.

  • kubectl describe pod <파드 이름> 명령어를 사용하여 파드의 상세 정보를 확인하면 마운트된 서비스 계정 토큰을 확인할 수 있다.
  • 기본 서비스 계정은 제한된 권한을 가지고 있다. 필요한 경우 사용자 정의 서비스 계정을 생성하여 파드에 연결할 수 있다.

  • 파드가 이미 실행중인 경우에는 서비스 계정의 변경이 불가능하고, 디플로이먼트의 경우에는 파드 정의 파일의 변경시 롤아웃이 발생하면서 새로운 파드가 생성되면서 서비스 계정의 변경이 적용된다.

  • 파드 정의 파일에서 automountServiceAccountToken: false를 설정하여 서비스 계정 토큰 자동 마운트를 비활성화할 수 있다.

Service Account 업데이트 사항

1.22 버전 이번의 서비스 계정 토큰

  • 각 네임스페이스에는 기본 서비스 계정이 있으며 이 계정에는 토큰이 포함된 시크릿 객체가 연결되어 있다.
  • 파드가 생성되면 서비스 계정이 자동으로 연결되고 토큰이 파드 내부의 특정 위치(/var/run/secrets/kubernetes.io/serviceaccount)에 마운트된다.
  • 이 토큰을 만료일이 설정되지 않아 서비스 계정이 존재하는 한 유효하다.
  • 이런 방식은 보안 및 확장성 문제를 야기한다.

1.22 버전의 변경 사항 (토큰 요청 API 도입)

  • 보안 및 확장성 문제를 해결하기 위해 토큰 요청 API(Token Request API)가 도입되었다. (KEP-1205)
  • 파드가 생성될 때 서비스 계정 어드미션 컨트롤러(Service Account Admission Controller)가 토큰 요청 API를 통해 수명이 정의된 토큰을 생성한다.
  • 이 토큰은 프로젝티드 볼륨(Projected Volume)으로 파드에 마운트된다.
  • 기존의 서비스 계정의 Secret이 직접적으로 마운트 되는 방식에서, 토큰 요청 API를 통해 토큰을 발급받아 프로젝티드 볼륨에 마운트하는 방식으로 변경되었다.

1.24 버전의 변경 사항 (시크릿 기반 서비스 계정 토큰 감소)

  • 서비스 계정 생성 시 자동으로 시크릿 및 토큰이 생성되지 않는다. (KEP-2799)
  • kubectl create token <서비스 계정 이름> 명령어를 사용하여 필요한 경우 토큰을 생성해야 한다.

  • 이 명령어로 생성된 토큰은 만료일이 설정된다. (기본적으로 1시간)
  • 만료 시간을 늘리는 추가 옵션을 명령어에 전달할 수 있다.
  • 기존의 서비스 계정 생성시 자동으로 생성되던 시크릿이 더이상 자동으로 생성되지 않는다.

1.24 버전 이후의 이전 방식 시크릿 생성

  • 만료되지 않는 토큰을 사용하는 이전 방식의 시크릿을 생성하려면 시크릿 객체를 생성하고 유형(type)을 kubernetes.io/service-account-token으로 설정해야 한다.
  • 메타데이터(metadata) 영역의 어노테이션(annotations)에 서비스 계정 이름을 지정해야 한다.
  • 서비스 계정을 먼저 생성한 후 시크릿 객체를 생성해야 한다.

권장 사항

  • 쿠버네티스 문서에 따르면 토큰 요청 API를 사용하여 토큰을 얻을 수 없는 경우에만 서비스 계정 토큰 시크릿을 생성해야 한다.
  • kubectl create token 명령어나, 토큰 요청 API를 사용하는 것이 권장된다.
  • 만료되지 않는 토큰 자격 증명을 유지하는 보안 노출이 허용되는 경우에만 서비스 계정 토큰 시크릿을 생성해야 한다.
  • 토큰 요청 API는 서비스 계정 토큰 시크릿보다 안전하고 수명이 제한되어 권장된다.

Image Security

Image

이미지 이름의 기본

  • 컨테이너 이미지 이름은 Docker의 이미지 명명 규칙을 따른다.
  • User 또는 User/Image 형식으로 구성된다.
  • User 부분을 생략하면 기본적으로 library로 간주된다.
  • library는 Docker의 공식 이미지가 저장되는 기본 계정이다.
  • 예시: nginxlibrary/nginx와 같다.

이미지 저장소(Registry)

  • 이미지는 이미지 저장소에 저장되고 가져온다.
  • 기본 이미지 저장소는 Docker Hub(docker.io)이다.
  • 다른 인기 있는 저장소로는 Google Container Registry(gcr.io) 등이 있다.
  • 사내에서 사용하는 비공개 이미지를 위한 내부 사설 저장소도 구축할 수 있다.
  • AWS, Azure, GCP와 같은 클라우드 서비스 제공업체는 기본적으로 사설 저장소를 제공한다.

Private Repository

비공개 이미지 저장소 사용

  • 비공개 저장소의 이미지를 사용하려면 인증이 필요하다.
  • 도커에서는 docker login 명령어를 사용하여 비공개 저장소에 로그인한다.
  • 쿠버네티스에서는 시크릿(Secret) 객체를 사용하여 인증 정보를 전달한다.

쿠버네티스에서 비공개 이미지 사용 설정

  • 파드 정의 파일에서 image 필드에 비공개 저장소의 이미지 전체 경로를 지정한다.
  • 시크릿 객체를 생성하여 저장소 인증 정보를 저장한다.
  • 시크릿의 타입은 docker-registry로 생성한다.
  • 시크릿 객체에는 저장소 서버 이름, 사용자 이름, 암호, 이메일 주소를 포함한다.
  • 파드 정의 파일의 imagePullSecrets 영역에 생성한 시크릿 이름을 지정한다.
  • 쿠버네티스(kubelet)는 시크릿의 인증 정보를 사용하여 이미지를 가져온다.

참고한 강의

'Infrastructure > Kubernetes' 카테고리의 다른 글