클러스터 권한 제어

Kubernetes Service에서 제공하는 kubeconfig.yaml 인증 파일은 관리자 권한을 갖고 있기 때문에 Jenkins, Github Action와 같은 3rd-party 서비스를 사용할 때 보안 이슈가 발생할 수 있습니다. 이 서비스를 이용하는 경우 최소한의 권한으로 제한하여 사용하는 것을 권장합니다.

준비 사항

  • 운영 중인 클러스터, kubectl 설치 및 환경변수 설정이 필요합니다.
  • 클러스터 생성은 클러스터 생성하기를 참고하시기 바랍니다.
  • kubectl 설치 및 환경변수 설정은 kubectl 설치하기를 참고하시기 바랍니다.

Service Account, Role 및 Role Binding 만들기

Namespace 추가

테스트를 위한 namespace를 생성합니다.

$ kubectl --kubeconfig $KUBE_CONFIG create ns hello-world

Service Account 추가

$ cat <<EOF | kubectl --kubeconfig $KUBE_CONFIG apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: hello-user
  namespace: hello-world
EOF

Role / Role Binding 추가

Role의 resources, verbs에서 사용할 권한을 정의합니다. 다음 설정은 hello-world라는 namespace에 pod 리소스만 제어하도록 제한됩니다.

$ cat <<EOF | kubectl --kubeconfig $KUBE_CONFIG apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: hello-world
  name: hello-role
rules:
- apiGroups: [""]
  resources: ["pods"] # Object 지정
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # Action 제어 
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: hello-world
  name: hello-rb
subjects:
- kind: ServiceAccount
  name: hello-user
  namespace: hello-world
roleRef:
  kind: Role 
  name: hello-role
  apiGroup: rbac.authorization.k8s.io
EOF

Service Account Token 확인

$ kubectl --kubeconfig $KUBE_CONFIG -n hello-world describe secret $(kubectl --kubeconfig $KUBE_CONFIG -n hello-world get secret | grep hello-user2 | awk '{print $1}')
Name:         hello-user-token-6zjw7
Namespace:    hello-world
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: hello-user
              kubernetes.io/service-account.uid: 9546d5be-1b27-11ea-8845-f220cdab2dde

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1029 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSU...

Token으로 인증하는 kubeconfig-token.yaml 생성

다운로드한 kubeconfig.yamlkubeconfig-token.yaml로 복사한 후 kubeconfig-token.yaml 의 user에 client-certificate-data, client-key-data 부분을 제거합니다.

$ cp kubeconfig.yaml kubeconfig-token.yaml
$ vi kubeconfig-token.yaml
apiVersion: v1
clusters:
...
users:
- name: kubernetes-admin
  user:
    client-key-data:  LS0tLS1CRUdJTiBDRV...
    client-certificate-data: LS0tLS1CRUdJTiB...

user 부분을 삭제한 후 이전 단계에서 확인한 Token 정보를 다음과 같이 추가합니다.

$ cat kubeconfig-token.yaml
apiVersion: v1
clusters:
...
users:
- name: kubernetes-admin
  user:
    token:  eyJhbGciOiJSU... # Service Account Token 추가

권한 확인

Token을 이용하여 Kubernetes API 호출 시 정상적으로 권한을 제한하는지 확인합니다.

  • kubeconfig-token.yaml를 환경변수로 선언
$ export KUBE_CONFIG_TOKEN=kubeconfig-token.yaml
  • Pod 객체 조회 (접근 가능)
$ kubectl --kubeconfig $KUBE_CONFIG_TOKEN -n hello-world get pod
No resources found in hello-world namespace.
  • Deployment 객체 조회 (접근 불가능)
$ kubectl --kubeconfig $KUBE_CONFIG_TOKEN -n hello-world get deploy
Error from server (Forbidden): deployments.extensions is forbidden: User "system:serviceaccount:hello-world:hello-user" cannot list resource "deployments" in API group "extensions" in the namespace "hello-world"
  • 다른 namespace 조회 (접근 불가능)
$ kubectl --kubeconfig $KUBE_CONFIG_TOKEN get pod
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:hello-world:hello-user" cannot list resource "pods" in API group "" in the namespace "default"

""에 대한 건이 검색되었습니다.

    ""에 대한 검색 결과가 없습니다.

    처리중...