K8s 클러스터는 물론 혼자서 사용하는 환경이 아니다.
다양한 서비스를 배포할 수 있고, 한명의 개발자가 여러개의 서비스/여러명의 사용자가 하나의 서비스를 관리할 수 있는 것이다.
클러스터의 규모가 커짐에 따라 사용자들의 역할 분리는 필수적이다.
1팀의 팀원이 실수로 2팀의 자원을 날려먹는 일과 같은
적절치 못한 접근에 제한을 주어 불미스러운 일이 발생하지 않도록 방지하는 것을 예로 들 수 있겠다.
우리가 클러스터 상에서 kubectl을 사용해 수행하는 모든 명령들은 K8s 클러스터를 관리하는데에 중추 역할을 하는 API Server로 통한다.
요청에서 응답까지 거치는 API Server의 내부 레이어 중에선 사용자의 신원을 파악하고 권한을 부여하는 Authenticating, Authorizing과 같은 과정을 거친다.
정확히 어떤 방법을 사용하는지는 다음에서 참고할 수 있다.
https://coffeewhale.com/kubernetes/authentication/x509/2020/05/02/auth01/
k8s 인증 완벽이해 #1 - X.509 Client Certs
쿠버네티스를 지금까지 사용해 오면서 어렴풋이만 인증서와 토큰을 이용하여 사용자 인증을 하는지는 알고 있엇지만 그 이상 다른 방법에 대해서는 자세히 몰랐었습니다. 쿠버네티스 공인 자
coffeewhale.com
https://coffeewhale.com/kubernetes/authentication/http-auth/2020/05/03/auth02/
k8s 인증 완벽이해 #2 - HTTP Authentication
쿠버네티스 인증 완벽 이해 시리즈 2탄, HTTP Authentication을 이용한 쿠버네티스 인증에 대해서 살펴보는 시간을 가져 보겠습니다.
coffeewhale.com
이러한 접근을 K8s에선 주체(사용자, 계정)의 역할에 기반하여 관리한다.
이를 RBAC(Rule-Based Access Control) Authorization; 역할 기반 접근 제어 방식이라 부른다.
주체가 접근 허가를 받기 위해선 역할을 미리 정의해주어야 한다,
Role/RoleBinding, ClusterRole/ClusterRoleBinding
K8s에선 이 역할을 정의하고, 주체와 역할을 연결할 수 있다.개발자 김씨가 회사의 구성원이란 역할과 집안의 가장이란 역할을 가지고 있으면, 회사와 집 모두 들어갈 수 있는 것처럼 말이다.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: 프로젝트A의-네임스페이스
name: 개발자
rules:
- apiGroups: ["", "apps", "batch", "autoscaling"]
resources: ["*"]
verbs: ["*"]
Role 자원을 통해서 역할을 정의할 수 있다. 역할이 접근할 수 있는 자원, 즉 접근 가능한 API를 apiGroups, resources, verbs의 목록으로 포함한다. K8s에서 제공하는 API들을 상당히 많다. 여기서 참고하면 된다.https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#-strong-api-groups-strong-
Kubernetes API Reference Docs
API Overview Welcome to the Kubernetes API. You can use the Kubernetes API to read and write Kubernetes resource objects via a Kubernetes API endpoint. Resource Categories This is a high-level overview of the basic types of resources provide by the Kuberne
kubernetes.io
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: 개발자김씨
namespace: 프로젝트A의-네임스페이스
subjects:
- kind: User
name: 김씨
roleRef:
kind: Role
name: 개발자
apiGroup: rbac.authorization.k8s.io
RoleBinding 자원은 Role 역할을 사용자 혹은 다른 주체에 연결해주는 역할을 한다.
만약 김씨가 프로젝트 B에서 관리자라면, 관리자 Role을 하나 더 생성하고 같은 사용자 주체인 김씨에게 RoleBinding 자원을 하나 더 생성해주면 되는것이다.
ClusterRole과 ClusterRoleBinding은 Role/RoleBinding과는 달리 Namespace를 명시하지 않는다. 클러스터 전체에 접근할 수 있는 역할을 부여하기 위해선 ClusterRole을 사용하면 된다.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: 데브옵스
rules:
- apiGroups: ["", "apps", "batch", "autoscaling", "networking.k8s.io", "scheduling.k8s.io"]
resources: ["*"]
verbs: ["*"]
기본적으론 namespace의 유무 뺴고는 Role과 많이 다를 게 없다.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: 데브옵스권씨
subjects:
- kind: User
name: 권씨
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: 데브옵스
apiGroup: rbac.authorization.k8s.io
ClusterRoleBinding 또한 마찬가지이다.
ClusterRole에선 특정 label을 통해 rule을 정의하는 방식도 있는데, ClusterRole을 정의하는 중요한 이유중 하나가 아닌가 생각한다.
https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles
Using RBAC Authorization
Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within your organization. RBAC authorization uses the rbac.authorization.k8s.io API group to drive authorization decis
kubernetes.io
User, Group, ServiceAccount
이렇게 역할을 생성하면 사용자가 API server를 통해 특정 자원에 접근할 수 있는 권한이 주어지게 된다.
그런데, 주체가 없으면 권한도 쓸모가 없다.
K8s애선 크게 3가지의 분류를 통해 권한의 주체를 설정하도록 해준다.
User와 Group은 K8s 클러스터를 처음 생성했을 때 이미 만들어져있다.
kubectl config view
명령어를 통해 Context를 확인할 수 있는데, 맨 밑에 users: 라고 나와있는 영역이 보일것이다.
kubernetes-admin 이라는 사용자가 K8s 클러스터의 기본 사용자이다.
kubectl get clusterrolebinding -o wide
system:masters 란 그룹도 이미 생성되어있는것을 확인할 수 있다. 이 외에도 Group에는 이미 생성된 그룹이 몇가지 더 있다.
하지만 config 에서 그 존재를 확인할 수 있는 것과는 달리, User와 Group이라는 자원은 존재하지 않는다.
이들은 K8s에서 추상적으로 존재하는 자원이며, kubectl을 통해 생성할 수 없다.
그러면 이들은 어디서 어떻게 인증을 받을 수 있고 권한이 주어질 수 있는걸까?
답은 앞서 언급된 사용자의 인증서에 있다.
https://coffeewhale.com/kubernetes/authentication/x509/2020/05/02/auth01/
k8s 인증 완벽이해 #1 - X.509 Client Certs
쿠버네티스를 지금까지 사용해 오면서 어렴풋이만 인증서와 토큰을 이용하여 사용자 인증을 하는지는 알고 있엇지만 그 이상 다른 방법에 대해서는 자세히 몰랐었습니다. 쿠버네티스 공인 자
coffeewhale.com
K8s의 서명으로 직접 인증 된 인증서에 사용자의 이름과 속한 그룹이 포함되어 있다.
K8s에 사용자를 등록하는 방법은 다음과 같다.
1. 사용자의 개인 키를 생성한다.
openssl genrsa -out my-user.key 2048
2. 생성한 사용자의 key로 CSR(Certification Signing Request); 서명 요청서를 생성한다.
여기서 사용자의 이름과 속한 그룹을 명시할 수 있다.
사용자의 이름은 my-user, 속한 그룹은 my-maintainers, my-developers일 때, 다음과 같이 CSR을 생성할 수 있다.
openssl req -new -key my-user.key -out my-user.csr -subj "/CN=my-user/O=my-maintainers/O=my-developers"
3. CSR에 CA(Certification Authority); 인증기관의 서명을 받는다.
여기선 CA는 Kubernetes가 된다.
서명을 위해선 인증기관의 key와 crt가 필요한데, 일반적으로 /etc/kubernetes/pki 디렉토리에서 찾아낼 수 있다.
대부분의 경우에 sudo로 root 권한을 주어야 할 것이다.
openssl x509 -req -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -days 730 -in my-user.csr -out my-user.crt
4. 생성된 인증서를 사용자에게 부여한다.
kubectl config set-credentials my-user --client-certificate=path/to/my-user.crt --client-key=path/to/my-user.key
사용자를 생성하고 로그인 하기 위해선 context를 새로 생성하고 use-context를 통해 프로필을 사용하면 된다.
kubectl config set-context my-user@kubernetes --cluster=kubernetes --user=my-user --namespace=my-namespace
kubectl config use-context my-user@kubernetes
앞서 Role과 RoleBinding을 생성하지 않았다면 API server에게서 자원 접근 권한을 얻을 수 없으니, context를 바꾸기 전에 생성해주어야 할 것이다.
ServiceAccount는 User와는 개념이 살짝 다르다.
User는 사용자 중심, ServiceAccount는 서비스 중심의 개념이다.
개발한 서비스의 부하에 따라 pod의 auto scaling 기능을 추가하는 경우, 해당 서비스에게 pod을 새로 생성하거나 자원을 조회하는 권한을 주는것을 예로 들 수 있다.
K8s 1.24버전 이전까지는 ServiceAccount를 생성하면 자동으로 Secret을 생성해주었는데, 이후 버전 부터는 직접 생성해야 한다.
apiVersion: v1
kind: ServiceAccount
metadata:
name: 오토스케일링봇
namespace: 프로젝트B
apiVersion: v1
kind: Secret
metadata:
name: 오토스케일링봇-시크릿
namespace: 프로젝트B
annotations:
kubernetes.io/service-account.name: 오토스케일링봇
type: kubernetes.io/service-account-token
이렇게 생성한 ServiceAccount는 Role 및 ClusterRole 역할 정의 후 Pod에게 적용줄 수 있다.
apiVersion: v1
kind: Pod
metadata:
name: 오토스케일링앱
spec:
serviceAccountName: 오토스케일링봇
...
'Today I Learned > 쿠버네티스' 카테고리의 다른 글
Kubernetes 클러스터 구축 초요약본 (1) | 2023.08.09 |
---|