Cloud/k8s-CKA

[CKA] 41. Authorization (권한부여)

jinkwon.kim 2023. 10. 28. 18:05
728x90
반응형

개요

k8s은 Authorization을 통하여 사용자가 할 수 있는 것을 제한하고 있습니다. 

그래서 이번에는 Authorization의 종류 및 사용법을 알아보겠습니다. 

Authorization mechanism 종류

k8s에서는 Authorizaion을 위하여 6개의 mechanism을 제공합니다.

Node Authorization

node authorizion은 kubelet이 API 서버에 요청할 때 사용됩니다. 이 mechanism은 kubelet이 자신에게 할당된 resource에만 access 할 수 있도록 제한합니다.

ABAC (Attribute-based access control)

ABAC는 속성 기반의 권한 부여 방식입니다. 정책 파일에서 정의된 속성 조합을 기반으로 요청이 허용되는지 여부를 결정합니다.

RBAC (Role-based access control)

RBAC는 역할 기반의 권한 부여 방식입니다. 사용자나 그룹에 역할을 할당하고, 각 역할에는 특정 권한이 부여됩니다. RBAC는 k8s의 native resource로서 Role 및 ClusterRole, RoleBinding 및 ClusterRoleBinding 객체를 사용합니다.

Webhook Mode

webhook mode는 권한 부여 결정을 외부 service에 위임합니다. API 서버는 HTTP callback을 사용하여 외부 service에 요청을 전송하고, 외부 serivce는 요청을 승인하거나 거부합니다.

AlwaysAllow and AlwaysDeny

AlwaysAllow는 모든 요청을 허용하는 권한 부여 모드이며, AlwaysDeny는 모든 요청을 거부하는 권한 부여 모드입니다.

주로 TEST 및 디버깅에 사용됩니다.

Service Account Permissions

service account은 자동으로 생성되는 특수한 종류의 계정으로, Pod에 연결되어 있습니다.

service account의 권한은 RBAC을 사용하여 관리될 수 있습니다.

Node Authorization

Node Authorization의 동작 원리는 다음과 같습니다

요청 확인

API 서버는 들어오는 요청을 확인하고, 요청이 kubelet에서 온 것인지 확인합니다. 이는 요청자의 사용자 이름이 system:node:<nodeName> 형식인지 확인함으로써 수행됩니다.

요청자의 이름은 kubelet이 통신과정에서 인증을 위해 사용하는 인증서의 CN이 사용됩니다. 

노드 자원 확인

Node Authorizer는 kubelet이 요청한 resource 노드 resource인지 확인합니다. 예를 들어, kubelet은 자신의 node object 또는 자신의 Node에서 실행 중인 Pod와 같은 resource에 accecss 할 수 있어야 합니다.

요청 허용 또는 거부

Node Authorizer는 kubelet이 요청한 resource에 대한 권한이 있는지 확인합니다. 권한이 있다면 요청이 허용되고, 그렇지 않다면 요청이 거부됩니다.

NodeRestriction admission controller

Node Authorization 플러그인과 함께 사용되는 NodeRestriction admission controller는 kubelet이 오직 자신의 Node와 연관된 Object만 생성, 수정, 삭제할 수 있도록 추가적인 제한을 부과합니다.

ABAC

ABAC (Attribute-Based Access Control)는 쿠버네티스에서 지원하는 권한 부여 메커니즘 중 하나입니다. ABAC는 요청자의 속성, 리소스의 속성 및 환경 속성을 기반으로 권한 부여 결정을 내립니다

ABAC 사용법은 다음과 같습니다.

정책 파일 준비

ABAC는 정책 파일을 사용하여 권한 부여 결정을 내립니다. 정책 파일에는 여러 정책 객체가 포함되며, 각 객체는 특정 사용자 또는 그룹에 대한 권한을 정의합니다.

API 서버 구성

API 서버를 시작할 때 --authorization-mode=ABAC 플래그를 설정하여 ABAC 모드를 활성화합니다.

--authorization-policy-file=/path/to/your/policyfile.json 플래그를 사용하여 정책 파일의 경로를 지정합니다.

정책 파일 형식

정책 파일에는 다음과 같은 필드를 포함하는 여러 정책 오브젝트가 있습니다:

이 정책은 사용자 'bob'이 'project-carol' 네임스페이스의 파드를 읽을 수 있도록 허용합니다.

{
    "apiVersion": "abac.authorization.kubernetes.io/v1beta1",
    "kind": "Policy",
    "spec": {
        "user": "bob",
        "namespace": "project-carol",
        "resource": "pods",
        "readonly": true
    }
}

apiVersion, kind

정책 오브젝트의 버전과 종류를 지정합니다.

spec

정책의 세부 사항을 지정합니다. 여기에는 사용자, 그룹, 리소스, 네임스페이스, 읽기/쓰기 권한 등에 대한 정보가 포함됩니다.

정책 적용

정책 파일을 수정한 후 API Server를 재시작하여 변경 사항을 적용합니다.


주의: ABAC는 쿠버네티스의 초기 권한 부여 메커니즘이었으나, 현재는 RBAC (Role-Based Access Control)가 권장되는 주요 메커니즘이므로, 신규 클러스터에서는 RBAC를 사용하는 것이 좋습니다. ABAC는 특정 사용 사례에는 여전히 적합할 수 있지만, RBAC는 더욱 유연하고 확장 가능합니다.

RBAC

RBAC (Role-Based Access Control)은 역할(role)과 역할 바인딩(role binding)을 중심으로 동작합니다.

Role

특정 resource와 작업에 대한 access 권한을 부여합니다.

종류

Role: 특정 namespace에 대한 권한을 정의합니다. 동작 scope가 namespace 입니다.

          Role 정의시 namespace가 없으면 default 입니다.

ClusterRole: cluster 전체에 대한 권한을 정의합니다.

 

yaml 형식

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-and-pod-logs-reader
rules:
- apiGroups: [""] 
    #Role이 적용되는 API 그룹입니다. Kubernetes API의 일부이며, 다양한 리소스들을 그룹화합니다.
    #Core API Group을 사용할 경우 빈값으로 놔두면 됩니다.\  
  resources: ["pods", "pods/log"] 
    #Role이 접근할 수 있는 리소스 유형들을 나타냅니다. 예를 들어 'pods', 'services' 등이 있습니다.
  verbs: ["get", "list"]
    #리소스에 대해 수행할 수 있는 동작들, 예를 들어 'get', 'list', 'create', 'update', 'delete' 등입니다.
  resourceNames: ["blue", "orange"]
  # 해당 Role을 적용할 Pod를 선택 합니다.
- apiGroup: [""]
  resources: ["ConfigMap"]
  verbs: ["create"]

적용 및 확인

kubectl apply -f role.yaml

kubectl get roles

role 상세 설정

kubectl describes roles

  • Name: Role의 이름을 나타냅니다.
  • Labels: Role에 붙어 있는 레이블들의 목록입니다. 레이블은 리소스를 구분하고 선택하는 데 사용됩니다.
  • Annotations: Role에 설정된 어노테이션들의 목록입니다. 어노테이션은 레이블과 유사하지만 더 많은 정보를 담을 수 있습니다.
  • PolicyRule: Role에 정의된 권한들의 목록입니다. 각 PolicyRule은 다음과 같은 정보를 포함할 수 있습니다:
    • Resources: Role이 접근할 수 있는 리소스 유형들을 나타냅니다. 예를 들어 'pods', 'services' 등이 있습니다.
    • Non-Resource URLs: API 서버의 리소스가 아닌 URL 경로에 대한 접근 권한을 정의합니다.
    • Resource Names: Role이 접근할 수 있는 리소스의 이름들입니다. 비어 있을 경우, 모든 이름의 리소스에 적용됩니다.
    • Verbs: 리소스에 대해 수행할 수 있는 동작들, 예를 들어 'get', 'list', 'create', 'update', 'delete' 등입니다.

Role Binding

Role을 사용자와 연결 시킵니다.

종류

RoleBinding: Role에 정의된 권한을 User 또는 Group에 연결합니다.

ClusterRoleBinding: ClusterRole에 정의된 권한을 User 또는 Group에 연결합니다.

유의 사항 

subjects에서 kind가 User일경우 

name의 값은  CSR에서 사용하는 CN(Common Name) 과 일치하거나 serviceaccount와 일치해야한다.

CSR CN확인 방법

openssl req -text --noout -verify -in {CSR파일명}

yaml 형식

apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
  name: jane # #CSR에서 사용하는 CN과 일치하거나 serviec serviceaccount와 일치해야한다.
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" specifies the binding to a Role / ClusterRole
  kind: Role #this must be Role or ClusterRole
  name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io

적용 및 확인

kubectl apply -f rolebinding.yaml

kubectl get rolebindings

실습

사용자 추가

openssl genrsa -out tester.key 2048

openssl req -new -key tester.key -out tester.csr -subj "/CN=tester"

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: tester
spec:
  request: $(cat tester.csr | base64 | tr -d '\n')
  groups:
  - system:authenticated
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - digital signature
  - key encipherment
  - client auth

kubectl apply -f csr.yaml

kubectl certificate approve tester

kubectl get csr test-user -o jsonpath='{.status.certificate}' | base64 --decode > test-user.crt

Role 추가

role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-read
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

kubectl apply -f role.yaml

Rolebinding 추가

rolebinding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: test-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-read
  apiGroup: rbac.authorization.k8s.io

kubectl apply -f rolebinding.yaml

동작 확인

kubectl get pod --as tester

k8s Authorization 적용 방법

apiserver yaml 파일을 수정하여 적용가능합니다.

파일

/etc/kubernetes/manifests/kube-apiserver.yaml

항목

--authorization

동작 순서

기록된 서대로 동작합니다. 위 설정에서는 Node -> RBAC 순서로 동작합니다.

그리고 다음 모듈로 넘어가는 조건은 현재 모듈에서 권한 부여를 하지 않는 경우에만 넘어갑니다. 

위예제에서 Node에서 권한부여를 하지 않으면 RBAC으로 넘어가고 RBAC에서 권한 부여가 이루어지면 더 이상 그위로 넘어가지 않습니다. 

정리

k8s에서는 여러 가지 권한제어 방법이 존재하는데 그중 제일 대표되는 방법이 RBAC입니다.

RBAC은 Role과 User를 Rolebinding으로 연결하여 관리하고 Role을 통해서 User에 권한을 부여합니다.

Next Post

[CKA] 42. service account

728x90
반응형