[kubernetes] 쿠버네티스에서 권한을 부여하는 방법 (RBAC)

vinca·2023년 12월 15일
0

☸️ kubernetes

목록 보기
27/35
post-thumbnail
post-custom-banner

RBAC(Role-Based Access Control)란?

Kubernetes(k8s)의 Role-Based Access Control (RBAC)은 사용자, 그룹 또는 서비스 계정(SA)에 클러스터 내의 리소스에 대한 접근을 제어하는 방법이다.

예시에 사용될 Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment
  labels:
    app: test-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test-deployment
  template:
    metadata:
      labels:
        app: test-deployment
    spec:
      containers:
      - name: test-deployment
        image: nginx:latest
        ports:
        - containerPort: 80

Role

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: role-dev
rules:
- apiGroups: ["", "apps"]
  resources: ["pods", "deployments"]
  verbs: ["get", "list", "edit"]

Role은 특정 네임스페이스에 권한 부여를 정의한다.

🪧네임스페이스(namespace)
쿠버네티스의 리소스(파드, 서비스, 시크릿 등)를 논리적으로 그룹화하는 단위

Role은 이러한 네임스페이스에 사용자나 그룹이 수행할 수 있는 행동(예: 읽기, 쓰기, 삭제)과 그 행동이 적용될 리소스(예: 파드, 서비스)를 지정하게 된다.

예를 들어, 특정 네임스페이스(default)에서 파드디플로이먼트조회(get, list)하고 수정(edit)할 수 있는 권한을 Role로 정의하고 이를 사용자에게 부여할 수 있다.


RoleBinding

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: dev-rolebinding
  namespace: default
subjects:
- kind: ServiceAccount
  name: dev01
  apiGroup: ""
roleRef:
  kind: Role
  name: role-dev
  apiGroup: rbac.authorization.k8s.io

RoleBinding은 특정 사용자, 그룹, 또는 서비스 계정에 Role을 연결시키는 방법이다.

이러한 RoleBinding을 통해, 해당 Role에 정의된 권한을 실제 사용자(user), 그룹(group), 사용자 계정(sa)에 부여할 수 있다.

RoleBinding은 네임스페이스 범위 내에서만 작동하며, Role이 정의된 동일한 네임스페이스에 존재해야 한다.


ClusterRole

ClusterRole은 클러스터 전체에 걸쳐 권한을 정의한다.

ClusterRole은 Role과 비슷하게 작동하지만, 이는 주로 클러스터 수준의 리소스(전체 노드)에 대한 권한을 정의한다.
즉, 클러스터 내 모든 namespace를 다 사용할 수 있는 권한이다.

ClusterRole은 ClusterRoleBinding을 통해서 사용자나 그룹에 클러스터 전체의 권한을 부여할 수 있다.

⚠️주의!
ClusterRoleBindingRoleBinding보다 더 넓은 권한 부여 방법이므로, 클러스터 수준의 리소스(예: 노드) 뿐만 아니라 모든 네임스페이스네임스페이스 수준 리소스(예: 파드, 시크릿)에 대한 권한도 당연하게 부여할 수 있다.


Rolebinding은 SA(ServiceAccount)에게만 권한을 줄 수 있을까?

당연히 NO❗
쿠버네티스의 RoleBinding은 ServiceAccount뿐만 아니라 User, Group에 대해서도 설정할 수 있다.

  • ServiceAccount에 대한 RoleBinding

  • User에 대한 RoleBinding

  • Group에 대한 RoleBinding

  • Group에 대한 ClusterRoleBinding
    특정 그룹에 대해서 클러스터 수준의 권한을 바인딩
    namespace에 상관 없으므로, namespace를 지정하는 부분이 없다!

정리

RoleBinding은 특정 네임스페이스 내에서 역할(Role)을 부여하는데 사용되며, ClusterRoleBinding은 주로 클러스터 전체에 대해 역할(ClusterRole)을 부여하는데 사용된다.


실습 2

Node, RBAC 인증 모드

먼저 api 서비스에 부여되어 있는 인증 모드(authorization-mode)에는 어떤 것들이 있는지 살펴보자.

 k describe -n kube-system po kube-apiserver-m-k8s | grep -i authorization-mode -F4

static pod인 api 서비스에는 총 2개의 인증 모드가 부여된 것을 확인할 수 있다.

  • Node 인증 모드
    클러스터 내의 각 노드가 자신의 리소스를 접근/관리할 수 있도록 하는 인증 권한.

  • RBAC 인증 모드
    사용자 및 그룹에 부여된 정해진 Role에 따른 리소스에 대한 접근/관리 권한.


Namespace 및 SA 생성

Namespace를 2개 생성하고, 해당 Namespace내에 각각 ServiceAccount를 생성해 보도록 하자.

# dev1 namespace
apiVersion: v1
kind: Namespace
metadata:
  name: dev1
---
# ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dev1-hoon
  namespace: dev1
---
# dev2 namespace
apiVersion: v1
kind: Namespace
metadata:
  name: dev2
---
# ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dev2-moon
  namespace: dev2
  • 확인
k get ns
k get serviceaccounts -n dev1
k get serviceaccounts -n dev2


Role 생성

다음과 같이 파드와 디플로이먼트에 대해서 get, list 권한을 가진 Role을 생성해 주자.

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: dev1
  name: role-get-dev1
rules:
- apiGroups: ["*"]
  resources: ["pods", "deployments"]
  verbs: ["get", "list"]
  • 확인
k get role -n dev1 -o yaml

RoleBinding 생성

다음과 같이 Role(role-get-dev1)과 연결되는 RoleBinding을 생성해 주도록 하자.

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: rolebinding-dev1
  namespace: dev1
subjects:
- kind: ServiceAccount
  name: dev1-hoon
  apiGroup: ""
roleRef:
  kind: Role
  name: role-get-dev1
  apiGroup: rbac.authorization.k8s.io
  • 확인
k get rolebindings.rbac.authorization.k8s.io -n dev1

기존 생성 하였던 Role(role-get-dev1)과 연결된 것을 확인할 수 있다.

context 단위로 묶기

이러한 Role을 새로운 context(클러스터) 단위로 묶은 뒤 실제로 Role이 잘 적용되는지 테스트 해보도록 하자.

잠깐! Context란?

컨텍스트는 클러스터, 사용자, 그리고 네임스페이스의 조합으로 정의되는 환경 설정이다.
이러한 컨텍스트는 특정 클러스터(EKS, GKE, AKE 등)에 접근하기 위한 "환경 설정"이므로, 이를 클러스터 단위라고 봐도 사실 얼추 맞다.

이 실습에서는?

💡 SA의 크레덴셜(API토큰)을 추출하고 이를 새로운 Context에 할당한다.

1. SA의 크레덴셜(API토큰)을 추출 후 Context에 할당

#!/usr/bin/env bash

# 변수 설정: 스크립트는 NAMESPACE, SERVICEACCOUNT, SETCRED, SETCTXNAME라는 변수들을 설정합니다. 
# 이들은 각각 네임스페이스, 서비스 어카운트 이름, 새로운 크레덴셜(자격 증명) 이름 그리고 새로운 컨텍스트 이름을 정의합니다.
NAMESPACE='dev1'
SERVICEACCOUNT='dev1-hoon'
SETCRED='dev1-set-hoon'
SETCTXNAME='ctx-dev1-hoon'
TOKENNAME=`kubectl -n $NAMESPACE get serviceaccount $SERVICEACCOUNT -o jsonpath={.secrets[0].name}`

# 토큰 이름 추출: kubectl 명령어를 사용하여 지정된 네임스페이스와 서비스 어카운트에 대한 토큰 이름을 가져옵니다.
echo "$SERVICEACCOUNT of $NAMESPACE Token: `kubectl -n $NAMESPACE get secret $TOKENNAME -o jsonpath={.data.token}| base64 --decode`"

# 자격 증명 설정: 새로운 크레덴셜을 생성하고, 이전 단계에서 가져온 토큰을 이 크레덴셜에 할당합니다.
kubectl config set-credentials $SETCRED --token=`kubectl -n $NAMESPACE get secret $TOKENNAME -o jsonpath={.data.token}| base64 --decode`
# 컨텍스트 설정: 마지막으로, 새로운 컨텍스트를 생성하고, 이를 위에서 생성한 크레덴셜과 연결합니다.
# 이 컨텍스트는 kubernetes 클러스터와 연결되어 있으며, 지정된 사용자(여기서는 새 크레덴셜)를 사용합니다.
kubectl config set-context $SETCTXNAME --cluster=kubernetes --user=$SETCRED

🔑크레덴셜이란?
시스템이나 리소스에 접근하기 위해서 사용되는 인증 정보로 사용자를 확인하고, 적절한 권한을 부여하는데 사용한다.

SA는 RBAC 권한과 연결된 크레덴셜(SA는 API 토큰형식의 크레덴셜을 씀)을 가지고 있다.
위는 이러한 크레덴셜(API 토큰)을 Context에 연결하는 과정의 쉘 스크립트 명령어이다.

일반적으로 한 Context는 하나의 사용자 또는 SA의 크레덴셜만을 참조하고, 이러한 SA의 크레덴셜에 따라서 수행할 수 있는 작업 권한이 제한된다.

2. 생성된 context 조회 및 전환

# contexts 조회
k config get-contexts
# contexts 전환
k config use-context ctx-dev1-hoon


적용 확인

default 네임스페이스에서 pod, service, nodes를 조회해 보려고 하였는데, 모두 Forbidden 즉, 차단되어 있는 것을 확인할 수 있다.

dev1 네임스페이스에 대해서 get, list 권한은 있으므로 조회가 가능한 것을 확인할 수 있다.
물론 배포된 게 없으므로 나오는 리소스는 현재 없다.

Reference

쿠버네티스 RBAC - RedHat
RBAC - 티스토리
CNCF - RBCA

profile
붉은 배 오색 딱다구리 개발자 🦃Cloud & DevOps
post-custom-banner

0개의 댓글