🥞 BE
home

Ch13. 인증과 권한 관리

목차
쿠버네티스 클러스터에 접근할 때는 허가받은 사용자인지 확인하는 인증 과정이 필요하다. 또한 인증받은 사용자에게 특정 자원의 사용 권한을 부여하는 방법인 권한 관리도 필요하다.

13.1 인증

사용자가 쿠버네티스의 API에 접근하려면 인증을 거쳐야 한다. 외부에서 쿠버네티스의 API에 접근할 수 있는 기본 포트는 6443이고 TLS 인증이 적용되어 있다. 6443 포트에 접근해 통신하려면 kube-apiserver에 있는 인증서와 클라이언트에 있는 인증서 사이의 검증을 통과해야 한다.
쿠버네티스는 일반적인 사용자 계정서비스 계정으로 인증을 요청한다.
일반적인 사용자 계정
구글 계정
키스톤
LDAP 등
외부 인증 시스템에 있는 사용자 정보를 연결해 사용. 쿠버네티스는 기본적으로 사용자 정보를 저장 X.
서비스 계정 - 쿠버네티스가 직접 관리하는 사용자 계정

13.1.1 kubectl의 config 파일에 있는 TLS 인증 정보 구조 확인하기

쿠버네티스는 kube-apiserver와 통신할 때의 기본 인증 방법으로 TLS(Transport Layer Security)를 사용한다. TLS인증은 통신할 때 오가는 패킷을 암호화 한다.
보통 HTTPS 웹 서버를 설정할 때는 서버에만 인증서를 설정하면 보안 통신이 가능하다. 하지만 TLS인증은 서버 뿐만 아니라 클라이언트가 유효한지도 검증하는 기능이 있다. 그래서 kube-apiserver에 있는 인증서와 연결되는 클라이언트 인증서를 이용해 접속한다.
사용자 홈 디렉터리에 있는 .kube 디렉터리의 config 파일에 인증 정보가 있다. kubectl config 명령으로 인증 정보를 설정하거나 인증 내용을 조회할 수 있다.
apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tLS1CRUdJTiB... server: https://kubernetes.docker.internal:6443 name: docker-desktop contexts: - context: cluster: docker-desktop user: docker-desktop name: docker-desktop current-context: docker-desktop kind: Config preferences: {} users: - name: docker-desktop user: client-certificate-data: LS0tLS1CRUdJTiB... client-key-data: LS0tLS1CRUdJTiB...
YAML
복사
config
다른 템플릿처럼 .apiVersion 필드가 맨 처음에 있다. 그 다음에 클러스터 관련 설정인 .clusters[] 필드가 위치한다. 하위 필드는 다음과 같다.
cluster.certificate-authority-data : 클러스터 인증에 필요한 해시값을 설정, 여기에서는 TLS 인증 기반의 해시값을 설정했다.
cluster.insecure-skip-tls-verify : config 파일에서는 생략되었지만 필드 값을 true로 설정하면, 사용하는 인증서가 공인 기관의 인증서인지 검증하는 과정을 건너뛴다.
cluster.server : 외부에서 쿠버네티스 API에 접속할 주소를 설정, 현재 도커 데스크탑을 사용하므로 https://localhost:6443을 설정했다. 외부의 쿠버네티스에 접근하려면 해당 url을 외부 쿠버네티스의 kube-apiserver 접근 주소로 변경한다.
name : 클러스터의 이름을 설정
.contexts[] 필드는 사용자나 네임스페이스를 연결하는 설정이다. 클러스터 설정처럼 상황에 따라 여러 개의 컨텍스트 설정이 있을 수도 있다. 하위 필드는 다음과 같다.
context.cluster : 접근할 클러스터를 설정
context.user : 클러스터에 접근할 사용자 그룹이 누구인지를 설정
context.namespace : config 파일에서는 생략되었지만 default 네임스페이스가 아닌 특정 네임스페이스를 설정
name : 컨텍스트의 이름
.current-context 필드는 .contexts 필드가 여러 개 있을 때 무엇을 선택해서 클러스터에 접근할지 결정한다. kubectl config set-context <컨텍스트이름> 명령으로 컨텍스트를 변경해서 다양한 클러스터에 다양한 사용자로 접근해서 사용할 수 있다.
name : 사용자 그룹의 이름을 설정
user.client-certificate-data : 클라이언트 인증에 필요한 해시값을 설정
user.client-key-data : 클라이언트의 키 해시값을 설정

13.1.2 서비스 계정 토큰을 이용해 인증하기

config 파일의 .user 필드를 TLS 인증이 아닌 서비스 계정을 사용하도록 변경한다.
먼저 kubectl get serviceaccount 명령으로 현재 서비스 계정을 확인하면, 기본 서비스 계정인 default를 볼 수 있다.
서비스 계정은 시크릿을 할당하므로 kubectl get serviceaccount default -o yaml 명령으로 default에 연결된 시크릿을 확인한다.
default-token-6746t이라는 시크릿을 확인할 수 있다.
다음으로 kubectl describe secret <시크릿이름> 명령으로 시크릿의 상세 내용을 확인한다.
token 항목에는 토큰 해시값을 확인할 수 있고 ca.crt 항목에서 인증서 용량을 확인할 수 있다.
이번에는 ~/.kube/config 파일의 .user 필드에 사용자 계정의 정보를 추가한다. 이때 token 항목의 해시값을 이용한다.
apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tLS1CRUdJTiB... server: https://kubernetes.docker.internal:6443 name: docker-desktop contexts: - context: cluster: docker-desktop user: default name: docker-desktop current-context: docker-desktop kind: Config preferences: {} users: - name: docker-desktop user: client-certificate-data: LS0tLS1CRUdJTiB... client-key-data: LS0tLS1CRUdJTiB... - name: default user: token: eyJhbGci0iJSU...
YAML
복사
변경 후 kubectl get pods --v=7 명령을 입력한다. --v=7 옵션은 디버그용 내용을 출력하므로 방금 변경한 서비스 계정 정보를 이용하는지 확인할 수 있다.
Authorization 항목을 살펴보면 Bearer <masked> 이다. 앞에서 입력한 token 항목의 해시값을 이용해서 요청했다는 뜻이다. 마지막에는 파드 내역이 정상적으로 조회된다. 만약 해시값을 잘못 넣으면 “error: You must be logged in to the server (Unauthorized)” 라는 인증 실패 메시지를 확인할 수 있다.

13.2 권한 관리

인증 후에는 사용자가 접근하려는 API를 사용할 권한이 있는지 확인 후 API를 사용할 수 있다.
클러스터 하나를 여러 명이 사용할 때는 API나 네임스페이스별로 권한을 구분해서 권한이 있는 곳에만 접근하게 만들 수 있다. 특정 자원의 읽기 전용 권한만 추가해 다른 사람이 관리하는 네임스페이스를 참고용으로 살펴보게 할 수도 있다.
쿠버네티스의 권한 관리 방법
ABAC (Attribute-Based Access Control)
RBAC (Role-Based Access Control)
ABAC는 속성 기반의 권한 관리이다. 사용할 수 있는 속성에는 사용자(user), 그룹(group), 요청 경로(request path), 요청 동사(request verb) 등이 있다. 권한 설정 내용을 파일로 관리하므로 권한을 변경하려면 직접 마스터에 접속해서 파일을 변경한 후 kube-apiserver 컴포넌트를 재시작해야 하므로 관리하기 번거롭다.
RBAC는 역할 기반 권한 관리이다. 대부분의 권한 관리 시스템에서 많이 사용한다. 사용자와 역할을 별개로 선언한 후 두 가지를 조합(binding)해서 사용자에게 권한을 부여한다. RBAC는 ABAC처럼 마스터에 접근할 필요 없이 kubectl이나 API를 이용해 관리할 수 있다.

13.2.1 롤

롤(Role)특정 API나 자원 사용 권한들을 명시해둔 규칙의 집합이다. 일반 롤과 클러스터롤 두 가지가 있다.
일반 롤은 해당 롤이 속한 네임스페이스에만 적용된다. 추가로 네임스페이스에 한정되지 않은 자원과 API들의 사용 권한을 설정할 수 있다.
롤 설정 예시
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: default name: read-role rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list"]
YAML
복사
rbac/read-role.yaml
.kind 필드 값에는 롤을 의미하는 Role을 설정했고, .apiVersion 필드 값으로는 쿠버네티스의 RBAC 권한 관리 기능을 뜻하는 rbac.authorization.k8s.io/v1을 설정했다. .metadata.namespace 필드 값에는 이 롤이 속한 기본 네임스페이스인 default를 설정하고 .metadata.name 필드 값으로는 이 롤의 이름을 뜻하는 read-role을 설정한다.
.rules[] 필드에는 이 롤이 갖는 권한의 규칙을 구체적으로 설정한다.
apiGroups : 롤이 사용할 API 그룹들을 설정
resources : 어떤 자원에 접근할 수 있는지 명시
verbs : 어떤 동작을 할 수 있는지 설정
.rules[].verbs 필드에 설정할 수 있는 주요 값
.rules[].verbs 필드 값
설명
create
새로운 자원 생성
get
개별 자원 조회
list
여러 개 자원 조회
update
기존 자원 내용 전체 업데이트
patch
기존 자원 중 일부 내용 변경
delete
개별 자원 삭제
deletecollection
여러 개 자원 삭제
watch
개별 자원 혹은 자원 모음 관찰
설정 후, yaml파일을 클러스터에 적용한다.
특정 파드에만 규칙을 설정할수도 있는데, 이때는 .rules[] 필드 하위에 .resourceNames:[”특정파드이름”] 을 추가한다.
rules: - apiGroups: [""] resources: ["pods"] resourceNames: ["mypod"] verbs: ["get", "list"]
YAML
복사
.rules[].resourceNames 필드를 설정하면 get, update, delete, patch 등의 .rules[].verb 필드 값은 .rules[].resourceNames 필드에 설정된 자원에만 적용된다.

13.2.2 클러스터롤

클러스터롤(ClusterRole)은 특정 네임스페이스 사용 권한이 아닌 클러스터 전체 사용 권한을 관리한다.
클러스터롤 설정 예시
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: read-clusterrole rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list"]
YAML
복사
rbac/read-clusterrole.yaml
.kind 필드 값은 ClusterRole로 설정했고, .apiVersion 필드 값은 RBAC를 사용한다.
.metadata 필드가 롤과 다른 점은 하위에 .namespace 필드가 없다는 것이다. 클러스터롤은 전체 네임스페이스에 적용하므로 네임스페이스를 별도로 명시하지 않는 것.
클러스터롤은 .aggregationRule 필드를 이용해 다른 클러스터롤을 조합해 사용할 수 있다.
aggregationRule 필드 설정 예시
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: admin-aggregation aggregationRule: clusterRoleSelectors: - matchLabels: kubernetes.io/bootstrapping: rbac-defaults rules: []
YAML
복사
rbac/clusterrole-aggregation.yaml
쿠버네티스의 다른 컨트롤러와 비슷하게 클러스터롤에서도 레이블을 설정하고 .aggregation 필드에서 레이블을 선택해 사용하는 것이다. 여기서는 기본 레이블인 kubernetes.io/bootstrapping: rbac-defaults 를 사용했다. .rules 필드에는 아무 설정도 하지 않았는데, 레이블에 맞는 다른 클러스터롤에서 필요한 규칙들을 불러오기 때문.
마지막 클러스터롤의 자원이 아니라 URL 형식으로 규칙을 지정할 수 있다는 것이다.
rules: - nonResourceURLs: ["/healthcheck", "/metrics/*"] verbs: ["get", "post"]
YAML
복사
여기서는 "/healthcheck"로 헬스 체크용 URL 접근을 설정했고, “/metrics/*"로 설정해서 metric/cpu나 metric/memory 등의 여러가지 메트릭을 불러올 수 있는 경로를 한 번에 설정했다. URL요청을 관리하므로 .verbs 필드 값은 “get”“post”만 사용할 수 있다.

13.2.3 롤바인딩

롤바인딩(RoleBinding)은 롤과 사용자를 묶는 역할이다. 사용자가 어떤 롤을 사용하는지 설정한다. 권한을 롤과 클러스터로 구분하는 것처럼 바인딩도 롤바인딩과 클러스터롤바인딩으로 구분한다.
롤에 바인딩할 사용자 설정
apiVersion: v1 kind: ServiceAccount metadata: name: myuser namespace: default
YAML
복사
롤바인딩 설정 예시
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: read-rolebinding namespace: default subjects: - kind: ServiceAccount name: myuser apiGroup: "" roleRef: kind: Role name: read-role apiGroup: rbac.authorization.k8s.io
YAML
복사
rbac/read-rolebinding.yaml
.kind 필드 값은 롤바인딩을 뜻하는 RoleBinding을 설정.
.metadata.name 필드 값은 롤바인딩의 이름을 read-rolebinding으로 설정.
.metadata.namespace 필드 값은 default 네임스페이스를 설정해 사용하도록 명시.
.subjects 필드는 어떤 유형의 사용자 계정과 연결하는지 설정한다. .subject.kind[] 필드 값은 ServiceAccount로 설정했고, .subject.name에는 서비스 계정의 이름인 myuser를 설정.
apiGroup""로 설정했다. ""는 핵심 API 그룹으로 설정했다는 뜻.
.roleRef 필드에서는 사용자에게 어떤 롤을 할당할지를 설정한다. .roleRef.kind 필드 값으로는 Role과 ClusterRole을 설정할 수 있는데 여기에서는 롤을 할당할 것이므로 Role을 설정했다. .roleRef.apiGroup 필드 값은 사용하려는 API를 설정하므로 RBAC API를 뜻하는 rbac.authorization.k8s.io를 설정.

13.2.4 클러스터롤바인딩

클러스터롤바인딩(ClusterRoleBinding) 클러스터롤과 사용자를 묶는다.
클러스터롤바인딩 설정 예시
kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: read-clusterrolebinding subjects: - kind: ServiceAccount name: myuser namespace: default apiGroup: "" roleRef: kind: ClusterRole name: read-clusterrole apiGroup: rbac.authorization.k8s.io
YAML
복사
rbac/read-clusterrolebinding.yaml
롤바인딩과 대부분 비슷하지만, 차이점이라고 할 만한 부분은 .kind 필드 값을 ClusterRoleBinding으로 설정, .subject[].kind 필드 값은 ServiceAccount를 설정한 것이다. User, Group, ServiceAccount를 설정할 수 있으며, 이중 User와 ServiceAccount는 네임스페이스 정보가 필요하다. Group은 클러스터 전체에 사용할 수 있으므로 따로 네임스페이스를 명시하지 않아도 된다.

13.2.5 다양한 롤의 권한 관리 확인하기

롤과 롤바인딩, 클러스터롤과 클러스터롤바인딩의 관계
롤바인딩은 사용자의 롤을 묶어서 특정 네임스페이스에 권한을 할당하고, 클러스터롤바인딩은 사용자와 클러스터롤을 묶어서 쿠버네티스 클러스터에 권한을 할당한다.