[k8s] 계정, 인증과 권한

k8s에서 계정을 만들고, 권한을 제어하는 방법을 정리한다.

k8s는 기본적으로 토큰 방식의 인증 방식을 제공하며, RBAC에 기반한 섬세한 인가-권한 제어 방식을 지향한다.

그림으로 표현하면 이렇다.

https://medium.com/rahasak/kubernetes-role-base-access-control-with-service-account-e4c65e3f25cc

  1. ServiceAccount라는 단위를 통해 계정을 관리한다.
  2. 행위 기반으로 Role을 정의한다. Pod를 조회할 수만 있다든지 하는 실제 행동의 범위를 제약한다.
  3. ServiceAccount와 Role을 RoleBinding으로 연결한다.
  4. ServiceAccount는 RoleBinding을 통해 연결된 Role의 행위만을 허가받고 사용할 수 있다.

한번 직접 계정과 권한을 만들어서 접속해보고, 외부접속까지 해보는 시간을 가져보겠다.




ServiceAccount

ServiceAccount는 말 그대로 계정을 관리하는 리소스 단위다.
딱히 뭘 직접 만든게 아니라도

기본적으로 생성되어있는 계정은 많을 것이다.



apiVersion: v1
kind: ServiceAccount
metadata:
  name: testaccount
  namespace: default




ServiceAccount - Secret Token

k8s 1.24 버전 이전에서는 ServiceAccount를 만들면 토큰을 자동으로 만들어줬지만, 1.24부터는 보안상의 이유로 직접 만들게끔 바뀌었다.

그래서 아무리 조회해봐도

토큰이 나오지는 않을 것이다.

아래와 같이 시크릿 리소스를 정의해서

apiVersion: v1
kind: Secret
metadata:
  name: test-secret
  namespace: default
  annotations:
    kubernetes.io/service-account.name: testaccount
type: kubernetes.io/service-account-token

만들어주면


동기화가 될 것이다.


그럼 토큰 정보를 가져다가 쓸 수 있다.




Rest API로 호출해보기

토큰이 있으면 외부에서도 찔러서 사용해볼 수 있다.

k8s 클러스터의 엔드포인트를 모른다면, kubectl config view 명령으로 바로 확인할 수 있다.

이제 저기다 찔러보자.

이런 식으로 헤더에 토큰을 담아서 보내면

curl --insecure -H "Authorization: Bearer 토큰" https://IP:6443/apis

잘 호출되어야 한다.
이 apis라는 api는 그냥 api 목록을 조회하는 것 뿐이라서 별 동작은 없다.

근데 어떻게 해도 pods를 조회하거나 하는 일반적인 기능들에 대해서는 사용이 불가능할 것이다.

이건 권한이 하나도 없어서 그렇다.




ClusterRole과 ClusterRoleBinding

k8s는 RBAC 방식으로 세밀한 권한제어를 제공한다.
AWS 같은 클라우드에서 IAM 기반 권한관리를 사용해봤다면, 그것과 원리가 거의 같다고 볼 수 있다.

먼저 ClusterRole을 통해서 어떤 리소스에 대해서 어떤 행위를 할 수 있는지를 정의해야 한다.

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: testrole
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - 'list'
  - 'get'

이러면 pods list와 describe pods를 할 수 있는 역할이 된다.

그러면 이제 저 Role와 ServiceAccount를 연결해서 Account에 권한이 부여될 수 있도록 해야 한다.
이런 매핑은 ClusterRoleBinding이라는 리소스를 통해서 처리할 수 있다.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: test-rolebinding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: testrole
subjects:
- kind: ServiceAccount
  name: testaccount
  namespace: default

testaccount와 testrole를 연결하기만 하는 단순한 정의다.

이걸 먹여주면

이제 pods list는 잘 동작할 것이다.

이런 느낌으로 쓰면 된다.



참조
https://kubernetes.io/docs/reference/access-authn-authz/authentication/
https://kubernetes.io/ko/docs/tasks/access-application-cluster/access-cluster/