Kubernetes 인증과 권한 관리
인증과 권한관리
- Authentication: 접속한 사용자의 신분을 시스템이 인증하는 단계(신분증 확인)
- Authorization: 사용자가 어떤 권한 가지고 무슨 작업할 수 있는지 확인하는 단계
(view권한, create권한, edit 권한등) - Admission Controllers: 인증과 권한 확인 이후 추가적으로 요청 내용에 대한 검증이나 요청 내용을 강제로 변경할 때 사용
일반 사용자
클러스터 외부에서 쿠버네티스를 이용하는 사용자 (다양한 방법 인증 필요, key stone)
서비스 계정
내부적으로 관리되고 pod, 오브젝트끼리 api 다룰때 사용하는 사용자
주어진 권한에 따라 deploy pod 사용
이 포트를 이용 통신하기 위해서 kube-apiserver에 있는 인증서와 클라이언트에 있는 인증서 사이의 검증을 통과해야 한다. 클라이언트의 인증서는 일반적인 경우 .kube/config 파일에 저장되어 있다.
서비스 계정 및 일반 사용자의 권한은 RBAC(role based access control) 메커니즘을 통해 제어된다 . RBAC은 역할 (Role) 에 따라 리소스에 대한 권한을 제어하는 기능이자 개념으로 특정 사용자와 역할 (Role) 두가지를 조합하여 사용자에게 특정 권한을 부여 한다.
일반 사용자: 클러스터 외부에서 Kubernetes를 이용하는 사용자로 다양한 방법으로 인증을 거친다. 개발자 및 실무자가 Kubernetes를 이용하기 위해 사용하거나 Kubernetes 클러스터 외부로부터 들어오는 접근을 관리하기 위한 사용자이다 . 배포와 관련된 서비스나 디플로이먼트의 접근 권한을 일부 사용자에게만 허용하거나 Pod의 로그 열람 권한을 다른 일반 사용자에게 허용하는 등의 정책을 일반 사용자에게 권한 부여 할 수 있다.
서비스 계정 (ServiceAccount): Kubernetes 내부적으로 관리되며 Pod 가 Kubernetes API 를 다룰 때 사용하는 사용자로 주어진 권한에 따라 Kubernetes 리소스 Pod, Deployment 등 를 다룰 수 있다 이 계정은 애플리케이션을 통해 Kubernetes 사용을 통제할 수 있다는 점이 장점이다. 각 서비스 계정에는 Secret이 할당되어 비밀번호의 역할을 담당한다.
Role : 각 Kubernetes API 사용 권한 정의 하며 네임스페이스 안에서만 유효
RoleBinding : 일반 사용자 및 그룹 서비스 계정과 Role 연결
Cluster Role : 각 Kubernetes API 사용 권한 정의 하며 클러스터 전체에서 유 효
ClusterroleBinding : 일반사용자 및 그룹 서비스 계정과 ClusterRole 연결
Role => verb
roleBinding => resource
Default ClusterRole |
Default ClusterRoleBinding |
|
cluster-admin | system: Masters group | Kubernetes 클러스터에 대해서 수퍼사용자 권한을 부여한다. ClusterRoleBinding 을 이용해서 Role을 연결할 경우 모든 네임스페이스와 모든 리소스에 대한 권한을 부여한다. RoleBinding을 이용하여 Role을 부여하는 경우 해당 네임스페이스에 있는 리소스에 대한 모든 제어 권한을 부여한다 . |
admin | None | 관리자 권한의 Access를 제공한다. RoleBinding을 이용한 경우 해당 네임스페이스에 대한 대부분의 리소스에 대한 Access를 제공한다. 새로운 Role을 정의하고 RoleBinding을 정의하는 권한을 갖지만 resource quota에 대한 조정 기능은 없다. |
edit | None | 네임스페이스 내 객체를 읽고 쓰는 기능은 가지지만, role이나 rolebinding을 쓰거나 수정하는역할은 제외된다. |
view | None | 해당 네임스페이스 내 객체에 대한 읽기 기능을 갖는다. role이나 rolebinding을 조회하는 권한은 없다. |
ServiceAccount를 사용한 인증과 RBAC
1. deployment 생성
$ vi deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-deployment
labels:
app: user-deployment
spec:
replicas: 2
selector:
matchLabels:
app: user-deployment
template:
metadata:
labels:
app: user-deployment
spec:
containers:
- name: user-deployment
image: nginx
ports:
- containerPort: 80
$ kubectl apply -f deployment.yaml
2. Clusterrole 생성
$ vi clusterrole.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: user-clusterrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
3. ServiceAccount, Context 생성 및 등
1) ServiceAccount 생성
$ kubectl create sa dev-user
$ vi user-token.yaml
apiVersion: v1
kind: Secret
metadata:
name: dev-user-token
annotations:
kubernetes.io/service-account.name: dev-user
type: kubernetes.io/service-account-token
$ kubectl apply -f user-token.yaml
$ kubectl describe secret dev-user-token

2) Context 생성
$ kubectl config set-credentials dev-user --token=\
eyJhbGciOiJSUzI1NiIsImtpZCI6Im1Sc2VSWWFTVUJaYkZkZ3JRd3cyaWpTWkI2dnJPZk52ZUo5b0dRZXNTUWsifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRldi11c2VyLXRva2VuIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRldi11c2VyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiMjk0NTMwYTctYTJlZC00MDIyLWIxMmEtODdmNzEwYTYxZTFlIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6ZGV2LXVzZXIifQ.hb7uCDBfsD8HNAaYVoLbGWjKI-0HvjUdAsd20Kchkk_LXmKx0s9_hBdnk3nJoioRtx7dufkbwKZLywMirDL4YL31LOqrsL0xwDBwHpsfPecOXmiyhUZ1q2h-3lYr_ewW-TYgg8E0Zm4_IL0Z_kVmZdQrURKwpX-PK8N6Gm1U_-2GdbkXq02oIi_VB3V_Vsj4t1U6gsp6Mr12j4G6R9Lh32lOsYARuU4FFIqsjZBVa31C6gwvoyKA21KB6sytpE44keVWRuZecz94DWKcV6Et_7-9Ghb8uwFMUKOgz5b5Vo3wexdn5_eh9ImoDQmtsTOWeAQNwKL4L9C81vEY_26vRQ

$ kubectl config get-clusters

$ kubectl config set-context user-context --cluster=kubernetes --user=dev-user

$ kubectl config get-contexts

각 Context는 클러스터, 네임스페이스와 사용자라는 세가지 매개 변수를 가진다.
4. Clusterrolebinding
- RoleBinding은 Role과 사용자를 이어주는 역할을 한다.
$ vi clusterrole-bind.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: user-clusterrolebinding
subjects:
- kind: ServiceAccount
name: dev-user
namespace: default
apiGroup: ""
roleRef:
kind: ClusterRole
name: user-clusterrole
apiGroup: rbac.authorization.k8s.io
$ kubectl apply -f clusterrole-bind.yaml
$ k describe clusterrolebinding user-clusterrolebinding

SA Test
$ k confnig get-context
$ k config use-context user-context
$ k get pods
$ k get deploy
$ k config delete-context user-context
* Simple Role and RoleBinding
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: node-admin
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "watch", "list", "create", "delete"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: michelle-binding
subjects:
- kind: User
name: michelle
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: node-admin
apiGroup: rbac.authorization.k8s.io
X .509 기반으로 리눅스 일반 사용자 생성하기
1. 사용자 생성하기
$ useradd linux
$ passwd linux
$ mkdir /home/linux/.certs; cd /home/linux/.certs
2. 인증서 생성하기
$ openssl genrsa -out linux.key 2048
$ openssl req -new -key linux.key -out linux.csr \
-subj "/CN=linux/O=edu"
$ openssl x509 -req -in linux.csr \
-CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key \
-CAcreateserial -out linux.crt -days 365
3. namespace 생성하기
$ k create ns linux-space
$ k config set-context --current --namespace linux-space
4. Context 생성하기
$ kubectl config set-credentials linux \
--client-certificate=/home/linux/.certs/linux.crt \
--client-key=/home/linux/.certs/linux.key
$ kubectl config set-context linux-context \
--cluster=kubernetes --user=linux --namespace=linux-space
$ k config get-contexts
5. Role 생성하기
$ vi role.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: linux-role
namespace: linux-space
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch","create","update","delete","patch"]
- apiGroups: ["apps"]
resources: ["deployments","replicasets"]
verbs: ["get","list","watch","create","update","delete","patch"]
- apiGroups: [""]
resources: ["services"]
verbs: ["get","list","watch","create","update","delete","patch"]
$ k apply -f role.yaml
6. RoleBinding 생성하기
$ vi role-bind.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: linux-rolebinding
subjects:
- kind: User
name: linux
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: linux-role
apiGroup: rbac.authorization.k8s.io
$ k apply -f role-bind.yaml
$ k get rolebinding