[Kubernetes] 보안을 위한 인증과 인가 : ServiceAccount와 RBAC

연수·2021년 11월 30일
0

kubernetes

목록 보기
12/15

여러 개발자와 애플리케이션이 쿠버네티스를 동시에 사용할 때 깊이 있게 고려해야 할 부분 중 하나가 바로 보안이다.

쿠버네티스는 보안 측면에서도 다양한 기능을 제공하고 있는데, 그 중에서 가장 자주 사용되는 것은 RBAC(Role Based Access Control)를 기반으로 하는 서비스 어카운트(Service Account)라는 기능이다.

서비스 어카운트는 사용자 또는 애플리케이션 하나에 해당하며, RBAC라는 기능을 통해 특정 명령을 실행할 수 있는 권한을 서비스 어카운트에 부여한다. 권한을 부여 받은 서비스 어카운트는 해당 권한에 해당하는 기능만 사용할 수 있게 된다.

** 지금까지 kubectl 명령어를 사용해왔던 권한은 사실 최상위에 해당!

 

✅ 쿠버네티스의 권한 인증 과정

kubectl을 사용할 때는 기본적으로 ~/.kube/config라는 파일에 저장된 설정을 읽어 들여 쿠버네티스 클러스터를 제어한다. 기본적으로 이 파일에서는 인증서 키 쌍을 사용해 API 서버에 인증하지만, 이 인증 방법은 비교적 절차가 복잡하고 관리가 어렵기 때문에 자주 사용하는 방법은 아니다.

 

✅ 서비스 어카운트와 롤(Role), 클러스터 롤(Cluster Role)

  • 서비스 어카운트
    - 체계적으로 권한을 관리하기 위한 쿠버네티스 오브젝트
    - 네임스페이스에 속하는 오브젝트로, serviceaccount 또는 sa라는 이름으로 사용할 수 있다.
    - 각 네임스페이스에는 기본적으로 default라는 이름의 서비스 어카운트가 존재한다.
    - kubectl create나 delete를 통해 서비스 어카운트를 생성하거나 삭제할 수 있다.
    - 서비스 어카운트에 적절한 권한을 부여해야 쿠버네티스의 기능을 제대로 사용할 수 있다.

권한을 부여하는 방법은 크게 두 가지가 있다. 롤과 클러스터롤은 부여할 권한이 무엇인지를 나타내는 쿠버네티스 오브젝트이다.

  1. 롤(Role)

    • 네임스페이스에 속하는 오브젝트이므로 디플로이먼트나 서비스처럼 네임스페이스에 속하는 오브젝트들에 대한 권한을 정의할 때 쓰인다.
    • 롤은 특정 기능에 대한 권한만을 정의하는 오브젝트이기 때문에 롤을 생성하는 것만으로는 서비스 어카운트나 사용자에게 권한이 부여되지 않는다.
    • 롤을 특정 대상에게 부여하려면 롤 바인딩(RoleBinding)이라는 오브젝트를 통해 특정 대상과 롤을 연결해야 한다.
    • 롤 바인딩에서는 어떠한 대상을 어떠한 롤에 연결할 것인지를 정의한다.
    • 하나의 롤은 여러 개의 롤 바인딩에 의해 참조될 수 있고, 하나의 서비스 어카운트는 여러 개의 롤 바인딩에 의해 권한을 부여받을 수 있다.
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: default
      name: service-reader
    rules:
    - apiGroups: [""] # 1. 대상이 될 오브젝트 API 그룹
      resources: ["services"] # 2. 대상이 될 오브젝트의 이름
      verbs: ["get", "list"] # 3. 어떠한 동작을 허용할 것인지 명시
  2. 클러스터 롤(Cluster Role)

    • 클러스터 단위의 리소스에 대한 권한을 정의할 때 사용한다.
    • 예) '펴시스턴트 볼륨의 목록을 조회할 수 있다.'
    • 네임스페이스에 속하지 않는 오브젝트 뿐만 아니라 클러스터 전반에 걸친 기능을 사용하기 위해서도 클러스터 롤을 정의할 수 있으며, 여러 네임스페이스에서 반복적으로 사용되는 권한을 클러스터 롤로 만들어 재사용하는 것도 가능하다.
    • 클러스터 롤 바인딩은 클러스터 롤과 특정 대상을 연결하는 중간 매개체 역할을 한다.
  • 롤 애그리게이션(aggregation)
    • 자주 사용되는 클러스터 롤이 있다면 다른 클러스터 롤에 포함시켜 재사용할 수 있는데, 이를 롤 애그리게이션이라고 한다.
    • 여러 개의 클러스터 롤 권한을 하나의 클러스터 롤에 합쳐서 사용할 수도 있으며, 여러 단계의 클러스터 롤 권한 상속 구조를 만들 수도 있다.

 

✅ 쿠버네티스 API 서버에 접근

✔️ 서비스 어카운트의 시크릿을 이용해 쿠버네티스 API 서버에 접근

  • 쿠버네티스는 서비스 어카운트를 위한 인증 정보를 시크릿에 저장한다.
  • 서비스 어카운트를 생성하면 이에 대응하는 시크릿이 자동으로 생성되며, 해당 시크릿은 서비스 어카운트를 증명하기 위한 수단으로 사용된다.
  • 서비스 어카운트와 연결된 시크릿에는 ca, crt, namespace, token 총 3개의 데이터가 저장되어 있다.
    - ca, crt: 쿠버네티스 클러스터의 공개 인증서 저장
    - namespace: 해당 서비스 어카운트가 존재하는 네임스페이스를 저장
    - token: 쿠버네티스 API 서버와 JWT(JSON Web Token) 인증에 사용된다


✔️ 클러스터 내부에서 kubernetes 서비스를 통해 API 서버에 접근

  • 포드 내부에서도 쿠버네티스 API 서버에 접근하기 위한 방법이 필요할 뿐만 아니라, 포드를 위한 권한 인증도 수행할 수 있어야 한다.

  • 쿠버네티스는 클러스터 내부에서 API 서버에 접근할 수 있는 서비스 리소스를 미리 생성해 놓는다.

    → kubernetes라는 이름의 서비스

  • 그러나 kubernetes라는 이름의 서비스에 접근한다고 해서 특별한 권한이 따로 주어지는 것은 아니다.

  • 쿠버네티스는 포드를 생성할 때 자동으로 서비스 어카운트의 시크릿을 포드 내부에 마운트한다. 따라서 포드 내부에서 API 서버에 접근하기 위해 시크릿의 데이터를 일부로 포드 내부로 가져올 필요는 없다.

✔️ 쿠버네티스 SDK를 이용해 포드 내부에서 API 서버에 접근

  • 특정 서비스 어카운트의 시크릿을 마운트하도록 설정된 포드 내부에서 쿠버네티스 SDK를 사용해 쿠버네티스 API 서버에 접근한다.

 

✅ 서비스 어카운트에 이미지 레지스트리 접근을 위한 시크릿 설정

  • 서비스 어카운트를 이용하면 비공개 레지스트리 접근을 위한 시크릿을 서비스 어카운트 자체에 설정할 수 있다.
  • 즉, 디플로이먼트나 포드의 YAML 파일마다 docker-registry 타입의 시크릿 이름을 정의하지 않아도 된다. 어떤 시크릿을 사용할지는 서비스 어카운트의 정보에 저장돼 있기 때문이다.

 

✅ kubeconfig 파일에 서비스 어카운트 인증 정보 설정

  • 서비스 어카운트와 연결된 시크릿의 token 데이터를 kubeconfig에 명시함으로써 kubectl 명령어의 권한을 제한할 수 있다.

 

✅ 유저(User)와 그룹(Group)의 개념

  • 쿠버네티스에는 서비스 어카운트 외에도 유저와 그룹이라는 개념이 있다.
  • 유저는 실제 사용자를 뜻하며, 그룹은 여러 유저들을 모아 놓는 집합을 의미한다.
  • 롤 바인딩이나 클러스터 롤 바인딩을 정의하는 YAML 파일의 Kind 값에는 ServiceAccount 대신 User나 Group을 사용할 수 있다.
  • 사실 쿠버네티스에서 유저는 '사용자'를 나타내는 개념이며, 서비스 어카운트 또한 개념상으로는 유저의 한 종류입니다.
  • 쿠버네티스에는 유저나 그룹이라는 오브젝트가 없기 때문에 kubectl get user 또는 kubectl get group과 같은 명령어 또한 사용할 수 없다.

✔️ 다양한 인증 방법에서의 User와 Group

  • x509 인증서: 쿠버네티스에서 자체적으로 지원하는 인증 방법
  • 별도의 인증 서버를 사용하면 깃허브 계정, 구글 계정, LDAP 데이터 등을 쿠버네티스 사용자 인증에 사용할 수도 있다.
  • 별도의 인증 방법을 사용할 때는 유저(User)와 그룹(Group)의 개념을 더 특별하게 사용한다.
  • 예) 깃허브의 조직을 인증에 사용할 경우 조직의 팀 이름이 그룹으로, 깃허브 이메일이나 사용자 이름을 유저로 매칭해 사용할 수 있다.

✔️ x509 인증서를 이용한 사용자 인증

  • 쿠버네티스는 보안 연결을 위해 자체적으로 사인(self-signed)한 루트 인증서를 사용한다.
  • ca, crt: 루트 인증서
  • ca, key: 인증서에 대응하는 비밀키
  • apiserver, crt: 루트 인증서로부터 발급된 하위 인증서
  • 하위 인증서들은 쿠버네티스 핵심 컨포넌트들이 서로 보안 연결을 수립하는 데 사용된다.
  • 쿠버네티스의 루트 인증서로부터 발급된 하위 인증서를 사용하면 쿠버네티스 사용자를 읹ㅇ할 수 있다.
  • 쿠버네티스를 설치하면 기본적으로 설정되는 kubeconfig 파일에 저장되어 있던 인증 정보 또한 x509 인증서를 이용한 인증 방법이다.
  • 하위 인증서를 사용자 인증에 사용할 때는 인증서의 CN(Common Name)이 유저(User)로, O(Organization)가 그룹(Group으로 취급된다.
  • CertificateSigningRequest

 

[출처] 시작하세요! 도커/쿠버네티스 (용찬호 지음)

profile
DCDI

0개의 댓글