개발강의정리/DevOps

[데브옵스를 위한 쿠버네티스 마스터] 클러스터 유지와 보안, 트러블슈팅 - RBAC를 활용한 롤 기반 엑세스 컨트롤

nineDeveloper 2021. 1. 22.
728x90

RBAC를 활용한 롤 기반 엑세스 컨트롤


역할 기반 액세스 제어 (RBAC)

  • 기업 내에서 개별 사용자의 역할을 기반으로 컴퓨터, 네트워크 리소스에 대한 액세스를 제어
  • rbac.authorization.k8s.ioAPI를 사용하여 정의
  • 권한 결정을 내리고 관리자가 Kubernetes API를 통해 정책을 동적으로 구성
  • RBAC를 사용하여 룰을 정의하려면 apiserver에 --authorization-mode=RBAC 옵션이 필요

rbac.authorization.k8s.ioAPI

  • RBAC를 다루는 이 API는 총 4가지의 리소스를 컨트롤
    • Role
      • 네임스페이스에 종속되는 제한된 특정 사용자 권한
    • RoleBinding
    • ClusterRole
      • 네임스페이스에 제약이 없는 관리자 권한
    • ClusterRoleBinding

  • 롤과 롤바인딩의 차이
      • “누가”하는 것인지는 정하지 않고 룰만을 정의
      • 일반 롤의 경우에는 네임스페이스 단위로 역할을 관리
      • 클러스터롤은 네임스페이스 구애 받지 않고 특정 자원을 전체 클러스터에서 자원을 관리할 롤을 정의
    • 롤 바인딩
      • “누가”하는 것인지만 정하고 롤은 정의하지 않음
      • 롤을 정의하는 대신에 참조할 롤을 정의 (roleRef)
      • 어떤 사용자에게 어떤 권한을 부여할지 정하는(바인딩) 리소스
      • 클러스터롤에는 클러스터롤바인딩, 일반 롤에는 롤바인딩을 필요

  • 룰(Rule) 작성 요령
kind: Role
apiVersion: rbac.authorization.k8c.io/v1beta1
metadata:
  namespace: office
  name: deployment-manager
rules:
- apiGroups: ["", "extensions", "apps"]
  resources: ["deployments", "replicasets", "pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  • 룰에는 api 그룹, 리소스, 작업 가능한 동작을 작성
    • API를 사용하게 할 그룹 정의

사용자 권한 할당

  • 롤바인딩을 사용하여 office 네임스페이스 권한 할당
  • kubectl create -f 를 사용하여 생성
  • 해당 네임 스페이스에 모든 권한을 생성
kind: RoleBinding
apiVersion: rbac.authorization.k8c.io/v1beta1
metadata:
  name: deployment-manager-binding
  namespace: office
subjects:
- kind: User
  name: gasbugs
  apiGroup: ""
roleRef:
  kind: Role
  name: deployment-manager
  apiGroup: ""
kind: Role
apiVersion: rbac.authorization.k8c.io/v1beta1
metadata:
  namespace: office
  name: deployment-manager
rules:
- apiGroups: ["", "extensions", "apps"]
  resources: ["deployments", "replicasets", "pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

사용자 권한 테스트

  • 실행돼야 하는 명령어
    • 네임스페이스가 있으면 실행 가능
$ kubectl --context=gasbugs-context get pods -n office
$ kubectl --context=gasbugs-context run --generator=pod-run/v1 nginx -- image=nginx -n office
  • 실행되면 안되는 명령어
    • 네임스페이스가 없는 default 명령은 실행 불가능
$ kubectl --context=gasbugs-context get pods
$ kubectl --context=gasbugs-context run --generator=pod-run/v1 nginx -- image=nginx

권한의 종류


API의 종류

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/


실습

https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-example

pod-reader-role.yaml 파일 생성

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

kubectl 로 role 생성

$ kubectl create -f pod-reader-role.yaml
role.rbac.authorization.k8s.io/pod-reader created

https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-example

pod-reader-rolebinding.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: gasbugs # "name" is case sensitive
  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 로 rolebinding 생성

$ kubectl create -f pod-reader-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/read-pods created

user 의 context 로 조회시 여전히 네임스페이스 office 의 권한이 없어서 조회가 안됨

$ kubectl get pod --context=gasbugs@kubernetes
Error from server (Forbidden): pods is forbidden: User "gasbugs" cannot list resource "pods" in API group "" in the namespace "office"

default 에서 gasbugs user 에게 pod-reader 라는 권한을 줬으므로 조회가 됨
읽기 관련된 권한을 주었으므로 조회가 잘 동작됨

$ kubectl get pod --context=gasbugs@kubernetes -n default
NAME                      READY   STATUS    RESTARTS   AGE
http-go-568f649bb-crtcr   1/1     Running   2          45h

$ kubectl get pod --context=gasbugs@kubernetes -n default -o yaml
apiVersion: v1
items:
- apiVersion: v1
  kind: Pod
  metadata:
    creationTimestamp: "2021-01-19T09:39:15Z"
...

$ kubectl get pod --context=gasbugs@kubernetes -n default -w
NAME                      READY   STATUS    RESTARTS   AGE
http-go-568f649bb-crtcr   1/1     Running   2          45h

clusterrole admin 권한 조회

$ kubectl get clusterrole | grep admin
admin                                                                  2020-12-26T12:34:11Z
cluster-admin                                                          2020-12-26T12:34:11Z
system:aggregate-to-admin                                              2020-12-26T12:34:11Z
system:kubelet-api-admin                                               2020-12-26T12:34:11Z

clusterrole cluster-admin 설정 내용 확인

$ kubectl get clusterrole cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: "2020-12-26T12:34:11Z"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  managedFields:
  - apiVersion: rbac.authorization.k8s.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:rbac.authorization.kubernetes.io/autoupdate: {}
        f:labels:
          .: {}
          f:kubernetes.io/bootstrapping: {}
      f:rules: {}
    manager: kube-apiserver
    operation: Update
    time: "2020-12-26T12:34:11Z"
  name: cluster-admin
  resourceVersion: "86"
  uid: 1d7ab229-0924-46f8-8cc1-255045a75fa4
rules: # clusterrole 은 네임스페이스 없이 권한을 모두 다 가지고 있음
- apiGroups:
  - '*'
  resources:
  - '*'
  verbs:
  - '*'
- nonResourceURLs:
  - '*'
  verbs:
  - '*'

clusterrolebindings admin 권한 조회

$ kubectl get clusterrolebindings.rbac.authorization.k8s.io | grep admin
cluster-admin                                          ClusterRole/cluster-admin                                                          25d
$ kubectl get clusterrolebindings.rbac.authorization.k8s.io cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: "2020-12-26T12:34:12Z"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  managedFields:
  - apiVersion: rbac.authorization.k8s.io/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:rbac.authorization.kubernetes.io/autoupdate: {}
        f:labels:
          .: {}
          f:kubernetes.io/bootstrapping: {}
      f:roleRef:
        f:apiGroup: {}
        f:kind: {}
        f:name: {}
      f:subjects: {}
    manager: kube-apiserver
    operation: Update
    time: "2020-12-26T12:34:12Z"
  name: cluster-admin
  resourceVersion: "146"
  uid: 915d20c6-5db1-40e9-865c-d4e6a8d582cd
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:masters # system 에서 먼저 등록이된 masters 에 예약된 그룹들은 여기 속함 kubectl 에서 찾을 수 없음

연습문제

  • john 유저에게 dev1 네임스페이스에 대한 포드, 레플리카셋, 디플로이먼트를 조회, 생성하고 삭제할 수 있는 권한을 부여하라

dev1 네임스페이스 생성

$ kubectl create ns dev1
namespace/dev1 created

dev1 네임스페이스 필요 권한 확인

$ kubectl get pod --user john -n dev1
Error from server (Forbidden): pods is forbidden: User "john" cannot list resource "pods" in API group "" in the namespace "dev1"

$ kubectl get rs --user john -n dev1
Error from server (Forbidden): replicasets.apps is forbidden: User "john" cannot list resource "replicasets" in API group "apps" in the namespace "dev1"

$ kubectl get deploy --user john -n dev1
Error from server (Forbidden): deployments.apps is forbidden: User "john" cannot list resource "deployments" in API group "apps" in the namespace "dev1"

https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-example

dev1-john-role-rolebinding.yaml 파일 생성

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev1
  name: deployment-manager
rules:
- apiGroups: ["", "apps"] # "" indicates the core API group 그룹 추가
  resources: ["pods", "replicasets", "deployments"] # 리소스 추가
  verbs: ["get", "watch", "list", "create", "update", "patch", "delete"] # 권한 추가

---

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: deployment-manager
  namespace: dev1
subjects:
# You can specify more than one "subject"
- kind: User
  name: john # "name" is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" specifies the binding to a Role / ClusterRole
  kind: Role #this must be Role or ClusterRole
  name: deployment-manager # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io

kubectl 로 role 과 rolebinding 생성

$ kubectl create -f dev1-john-role-rolebinding.yaml
role.rbac.authorization.k8s.io/deployment-manager created
rolebinding.rbac.authorization.k8s.io/deployment-manager created

user john 네임스페이스 dev1 로 deploy 조회시 리소스가 없다고 나옴

$ kubectl get deploy --user john -n dev1
No resources found in dev1 namespace.

john user 로 deployment 리소스 생성

$ kubectl create deploy http-go --image=gasbugs/http-go --user john -n dev1
deployment.apps/http-go created

john 에 부여한 리소스 접근 권한에 따라
pods, replicasets, deployments 리소스 조회가 가능한 것을 확인

$ kubectl get pod -n dev1 --as john
NAME                      READY   STATUS    RESTARTS   AGE
http-go-568f649bb-bwq5h   1/1     Running   0          90s

$ kubectl get rs -n dev1 --as john
NAME                DESIRED   CURRENT   READY   AGE
http-go-568f649bb   1         1         1       97s

$ kubectl get deploy -n dev1 --as john
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
http-go   1/1     1            1           104s

부여하지 않은 권한은 접근하지 못함

$ kubectl get secret -n dev1 --as john
Error from server (Forbidden): secrets is forbidden: User "john" cannot list resource "secrets" in API group "" in the namespace "dev1"

secrets 리소스를 추가

resources: ["pods", "replicasets", "deployments", "secrets"] # secrets 리소스 추가

kubectl 로 secrets 리소스를 추가한 변경사항을 적용

$ kubectl apply -f dev1-john-role-rolebinding.yaml
Warning: resource roles/deployment-manager is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
role.rbac.authorization.k8s.io/deployment-manager configured
Warning: resource rolebindings/deployment-manager is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
rolebinding.rbac.authorization.k8s.io/deployment-manager configured

secret 조회가 잘되는 것을 확인

$ kubectl get secret -n dev1 --as john
NAME                  TYPE                                  DATA   AGE
default-token-rmjcf   kubernetes.io/service-account-token   3      35m
728x90

댓글

💲 추천 글